♻️ Make sha mean the full commit SHA, short_sha the 12-char one

sha is the full 40-char SHA in build-bundle.yml's output and
build-docker.yml's new checkout-pinning input, matching git and
GitHub's own convention. short_sha stays internal to each workflow
for the S3 keys and image tags that already used it — build-bundle.yml
no longer exposes it externally since nothing outside consumed it.

No S3 key, image tag, or marker value changes anywhere.

Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
This commit is contained in:
bameda 2026-09-22 15:01:06 +00:00 committed by David Barragán Merino
parent 5901af4187
commit 0622680691
5 changed files with 33 additions and 46 deletions

View File

@ -34,10 +34,7 @@ jobs:
secrets: inherit secrets: inherit
with: with:
gh_ref: ${{ inputs.gh_ref }} gh_ref: ${{ inputs.gh_ref }}
# Pin the exact commit build-bundle already resolved and uploaded to # Pin build-docker to the commit build-bundle actually bundled.
# S3, instead of letting build-docker re-resolve gh_ref on its own
# checkout minutes later, which can land on a newer commit than the
# one actually bundled if gh_ref names a branch that moved meanwhile.
sha: ${{ needs.build-bundle.outputs.sha }} sha: ${{ needs.build-bundle.outputs.sha }}
force: ${{ inputs.force }} force: ${{ inputs.force }}

View File

@ -28,12 +28,7 @@ on:
default: false default: false
outputs: outputs:
sha: sha:
description: >- description: 'Bundled commit, full 40-char SHA.'
The exact commit this run resolved gh_ref to and bundled. Callers
that also trigger build-docker.yml should pass it through as that
workflow's `sha` input, so both pipelines agree on one commit
instead of each re-resolving gh_ref independently at a different
time.
value: ${{ jobs.check.outputs.sha }} value: ${{ jobs.check.outputs.sha }}
# Literal group name: under `workflow_call`, `github.workflow` resolves to the # Literal group name: under `workflow_call`, `github.workflow` resolves to the
@ -53,6 +48,7 @@ jobs:
outputs: outputs:
gh_ref: ${{ steps.vars.outputs.gh_ref }} gh_ref: ${{ steps.vars.outputs.gh_ref }}
bundle_version: ${{ steps.vars.outputs.bundle_version }} bundle_version: ${{ steps.vars.outputs.bundle_version }}
short_sha: ${{ steps.vars.outputs.short_sha }}
sha: ${{ steps.vars.outputs.sha }} sha: ${{ steps.vars.outputs.sha }}
commit_title: ${{ steps.vars.outputs.commit_title }} commit_title: ${{ steps.vars.outputs.commit_title }}
exists: ${{ steps.check.outputs.exists }} exists: ${{ steps.check.outputs.exists }}
@ -69,7 +65,8 @@ jobs:
run: | run: |
echo "gh_ref=${{ inputs.gh_ref || github.ref_name }}" >> $GITHUB_OUTPUT echo "gh_ref=${{ inputs.gh_ref || github.ref_name }}" >> $GITHUB_OUTPUT
echo "bundle_version=$(git describe --tags --always)" >> $GITHUB_OUTPUT echo "bundle_version=$(git describe --tags --always)" >> $GITHUB_OUTPUT
echo "sha=$(git rev-parse --short=12 HEAD)" >> $GITHUB_OUTPUT echo "short_sha=$(git rev-parse --short=12 HEAD)" >> $GITHUB_OUTPUT
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "commit_title=$(git log -1 --pretty=%s)" >> $GITHUB_OUTPUT echo "commit_title=$(git log -1 --pretty=%s)" >> $GITHUB_OUTPUT
# Keyed by commit sha, same as build-docker.yml's marker check, so # Keyed by commit sha, same as build-docker.yml's marker check, so
@ -95,7 +92,7 @@ jobs:
BUNDLE_EXISTS=$(aws s3api head-object \ BUNDLE_EXISTS=$(aws s3api head-object \
--bucket ${{ secrets.S3_BUCKET }} \ --bucket ${{ secrets.S3_BUCKET }} \
--key "penpot-sha-${{ steps.vars.outputs.sha }}.zip" \ --key "penpot-sha-${{ steps.vars.outputs.short_sha }}.zip" \
> /dev/null 2>&1 && echo "true" || echo "false") > /dev/null 2>&1 && echo "true" || echo "false")
if [ "$BUNDLE_EXISTS" = "true" ]; then if [ "$BUNDLE_EXISTS" = "true" ]; then
@ -103,7 +100,7 @@ jobs:
{ {
echo "### ⏭️ Bundle build skipped" echo "### ⏭️ Bundle build skipped"
echo "" echo ""
echo "The bundle in S3 was already built from \`sha-${{ steps.vars.outputs.sha }}\` (\`${{ steps.vars.outputs.bundle_version }}\`)." echo "The bundle in S3 was already built from \`sha-${{ steps.vars.outputs.short_sha }}\` (\`${{ steps.vars.outputs.bundle_version }}\`)."
} >> "$GITHUB_STEP_SUMMARY" } >> "$GITHUB_STEP_SUMMARY"
else else
echo "exists=false" >> $GITHUB_OUTPUT echo "exists=false" >> $GITHUB_OUTPUT
@ -147,7 +144,7 @@ jobs:
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }} AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
run: | run: |
aws s3 cp zips/penpot.zip \ aws s3 cp zips/penpot.zip \
s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ needs.check.outputs.sha }}.zip \ s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ needs.check.outputs.short_sha }}.zip \
--metadata bundle-version=${{ needs.check.outputs.bundle_version }} --metadata bundle-version=${{ needs.check.outputs.bundle_version }}
- name: Write step summary - name: Write step summary
@ -156,7 +153,7 @@ jobs:
echo "### ✅ Bundle built" echo "### ✅ Bundle built"
echo "" echo ""
echo "- Version: \`${{ needs.check.outputs.bundle_version }}\` (\`git describe --tags --always\`)" echo "- Version: \`${{ needs.check.outputs.bundle_version }}\` (\`git describe --tags --always\`)"
echo "- Commit: [\`${{ needs.check.outputs.sha }}\`](https://github.com/${{ github.repository }}/commit/${{ needs.check.outputs.sha }}) — ${{ needs.check.outputs.commit_title }}" echo "- Commit: [\`${{ needs.check.outputs.short_sha }}\`](https://github.com/${{ github.repository }}/commit/${{ needs.check.outputs.short_sha }}) — ${{ needs.check.outputs.commit_title }}"
echo "- Built at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" echo "- Built at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
} >> "$GITHUB_STEP_SUMMARY" } >> "$GITHUB_STEP_SUMMARY"

