feat: implement version UI and short-sha CI versioning

This commit is contained in:
neon
2026-05-13 21:59:15 +00:00
parent 4fb157cc3b
commit f9c1e29911
25 changed files with 1107 additions and 63 deletions
+16 -8
View File
@@ -82,6 +82,7 @@ jobs:
packages: read
outputs:
source_sha: ${{ steps.ctx.outputs.source_sha }}
source_sha_short: ${{ steps.ctx.outputs.source_sha_short }}
update_main: ${{ steps.ctx.outputs.update_main }}
skip_build: ${{ steps.ctx.outputs.skip_build }}
steps:
@@ -108,14 +109,20 @@ jobs:
SOURCE_SHA="$GH_SHA"
echo "update_main=false" >> "$GITHUB_OUTPUT"
fi
SOURCE_SHA_SHORT="${SOURCE_SHA:0:12}"
echo "source_sha=${SOURCE_SHA}" >> "$GITHUB_OUTPUT"
echo "source_sha_short=${SOURCE_SHA_SHORT}" >> "$GITHUB_OUTPUT"
IMAGE_LOWER=$(echo "${IMAGE_NAME}" | tr '[:upper:]' '[:lower:]')
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
HTTP_STATUS_SHORT=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "Accept: application/vnd.oci.image.index.v1+json" \
"https://ghcr.io/v2/${IMAGE_LOWER}/manifests/sha-${SOURCE_SHA_SHORT}")
HTTP_STATUS_FULL=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "Accept: application/vnd.oci.image.index.v1+json" \
"https://ghcr.io/v2/${IMAGE_LOWER}/manifests/sha-${SOURCE_SHA}")
if [[ "$HTTP_STATUS" == "200" && "${FORCE_REBUILD}" != "true" ]]; then
echo "Image sha-${SOURCE_SHA} already exists in GHCR, skipping rebuild."
if [[ ("$HTTP_STATUS_SHORT" == "200" || "$HTTP_STATUS_FULL" == "200") && "${FORCE_REBUILD}" != "true" ]]; then
echo "Image sha-${SOURCE_SHA_SHORT} already exists in GHCR, skipping rebuild."
echo "skip_build=true" >> "$GITHUB_OUTPUT"
else
echo "skip_build=false" >> "$GITHUB_OUTPUT"
@@ -159,6 +166,7 @@ jobs:
file: ./Dockerfile
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
platforms: linux/amd64
build-args: APP_VERSION=sha-${{ needs.prepare.outputs.source_sha_short }}
cache-from: type=gha,scope=container-image-yml-amd64
cache-to: type=gha,mode=max,scope=container-image-yml-amd64
@@ -212,6 +220,7 @@ jobs:
file: ./Dockerfile
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
platforms: linux/arm64
build-args: APP_VERSION=sha-${{ needs.prepare.outputs.source_sha_short }}
cache-from: type=gha,scope=container-image-yml-arm64
cache-to: type=gha,mode=max,scope=container-image-yml-arm64
@@ -255,13 +264,13 @@ jobs:
env:
REGISTRY: ${{ env.REGISTRY }}
IMAGE: ${{ env.IMAGE_NAME }}
SHA: ${{ needs.prepare.outputs.source_sha }}
SHA_SHORT: ${{ needs.prepare.outputs.source_sha_short }}
AMD64_DIGEST: ${{ needs.build-amd64.outputs.digest }}
ARM64_DIGEST: ${{ needs.build-arm64.outputs.digest }}
run: |
FULL_IMAGE="${REGISTRY}/${IMAGE}"
docker buildx imagetools create \
--tag "${FULL_IMAGE}:sha-${SHA}" \
--tag "${FULL_IMAGE}:sha-${SHA_SHORT}" \
"${FULL_IMAGE}@${AMD64_DIGEST}" \
"${FULL_IMAGE}@${ARM64_DIGEST}"
@@ -271,7 +280,6 @@ jobs:
env:
REGISTRY: ${{ env.REGISTRY }}
IMAGE: ${{ env.IMAGE_NAME }}
SHA: ${{ needs.prepare.outputs.source_sha }}
AMD64_DIGEST: ${{ needs.build-amd64.outputs.digest }}
ARM64_DIGEST: ${{ needs.build-arm64.outputs.digest }}
run: |
@@ -286,5 +294,5 @@ jobs:
env:
REGISTRY: ${{ env.REGISTRY }}
IMAGE: ${{ env.IMAGE_NAME }}
SHA: ${{ needs.prepare.outputs.source_sha }}
run: docker buildx imagetools inspect "${REGISTRY}/${IMAGE}:sha-${SHA}"
SHA_SHORT: ${{ needs.prepare.outputs.source_sha_short }}
run: docker buildx imagetools inspect "${REGISTRY}/${IMAGE}:sha-${SHA_SHORT}"
+33 -48
View File
@@ -142,12 +142,13 @@ jobs:
IMAGE_NAME: ${{ github.repository }}
run: |
set -euo pipefail
SOURCE_TAG="ghcr.io/${IMAGE_NAME}:sha-${COMMIT_SHA}"
SHORT_SHA="${COMMIT_SHA:0:12}"
SOURCE_TAG="ghcr.io/${IMAGE_NAME}:sha-${SHORT_SHA}"
if ! docker buildx imagetools inspect "${SOURCE_TAG}" > /dev/null 2>&1; then
echo "::error::Multi-arch image sha-${COMMIT_SHA} not found in GHCR. Wait for the Container Image workflow to complete for this commit before releasing."
echo "::error::Multi-arch image sha-${SHORT_SHA} not found in GHCR. Wait for the Container Image workflow to complete for this commit before releasing."
exit 1
fi
echo "Image sha-${COMMIT_SHA} verified in GHCR."
echo "Image sha-${SHORT_SHA} verified in GHCR."
- name: Set up Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
@@ -192,7 +193,7 @@ jobs:
needs: [release]
if: needs.release.outputs.published == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 60
permissions:
contents: write
packages: write
@@ -200,6 +201,14 @@ jobs:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
steps:
- name: Checkout release tag
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ needs.release.outputs.tag }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
@@ -210,46 +219,21 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Verify SHA image and resolve digest
id: source
shell: bash
env:
REGISTRY: ${{ env.REGISTRY }}
IMAGE: ${{ env.IMAGE_NAME }}
SHA: ${{ github.sha }}
run: |
FULL_IMAGE="${REGISTRY}/${IMAGE}"
SOURCE_TAG="${FULL_IMAGE}:sha-${SHA}"
if ! docker buildx imagetools inspect "${SOURCE_TAG}" > /dev/null 2>&1; then
echo "::error::Multi-arch image sha-${SHA} not found in GHCR. Wait for the Container Image workflow to complete for this commit before releasing."
exit 1
fi
DIGEST=$(docker buildx imagetools inspect --format '{{json .Manifest}}' "${SOURCE_TAG}" | jq -r '.digest')
echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT"
echo "image=${FULL_IMAGE}" >> "$GITHUB_OUTPUT"
- name: Promote to version and latest
shell: bash
env:
VERSION: ${{ needs.release.outputs.version }}
DIGEST: ${{ steps.source.outputs.digest }}
IMAGE: ${{ steps.source.outputs.image }}
run: |
docker buildx imagetools create \
--tag "${IMAGE}:${VERSION}" \
"${IMAGE}@${DIGEST}"
docker buildx imagetools create \
--tag "${IMAGE}:latest" \
"${IMAGE}@${DIGEST}"
- name: Inspect promoted manifests
shell: bash
env:
VERSION: ${{ needs.release.outputs.version }}
IMAGE: ${{ steps.source.outputs.image }}
run: |
docker buildx imagetools inspect "${IMAGE}:${VERSION}"
docker buildx imagetools inspect "${IMAGE}:latest"
- name: Build and push versioned image
id: build
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.release.outputs.version }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
build-args: APP_VERSION=v${{ needs.release.outputs.version }}
cache-from: |
type=gha,scope=container-image-yml-amd64
type=gha,scope=container-image-yml-arm64
- name: Enrich release notes
shell: bash
@@ -259,8 +243,8 @@ jobs:
TAG: ${{ needs.release.outputs.tag }}
VERSION: ${{ needs.release.outputs.version }}
SHA: ${{ github.sha }}
IMAGE: ${{ steps.source.outputs.image }}
DIGEST: ${{ steps.source.outputs.digest }}
IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
DIGEST: ${{ steps.build.outputs.digest }}
run: |
set -euo pipefail
BODY_FILE="$(mktemp)"
@@ -300,7 +284,8 @@ jobs:
VERSION: ${{ needs.release.outputs.version }}
SHA: ${{ github.sha }}
run: |
echo "## Docker Image Promoted" >> "$GITHUB_STEP_SUMMARY"
echo "## Docker Image Published" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "- **Source:** \`sha-${SHA}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- **Version:** \`${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- **Tags:** \`${VERSION}\`, \`latest\` (linux/amd64, linux/arm64)" >> "$GITHUB_STEP_SUMMARY"
echo "- **APP_VERSION baked:** \`v${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"