diff --git a/File:** `README.md b/File:** `README.md new file mode 100644 index 00000000..8d346273 --- /dev/null +++ b/File:** `README.md @@ -0,0 +1,16 @@ +# Deployment Safety + +## Rollback Command + +To roll back a service to the last known good version: + +```bash +bezalel-rollback +``` + +Example: +```bash +bezalel-rollback the-nexus +``` + +This command swaps traffic to the last verified version of the service. diff --git a/index.html b/index.html index 94b54782..0ec21290 100644 --- a/index.html +++ b/index.html @@ -377,6 +377,10 @@ index.html + + @@ -410,6 +414,18 @@ index.html if (!sha) return; if (knownSha === null) { knownSha = sha; return; } if (sha !== knownSha) { + // Check for staging verification + const stagingStatus = await fetch(`${GITEA}/repos/${REPO}/actions/workflows/staging.yml/runs-success`); + if (!stagingStatus.ok) { + console.error('Staging verification failed or missing'); + return; + } + const stagingData = await stagingStatus.json(); + if (Date.now() - stagingData.updated_at > 30 * 60 * 1000) { + console.error('Staging verification older than 30 minutes'); + return; + } + // Check branch protection rules const branchRules = await fetch(`${GITEA}/repos/${REPO}/branches/${BRANCH}/protection`); if (!branchRules.ok) { @@ -421,6 +437,16 @@ index.html console.error('Branch protection rules not met'); return; } + + // POST signed token to staging health endpoint + const token = await fetch(`${GITEA}/repos/${REPO}/staging-health`, { + method: 'POST', + headers: { 'Authorization': `Bearer ${process.env.STAGING_TOKEN}` } + }); + if (!token.ok) { + console.error('Staging health check failed'); + return; + } knownSha = sha; const banner = document.getElementById('live-refresh-banner'); const countdown = document.getElementById('lr-countdown'); @@ -439,5 +465,20 @@ index.html setInterval(poll, INTERVAL); })(); + + diff --git a/style.css b/style.css index 2cc64ab0..2f5ec772 100644 --- a/style.css +++ b/style.css @@ -1093,7 +1093,8 @@ canvas#nexus-canvas { opacity: 0.3; } -#mem-palace-status { +#mem-palace-status, +#staging-verification { transition: all 0.3s ease; display: flex; align-items: center;