DEV Community

Natalí
Natalí

Posted on

Automating Tag Creation, Release, and Docker Image Publish with GitHub Actions

I'm currently working on the improvement of the wallabag-kindle-consumer service. Since the original repository hasn't been maintained, I decided to fork it. My first goal was to have an initial dev version (0.1.0) and a Docker image published on ghcr.io. Additionally, I wanted to automate the tag creation, the release of the service, and the process of building and publishing the Docker image using GitHub Actions.

I watched a couple of YouTube videos (I'll leave the links at the end of the article) and read GitHub Actions documentation, but the resources showed how to use different GitHub Actions separately and didn't combine them. After many tries, I finally managed to do it. I decided to write this article to show how I accomplished it, and hopefully, it can help others who want to do the same but don't know where to start.

Step 1 - Create a Personal Access Token (PAT)on GitHub. Make sure to select the repo and write:packages scopes.

Step 2 - Add the created PAT in the repository's secrets:
In the repository's page, navigate to:

  • Settings >> Secrets and variables >> Actions >> click in New repository secret and paste the created token.

Step 3 - Grant read and write permissions to GitHub Actions:
In the repository's page, navigate to:

  • Settings >> Actions >> General >> Scroll to the end of the page to find Workflow permissions, then select Read and write permissions.

These steps are necessary because when using GitHub Actions, the workflows automatically create a GITHUB_TOKEN, which is available as an environment variable within every GitHub Actions workflow. However, this token lacks the specific permissions we need in this case. By using the PAT, we can trigger subsequent workflows, such as building and publishing the Docker image after tag creation and release.

Step 4 - Create workflows using the following actions:

For automating releases based on conventional commits, I used the google-github-actions/release-please-action@v3.

For the Docker image workflow, I used:

First workflow file (relese-please.yml):


 yaml
name: release-please

on:
  push:
    branches:
      - main

permissions:
  contents: write
  pull-requests: write

jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - name: release-please
        id: release
        uses: google-github-actions/release-please-action@v3
        with:
          release-type: simple
          package-name: release
          bump-minor-pre-major: true
          bump-patch-for-minor-pre-major: true
          token: ${{ secrets.PAT }}


Enter fullscreen mode Exit fullscreen mode

Second workflow file (deploy.yml):


 yaml
name: build-docker-image

on:
  push:
    tags:
      - 'v*'

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Log in to the Container registry
        uses: docker/login-action@v2
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.PAT }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}}

      - name: Build and push Docker image
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}



Enter fullscreen mode Exit fullscreen mode

It's important to note that the first version of the release when using Release Please Action will be "1.0.0" by default. If you want "0.1.0" as initial version (like me), you can achieve this by creating an empty commit with the following command:


 bash
git commit --allow-empty -m "chore: release 0.1.0" -m "Release-As: 0.1.0"{% raw %}`
``` 
This will create a pull request with the desired version. You can find more information in the [documentation](https://github.com/googleapis/release-please#how-do-i-change-the-version-number).

In summary, using these two workflows and a Personal Access Token, we can configure GitHub Actions to automate the tags creation, releases, and the process of building and publishing the Docker image.


Thanks to [@DevOpsJourney](https://www.youtube.com/@DevOpsJourney) for the [GitHub Packages.. Containers in a GitHub repo?](https://www.youtube.com/watch?v=gqseP_wTZsk) video and thanks to [@eddiejaoude](https://www.youtube.com/@eddiejaoude) for the [GitHub Actions can automate your releases from your git commit messages - conventional commits](https://www.youtube.com/watch?v=fcHJZ4pMzBs&t=319s) video. 

Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
softwaresennin profile image
Lionel♾️☁️

Awesome article. Thank you for writing it

Collapse
 
olodocoder profile image
Adams Adebayo

This is a very insightful article!

However, adding language tags helps improve your readers' reading experience. For example, the following code block looks better:

name: release-please

on:
  push:
    branches:
      - main

permissions:
  contents: write
  pull-requests: write

jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - name: release-please
        id: release
        uses: google-github-actions/release-please-action@v3
        with:
          release-type: simple
          package-name: release
          bump-minor-pre-major: true
          bump-patch-for-minor-pre-major: true
          token: ${{ secrets.PAT }}
Enter fullscreen mode Exit fullscreen mode

Just add yaml beside the opening quotes of the code block and you should have a colorized code block like the one above.

Happy coding!

Collapse
 
natilou profile image
Natalí • Edited

Thanks for the tip!! Glad you found this article interesting!