From ec80e76cdcf205060003e3ebd8f6d31e4b6c2715 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Wed, 16 Sep 2026 04:28:53 +0200 Subject: [PATCH] ci: run the build pipeline on Gitea Actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Point `uses:` at full GitHub URLs so step resolution does not depend on the instance's DEFAULT_ACTIONS_URL, publish the image to Gitea's own container registry, and drop the Pages deploy. Pages has no Gitea equivalent and the container image is the deploy artefact now, so the job is removed rather than replaced. `build` stays: it is what produces the site bundle, and test/refresh.test.ts pins the refresh-bookkeeping restore to the slice between `build:` and `image:`. Its BASE_PATH goes, though — that existed only for the // subpath Pages served from, and serve.ts serves the image at the root. The registry host is derived from github.server_url rather than hardcoded, so a fork on another instance pushes to its own registry. Layer cache moves from type=gha to type=registry: Gitea does expose the Actions cache API, but buildx's gha backend is the least reliable part of that compatibility surface and we are already authenticated to a registry that can hold the layers. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 97 ++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 59 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de4557a..31ee4a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,9 +20,9 @@ jobs: name: Typecheck, test, feed runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: https://github.com/actions/checkout@v4 - - uses: oven-sh/setup-bun@v2 + - uses: https://github.com/oven-sh/setup-bun@v2 with: bun-version: "1.3" @@ -36,7 +36,7 @@ jobs: # Restore-only: refresh.yml owns writing this cache, and a miss just # returns the pre-existing fallback behaviour. - name: Restore refresh bookkeeping - uses: actions/cache/restore@v4 + uses: https://github.com/actions/cache/restore@v4 with: path: snapshots/*.state.json key: refresh-state- @@ -105,8 +105,8 @@ jobs: runs-on: ubuntu-latest needs: check steps: - - uses: actions/checkout@v4 - - uses: oven-sh/setup-bun@v2 + - uses: https://github.com/actions/checkout@v4 + - uses: https://github.com/oven-sh/setup-bun@v2 with: bun-version: "1.3" - run: bun install --frozen-lockfile @@ -114,19 +114,19 @@ jobs: # This is the job whose output is deployed, so this is the one that must # see the refresh bookkeeping; see the same step in `check`. - name: Restore refresh bookkeeping - uses: actions/cache/restore@v4 + uses: https://github.com/actions/cache/restore@v4 with: path: snapshots/*.state.json key: refresh-state- restore-keys: refresh-state- - name: Build - # Pages serves from //, so the app is built with a matching base - # href. Built at the domain root it would 404 on every asset. - env: - BASE_PATH: /${{ github.event.repository.name }}/ + # Built at the domain root, because the container image is what gets + # deployed and `serve.ts` serves from `/`. A BASE_PATH belongs here only + # if this artefact is ever hosted under a subpath again — it was set to + # // for GitHub Pages, which this pipeline no longer deploys to. run: bun run build - - uses: actions/upload-artifact@v4 + - uses: https://github.com/actions/upload-artifact@v4 with: name: site path: public/ @@ -143,66 +143,45 @@ jobs: contents: read packages: write steps: - - uses: actions/checkout@v4 + - uses: https://github.com/actions/checkout@v4 - - uses: docker/setup-buildx-action@v3 + - uses: https://github.com/docker/setup-buildx-action@v3 - name: Lowercase image name id: img - # GHCR rejects any uppercase in a repository name, and - # github.repository preserves the owner's casing verbatim. - run: echo "name=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + # Gitea's container registry, like GHCR before it, rejects any uppercase + # in a repository name, and github.repository preserves the owner's + # casing verbatim. The host is read from github.server_url rather than + # hardcoded, so a fork on another Gitea instance pushes to its own + # registry instead of this one. + env: + SERVER_URL: ${{ github.server_url }} + run: | + host="${SERVER_URL#https://}" + host="${host#http://}" + host="${host%%/*}" + # Two outputs on purpose: login wants the bare host, the tags want the + # full path. Passing the full path as the registry authenticates + # against a host that does not exist. + echo "host=${host}" >> "$GITHUB_OUTPUT" + echo "name=${host}/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" - - uses: docker/login-action@v3 + - uses: https://github.com/docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ steps.img.outputs.host }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - uses: docker/build-push-action@v6 + - uses: https://github.com/docker/build-push-action@v6 with: context: . push: true tags: | ${{ steps.img.outputs.name }}:latest ${{ steps.img.outputs.name }}:${{ github.sha }} - cache-from: type=gha - cache-to: type=gha,mode=max - - # Deploying to Pages needs two one-time steps that CI cannot do for itself: - # - # 1. Settings → Pages → Source: "GitHub Actions". - # The default GITHUB_TOKEN cannot do this. Creating a Pages site needs - # `administration: write`, which is not a permission a workflow can grant - # GITHUB_TOKEN, so `configure-pages` with enablement: true fails with - # "Resource not accessible by integration". - # 2. Settings → Secrets and variables → Actions → Variables: - # set DEPLOY_PAGES to "true". - # - # Gated on that variable so the pipeline stays green for anyone who does not - # want Pages, rather than failing on every push forever. - pages: - name: Deploy to Pages - runs-on: ubuntu-latest - needs: build - if: >- - github.ref == 'refs/heads/main' && - github.event_name != 'pull_request' && - vars.DEPLOY_PAGES == 'true' - permissions: - pages: write - id-token: write - environment: - name: github-pages - url: ${{ steps.deploy.outputs.page_url }} - steps: - - uses: actions/download-artifact@v4 - with: - name: site - path: public - - uses: actions/configure-pages@v5 - - uses: actions/upload-pages-artifact@v3 - with: - path: public - - id: deploy - uses: actions/deploy-pages@v4 + # Registry cache rather than `type=gha`. Gitea does expose the Actions + # cache API, but buildx's gha backend is the least reliable corner of + # that compatibility surface, and we are already authenticated to a + # registry that can hold the layers. + cache-from: type=registry,ref=${{ steps.img.outputs.name }}:buildcache + cache-to: type=registry,ref=${{ steps.img.outputs.name }}:buildcache,mode=max