View File

@ -32,10 +32,7 @@ jobs:
secrets: inherit secrets: inherit
with: with:
gh_ref: "develop" gh_ref: "develop"
# Pin the exact commit build-bundle already resolved and uploaded to # Pin build-docker to the commit build-bundle actually bundled.
# S3, instead of letting build-docker re-resolve "develop" on its own
# checkout minutes later, which can land on a newer commit than the
# one actually bundled.
sha: ${{ needs.build-bundle.outputs.sha }} sha: ${{ needs.build-bundle.outputs.sha }}
force: ${{ inputs.force || false }} force: ${{ inputs.force || false }}

View File

@ -22,12 +22,9 @@ on:
default: 'develop' default: 'develop'
sha: sha:
description: >- description: >-
Exact commit to check out and build, e.g. from build-bundle.yml's Exact commit to check out (full 40-char SHA, e.g. from
`sha` output. gh_ref is still used to resolve the checkout when build-bundle.yml). Falls back to gh_ref when empty; gh_ref
this is empty, and always names the branch tag to move — passing always still names the branch tag to move.
both avoids the checkout re-resolving gh_ref on its own, possibly
to a newer commit than the one build-bundle.yml already bundled
and uploaded to S3 under its own resolved sha.
type: string type: string
required: false required: false
default: '' default: ''
@ -63,6 +60,7 @@ jobs:
gh_ref: ${{ steps.vars.outputs.gh_ref }} gh_ref: ${{ steps.vars.outputs.gh_ref }}
bundle_version: ${{ steps.vars.outputs.bundle_version }} bundle_version: ${{ steps.vars.outputs.bundle_version }}
sha: ${{ steps.vars.outputs.sha }} sha: ${{ steps.vars.outputs.sha }}
short_sha: ${{ steps.vars.outputs.short_sha }}
commit_title: ${{ steps.vars.outputs.commit_title }} commit_title: ${{ steps.vars.outputs.commit_title }}
exists: ${{ steps.check.outputs.exists }} exists: ${{ steps.check.outputs.exists }}
@ -78,7 +76,8 @@ jobs:
run: | run: |
GH_REF="${{ inputs.gh_ref || github.ref_name }}" GH_REF="${{ inputs.gh_ref || github.ref_name }}"
echo "gh_ref=$GH_REF" >> $GITHUB_OUTPUT echo "gh_ref=$GH_REF" >> $GITHUB_OUTPUT
echo "sha=$(git rev-parse --short=12 HEAD)" >> $GITHUB_OUTPUT echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "short_sha=$(git rev-parse --short=12 HEAD)" >> $GITHUB_OUTPUT
echo "commit_title=$(git log -1 --pretty=%s)" >> $GITHUB_OUTPUT echo "commit_title=$(git log -1 --pretty=%s)" >> $GITHUB_OUTPUT
echo "bundle_version=$(git describe --tags --always)" >> $GITHUB_OUTPUT echo "bundle_version=$(git describe --tags --always)" >> $GITHUB_OUTPUT
@ -98,8 +97,8 @@ jobs:
echo "exists=false" >> $GITHUB_OUTPUT echo "exists=false" >> $GITHUB_OUTPUT
mkdir -p "$BUNDLE_CACHE" mkdir -p "$BUNDLE_CACHE"
find "$BUNDLE_CACHE" -type f -mtime +1 -delete || true find "$BUNDLE_CACHE" -type f -mtime +1 -delete || true
ZIP="$BUNDLE_CACHE/penpot-sha-${{ steps.vars.outputs.sha }}.zip" ZIP="$BUNDLE_CACHE/penpot-sha-${{ steps.vars.outputs.short_sha }}.zip"
aws s3 cp "s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ steps.vars.outputs.sha }}.zip" "$ZIP.$$.tmp" aws s3 cp "s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ steps.vars.outputs.short_sha }}.zip" "$ZIP.$$.tmp"
mv "$ZIP.$$.tmp" "$ZIP" mv "$ZIP.$$.tmp" "$ZIP"
{ {
echo "### 🔁 Image set build forced" echo "### 🔁 Image set build forced"
@ -111,13 +110,13 @@ jobs:
if aws s3api head-object \ if aws s3api head-object \
--bucket ${{ secrets.S3_BUCKET }} \ --bucket ${{ secrets.S3_BUCKET }} \
--key "markers/images-sha-${{ steps.vars.outputs.sha }}" \ --key "markers/images-sha-${{ steps.vars.outputs.short_sha }}" \
> /dev/null 2>&1; then > /dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT echo "exists=true" >> $GITHUB_OUTPUT
{ {
echo "### ⏭️ Image set build skipped" echo "### ⏭️ Image set build skipped"
echo "" echo ""
echo "The whole set was already built and promoted for \`sha-${{ steps.vars.outputs.sha }}\`." echo "The whole set was already built and promoted for \`sha-${{ steps.vars.outputs.short_sha }}\`."
} >> "$GITHUB_STEP_SUMMARY" } >> "$GITHUB_STEP_SUMMARY"
else else
echo "exists=false" >> $GITHUB_OUTPUT echo "exists=false" >> $GITHUB_OUTPUT
@ -127,9 +126,9 @@ jobs:
# prune stale bundles while at it. # prune stale bundles while at it.
mkdir -p "$BUNDLE_CACHE" mkdir -p "$BUNDLE_CACHE"
find "$BUNDLE_CACHE" -type f -mtime +1 -delete || true find "$BUNDLE_CACHE" -type f -mtime +1 -delete || true
ZIP="$BUNDLE_CACHE/penpot-sha-${{ steps.vars.outputs.sha }}.zip" ZIP="$BUNDLE_CACHE/penpot-sha-${{ steps.vars.outputs.short_sha }}.zip"
if [ ! -f "$ZIP" ]; then if [ ! -f "$ZIP" ]; then
aws s3 cp "s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ steps.vars.outputs.sha }}.zip" "$ZIP.$$.tmp" aws s3 cp "s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ steps.vars.outputs.short_sha }}.zip" "$ZIP.$$.tmp"
mv "$ZIP.$$.tmp" "$ZIP" mv "$ZIP.$$.tmp" "$ZIP"
fi fi
fi fi
@ -199,11 +198,11 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }} AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
run: | run: |
ZIP="$BUNDLE_CACHE/penpot-sha-${{ needs.prepare.outputs.sha }}.zip" ZIP="$BUNDLE_CACHE/penpot-sha-${{ needs.prepare.outputs.short_sha }}.zip"
if [ ! -f "$ZIP" ]; then if [ ! -f "$ZIP" ]; then
echo "Bundle not found in host cache; falling back to S3." echo "Bundle not found in host cache; falling back to S3."
mkdir -p "$BUNDLE_CACHE" mkdir -p "$BUNDLE_CACHE"
aws s3 cp "s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ needs.prepare.outputs.sha }}.zip" "$ZIP.$$.tmp" aws s3 cp "s3://${{ secrets.S3_BUCKET }}/penpot-sha-${{ needs.prepare.outputs.short_sha }}.zip" "$ZIP.$$.tmp"
mv "$ZIP.$$.tmp" "$ZIP" mv "$ZIP.$$.tmp" "$ZIP"
fi fi
# Extract only the bundle this job needs. # Extract only the bundle this job needs.
@ -239,7 +238,7 @@ jobs:
sbom: true sbom: true
# Immutable tag only; branch tags are moved atomically for the # Immutable tag only; branch tags are moved atomically for the
# whole image set by the `promote` job. # whole image set by the `promote` job.
tags: ${{ secrets.DOCKER_REGISTRY }}/${{ matrix.image }}:sha-${{ needs.prepare.outputs.sha }} tags: ${{ secrets.DOCKER_REGISTRY }}/${{ matrix.image }}:sha-${{ needs.prepare.outputs.short_sha }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ secrets.DOCKER_REGISTRY }}/${{ matrix.image }}:buildcache cache-from: type=registry,ref=${{ secrets.DOCKER_REGISTRY }}/${{ matrix.image }}:buildcache
cache-to: type=registry,ref=${{ secrets.DOCKER_REGISTRY }}/${{ matrix.image }}:buildcache,mode=max cache-to: type=registry,ref=${{ secrets.DOCKER_REGISTRY }}/${{ matrix.image }}:buildcache,mode=max
@ -272,7 +271,7 @@ jobs:
for image in $ALL_IMAGES; do for image in $ALL_IMAGES; do
docker buildx imagetools create \ docker buildx imagetools create \
-t "${{ secrets.DOCKER_REGISTRY }}/$image:${{ needs.prepare.outputs.gh_ref }}" \ -t "${{ secrets.DOCKER_REGISTRY }}/$image:${{ needs.prepare.outputs.gh_ref }}" \
"${{ secrets.DOCKER_REGISTRY }}/$image:sha-${{ needs.prepare.outputs.sha }}" "${{ secrets.DOCKER_REGISTRY }}/$image:sha-${{ needs.prepare.outputs.short_sha }}"
done done
# The marker is written LAST: its presence certifies that all five # The marker is written LAST: its presence certifies that all five
@ -284,7 +283,7 @@ jobs:
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }} AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
run: | run: |
echo "${{ github.run_id }}" | aws s3 cp - \ echo "${{ github.run_id }}" | aws s3 cp - \
"s3://${{ secrets.S3_BUCKET }}/markers/images-sha-${{ needs.prepare.outputs.sha }}" "s3://${{ secrets.S3_BUCKET }}/markers/images-sha-${{ needs.prepare.outputs.short_sha }}"
- name: Write step summary - name: Write step summary
run: | run: |
@ -292,10 +291,10 @@ jobs:
echo "### ✅ Image set promoted" echo "### ✅ Image set promoted"
echo "" echo ""
echo "- Version: \`${{ needs.prepare.outputs.bundle_version }}\` (\`git describe --tags --always\`)" echo "- Version: \`${{ needs.prepare.outputs.bundle_version }}\` (\`git describe --tags --always\`)"
echo "- Commit: [\`${{ needs.prepare.outputs.sha }}\`](https://github.com/${{ github.repository }}/commit/${{ needs.prepare.outputs.sha }}) — ${{ needs.prepare.outputs.commit_title }}" echo "- Commit: [\`${{ needs.prepare.outputs.short_sha }}\`](https://github.com/${{ github.repository }}/commit/${{ needs.prepare.outputs.short_sha }}) — ${{ needs.prepare.outputs.commit_title }}"
echo "- Built at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" echo "- Built at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
echo "" echo ""
echo "All \`:${{ needs.prepare.outputs.gh_ref }}\` tags now point to \`sha-${{ needs.prepare.outputs.sha }}\`." echo "All \`:${{ needs.prepare.outputs.gh_ref }}\` tags now point to \`sha-${{ needs.prepare.outputs.short_sha }}\`."
} >> "$GITHUB_STEP_SUMMARY" } >> "$GITHUB_STEP_SUMMARY"
# ── 3b. Skip path: make sure THIS ref's tags point to the existing # ── 3b. Skip path: make sure THIS ref's tags point to the existing
@ -330,7 +329,7 @@ jobs:
for image in $ALL_IMAGES; do for image in $ALL_IMAGES; do
docker buildx imagetools create \ docker buildx imagetools create \
-t "${{ secrets.DOCKER_REGISTRY }}/$image:${{ needs.prepare.outputs.gh_ref }}" \ -t "${{ secrets.DOCKER_REGISTRY }}/$image:${{ needs.prepare.outputs.gh_ref }}" \
"${{ secrets.DOCKER_REGISTRY }}/$image:sha-${{ needs.prepare.outputs.sha }}" "${{ secrets.DOCKER_REGISTRY }}/$image:sha-${{ needs.prepare.outputs.short_sha }}"
done done
- name: Write step summary - name: Write step summary
@ -339,10 +338,10 @@ jobs:
echo "### ✅ Image set already built (branch tags ensured)" echo "### ✅ Image set already built (branch tags ensured)"
echo "" echo ""
echo "- Version: \`${{ needs.prepare.outputs.bundle_version }}\` (\`git describe --tags --always\`)" echo "- Version: \`${{ needs.prepare.outputs.bundle_version }}\` (\`git describe --tags --always\`)"
echo "- Commit: [\`${{ needs.prepare.outputs.sha }}\`](https://github.com/${{ github.repository }}/commit/${{ needs.prepare.outputs.sha }}) — ${{ needs.prepare.outputs.commit_title }}" echo "- Commit: [\`${{ needs.prepare.outputs.short_sha }}\`](https://github.com/${{ github.repository }}/commit/${{ needs.prepare.outputs.short_sha }}) — ${{ needs.prepare.outputs.commit_title }}"
echo "- Checked at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" echo "- Checked at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
echo "" echo ""
echo "All \`:${{ needs.prepare.outputs.gh_ref }}\` tags now point to \`sha-${{ needs.prepare.outputs.sha }}\`." echo "All \`:${{ needs.prepare.outputs.gh_ref }}\` tags now point to \`sha-${{ needs.prepare.outputs.short_sha }}\`."
} >> "$GITHUB_STEP_SUMMARY" } >> "$GITHUB_STEP_SUMMARY"
# ── 4. Single failure notification for the whole workflow ───────────── # ── 4. Single failure notification for the whole workflow ─────────────

View File

@ -32,10 +32,7 @@ jobs:
secrets: inherit secrets: inherit
with: with:
gh_ref: "staging" gh_ref: "staging"
# Pin the exact commit build-bundle already resolved and uploaded to # Pin build-docker to the commit build-bundle actually bundled.
# S3, instead of letting build-docker re-resolve "staging" on its own
# checkout minutes later, which can land on a newer commit than the
# one actually bundled.
sha: ${{ needs.build-bundle.outputs.sha }} sha: ${{ needs.build-bundle.outputs.sha }}
force: ${{ inputs.force || false }} force: ${{ inputs.force || false }}