Files
HealthLog/.github/workflows/post-publish-verify.yml
T
dependabot[bot] 95293461f2 build(deps): bump docker/login-action from 4.5.1 to 4.6.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.5.1 to 4.6.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/abd2ef45e78c5afb21d64d4ca52ee8550d9572c7...dbcb813823bdd20940b903addbd779551569679f)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 11:02:10 +00:00

174 lines
5.7 KiB
YAML

name: Post-publish verify
on:
workflow_call:
inputs:
image_ref:
description: Exact registry repository to verify
required: true
type: string
image_tag:
description: Exact published release tag
required: true
type: string
image_digest:
description: Exact published multi-arch manifest digest
required: true
type: string
build_sha:
description: Expected short source commit SHA
required: true
type: string
workflow_dispatch:
inputs:
image_ref:
description: Exact registry repository to verify
required: true
type: string
image_tag:
description: Exact published release tag
required: true
type: string
image_digest:
description: Exact published multi-arch manifest digest
required: true
type: string
build_sha:
description: Expected short source commit SHA
required: true
type: string
permissions:
contents: read
packages: read
jobs:
verify:
name: Pull and smoke-test exact published image
runs-on: ubuntu-latest
timeout-minutes: 10
env:
IMAGE_REF: ${{ inputs.image_ref }}
IMAGE_TAG: ${{ inputs.image_tag }}
IMAGE_DIGEST: ${{ inputs.image_digest }}
BUILD_SHA: ${{ inputs.build_sha }}
DATABASE_URL: postgresql://healthlog:healthlog@localhost:5432/healthlog?schema=public
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: healthlog
POSTGRES_PASSWORD: healthlog
POSTGRES_DB: healthlog
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U healthlog"
--health-interval 5s
--health-timeout 5s
--health-retries 10
steps:
- name: Log in to GHCR
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pull exact image
run: |
TAG_REF="${IMAGE_REF}:${IMAGE_TAG}"
DIGEST_REF="${IMAGE_REF}@${IMAGE_DIGEST}"
echo "Pulling published tag $TAG_REF"
docker pull "$TAG_REF"
resolved_digest="$(docker buildx imagetools inspect "$TAG_REF" --format '{{json .Manifest.Digest}}' | tr -d '"')"
if [ "$resolved_digest" != "$IMAGE_DIGEST" ]; then
echo "::error::Published tag digest mismatch: $TAG_REF resolved to '$resolved_digest', expected '$IMAGE_DIGEST'." >&2
exit 1
fi
echo "Pulling immutable image $DIGEST_REF"
docker pull "$DIGEST_REF"
- name: Run migrations
run: |
DIGEST_REF="${IMAGE_REF}@${IMAGE_DIGEST}"
docker run --rm \
--network host \
--entrypoint node \
-e DATABASE_URL="$DATABASE_URL" \
"$DIGEST_REF" \
/opt/prisma-cli/node_modules/prisma/build/index.js migrate deploy
- name: Start exact image
run: |
DIGEST_REF="${IMAGE_REF}@${IMAGE_DIGEST}"
docker run -d --name healthlog-verify \
--network host \
-e DATABASE_URL="$DATABASE_URL" \
-e ENCRYPTION_KEYS='{"v1":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}' \
-e ENCRYPTION_ACTIVE_KEY_ID=v1 \
-e API_TOKEN_HMAC_KEY=cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc \
-e AUTH_RP_NAME=HealthLog \
-e AUTH_RP_ID=localhost \
-e AUTH_RP_ORIGIN=http://localhost:3000 \
-e NODE_ENV=production \
-e PORT=3000 \
"$DIGEST_REF"
- name: Verify exact version
run: |
body=""
for i in $(seq 1 30); do
if body="$(curl -sf http://localhost:3000/api/version)"; then
echo "Version endpoint ready after $((i * 2))s"
break
fi
sleep 2
done
if [ -z "$body" ]; then
echo "::error::Exact image did not expose /api/version within 60 seconds." >&2
docker logs healthlog-verify || true
exit 1
fi
EXPECTED_VERSION="${IMAGE_TAG#v}"
echo "$body" | jq .
if ! jq -e --arg expected "$EXPECTED_VERSION" '.data.version == $expected' <<< "$body" >/dev/null; then
actual="$(jq -r '.data.version // "<missing>"' <<< "$body")"
echo "::error::Version mismatch: exact image reports '$actual', expected '$EXPECTED_VERSION' (release tag '$IMAGE_TAG')." >&2
exit 1
fi
if ! jq -e --arg expected "$BUILD_SHA" '.data.buildSha == $expected' <<< "$body" >/dev/null; then
actual="$(jq -r '.data.buildSha // "<missing>"' <<< "$body")"
echo "::error::Build SHA mismatch: exact image reports '$actual', expected '$BUILD_SHA'." >&2
exit 1
fi
- name: Verify health
run: |
for i in $(seq 1 30); do
if body="$(curl -sf http://localhost:3000/api/health)" && jq -e '.status == "ok"' <<< "$body" >/dev/null; then
echo "$body" | jq .
echo "Health endpoint ready after $((i * 2))s"
exit 0
fi
sleep 2
done
echo "::error::Exact image did not report healthy within 60 seconds." >&2
docker logs healthlog-verify || true
exit 1
- name: Container logs
if: always()
continue-on-error: true
run: docker logs healthlog-verify
- name: Tear down
if: always()
continue-on-error: true
run: docker rm -f healthlog-verify