I used to execute MVN deploy manually from Payment Spring Boot to Maven’s central repository, which is a bit “primitive” in the days of CI/CD. So I’ve been looking for a release tool that supports pipelining and automatically triggers a build release when I merge code. One free product that does this is Github Action.

Github Action

Github Action is a CI/CD service created by Github. It is intended to make it easy to automate all software development workflows. Build, test, and deploy code directly from GitHub. CI (continuous integration) consists of many operations, such as code merging, running tests, logging into remote servers, publishing to third-party services, and so on.

Today I will try to publish the Payment Spring Boot to Maven’s central repository using Github Action.

Expect effect

Trigger an effect that publishes the branches contained in the Release to Maven’s central repository when the repository releases a Release.

Read more:

A Release is a first-class object with Changelogs and binaries that can represent all project history up to a specific point in time beyond the Git architecture itself.

The premise condition

How to publish a project to the Maven central repository and the necessary conditions is not discussed here, but there are many tutorials on the web that you can search for. You can also refer to Payment Spring Boot’s POM.xml. Here are just a few of the key points you need:

  • OSSRH account.
  • GPG key information.

💡 Note: Both of these are sensitive data do not disclose to others, or your project may be controlled by others.

Github Action Secrets

In order to publish from Github Action, we need to make Github Action available with our GPG private key and OSSRH user information. To keep these sensitive messages safe, we can use Github Action Secrets to store them.

GPG details added

The GPG_PASSWORD is GPG’s Passphrase, which will definitely be mentioned in the Maven central repository tutorial. Note that the public key must be uploaded to the public key server.

The steps for obtaining GPG_SECRET are as follows:

  • Make sure you have a GPG environment and follow the other tutorials to configure the GPG key pairs.

  • Run GPG –list-secret-keys to see the list of keys and copy the ids you need

[root@192 ~]# gpg --list-secret-keys
/root/.gnupg/pubring.kbx
------------------------
sec   rsa2048 2020-07-27 [SC]
      8AC0AB86C34ADC6ED110A5A9E6730F4374866065
