fix(ci): stop stamping app version onto master and branch Docker tags (#4709)

Closes #4695

Master and PR builds were tagging every Docker image with the App.php
version (e.g. 3.4.2-master-<sha>), flooding Docker Hub with tags for
versions that were never released.

Docker tags are now scoped to the ref:
- master  → master, <sha>
- branch  → <branch>-<sha>
- semver tag → <version>, latest

Additional hardening:
- Release tag trigger restricted to three-component semver (N.N.N) so
  non-semver tags (e.g. 3.preview) no longer publish a `latest` image
- Branch names sanitized: chars outside [a-zA-Z0-9_.-] replaced with _,
  total tag truncated to stay within Docker's 128-char limit, leading
  `.` or `-` prevented
- Fixed README.md claim that master builds push a `latest` tag
This commit is contained in:
jekkos authored and GitHub committed 2026-09-23 13:38:31 +04:00
1 parent 4e0466fbf1
commit ca3d982dc2
2 files changed
+24 -10

No files matched your search

+8 -6
View File
@@ -13,8 +13,10 @@ This document describes the CI/CD workflows for OSPOS.
### Docker Images
- Build and push `opensourcepos` Docker image for multiple architectures (linux/amd64, linux/arm64)
- On master: tagged with version and `latest`
- On other branches: tagged with version only
- On `master`: tagged `master` and `<sha>`
- On other branches: tagged `<branch>-<sha>`
- On a semver tag (e.g. `3.4.2`): tagged `<version>` and `latest`
- The version number is never stamped onto `master`/branch builds — it only appears on tag releases
- Pushed to Docker Hub
### Releases
@@ -39,10 +41,10 @@ The `GITHUB_TOKEN` is automatically provided by GitHub Actions.
## Workflow Triggers
- **Push to master** - Runs build, Docker push (with `latest` tag), and release
- **Push to other branches** - Runs build and Docker push (version tag only)
- **Push tags** - Runs build and Docker push (version tag only)
- **Pull requests** - Runs build only (PHPUnit tests run in parallel via phpunit.yml)
- **Push to master** - Runs build, Docker push (`master` + `<sha>` tags), and creates/updates the `unstable` release
- **Push to other branches** - Runs build and Docker push (`<branch>-<sha>` tag)
- **Push a semver tag** (e.g. `3.4.2`) - Runs build and Docker push (`<version>` + `latest` tags)
- **Pull requests** - Runs build only (PHPUnit tests run in parallel via phpunit.yml); no Docker push
## Existing Workflows
+16 -4
View File
@@ -2,6 +2,10 @@ name: Build and Release
on:
push:
branches:
- '**'
tags:
- '[0-9]+.[0-9]+.[0-9]+'
pull_request:
branches:
- master
@@ -154,11 +158,19 @@ jobs:
- name: Determine Docker tags
id: tags
run: |
BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | tr '/' '_')
if [ "$BRANCH" = "master" ]; then
echo "tags=${{ secrets.DOCKER_USERNAME }}/opensourcepos:${{ needs.build.outputs.version-tag }},${{ secrets.DOCKER_USERNAME }}/opensourcepos:master" >> $GITHUB_OUTPUT
REGISTRY="${{ secrets.DOCKER_USERNAME }}/opensourcepos"
SHA="${{ needs.build.outputs.short-sha }}"
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
echo "tags=${REGISTRY}:${VERSION},${REGISTRY}:latest" >> "$GITHUB_OUTPUT"
elif [[ "$GITHUB_REF" == refs/heads/master ]]; then
echo "tags=${REGISTRY}:master,${REGISTRY}:${SHA}" >> "$GITHUB_OUTPUT"
else
echo "tags=${{ secrets.DOCKER_USERNAME }}/opensourcepos:${{ needs.build.outputs.version-tag }}" >> $GITHUB_OUTPUT
BRANCH="${GITHUB_REF#refs/heads/}"
BRANCH="$(printf '%s' "$BRANCH" | LC_ALL=C tr -c 'A-Za-z0-9_.-' '_')"
BRANCH="${BRANCH:0:$((128 - ${#SHA} - 1))}"
[[ "$BRANCH" == [-.]* ]] && BRANCH="_${BRANCH:1}"
echo "tags=${REGISTRY}:${BRANCH}-${SHA}" >> "$GITHUB_OUTPUT"
fi
env:
GITHUB_REF: ${{ github.ref }}