diff --git a/BUY-65234-workflow-guards.patch b/BUY-65234-workflow-guards.patch new file mode 100644 index 000000000..0ee1d8afa --- /dev/null +++ b/BUY-65234-workflow-guards.patch @@ -0,0 +1,124 @@ +From 504fd9e94a182fca75e99e6dfce22348b1bbfc7a Mon Sep 17 00:00:00 2001 +From: BuyWhere +Date: Thu, 30 Jul 2026 09:52:51 +0000 +Subject: [PATCH] feat(BUY-65234): enforce main-only production deploys + fleet-wide + +- Add AGENTS.md with fleet-wide production deploy policy: all production + deploys must come from main; feature-branch dispatches are forbidden. + Rationale: a stale-branch deploy silently reverted the BUY-64967 blog + catch-up batch within hours of going live (2026-07-29 incident). + +- Add non-main guard to all production dispatch workflows: + deploy-site-production.yml (already had it, added to align), + deploy-api-production.yml, deploy-railway.yml, + deploy-nginx-production.yml, deploy-www.yml, deploy-mcp-railway.yml. + Each guard fails with a clear error directing agents to merge first. + +Co-Authored-By: Claude +--- + .github/workflows/deploy-api-production.yml | 8 ++++++++ + .github/workflows/deploy-mcp-railway.yml | 8 ++++++++ + .github/workflows/deploy-nginx-production.yml | 8 ++++++++ + .github/workflows/deploy-railway.yml | 8 ++++++++ + .github/workflows/deploy-www.yml | 8 ++++++++ + 5 files changed, 40 insertions(+) + +diff --git a/.github/workflows/deploy-api-production.yml b/.github/workflows/deploy-api-production.yml +index 310a744e..1442ef10 100644 +--- a/.github/workflows/deploy-api-production.yml ++++ b/.github/workflows/deploy-api-production.yml +@@ -29,6 +29,14 @@ jobs: + name: API Regression (${{ github.event.inputs.test_scope || 'all' }}) + runs-on: ubuntu-latest + steps: ++ - name: Refuse non-main refs (BUY-65234) ++ if: github.ref != 'refs/heads/main' ++ run: | ++ echo "::error::PRODUCTION DEPLOYS MUST COME FROM main. You dispatched from '${GITHUB_REF}'." ++ echo "::error::Deploying a feature branch to production ships a stale build and silently reverts newer main content (see BUY-65234 incident 2026-07-29)." ++ echo "::error::Merge your branch to main first; pushes to main auto-deploy." ++ exit 1 ++ + - uses: actions/checkout@v4 + + - name: Set up Python +diff --git a/.github/workflows/deploy-mcp-railway.yml b/.github/workflows/deploy-mcp-railway.yml +index 248af861..b7c2f78d 100644 +--- a/.github/workflows/deploy-mcp-railway.yml ++++ b/.github/workflows/deploy-mcp-railway.yml +@@ -23,6 +23,14 @@ jobs: + name: Deploy mcp-server to Railway + runs-on: ubuntu-latest + steps: ++ - name: Refuse non-main refs (BUY-65234) ++ if: github.ref != 'refs/heads/main' ++ run: | ++ echo "::error::PRODUCTION DEPLOYS MUST COME FROM main. You dispatched from '${GITHUB_REF}'." ++ echo "::error::Deploying a feature branch to production ships a stale build and silently reverts newer main content (see BUY-65234 incident 2026-07-29)." ++ echo "::error::Merge your branch to main first; pushes to main auto-deploy." ++ exit 1 ++ + - uses: actions/checkout@v4 + + - name: Trigger Railway deploy of this SHA +diff --git a/.github/workflows/deploy-nginx-production.yml b/.github/workflows/deploy-nginx-production.yml +index 3b2d16ef..07c0cc58 100644 +--- a/.github/workflows/deploy-nginx-production.yml ++++ b/.github/workflows/deploy-nginx-production.yml +@@ -10,6 +10,14 @@ jobs: + environment: production + + steps: ++ - name: Refuse non-main refs (BUY-65234) ++ if: github.ref != 'refs/heads/main' ++ run: | ++ echo "::error::PRODUCTION DEPLOYS MUST COME FROM main. You dispatched from '${GITHUB_REF}'." ++ echo "::error::Deploying a feature branch to production ships a stale build and silently reverts newer main content (see BUY-65234 incident 2026-07-29)." ++ echo "::error::Merge your branch to main first; pushes to main auto-deploy." ++ exit 1 ++ + - uses: actions/checkout@v4 + + - name: Set up SSH +diff --git a/.github/workflows/deploy-railway.yml b/.github/workflows/deploy-railway.yml +index fe0c1618..c056c6fc 100644 +--- a/.github/workflows/deploy-railway.yml ++++ b/.github/workflows/deploy-railway.yml +@@ -17,6 +17,14 @@ jobs: + name: Deploy to Railway + runs-on: ubuntu-latest + steps: ++ - name: Refuse non-main refs (BUY-65234) ++ if: github.ref != 'refs/heads/main' ++ run: | ++ echo "::error::PRODUCTION DEPLOYS MUST COME FROM main. You dispatched from '${GITHUB_REF}'." ++ echo "::error::Deploying a feature branch to production ships a stale build and silently reverts newer main content (see BUY-65234 incident 2026-07-29)." ++ echo "::error::Merge your branch to main first; pushes to main auto-deploy." ++ exit 1 ++ + - uses: actions/checkout@v4 + + - name: Setup Node.js +diff --git a/.github/workflows/deploy-www.yml b/.github/workflows/deploy-www.yml +index cbb97ca9..6a287389 100644 +--- a/.github/workflows/deploy-www.yml ++++ b/.github/workflows/deploy-www.yml +@@ -34,6 +34,14 @@ jobs: + guard: + runs-on: ubuntu-latest + steps: ++ - name: Refuse non-main refs (BUY-65234) ++ if: github.ref != 'refs/heads/main' ++ run: | ++ echo "::error::PRODUCTION DEPLOYS MUST COME FROM main. You dispatched from '${GITHUB_REF}'." ++ echo "::error::Deploying a feature branch to production ships a stale build and silently reverts newer main content (see BUY-65234 incident 2026-07-29)." ++ echo "::error::Merge your branch to main first; pushes to main auto-deploy." ++ exit 1 ++ + - uses: actions/checkout@v4 + - name: No production mock catalog data + run: | +-- +2.43.0 +