From 7dfdf8d5931adbaa12521b7a5ca3f37974a94904 Mon Sep 17 00:00:00 2001 From: Quintine <15965533+Quintine@users.noreply.github.com> Date: Wed, 28 Oct 2026 20:35:37 +1100 Subject: [PATCH] Prepare Gitea checkpoint container workflow --- .gitea/workflows/container.yml | 78 ++++++++++++++++++++++++++++++++++ AGENTS.md | 6 ++- Dockerfile | 2 +- docs/CURRENT_STATUS.md | 8 ++++ docs/TRUENAS.md | 45 ++++++++++++++------ 5 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 .gitea/workflows/container.yml diff --git a/.gitea/workflows/container.yml b/.gitea/workflows/container.yml new file mode 100644 index 00000000..afec235c --- /dev/null +++ b/.gitea/workflows/container.yml @@ -0,0 +1,78 @@ +name: Verify and publish checkpoint container + +on: + push: + branches: [main, 'codex/**'] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: dune-checkpoint-container + cancel-in-progress: false + +jobs: + container: + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + DUNE_CONTAINER_IMAGE: ${{ vars.DUNE_CONTAINER_IMAGE || 'git.juiced.computer/admin/dune' }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + - run: npm ci + - uses: docker/setup-buildx-action@v3 + - name: Build container + uses: docker/build-push-action@v6 + with: + context: . + build-args: | + BUILD_REVISION=${{ github.sha }} + load: true + tags: dune:verify + - name: Verify isolated storage and HTTP behavior + run: node tools/verify-container.mjs dune:verify + - name: Configure container registry + if: github.ref == 'refs/heads/main' + env: + REGISTRY_TOKEN: ${{ secrets.CONTAINER_REGISTRY_TOKEN }} + REGISTRY_USERNAME: ${{ vars.DUNE_REGISTRY_USERNAME || github.repository_owner }} + run: | + if [[ -z "$REGISTRY_TOKEN" ]]; then + echo '::error::Set the CONTAINER_REGISTRY_TOKEN repository secret to publish the verified image.' + exit 1 + fi + if [[ -z "$REGISTRY_USERNAME" ]]; then + echo '::error::Set the DUNE_REGISTRY_USERNAME repository variable to a registry account.' + exit 1 + fi + image="${DUNE_CONTAINER_IMAGE,,}" + if [[ "$image" != */* || "$image" == *[!a-z0-9._/:-]* || "${image#*/}" == *:* ]]; then + echo '::error::DUNE_CONTAINER_IMAGE must be an untagged registry/owner/image name.' + exit 1 + fi + registry="${image%%/*}" + if [[ -z "$registry" || -z "${image#*/}" ]]; then + echo '::error::DUNE_CONTAINER_IMAGE must include a registry and image name.' + exit 1 + fi + printf 'DUNE_REGISTRY=%s\nDUNE_IMAGE=%s\n' "$registry" "$image" >> "$GITHUB_ENV" + - name: Log in to container registry + if: github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + registry: ${{ env.DUNE_REGISTRY }} + username: ${{ vars.DUNE_REGISTRY_USERNAME || github.repository_owner }} + password: ${{ secrets.CONTAINER_REGISTRY_TOKEN }} + - name: Publish the verified image + if: github.ref == 'refs/heads/main' + env: + REVISION: ${{ github.sha }} + run: | + docker tag dune:verify "$DUNE_IMAGE:sha-$REVISION" + docker tag dune:verify "$DUNE_IMAGE:checkpoint" + docker push "$DUNE_IMAGE:sha-$REVISION" + docker push "$DUNE_IMAGE:checkpoint" diff --git a/AGENTS.md b/AGENTS.md index 1979376e..bfe30bb7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -136,4 +136,8 @@ integration owner freezes related work before running shared checks. - Use subagents selectively for bounded independent tasks and complex reviews; they remain explicitly authorized. Share concise briefs and file ownership. - Review, verify, commit and push completed checkpoints automatically under - “Push all from now on.” Confirm push success; never force-push or expose secrets. + “Push all from now on.” The intended `origin` is + `https://git.juiced.computer/admin/Dune.git`; verify the destination and push + success. Do not fall back to GitHub, force-push or expose secrets. Gitea + Actions and container publication require a configured runner and credentials; + a source push alone does not prove an image was published or deployed. diff --git a/Dockerfile b/Dockerfile index 7b053bf7..51c1341b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ FROM node:22-bookworm-slim AS runtime WORKDIR /app ENV NODE_ENV=production CI=true WRANGLER_SEND_METRICS=false \ WRANGLER_WRITE_LOGS=false MINIFLARE_REGISTRY_PATH=/tmp/dune-registry -LABEL org.opencontainers.image.source="https://github.com/Quintine/Dune" +LABEL org.opencontainers.image.source="https://git.juiced.computer/admin/Dune" COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/dist ./dist COPY --from=build /app/drizzle ./drizzle diff --git a/docs/CURRENT_STATUS.md b/docs/CURRENT_STATUS.md index 15261bc3..b8e94a30 100644 --- a/docs/CURRENT_STATUS.md +++ b/docs/CURRENT_STATUS.md @@ -16,6 +16,14 @@ open mode gates. ## Current checkpoint and work +**In progress: Gitea migration — 28 October.** The local `origin` now tracks +`https://git.juiced.computer/admin/Dune`; its imported `main` is an ancestor of +the local checkout. Git push authentication and an Actions runner are not yet +available. The integration owner is preparing a Gitea-native container workflow +that preserves build, isolated verification and gated image publication; registry +selection and runner installation are pending the user's response. Existing NAS +deployment and its persistent storage remain untouched. + **Semuta before Basic Moritani ally retention — 28 October. Prototyped / Partial.** In the bare Basic Semuta preview, mandatory loser cards form an initial battle discard batch before the original allied-retention choice; diff --git a/docs/TRUENAS.md b/docs/TRUENAS.md index b2f583ca..3047cf80 100644 --- a/docs/TRUENAS.md +++ b/docs/TRUENAS.md @@ -8,21 +8,39 @@ runtime prototype does not change public release or rules-mode gates. ## Checkpoint images -Every push to `main` starts `.github/workflows/container.yml`. The Docker build -runs the production build using the lockfile. Types, lint and offline tests -remain part of source checkpoint verification rather than being repeated in -the container build. +The source repository is moving to [Gitea](https://git.juiced.computer/admin/Dune). +Its `.gitea/workflows/container.yml` is intended to build and verify checkpoint +images on pushes to `main`. Configure the Gitea Actions variables +`DUNE_CONTAINER_IMAGE` for the full registry image name and +`DUNE_REGISTRY_USERNAME` for the registry account; supply the registry token as +the `CONTAINER_REGISTRY_TOKEN` Actions secret. The default image name is +`git.juiced.computer/admin/dune`. Registry access and image visibility depend +on the actual Gitea package settings; do not assume anonymous pulls work. + +No Gitea runner has been registered and no Gitea image build has succeeded yet. +A source push is therefore not a verified container image or a deployment. +Register and configure an `ubuntu-latest` runner whose job environment has a +working Docker CLI, daemon and Buildx, plus network access to actions, npm and +container images. Configure registry access, then verify the +workflow and its published image before considering a manual NAS update. The +existing Compose configuration continues to reference the GHCR image until a +separately verified migration is applied at a safe point. + +The previous GitHub workflow, `.github/workflows/container.yml`, builds a +production image using the lockfile on GitHub pushes. Types, lint and offline +tests remain part of source checkpoint verification rather than being repeated +in the container build. Before publishing, CI creates an isolated container and volume, checks accepted and rejected HTTP origins, verifies saved-seat restoration through restart and container replacement, then runs the HTTP integration suite. -Only a passing image is pushed to `ghcr.io/quintine/dune:checkpoint`, alongside -`ghcr.io/quintine/dune:sha-`. GitHub Actions builds; TrueNAS pulls the -image. Failed checks leave the previous update tag untouched. This workflow -targets Linux AMD64, the architecture of ordinary x86 TrueNAS systems. +Only a passing GitHub image is pushed to `ghcr.io/quintine/dune:checkpoint`, +alongside `ghcr.io/quintine/dune:sha-`. TrueNAS currently pulls +that image. Failed checks leave the previous update tag untouched. This +workflow targets Linux AMD64, the architecture of ordinary x86 TrueNAS systems. -The user selected a **public image**, matching the existing public source -repository, so TrueNAS needs no registry login. GitHub initially creates packages +The user selected the existing GHCR image as **public**, matching the public +source repository, so TrueNAS needs no registry login for that image. GitHub initially creates packages privately; after the first successful publication, set this package's visibility to public in GitHub package settings. Images contain application code and assets, never saved games or credentials. Publishing uses the workflow's built-in token. @@ -93,8 +111,11 @@ See [NGINX WebSocket forwarding](https://nginx.org/en/docs/http/websocket.html). ### Applying an update -1. Wait for the checkpoint workflow to succeed. Check for image updates in - TrueNAS and apply the update manually at a safe point between decisions. +1. Wait for the checkpoint workflow for the configured image registry to + succeed and confirm the intended revision was published. A Gitea source + push alone is insufficient, and the GHCR Compose image does not automatically + switch registries. Check for image updates in TrueNAS and apply the update + manually at a safe point between decisions. 2. Before updating, stop the app and back up or snapshot its persistent storage. Include the named volume in the Apps backup procedure; a dedicated host dataset provides a more explicit ZFS snapshot boundary.