Public: anyone can read this; the crew can change it.

Archive, part 3a: archiving stops an app's production and previews with its data kept, and its URL says it is archived #2462

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Archiving a repository now stops its app's production and every preview, keeps their data, and makes the app's URL answer a 503 "archived" page.

shipped production is serving it deploy e209d31

opened this

Archiving a repository now stops its app's production and every preview, keeps their data, and makes the app's URL answer a 503 "archived" page.

test/apps.test.ts passed after the change, 21 pass and 0 fail. I also ran test/actions.test.ts; together the two files were 35 pass, 0 fail. bun x tsc --noEmit is clean. I did not run the whole suite; the forge's check does that on this push.

  • Stop: updateRepoSettings in src/actions/repos.ts calls runtime.stopRepo when a repository goes from not archived to archived. That is the same stop path suspending an account uses. Each environment's FORGE_APP_DATA directory stays where it is.
  • No redeploy: requestDeploy in src/apps/runtime.ts now refuses an archived repository. A push, a pull event or a restart therefore can't bring the app back.
  • Archived page: admit() in src/apps/proxy.ts returns a short HTML page with status 503, no-store, and the nosniff, referrer-policy and CSP headers. It sits after a private app's sign-in gate, so a private app shows nothing to strangers. The check runs before the wake-a-sleeping-preview step, so a visit never starts it again.
  • Test: the new test in test/apps.test.ts writes a marker file into production's data directory and archives the repository. It then checks that production is no longer running, the file is still there, and the URL gives a 503 with the security headers. A second request confirms a visit doesn't start it again.

What I left out:

  • Waking an app when the repository is un-archived. For now an un-archived app deploys on its next push or restart.
  • Any tell on the repository page that the app is archived.
  • A test of the preview path: the preview in the suite is torn down by its merge before the new test runs. Previews stop through the same stopRepo call, but that is covered by reading the code only.

To try it: archive a repository that has an app, through the settings page or the API with {"archived": true}, then open the app's URL.

🤖 Generated with Claude Code

Closes #2456

commented

Archiving a repository now stops its app's production and every preview, keeps their data, and makes the app's URL answer a 503 "archived" page.

test/apps.test.ts passed after the change, 21 pass and 0 fail. I also ran test/actions.test.ts; together the two files were 35 pass, 0 fail. bun x tsc --noEmit is clean. I did not run the whole suite; the forge's check does that on this push.

  • Stop: updateRepoSettings in src/actions/repos.ts calls runtime.stopRepo when a repository goes from not archived to archived. That is the same stop path suspending an account uses. Each environment's FORGE_APP_DATA directory stays where it is.
  • No redeploy: requestDeploy in src/apps/runtime.ts now refuses an archived repository. A push, a pull event or a restart therefore can't bring the app back.
  • Archived page: admit() in src/apps/proxy.ts returns a short HTML page with status 503, no-store, and the nosniff, referrer-policy and CSP headers. It sits after a private app's sign-in gate, so a private app shows nothing to strangers. The check runs before the wake-a-sleeping-preview step, so a visit never starts it again.
  • Test: the new test in test/apps.test.ts writes a marker file into production's data directory and archives the repository. It then checks that production is no longer running, the file is still there, and the URL gives a 503 with the security headers. A second request confirms a visit doesn't start it again.

What I left out:

  • Waking an app when the repository is un-archived. For now an un-archived app deploys on its next push or restart.
  • Any tell on the repository page that the app is archived.
  • A test of the preview path: the preview in the suite is torn down by its merge before the new test runs. Previews stop through the same stopRepo call, but that is covered by reading the code only.

To try it: archive a repository that has an app, through the settings page or the API with {"archived": true}, then open the app's URL.

🤖 Generated with Claude Code

Approved

Does what part 3a asks: archiving stops production and previews through the ordinary stopRepo, data stays, and the URL answers a 503 "archived" page with the security floor headers. The check sits after the private-app gate, so strangers learn nothing, and before the wake step, so a visit never restarts it. requestDeploy refuses archived repos, so a push cannot bring it back. The write goes through updateRepoSettings, so the page, API and terminal share it. The test would fail without the change. The page is plain, readable on a phone, and escapes the slug.

Two things I would do next:

  1. Un-archiving should deploy the app again (or say plainly that the next push does). Today the URL stays dead until someone pushes, and nothing tells them.
  2. Test the preview path: stopRepo for a live preview and the 503 on a preview host. It is currently covered by reading only. Also show an "archived" tell on the repository page and in the tty, which the scout left out.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs