1212 required : false
1313 default : ' ghcr.io'
1414 type : string
15+ tag :
16+ description : ' The release tag to derive semver from (e.g. 1.2.3 or v1.2.3)'
17+ required : true
18+ type : string
1519
1620env :
1721 image-name : ${{ inputs.image-name }}
@@ -22,47 +26,74 @@ jobs:
2226 runs-on : ubuntu-latest
2327 permissions :
2428 packages : write # container images
25- contents : write # releases
2629 steps :
27- - name : Check out the repo
28- uses : actions/checkout@v4
29-
30- # some docker actions need all lowercase
30+ # docker/metadata-action and akhilerm/tag-push-action require lowercase registry paths.
31+ # GITHUB_REPOSITORY_OWNER can contain uppercase letters (e.g. "Health-Informatics-UoN"),
32+ # so we normalise it here and store it in GITHUB_ENV for all subsequent steps.
3133 - name : downcase repo-owner
3234 run : |
3335 echo "REPO_OWNER_LOWER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
3436
3537 - name : Parse version from tag
3638 id : version
37- uses : release-kit/semver@97491c46500b6e758ced599794164a234b8aa08c # v2.0.7
39+ run : |
40+ # The tag input may optionally be prefixed with 'v' (e.g. v1.2.3).
41+ # Strip it so all subsequent steps work with a bare semver string.
42+ version="${{ inputs.tag }}"
43+ version="${version#v}"
44+
45+ # Extract the major and minor components for floating tags (e.g. '1' and '1.2').
46+ # Floating tags let consumers pin to a major or minor version without knowing
47+ # the exact patch, following standard container image tagging conventions.
48+ major=$(echo "$version" | cut -d. -f1)
49+ minor=$(echo "$version" | cut -d. -f2)
50+ echo "version=$version" >> "$GITHUB_OUTPUT"
51+ echo "major=$major" >> "$GITHUB_OUTPUT"
52+ echo "major-minor=$major.$minor" >> "$GITHUB_OUTPUT"
53+
54+ # A hyphen in the version string indicates a pre-release (e.g. 1.0.0-beta.1).
55+ # Floating major/minor tags must NOT be applied to pre-releases — those tags
56+ # should always point at the latest stable release, not a pre-release build.
57+ if [[ "$version" == *-* ]]; then
58+ echo "is-prerelease=true" >> "$GITHUB_OUTPUT"
59+ else
60+ echo "is-prerelease=false" >> "$GITHUB_OUTPUT"
61+ fi
3862
39- # check image exists for commit
40- - uses : tyriis/docker-image-tag-exists@71a750a41aa78e4efb0842f538140c5df5b8166f # v2.1.0
63+ # Verify that the edge image built from this commit SHA actually exists in the registry
64+ # before attempting to retag it. Fails fast rather than producing a misleading error
65+ # from the tag-push step if the publish-container workflow hasn't run yet.
66+ - name : Check image exists for commit
67+ uses : tyriis/docker-image-tag-exists@71a750a41aa78e4efb0842f538140c5df5b8166f # v2.1.0
4168 with :
4269 registry : ${{ env.registry }}
4370 repository : ${{ env.REPO_OWNER_LOWER }}/${{ env.image-name }}
4471 tag : ${{ github.sha }}
4572
46- # standard login to the container registry
4773 - name : Docker Login
4874 uses : docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
4975 with :
5076 registry : ${{ env.registry }}
5177 username : ${{github.actor}}
5278 password : ${{secrets.GITHUB_TOKEN}}
5379
54- # We still use the metadata action to help build out our tags from the Workflow Run
80+ # Build the list of tags to apply. We use type=raw because the version comes from
81+ # the 'tag' input rather than from GITHUB_REF — this workflow is triggered via
82+ # workflow_call on a branch push, so GITHUB_REF is a branch ref, not a tag ref.
83+ # The major and minor floating tags are gated on is-prerelease so they are only
84+ # moved forward for stable releases.
5585 - name : Docker Metadata action
5686 id : meta
5787 uses : docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
5888 with :
5989 images : ${{ env.registry }}/${{ env.REPO_OWNER_LOWER }}/${{ env.image-name }}
60- tags : | # new tags only
61- type=semver,pattern={{ version}}
62- type=semver,pattern={{ major}}
63- type=semver,pattern={{ major}}.{{minor }}
90+ tags : |
91+ type=raw,value=${{ steps. version.outputs.version }}
92+ type=raw,value=${{ steps.version.outputs. major }},enable=${{ steps.version.outputs.is-prerelease == 'false' }}
93+ type=raw,value=${{ steps.version.outputs. major-minor }},enable=${{ steps.version.outputs.is-prerelease == 'false' }}
6494
65- # apply the new tags to the existing images
95+ # Rather than rebuilding the image, we retag the existing edge image (tagged with
96+ # the commit SHA by publish-container) with the semver tags computed above.
6697 - name : Push updated image tags
6798 uses : akhilerm/tag-push-action@f35ff2cb99d407368b5c727adbcc14a2ed81d509 # v2.2.0
6899 with :
0 commit comments