A single tag = A new release?
In general, Git tags are like bookmarks of a specific commit in any branch that will give you a quick pointer to a specific point in the Git history. Those tags specify a point or a milestone in the history, such as a new version release in our case.
However, in GitHub, what if tags contained a hidden power that turns itself to a fully-fledged release? In this article, let’s explore what’s happening behind the scenes, with Terminaux as the target repository that we’ll be using.
The GitHub Actions Workflow
GitHub Actions is a Continuous Integration (CI) automated system that allows you to offload your build, your test, and your other workflows related to your projects to a host of runners (self-hosted or GitHub-hosted), with clean virtual machines as the medium to save time and effort, to ensure automated code integration.
When we push a tag to our project’s repository, such as Terminaux, a GitHub Actions workflow, called release.yml, automatically gets run as per the conditional run:
on: push: tags: - '**'
The following steps are run:
- First of all, the repository gets checked out, with all submodules being fetched for both the build tools scripts and the Aptivi DocFX theme.
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
ref: ${{ github.ref }}
- Second, the environment gets set up, with the most minimal dependencies being the .NET 10.0 SDK (using a GitHub Actions module called actions/setup-dotnet@v4) and the DocFX global .NET tool.
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Setup DocFX
run: dotnet tool install --global docfx
- Then, the project gets built and its documentation gets built. Since Terminaux is a library, there is no need to pack the binaries because they’d be released to NuGet; just the documentation.
- name: Release Asset Preparation
id: release-asset
run: |
make rel-ci
make doc
./tools/docgen-pack.sh
- After the build succeeds, both the
$SUBJECT and the $BODY variables get populated with both CHANGES.TITLE as the input for the subject variable and CHANGES as the input for the body variable, with SHA256 checksum appended for each binary that would make it to the release. Those variables would then get exported to this steps variable by appending them to $GITHUB_OUTPUT as per the docs.
- name: Release Asset Preparation
id: release-asset
run: |
[...]
echo "SUBJECT=$(cat CHANGES.TITLE)" >> "$GITHUB_OUTPUT"
echo 'BODY<<EOF' >> "$GITHUB_OUTPUT"
cat CHANGES >> "$GITHUB_OUTPUT"
sha256sum tools/*.zip | sed -e 's/^/- /g' >> "$GITHUB_OUTPUT"
echo 'EOF' >> "$GITHUB_OUTPUT"
- After the export step is done, the workflow generates the binary attestation metadata for all binaries. For example, since we’ve only generated the documentation archive, the binary attestation for the docs archive gets generated.
- name: Binary Attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: 'tools/*.zip'
- Then, another automated GitHub Actions module,
softprops/action-gh-release@v2, gets called with our generated body and the title parameters as variables from the build step, along with all the binary files.
- name: Release Making
uses: softprops/action-gh-release@v2
with:
body: ${{ steps.release-asset.outputs.BODY }}
name: ${{ steps.release-asset.outputs.SUBJECT }}
files: |
tools/*.zip
- Finally, the resulting NuGet packages that the build step generates are uploaded to NuGet with the necessary API key.
- name: Package Publication
run: NUGET_APIKEY=${{ secrets.NUGET_APIKEY }} ./tools/push.sh
- After that, you’ll be able to find a new release that the automated workflow has generated from just a simple tag.
Why not make releases manually?
We have decided to automate the releases like this instead of relying on manual releases, because our reliance on continuous integration allows us to build and test our project on a clean environment to ensure code integrity.
But, why don’t we rely on our systems to make releases? This workflow file was authored on purpose to both save time and effort and to avoid inconsistencies in our builds that result from dirty development systems.
As for the release changelogs, we are aiming to make them more readable for both users and developers alike, by not automatically generating changelogs using a built-in GitHub changelogs generation feature. We generate changelogs by manually editing the CHANGES and the CHANGES.TITLE files and using them as inputs to our final release notes of a version on GitHub.
For example, for Terminaux 8.1.1.1, we have this line as CHANGES.TITLE file contents:
[servicing] Terminaux v8.1.1.1: Where's the History?
The above contents would be the release title for a release that was generated from a tag automatically as per the above steps.
And for the same version, we have the following contents of CHANGES:
This is a quick hotfix release to fix history loading issues for the first shell input. ### Changes This release contains a variety of changes, including, but not limited to: - `[*]` Fixed history loading issues for the first shell input Review the commit history if you want to get a deep insight about the changes. ### Feedback? If you have issues with this version, report to us by [making a new issue ticket](https://github.com/Aptivi/Terminaux/issues/new). ### Sum hashes To verify integrity of your download, compare the SHA256 sum of your downloaded file with the following information:
The above contents would be found in the release’s body in the final release page on GitHub, exactly coded as Markdown.
The final result, along with the release assets that got uploaded by the softprops/action-gh-release@v2 step, looks like this:
Notice the “github-actions” account that made the release because of the softprops/action-gh-release@v2 step. It’s made nicely!
This tag has become a release after all the steps executed successfully. After that, this version of Terminaux was released on NuGet.
#git #GitTag #github #news #Tag #Tech #Technology #update