diff --git a/.env.production.example b/.env.production.example index 2eac01d..91a5282 100644 --- a/.env.production.example +++ b/.env.production.example @@ -18,6 +18,6 @@ APERIO_METRICS_TOKEN=replace-me-with-a-long-random-metrics-token # The release image is signed and published to GHCR. Prefer the immutable # digest from the release-receipt artifact after the first pull/verification. -APERIO_IMAGE_REF=ghcr.io/writer/aperio:v0.1.0 +APERIO_IMAGE_REF=ghcr.io/writer/aperio:v0.1.1 APERIO_EVENT_BUS=nats APERIO_NATS_STREAM=CEREBRO_EVENTS diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 78be6ab..c8f42f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,6 +34,7 @@ jobs: with: go-version: "1.26.6" - run: npm ci + - run: npm run db:generate - run: npm run db:validate - run: npm run typecheck - run: npm run audit:prod diff --git a/CHANGELOG.md b/CHANGELOG.md index fa1982b..7f30c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to Aperio are recorded here. Release entries are tied to a s ## [Unreleased] +## [0.1.1] - 2026-08-21 + +- Fixed release validation to generate the Prisma client before typechecking. +- Republished the `0.1.0` feature set after the `v0.1.0` workflow stopped + before image publication. + ## [0.1.0] - 2026-08-21 - Added tenant-scoped, hashed API tokens with read, write, and admin scopes, diff --git a/deploy/compose/compose.production.yml b/deploy/compose/compose.production.yml index 98b0b6f..dc44ef1 100644 --- a/deploy/compose/compose.production.yml +++ b/deploy/compose/compose.production.yml @@ -30,7 +30,7 @@ services: retries: 12 migrate: - image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.0} + image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.1} restart: "no" environment: DATABASE_URL: postgresql://${POSTGRES_USER:-aperio}:${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env.production}@postgres:5432/${POSTGRES_DB:-aperio}?schema=public @@ -41,7 +41,7 @@ services: condition: service_healthy api: - image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.0} + image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.1} restart: unless-stopped init: true command: ["api"] @@ -73,7 +73,7 @@ services: start_period: 15s web: - image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.0} + image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.1} restart: unless-stopped init: true command: ["web"] @@ -95,7 +95,7 @@ services: start_period: 15s ingestion-worker: - image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.0} + image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.1} restart: unless-stopped init: true command: ["ingestion-worker"] @@ -113,7 +113,7 @@ services: condition: service_healthy siem-dispatcher: - image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.0} + image: ${APERIO_IMAGE_REF:-ghcr.io/writer/aperio:v0.1.1} restart: unless-stopped init: true command: ["siem-dispatcher"] diff --git a/docs/release.md b/docs/release.md index a6446d6..a5d243f 100644 --- a/docs/release.md +++ b/docs/release.md @@ -10,6 +10,7 @@ The public repository owns source validation and image publication. Deployment c ```bash npm ci +npm run db:generate npm run db:validate npm run typecheck npm run audit:prod @@ -23,18 +24,19 @@ Update [`CHANGELOG.md`](../CHANGELOG.md), confirm the image tag in [`.env.produc ## Publish ```bash -git tag -a v0.1.0 -m "Aperio v0.1.0" -git push origin v0.1.0 +VERSION=v0.1.1 +git tag -a "${VERSION}" -m "Aperio ${VERSION}" +git push origin "${VERSION}" ``` -The workflow publishes `ghcr.io/writer/aperio:v0.1.0` and uploads a `release-receipt` artifact containing the image tag, immutable digest, source commit, and signing result. Download that artifact and record the digest before deployment: +The workflow publishes `ghcr.io/writer/aperio:${VERSION}` and uploads a `release-receipt` artifact containing the image tag, immutable digest, source commit, and signing result. Download that artifact and record the digest before deployment: ```bash cosign verify \ - --certificate-identity "https://github.com/writer/aperio/.github/workflows/release.yml@refs/tags/v0.1.0" \ + --certificate-identity "https://github.com/writer/aperio/.github/workflows/release.yml@refs/tags/${VERSION}" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ - ghcr.io/writer/aperio:v0.1.0 -docker buildx imagetools inspect ghcr.io/writer/aperio:v0.1.0 + "ghcr.io/writer/aperio:${VERSION}" +docker buildx imagetools inspect "ghcr.io/writer/aperio:${VERSION}" ``` The public workflow does not dispatch into a private environment. The operator-owned deployment process must use the receipt digest, apply it through the private deployment system or the production Compose bundle, and retain the resulting deployment and user-path checks with the release record. For Compose, set `APERIO_IMAGE_REF` to the `image@sha256:...` value from the release receipt and capture `docker compose ... ps` plus the `/readyz` response after the migration service completes. diff --git a/tests/migration-ownership-guardrails.test.ts b/tests/migration-ownership-guardrails.test.ts index 08446ed..952b31c 100644 --- a/tests/migration-ownership-guardrails.test.ts +++ b/tests/migration-ownership-guardrails.test.ts @@ -764,6 +764,11 @@ test("validator and CI gates include contracts, audit, worker smoke, and secret assert.match(reviewPreflight, /name: Droid Review Preflight/); assert.match(reviewPreflight, /name: Droid Review Required/); assert.doesNotMatch(reviewPreflight, /Factory-AI|pull-requests:\s*write/i); + assert.match( + release, + /npm ci[\s\S]*npm run db:generate[\s\S]*npm run db:validate[\s\S]*npm run typecheck/, + "release validation must generate the Prisma client before typechecking" + ); assert.match(release, /name: Upload release receipt/); assert.match(release, /deployment: \"operator-owned\"/); assert.doesNotMatch(release, /notify-infra-release|APERIO_INFRA_|target_environment|repository_dispatch/i);