uid           felord (felord) <[email protected]>
Copy the code
  • performgpg -a --export-secret-keys KEY_ID(KEY_IDIs in the figure above8AC0ABTo export the private key, enter the password to protect the private key (GPG_PASSWORD). The following ciphertext will then appear:
-----BEGIN PGP PRIVATE KEY BLOCK---- ............ Ciphertext area............. -----END PGP PRIVATE KEY BLOCK-----Copy the code

That’s GPG_SECRET.

Modify the POM of the project

Then modify the project’s POM. XML file. I have proposed the template.


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <groupId>cn.felord</groupId>
    <artifactId>payment-spring-boot</artifactId>
    <version>1.0.9. RELEASE</version>
    <packaging>pom</packaging>
    <modelVersion>4.0.0</modelVersion>

    <name>payment-spring-boot</name>
    <description>wechat-pay and alipay sdk</description>
    <url>https://github.com/NotFound403/payment-spring-boot</url>

    <licenses>
        <license>
            <name>The Apache License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
            <comments>A business-friendly OSS license</comments>
        </license>
    </licenses>

    <developers>
        <developer>
            <name>felord</name>
            <email>[email protected]</email>
            <organization>felord.cn</organization>
        </developer>
    </developers>

    <scm>
        <tag>Payment - spring - the boot - 1.0.9. RELEASE</tag>
        <url>https://github.com/NotFound403/payment-spring-boot</url>
        <connection>scm:git:https://github.com/NotFound403/payment-spring-boot.git</connection>
        <developerConnection>scm:git:https://github.com/NotFound403/payment-spring-boot.git</developerConnection>
    </scm>

    <profiles>
        <! -- Deployment profile (required so these plugins are only used when deploying) -->
         <! -- The following tag cannot be changed -->
        <profile>
            <id>deploy</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                    </plugin>
                    <! -- GPG plugin -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

    <modules>
        <module>payment-spring-boot-autoconfigure</module>
        <module>payment-spring-boot-starter</module>
    </modules>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-boot.version>2.4.2</spring-boot.version>
        <aliy-pay-sdk.version>4.10.167. ALL</aliy-pay-sdk.version>
        <oss-starter.version>1.0.0. RELEASE</oss-starter.version>
        <lombok.verison>1.18.12</lombok.verison>
        <jackson.version>2.9.10</jackson.version>
        <bcprov.version>1.66</bcprov.version>
        <jackson.version>2.11.4</jackson.version>
        <httpclient.version>4.5.13</httpclient.version>
    </properties>

    <! -- The following tag cannot be changed -->
    <distributionManagement>
        <repository>
            <id>ossrh</id>
            <name>Nexus Release Repository</name>
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
        </repository>
        <snapshotRepository>
            <id>sonatype-nexus-snapshots</id>
            <name>Nexus Snapshot Repository</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>

    <dependencyManagement>
        <dependencies>
            <! Your project's dependencies are written here.
        </dependencies>
    </dependencyManagement>
         <! -- The following tag cannot be changed -->
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>3.1.0</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>jar-no-fork</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <version>3.2.0</version>
                    <configuration>
                        <show>private</show>
                        <nohelp>true</nohelp>
                        <charset>UTF-8</charset>
                        <encoding>UTF-8</encoding>
                        <docencoding>UTF-8</docencoding>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>compile</phase>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-gpg-plugin</artifactId>
                    <version>1.6</version>
                    <executions>
                        <execution>
                            <id>sign-artifacts</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>sign</goal>
                            </goals>
                            <configuration>
                                <! -- Prevent `gpg` from using pinentry programs -->
                                <gpgArguments>
                                    <arg>--pinentry-mode</arg>
                                    <arg>loopback</arg>
                                </gpgArguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.sonatype.plugins</groupId>
                    <artifactId>nexus-staging-maven-plugin</artifactId>
                    <version>1.6.8</version>
                    <extensions>true</extensions>
                    <configuration>
                        <serverId>ossrh</serverId>
                        <nexusUrl>https://oss.sonatype.org/</nexusUrl>
                        <autoReleaseAfterClose>false</autoReleaseAfterClose>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.sonatype.plugins</groupId>
                <artifactId>nexus-staging-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
Copy the code

Make the necessary padding in conjunction with your own project.

Write Github Action scripts

The Github Action script is saved in the. Github /workflows path under the project root directory. We only need to write a YAML to declare the steps to be performed. The syntax can be found in the Chinese documentation, which lists only the action scripts published to Maven’s central repository:

# is equivalent to a declaration of the purpose of the script
name: Maven Central Repo Deployment
The event that triggers the script is triggered after release
on:
  release:
    types: [released]
Define a release task
jobs:
  publish:
The environment in which the task runs
    runs-on: ubuntu-latest
# Steps of the task
    steps:
# 1. Declare the checkout repository code to the workspace
      - name: Checkout Git Repo
        uses: actions/checkout@v2
Git Action Secrets Git Action Secrets
# add secrets to key
      - name: Set up Maven Central Repo
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
          server-id: sonatype-nexus-staging
          server-username: The ${{ secrets.OSSRH_USER }}
          server-password: The ${{ secrets.OSSRH_PASSWORD }}
          gpg-passphrase:  The ${{ secrets.GPG_PASSWORD }}
# 3. Publish to Maven central repository
      - name: Publish to Maven Central Repo
The action script written by someone else is used here. For details, please refer to his documentation.
        uses: samuelmeuli/action-maven-publish@v1
        with:
          gpg_private_key: The ${{ secrets.GPG_SECRET }}
          gpg_passphrase: The ${{ secrets.GPG_PASSWORD }}
          nexus_username: The ${{ secrets.OSSRH_USER }}
          nexus_password: The ${{ secrets.OSSRH_PASSWORD }}

Copy the code

Trigger Action

When all is ready, the action script will be submitted to Github, and when you use release it will automatically execute the entire release process in the Action column:

This way, you configure it once and publish it everywhere. We don’t need to care about how anymore, just when.

Refer to the Payment Spring Boot project.

conclusion

Today I introduced the role of CI/CD through a simple use of Github Action. This technical architecture is a trend in project integration delivery and a highlight skill in interviews. And this way can achieve “one configuration, anytime, anywhere integration deployment”.

Follow our public id: Felordcn for more information

Personal blog: https://felord.cn