diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 8df8ddd..cc621c6 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -5,6 +5,10 @@ on: branches: [main] pull_request: +permissions: + contents: read + releases: write + jobs: build: runs-on: ubuntu-latest @@ -27,8 +31,38 @@ jobs: name: dist path: dist/ - # Deploy step intentionally not wired up yet: this runner spins up - # ephemeral job containers (no host bind-mount for the workspace), so - # syncing dist/ to /mnt/e/sites/ needs an SSH deploy key added as - # a Gitea Actions secret. See repo README for the manual deploy steps - # used until that's set up. + # Publishes dist/ as a Gitea Release asset (tag "deploy") using the + # automatic per-job token - no secrets needed. A separate watcher + # container on octo-winsrv (site-deployer) polls this release and + # extracts it into /mnt/e/sites/, which Caddy serves - see + # README "Deploy" section. + - name: Publish deploy release + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }} + run: | + set -e + command -v zip >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y -qq zip) + command -v jq >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y -qq jq) + (cd dist && zip -rq ../site.zip .) + + # replace the previous "deploy" release/tag, if any, so exactly + # one always exists + curl -s -X DELETE -H "Authorization: token $GITEA_TOKEN" \ + "$API/releases/tags/deploy" >/dev/null || true + curl -s -X DELETE -H "Authorization: token $GITEA_TOKEN" \ + "$API/tags/deploy" >/dev/null || true + + REL_ID="$(curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"deploy\",\"name\":\"deploy\",\"target_commitish\":\"${{ github.sha }}\",\"draft\":false,\"prerelease\":false}" \ + "$API/releases" | jq -r '.id // empty')" + if [ -z "$REL_ID" ]; then + echo "::error::Failed to create deploy release" + exit 1 + fi + + curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \ + -F "attachment=@site.zip" \ + "$API/releases/$REL_ID/assets?name=site.zip" >/dev/null diff --git a/README.md b/README.md index 381047f..612e059 100644 --- a/README.md +++ b/README.md @@ -24,18 +24,20 @@ npm run build Output goes to `dist/`. -## Deploy (manual, for now) +## Deploy -CI builds and uploads `dist/` as an artifact on every push to `main`, but -does not yet sync it to the server automatically — the Gitea act runner -uses ephemeral job containers with no host-visible workspace path, so an -auto-deploy step needs an SSH deploy key added as a Gitea Actions secret -first. Until that's set up, deploy manually: +Every push to `main` builds the site and publishes `dist/` (zipped) as the +asset on a Gitea Release tagged `deploy`, using the automatic per-job +`GITEA_TOKEN` — no secrets to configure. A separate `site-deployer` watcher +container on octo-winsrv polls that release (`releases/tags/deploy`) every +~45s and, when it changes, extracts it into `/mnt/e/sites/continuum-3d-com/`, +which Caddy serves as the document root for `continuum-3d.com`. No SSH keys +or admin credentials are involved — the watcher only has filesystem access +to `/mnt/e/sites`, nothing else on the host. + +Manual deploy still works if you need it immediately (bypasses the watcher): ``` npm run build scp -r dist/* :/mnt/e/sites/continuum-3d-com/ ``` - -Caddy serves `/mnt/e/sites/continuum-3d-com` as the document root for -`continuum-3d.com`.