Stuck with TravisCI? Looking for a worthy alternative to GitLab CI? Here’s a guide on how to create a full CI pipeline publishing GitHub Packages, Codecov reports, releasing to Maven Central and GitHub, including dynamic commitlogs.
GitHub Actions – blog series
Part 1: GitHub Actions CI pipeline: GitHub Packages, Codecov, release to Maven Central & GitHub
Part 2: Publishing Docker images to GitHub Container Registry with GitHub Actions
Part 3: Stop re-writing pipelines! Why GitHub Actions drive the future of CI/CD
Until late 2020 my advice to customers was quite clear on which Continuous Integration platform they should choose. Taking a look at GitLab was (and is!) not a bad idea (I wrote about “the changing of the guard” from Jenkins to GitLab nearly three years ago ). I found that their implementation of the pipeline-as-code pattern was the best to date. Plus, having all the deployment options and being able to “just go” with the open-source version simply fitted most scenarios. Also, in complex scenarios the option to use templates was really nice. No need to search for other solutions – getting up to speed in projects was quick and easy.
My open-source projects remained with TravisCI, though. Since I was able to do nearly everything I needed (including even running full VMs with Vagrant ) I simply stayed with Travis. But then, for quite a while, it didn’t feel right any more. I think it all started with Idera buying Travis in 2019, after which quite a few engineers were simply thrown out. I guess habit is quite strong sometimes and after I did an estimate of the time it would take to switch to another CI platform, I didn’t find a time slot to migrate all my stuff. And to which platform anyway? Travis was really nicely integrated and it simply worked …
The problem with TravisCI
Well, at least until GitHub released a new way of integrating with third-party CI platforms along with the availability of their own CI solution called GitHub Actions. Soon Travis started to move their GitHub integration to GitHub Apps . Back then, many of my Travis builds stopped working occasionally. And I had renovate configured to do auto-merging …
This didn’t work very well since either repositories didn’t get updated any more, or renovate just pushed changes without running CI. This meant no build and test were run before merging. Soon many of my repositories were just screwed up. But you know, habit can be powerful. I went through my repositories and migrated them to travis-ci.com, since the new GitHub App integration was only available on a completely new Travis clone they released also. This burned many hours where I wasn’t able to work on interesting stuff … I migrated maybe half of my 100+ repositories.
Then, finally, December 2020 came and I realized what the new pricing model of travis-ci.com meant for open-source repositories. All of my migrated repos builds simply used the 10.000 free credits in less than one month. Which meant that around 50 repositories’ CI builds stopped working again. And the other 50 repositories that remained with the old GitHub integration at travis-ci.org were put into read-only mode on December 31st, 2020 . Finally nearly none of my open-source projects had a working build any more.
GitHub Actions to the rescue!
Did I say “nearly”? Yeah! I had some repositories running with GitHub Actions already. I created most of them for my lecture on Software Engineering and Java programming at the University of Applied Sciences Erfurt . And I wanted to introduce my students to Continuous Integration in the simplest possible way. Since they were already used to working with GitHub , using Actions was the way to go. Starting in December 2020, I finally migrated more and more repositories from TravisCI to GitHub Actions. Building and testing a Java application, for example, is quite easy. Just have a look at this example build.yml
, which builds a Maven project using three parallel jobs with JDK 8
, 11
and 15
:
1name: build 2 3on: [push] 4 5jobs: 6 build: 7 runs-on: ubuntu-latest 8 9 strategy: 10 matrix: 11 java-version: [ 8, 11, 15 ] 12 13 steps: 14 - uses: actions/checkout@v2 15 - uses: actions/setup-java@v1 16 with: 17 java-version: ${{ matrix.java-version }} 18 - run: mvn -B install --no-transfer-progress --file pom.xml
Even running Docker Compose setups with a great library such as Testcontainers is not a problem. Here’s a simple test class from one of my projects , which uses the Docker Compose integration of Testcontainers if you’re interested.
In the beginning of 2021 I wanted to have the most important repositories migrated to GitHub Actions. This included two of our open-source projects at codecentric: the CXF Spring Boot Starter which I was able to create in one of our projets together with my great colleague Marco Paga . Another big project was Spring Boot Admin , which was mainly driven by my former colleague Johannes Edmeier , and which we’re currently taking over in our Spring Boot Admin Expert Group at codecentric (we’re always looking for people who want to join!).
This article’s setup
However, both projects don’t stop with “normal” build or test cases. Since they are used by many people and organizations out there, they are released on Maven Central . These releases also need to be added as GitHub releases. What’s more, they should ideally contain a changelog of all the cool new stuff inside. Additionally there’s a huge developer community taking part in the development of the projects – especially in Spring Boot Admin. So we also need to publish SNAPSHOT
versions of every build. Finally we shouldn’t forget to have coverage reports generated and published into the pull requests and commits in general.
Logo sources: GitHub & GitHub Actions & GitHub Packages logo , Codecov logo , Sonatype logo
Publishing SNAPSHOT versions to GitHub Packages
As I like to write comprehensible posts that allow you to easily adapt every step to your own project, we should now get our hands dirty! Fully working examples can be found in the cxf-spring-boot-starter and spring-boot-admin projects on GitHub.
So let’s first start by publishing our Maven artifacts to the GitHub Packages Registry . There’s also an in-depth description in the docs for Java package publishing , along with many other languages. The idea is to have our SNAPSHOT
versions available on GitHub Packages – and to use Maven Central for the release versions later.
Therefore we need to add GitHub Packages to our pom.xml ‘s distributionManagement
section. As we can’t add two repository
tags to distributionManagement
, we simply use the snapshotRepository
tag here for GitHub Packages configuration:
1<distributionManagement> 2 <repository> 3 <id>oss.sonatype.org</id> 4 <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> 5 </repository> 6 <snapshotRepository> 7 <id>github</id> 8 <name>GitHub Packages</name> 9 <url>https://maven.pkg.github.com/codecentric/cxf-spring-boot-starter</url> 10 </snapshotRepository> 11</distributionManagement>
In contrast to the Sonatype deployment, we need to also mind the url
of the GitHub Packages configuration in one of the following steps, since it must match your GitHub organization and repository like this:
1https://maven.pkg.github.com/yourOrganisationHere/yourRepositoryNameHere
Otherwise we’ll run into errors like this (I “tried” that several times 🙂 ):
1Could not find artifact de.codecentric:cxf-spring-boot-starter:jar:2.4.0-20210112.171149-1 in github (https://maven.pkg.github.com/jonashackt/cxf-spring-boot-starter)
A new GitHub Action job
The next step is to create a new publish-snapshot
job inside our build.yml workflow. My requirement was to only start the publish-snapshot
job if the build
job was successfully done. Because if you simply describe two jobs inside a workflow, both jobs will be run in parallel (see this build log for example ):
In GitHub Actions we have two options to implement a sequence of jobs . The first possibility is to create a separate workflow in a separate yaml file and use the workflow_run
event :
This event occurs when a workflow run is requested or completed, and allows you to execute a workflow based on the finished result of another workflow.
This event is quite similar to the workflow_dispatch
event we’ll use later on since it is only triggerable on the default branch (which is master
in our example repositories). Using the completed
keyword, the workflow_run
event can be configured to only run when another workflow has finished. An example publish-snapshot.yml
looks like this:
1name: publish-snapshot 2 3# Only trigger a SNAPSHOT release to GitHub Packages, when the build workflow succeeded 4on: 5 workflow_run: 6 workflows: ["build"] 7 types: 8 - completed 9 10jobs: 11 publish-snapshot: 12 runs-on: ubuntu-latest 13 14 steps: 15 ...
The “needs” keyword as an elegant trigger
The second option on how to run GitHub Action jobs in sequence is to simply use the needs
keyword inside a job definition . This is very elegant since we’re able to define the sequence of Action jobs inside the same workflow file like this:
1name: build 2 3on: [push] 4 5jobs: 6 build: 7 runs-on: ubuntu-latest 8 9 strategy: 10 matrix: 11 java-version: [ 8, 11, 15 ] 12 13 steps: 14 - uses: actions/checkout@v2 15 - uses: actions/setup-java@v1 16 with: 17 java-version: ${{ matrix.java-version }} 18 - run: mvn -B install --no-transfer-progress --file pom.xml 19 20 publish-snapshot: 21 needs: build 22 runs-on: ubuntu-latest 23 24 steps: 25 - uses: actions/checkout@v2 26 27 - name: Set up settings.xml for GitHub Packages 28 uses: actions/setup-java@v1 29 with: 30 java-version: 8 31 32 - name: Publish SNAPSHOT version to GitHub Packages (we can skip tests since we only deploy if the build workflow succeeded) 33 run: mvn -B --no-transfer-progress deploy -DskipTests --projects cxf-spring-boot-starter 34 env: 35 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Now the publish-snapshot
job is only triggered when our build
workflow has successfully done its matrix build with three Java versions. If you don’t need the matrix build, you can even do the mvn install
and mvn deploy
in one single step if you like. In my scenario I also added the -DskipTests
parameter, since the second job doesn’t need to run all tests again. This is already done by our build
job. Additionally I added --projects cxf-spring-boot-starter
because I have a Maven multi-module project and only wanted this module to be published as a GitHub Package (not the samples).
Last but not least, the GitHub Actions UI implements this kind of sequence quite nicely because we see all depending jobs in one overview:
After a successful mvn deploy
to GitHub Packages, you should also see a new entry on the front page of your repository like this:
Also, all of your packages, regardless which repository they were published in, are listed at the top level of your GitHub organization. The docs contain even more detailed information on where your packages will be visible .
Adding coverage reports with JaCoCo
After we have our SNAPSHOT versions published to GitHub Packages, we should also make sure we have a regular coverage report for our builds. Looking at Java-based projects, there’s a widely used framework called JaCoCo (Java Code Coverage library) with a corresponding jacoco-maven-plugin available. Since I wanted to create a separate GitHub Actions job for the coverage report, I also applied a separate Maven profile inside our pom.xml like this:
1<profile> 2 <id>coverage</id> 3 <build> 4 <plugins> 5 <plugin> 6 <groupId>org.jacoco</groupId> 7 <artifactId>jacoco-maven-plugin</artifactId> 8 <version>${build-plugin.jacoco.version}</version> 9 <executions> 10 <!-- Prepares the property pointing to the JaCoCo runtime agent 11 which is passed as VM argument when Maven the Surefire plugin is executed. --> 12 <execution> 13 <goals> 14 <goal>prepare-agent</goal> 15 </goals> 16 </execution> 17 <!-- Ensures that the code coverage report is created after 18 all tests have been run. --> 19 <execution> 20 <id>generate-report</id> 21 <goals> 22 <goal>report</goal> 23 </goals> 24 </execution> 25 </executions> 26 </plugin> 27 </plugins> 28 </build> 29 </profile>
Using the Maven command mvn verify -P coverage
, we can now generate the coverage report. It will be placed inside the usual target/site/jacoco
directory. But that’s only half the battle. We also need some sort of frontend where we can get insights into the coverage reports over time. Additionally it would be great to have an integration into our CI process to see if coverage increases or decreases with new commits and pull requests. For many years I used coveralls.io in many of my open-source repositories. But sadly the Coveralls GitHub Action doesn’t support JaCoCo/Java out-of-the-box at the moment (see this issue ) and there doesn’t seem to be a roadmap as to whether this is going to be supported in the near future.
Visualizing coverage reports using Codecov.io
It’s often a good start to get some inspiration by looking into the issue’s discussions. For example, the cucumber-jvm team switched over to Codecov . As I’d had it on my list for a long time, I thought, why not also use it inside our repos? And the Codecov GitHub Action supports Java and JaCoCo out-of-the-box. Now we can create a new GitHub Actions job inside our build.yml workflow that does everything coverage-related. The job again uses the needs
keyword to be dependent on the build
job:
1... 2 coverage: 3 needs: build 4 runs-on: ubuntu-latest 5 6 steps: 7 - uses: actions/checkout@v2 8 - uses: actions/setup-java@v1 9 with: 10 java-version: 15 11 - run: mvn -B verify -P coverage --no-transfer-progress 12 13 - uses: codecov/codecov-action@v1 14 with: 15 file: ./**/target/site/jacoco/jacoco.xml 16 name: codecov 17...
As already done with the publish-snapshot
job, we use only one Java version and explicitly specify our coverage
Maven profile here. Be sure to also create a Codecov orga if you don’t have it already. Simply log in at codecov.com with your GitHub login, for example. You can also add the repository to your Codecov orga. Just click on the Settings
tag of your newly created Codecov repo and you should see a nice badge generated for your repo’s README.md
.
Now, running our GitHub Actions build workflow including the new coverage
job, we should see the reports of all of our repos inside the Codecov portal like this:
If a new commit or pull request is submitted to our repository, we now also see a great overview on how the coverage changed with those code changes:
Learning from rultor …
Let’s now focus on the release to Maven Central. Already having a dedicated GitHub Actions workflow for our default build, it would be great to be able to have another workflow file specifically for the Maven Central release. As it’s absolutely no problem to have multiple workflow files with GitHub Actions we simply create a second workflow called release-to-maven-central.yml .
Thinking about the Maven Central release, I often realize that this process is something you don’t do on an everyday basis. Looking at the two Spring-Boot-related projects mentioned above, I see a pattern, namely that we tend to release about once every 1-3 months. For the cxf-spring-boot-starter project I learned to love the tooling around rultor. There was also a great blog post from the inventor of rultor back then on how to release to Maven Central with just mentioning a bot inside a GitHub issue. I found that this kind of solution was a great fit for many small to medium open-source projects since mentioning a person or bot is something you always remember how to do – even if it was months ago.
A UI trigger for the Maven Central release
However, since the rultor development somehow stopped in mid-2020 and the Maven version was quite old, I wanted to create a similar experience using GitHub Actions’s built-in tooling only. After some research I found a great feature on how to trigger GitHub Actions through the GitHub Actions UI . This incorporates the workflow_dispatch event, which I included into our newly created release-to-maven-central.yml inside our .github/workflows
directory:
1name: release-to-maven-central 2on: 3 workflow_dispatch: 4 inputs: 5 releaseversion: 6 description: 'Release version' 7 required: true 8 default: '2.4.0' 9jobs: 10 publish: 11 runs-on: ubuntu-latest 12 steps: 13 - run: | 14 echo "Release version ${{ github.event.inputs.releaseversion }}!"
Using the workflow_dispatch:inputs
field, we can configure a UI element where we can set the release version dynamically right before triggering the Maven Central release workflow (or any other release workflow). There’s only one small pain point which is mentioned in the docs:
To trigger the workflow_dispatch event on GitHub, your workflow must be in the default branch.
Therefore we need to merge this workflow to master/main first. After the merge, our GitHub Actions UI should look as intended:
Also, the variable we defined inside the workflow_dispatch:inputs
field is accessible inside the GitHub Actions workflow! The variable ${{ github.event.inputs.releaseversion }}
can be simply printed into the build log as shown in the code above. Now clicking onto run workflow
, it will print the version into the log:
Preparing your project for the Maven Central deployment
This article assumes that you already have a suitable pom.xml
to run a successful Maven Central deployment. Both example projects also provide a pom.xml
that has everything in place. Escpecially a correct distributionManagement
section (we’ll cover that in a moment) and a separate Maven profile like central-deploy
containing no less than five plugins are crucial. Just to be sure you don’t miss anything, these are: the maven-source-plugin
& maven-javadoc-plugin
, the maven-deploy-plugin
& the nexus-staging-maven-plugin
and finally the maven-gpg-plugin
.
Escpecially for the latter, one needs to generate a key pair with GPG and distribute the public key to key servers. There’s a good article in the Sonatype docs on how to do that. In this post we assume that you already created and distributed your key as described in the linked Sonatype docs. To make sure you didn’t miss anything, I recommend you take a look into the Sonatype docs on how to deploy to Maven Central . Here’s also a fully working example pom.xml of the cxf-spring-boot-starter project containing all the necessary plugins inside the central-deploy
profile.
Creating encrypted variables in GitHub Actions
Now coming back to GitHub Actions, I have to admit I was really amazed at one thing. The GitHub Action setup-java
already ships with a pre-configured settings.xml
we can use for the Maven Central deployment!
“…it also configures a Maven
settings.xml
for publishing packages. By default, the settings file will be configured for GitHub Packages, but it can be configured to deploy to another package registry, such as the Maven Central Repository.“
So the only thing we need to do here is to create some variables containing the required credentials for the Sonatype Maven repo! In fact we need to configure four encrypted variables for the Maven Central release process. Both OSS_SONATYPE_USERNAME
and OSS_SONATYPE_PASSWORD
are crucial for the Sonatype Nexus access. The MAVEN_GPG_PRIVATE_KEY
and MAVEN_GPG_PASSPHRASE
are important for the signing of our artifacts that will get uploaded to the Sonatype Nexus. Therefore, head over to the Settings
tab of your repository and go to Secrets
. There should be a button New repository secret
:
Use your Sonatype Nexus credentials to create the variables OSS_SONATYPE_USERNAME
and OSS_SONATYPE_PASSWORD
. Then you need to also create the other two variables. If you have multiple private keys listed when running gpg --list-secret-keys
, you need to export the one you chose for signing the Sonatype artifacts only! This can be done with :
gpg --output private.pgp --armor --export-secret-key username@email
Now fill the contents of the newly exported private.pgp
into the GitHub repository secret named MAVEN_GPG_PRIVATE_KEY
and the corresponding passphrase into MAVEN_GPG_PASSPHRASE
. As we only use this key for the signing of Maven Central artifacts, it should be okay to simply use GitHub encrypted secrets here. If you want to know more about GitHub’s encrypted variables, take a look at the docs . Please never ever use a key you use for any other use case here!
Completing the GitHub Actions Maven Central release workflow
We’re nearly there now! We can now start using the pre-configured settings.xml
from the setup-java Action to do our Maven release. Depending on your pom.xml
‘s distributionManagement
section, we need to configure the server-id
correctly. In the cxf-spring-boot-starter project’s pom.xml this is oss.sonatype.org
. Make sure to also have the correct url to the Sonatype repo inside the distributionManagement
section:
1<distributionManagement> 2 <repository> 3 <id>oss.sonatype.org</id> 4 <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> 5 </repository> 6 <snapshotRepository> 7 <id>github</id> 8 <name>GitHub Packages</name> 9 <url>https://maven.pkg.github.com/codecentric/cxf-spring-boot-starter</url> 10 </snapshotRepository> 11</distributionManagement>
Now let’s complete the release-to-maven-central.yml GitHub Actions workflow file. Therefore we use our newly created encrypted secrets to override the values of the pre-configured settings.xml
:
1name: release-to-maven-central 2on: 3 workflow_dispatch: 4 inputs: 5 releaseversion: 6 description: 'Release version' 7 required: true 8 default: '2.4.0' 9jobs: 10 publish: 11 runs-on: ubuntu-latest 12 steps: 13 - run: echo "Will start a Maven Central upload with version ${{ github.event.inputs.releaseversion }}" 14 15 - uses: actions/checkout@v2 16 17 - name: Set up Maven Central Repository 18 uses: actions/setup-java@v1 19 with: 20 java-version: 11 21 server-id: oss.sonatype.org 22 server-username: MAVEN_USERNAME 23 server-password: MAVEN_PASSWORD 24 gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 25 gpg-passphrase: MAVEN_GPG_PASSPHRASE 26 27 - name: Set projects Maven version to GitHub Action GUI set version 28 run: mvn versions:set "-DnewVersion=${{ github.event.inputs.releaseversion }}" 29 30 - name: Publish package 31 run: mvn --batch-mode clean deploy -P central-deploy -DskipTests=true 32 env: 33 MAVEN_USERNAME: ${{ secrets.OSS_SONATYPE_USERNAME }} 34 MAVEN_PASSWORD: ${{ secrets.OSS_SONATYPE_PASSWORD }} 35 MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
Using the maven-versions-plugin
, we also set the version number to the value that was inserted into the GitHub actions UI we created with the workflow_dispatch
event. Defining some environment variables, we finally deploy our application to Maven Central.
Only if you run into the Tackling the 'gpg: signing failed: Inappropriate ioctl for device'
error should you examine the configuration of the maven-gpg-plugin
inside your pom.xml more closely. Just add the following gpgArguments
to the configuration using the --pinentry-mode
parameter:
1<plugin> 2 <artifactId>maven-gpg-plugin</artifactId> 3 <version>${maven-gpg-plugin.version}</version> 4 <executions> 5 <execution> 6 <id>sign-artifacts</id> 7 <phase>verify</phase> 8 <goals> 9 <goal>sign</goal> 10 </goals> 11 <configuration> 12 <!-- This is necessary for gpg to not try to use the pinentry programs --> 13 <gpgArguments> 14 <arg>--pinentry-mode</arg> 15 <arg>loopback</arg> 16 </gpgArguments> 17 </configuration> 18 </execution> 19 </executions> 20</plugin>
Now it’s time to let our release-to-maven-central
workflow run again! Create a new release by simply clicking on Run workflow
. The resulting build log output should look similar to this successful Maven Central Release GitHub Actions build. If you check Maven Central, you should find the newly released artifact also (this could take some time though due to synchronization issues):
That’s great news! We successfully released to Maven Central 🙂
Creating a GitHub release with every Maven Central release
We could stop here. But there’s one more thing, I guess. Being now able to automatically create Maven Central releases of our project using GitHub Actions, we can go one step further. Wouldn’t it be cool to have a GitHub release on our repository’s front page containing the newly released jar
files?
There are multiple release actions out there. I went with the GitHub default create-release action , which should easily create a new release for us. Let’s enhance our release-to-maven-central.yml :
1- name: Create GitHub Release 2 id: create_release 3 uses: actions/create-release@v1 4 env: 5 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 6 with: 7 tag_name: ${{ github.event.inputs.releaseversion }} 8 release_name: ${{ github.event.inputs.releaseversion }} 9 body: | 10 Grab the new version from Maven central https://repo1.maven.org/maven2/de/codecentric/cxf-spring-boot-starter/${{ github.event.inputs.releaseversion }}/ by using it in your deps (also use the newest cxf-spring-boot-starter-maven-plugin https://github.com/codecentric/cxf-spring-boot-starter-maven-plugin): 11 12 ``` 13 <dependencies> 14 <dependency> 15 <groupId>de.codecentric</groupId> 16 <artifactId>cxf-spring-boot-starter</artifactId> 17 <version>${{ github.event.inputs.releaseversion }}</version> 18 </dependency> 19 </dependencies> 20 ``` 21 draft: false 22 prerelease: false
Inside the release_name
and tag_name
variables we simply use the version number we defined through the GitHub Actions workflow UI. The action also creates a Git tag inside our repo for us – so no need to do this ourselves. Using the body
tag’s capabilities of multi-line comments, we also add a description of where our newly released jar
can be downloaded from (Maven Central) and how to embed it into your project. All this is dynamically based on the ${{ github.event.inputs.releaseversion }}
variable again.
Extending the GitHub Release with a changelog
We can even improve our GitHub release even more if we add a changelog to the body
. Again, there are multiple actions that generate changelogs for us automatically. Maybe you’re looking for a really simple one which only lists the commits that are new inside this release compared to the last one. Then you can check out metcalfc/changelog-generator . It’s really straightforward to use. Before our create-release
phase, we add it to generate the changelog:
1- name: Generate changelog 2 id: changelog 3 uses: metcalfc/changelog-generator@v0.4.4 4 with: 5 myToken: ${{ secrets.GITHUB_TOKEN }}
Now we’re able to use the generated log inside the body
tag with ${{ steps.changelog.outputs.changelog }}
in our create-release
step:
1- name: Create GitHub Release 2 id: create_release 3 uses: actions/create-release@v1 4 env: 5 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 6 with: 7 tag_name: ${{ github.event.inputs.releaseversion }} 8 release_name: ${{ github.event.inputs.releaseversion }} 9 body: | 10 Grab the new version from Maven central https://repo1.maven.org/maven2/de/codecentric/cxf-spring-boot-starter/${{ github.event.inputs.releaseversion }}/ by using it in your deps (also use the newest cxf-spring-boot-starter-maven-plugin https://github.com/codecentric/cxf-spring-boot-starter-maven-plugin): 11 12 ``` 13 <dependencies> 14 <dependency> 15 <groupId>de.codecentric</groupId> 16 <artifactId>cxf-spring-boot-starter</artifactId> 17 <version>${{ github.event.inputs.releaseversion }}</version> 18 </dependency> 19 </dependencies> 20 ``` 21 22 ### Things that changed in this release 23 ${{ steps.changelog.outputs.changelog }} 24 draft: false 25 prerelease: false
Finally, after another release-to-maven-central
workflow run, we should see a new release on our repository’s front page:
Digging into the very details of this release, we should see a customized download advice to our released JAR – together with a nice changelog list:
GitHub Actions are here to stay!
Wow! I have to admit I really fell in love with GitHub Actions in the end 🙂 I also have to admit that in the beginning I wasn’t really aware of the power implicit in the second part of the name – “Actions”. But what makes GitHub Actions really a pleasure to work with is the great variety of all the many different actions out there. Be it GitHub’s own maintained actions – or all the community actions available . Quoting from the docs :
Actions are the smallest portable building block of a workflow. You can create your own actions, or use actions created by the GitHub community.
From my experience as an architect and developer who has worked in the DevOps space for more than a decade, this could be a game changer! None of the CI/CD platforms I know have this advantage that brings you up to speed as quickly. No more creating your own building blocks – just pick the ones you need and get started! I hope I was able to show some of the magic that’s possible with GitHub Actions. We publish our SNAPSHOT
versions to GitHub Packages and create Codecov coverage reports on every push made to our repository. Also, we crafted a nice way to do our Maven Central releases with GitHub Actions and didn’t even forget to create cool GitHub releases including commitlogs.
I really hope I was able to inspire you to check out GitHub Actions. I think they are absolutely worth a try. If you’re working on open-source projects on GitHub, there’s hardly anything better at the moment. I’d really like to hear about your experiences in the comments!
More articles
fromJonas Hecht
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Jonas Hecht
Senior Solution Architect
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.