ghaction_version_gen 0.20.0

Generate various version options as github action outputs
Documentation

marketplace CI coveralls github docker

ghaction-version-gen

ghaction-version-gen is a docker github action that outputs a version number for you to use in a deploy action.

There are many ways to generate version information for a repository. They usually involve processing GITHUB_REF in some way, maybe even using github-script.

This repository is also an example of how to create a docker github action that compiles a rust entrypoint in a container and then moves it to a second, minimal container.

Outputs

The following are the primary outputs of this action, usually the ones used for versioning:

  • version_tagged: for repositories that should only deploy on tags, it's defined if the github event was a push of a tag.

    The output itself is the tag, with the optional v stripped.

    This output can be overridden via the OVERRIDE_VERSION_TAGGED environment variable.

  • version_commit: for repositories that deploy on tags and on all commits to master or main. It's defined if the github event was a push of a tag or of one of those branches (but only when the commit is not on a tag itself, i.e. distance > 0).

    The output itself is the tag that was pushed, or the most recent tag on the branch followed by the distance between the branch and the tag (always with the v stripped).

    This output can be overridden via the OVERRIDE_VERSION_COMMIT environment variable.

  • version_docker_ci: for repositories that deploy to hub.docker continuously. If the commit was pushed to master or main, the variable has the value "latest"; if a tag was pushed, it has the tag (v stripped); otherwise, it has the value "null" as a string. This last case allows us to always use the variable as the version for the build-push-action, which doesn't like empty strings.

    This output can be overridden via the OVERRIDE_VERSION_DOCKER_CI environment variable.

You can see these variables in action in the Examples section.

This github action is also able to check if a project-specific version matches with the latest tags. At the moment, rust's Cargo.toml and python's setup.cfg files are checked. If there's a mismatch and a new tag is being pushed, the action fails.

Secondary outputs

These are the secondary outputs that might be useful for debugging or as alternative versioning schemes:

  • is_push: if the github event was identified, "true" if the event was a push or "false" otherwise.
  • is_tag: if the github ref was identified, "true" if the ref is a tag, false otherwise.
  • is_main: "true" if the github ref was for a branch named main or master.
  • is_push_tag: "true" if a tag was pushed.
  • is_push_main: "true" if main or master were pushed.
  • commit: the hash of the commit.
  • commit_main: the hash of the commit where the main/master branch is.
  • is_main_here: "true" if the main/master branch coincides with the current commit.
  • git_describe_tags: the output of git describe --tags
  • tag_latest: the most recent tag.
  • distance: the distance between the current commit and tag_latest.
  • tag_distance: tag_latest-distance
  • tag_head: the tag on HEAD, if there's a tag on HEAD (does not depend on the github event).
  • dash_distance: - prepended to distance
  • tag_latest_ltrimv: tag_latest without the optional leading v.
  • tag_head_ltrimv: tag_head without the optional leading v, if tag_head was defined.
  • rust_crate_version: the version in Cargo.toml if it exists.
  • version_tagged: tag_head_ltrimv if is_push_tag.
  • version_commit: tag_head_ltrimv if is_push_tag or tag_distance_ltrimv if is_push_main.
  • version_docker_ci: "latest" if is_push_main, tag_head_ltrimv if is_push_tag.
  • version_mismatch: if there's a version mismatch between the contents of a file and the latest tag, this is the error message. This also appears as a github action "error".

Examples

version_tagged and version_commit

Using version_tagged and version_commit is quite simple:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - id: version
        uses: docker://lpenz/ghaction-version-gen:0.19.0
      ...
      - name: deploy
        uses: <deploy action>
        if: steps.version.outputs.version_tagged != ''
        with:
          version: ${{ steps.version.outputs.version_tagged }}

That gets the deploy step to run only when a tag is pushed, and sets version to the tag with the optional v prefix stripped.

If we replace version_tagged with version_commit in the example above, we get an additional behavior: version_commit is also defined when main or master are pushed, and it assumes the value of the last tag (v stripped) suffixed with - and the distance of the pushed commit to that tag. This should be used in projects that want to deploy every time main is pushed.

version_docker_ci

The version_docker_ci variable was designed to work with the docker's build-push-action. It should be used in projects where we want to deploy from tags and from main/master, but we want main/master to be identified as latest in docker hub.

This is how it's used:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - id: version
        uses: docker://lpenz/ghaction-version-gen:0.19.0
      - uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          push: ${{ steps.version.outputs.version_docker_ci != 'null' }}
          tags: ${{ github.repository }}:${{ steps.version.outputs.version_docker_ci }}

Note that we don't make the build-push-action step conditional because we always want to build the container. Instead, we make push conditional, by checking that version_docker_ci is not null. We use null instead of the empty string as a workaround, because the action doesn't let us use an empty string as the version in tags.