diff --git a/.github/workflows/nsite-archive.yml b/.github/workflows/nsite-archive.yml index 739ae376..7f20344b 100644 --- a/.github/workflows/nsite-archive.yml +++ b/.github/workflows/nsite-archive.yml @@ -1,8 +1,13 @@ # Build a fresh, downloadable site archive on every push (any branch), so a # ready-to-upload copy of the compiled app is always available for a MANUAL nsite -# publish (NIP-5A). This does NOT publish anything or touch any signing key — it -# just builds `dist/` and uploads it as a workflow artifact (GitHub serves -# artifacts as a .zip on download). See docs/nsite-mirror-plan.md. +# publish (NIP-5A). This does NOT publish to nsite or touch any Nostr signing key — +# it just builds `dist/`. +# - every branch: upload it as a 30-day workflow artifact. +# - main only: also cut an immutable GitHub Release with the .zip attached, +# giving a stable download URL: +# https://github.com/PR0M3TH3AN/bitvid/releases/latest/download/bitvid-site.zip +# The Release contains only the public compiled app (same as Vercel serves) — no +# secret. See docs/nsite-mirror-plan.md. name: Build site archive on: @@ -47,3 +52,46 @@ jobs: path: dist if-no-files-found: error retention-days: 30 + + # Production only: publish an immutable GitHub Release with the .zip attached, so + # the latest prod archive is always at a stable URL: + # https://github.com/PR0M3TH3AN/bitvid/releases/latest/download/bitvid-site.zip + # This is purely a download convenience + per-release snapshot — it does NOT + # publish to nsite and holds no Nostr signing key (that step stays manual). + release: + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + # `npm run archive` builds dist/ and writes bitvid-site.zip (index.html at root). + - name: Build site archive + run: npm run archive + + - name: Publish site release + env: + GH_TOKEN: ${{ github.token }} + run: | + tag="site-$(date -u +%Y%m%d)-${GITHUB_SHA::7}" + notes="Compiled bitvid static app (\`dist/\`) at ${GITHUB_SHA}. + Stable latest link: https://github.com/${GITHUB_REPOSITORY}/releases/latest/download/bitvid-site.zip" + # Re-runs of the same commit reuse the tag: refresh the asset instead of failing. + if gh release view "$tag" >/dev/null 2>&1; then + gh release upload "$tag" bitvid-site.zip --clobber + gh release edit "$tag" --latest + else + gh release create "$tag" bitvid-site.zip \ + --title "Site archive $tag" \ + --notes "$notes" \ + --latest + fi diff --git a/docs/nsite-mirror-plan.md b/docs/nsite-mirror-plan.md index 207157b0..0a39af55 100644 --- a/docs/nsite-mirror-plan.md +++ b/docs/nsite-mirror-plan.md @@ -148,8 +148,10 @@ push to any branch ├── Vercel → production build → bitvid.network (primary, unchanged) └── GitHub Action (.github/workflows/nsite-archive.yml) [SHIPPED] npm ci && npm run build → dist/ - → actions/upload-artifact: downloadable site .zip (root = index.html) - (no signing key, publishes nothing) + → any branch: actions/upload-artifact → downloadable site .zip (30d) + → main only: GitHub Release (site--, --latest) w/ bitvid-site.zip + stable URL: /releases/latest/download/bitvid-site.zip + (no Nostr signing key, does not publish to nsite) manual release (maintainer, when promoting to prod) download latest archive (or: npm run archive → bitvid-site.zip) @@ -162,10 +164,32 @@ manual release (maintainer, when promoting to prod) ## The archive workflow (shipped) `.github/workflows/nsite-archive.yml` — runs on **push to any branch** + manual -`workflow_dispatch`. It builds `dist/` and uploads it as an artifact named -`bitvid-site--` (30-day retention). GitHub serves the artifact as -a `.zip` on download, with `index.html` at the root — drop-in for an nsite deployer. -It holds **no secret** and publishes nothing. +`workflow_dispatch`. It holds **no Nostr signing key** and does not publish to nsite; +it only produces the compiled `dist/` for a manual publish: + +- **Every branch** → uploads `dist/` as an artifact `bitvid-site--` + (30-day retention). GitHub serves it as a `.zip` on download, `index.html` at the + root — drop-in for an nsite deployer. Grab the latest for a branch with + `gh run download` (see below). +- **`main` only** → additionally cuts an **immutable GitHub Release** (tag + `site--`, marked `--latest`) with `bitvid-site.zip` attached, giving + a **stable download URL** for the current production archive: + + ``` + https://github.com/PR0M3TH3AN/bitvid/releases/latest/download/bitvid-site.zip + ``` + + The Release contains only the public compiled app (identical to what Vercel serves), + so it's safe to expose permanently; it doubles as the per-release snapshot from D8. + +Grab the latest archive for a non-prod branch: + +```bash +gh run download -R PR0M3TH3AN/bitvid \ + "$(gh run list -R PR0M3TH3AN/bitvid --workflow=nsite-archive.yml \ + --branch unstable --status success -L1 --json databaseId -q '.[0].databaseId')" \ + --dir ./site-archive +``` Locally, `npm run archive` produces the same thing as `bitvid-site.zip` (gitignored) for an offline/manual publish.