Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions .github/workflows/prod-canary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Production E2E Canary

# Daily read-only synthetic check that production works for users right now,
# regardless of whose deploy broke it: backend releases, data issues and
# third-party changes never trigger the frontend deploy gates, and the prod
# deploy workflow has no post-deploy E2E of its own.
#
# Runs the manifest-resolved production canary packs (safety: readonly,
# trigger: cron in tests/packs.manifest.ts) through scripts/e2e-packs.cjs.
# Read-only is enforced at the network layer by the readonly mutation guard
# (PLAYWRIGHT_READONLY / production base URL), not by convention.
#
# No secrets are required: production is publicly reachable and the packs
# are unauthenticated.

on:
workflow_dispatch: {}
schedule:
# Daily, offset from the 04:00 Device Farm crons so scheduled QA
# failures arrive as distinct signals.
- cron: "30 5 * * *"

permissions:
contents: read

concurrency:
group: prod-e2e-canary
cancel-in-progress: false

jobs:
canary-packs:
name: Production canary packs
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false

- name: Install Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "22"

- name: Activate pinned pnpm
run: |
corepack enable pnpm
corepack prepare "$(node -p 'require("./package.json").packageManager')" --activate
pnpm --version

- name: Install Socket Firewall
id: socket_firewall
uses: SocketDev/action@2d3f25590c6ed6ba11a9a14c064d962a3a04698f # v1.3.1
with:
mode: firewall

- name: Assert npm lockfile is absent
run: ./bin/6529 guard:no-package-lock

- name: Install dependencies
env:
SFW_BIN: ${{ steps.socket_firewall.outputs.firewall-path-binary }}
run: ./bin/6529 install:frozen

- name: Install Playwright browser
run: ./bin/6529 exec playwright install --with-deps chromium

- name: Run production canary packs against 6529.io
run: ./bin/6529 run e2e:packs -- --env production --trigger cron

- name: Upload Playwright artifacts on failure
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: prod-canary-artifacts
path: |
test-results/
playwright-report/
retention-days: 7
if-no-files-found: ignore

- name: Notify about scheduled failure
uses: sarisia/actions-status-discord@eb045afee445dc055c18d3d90bd0f244fd062708 # v1.16.0
if: failure() && github.event_name == 'schedule'
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
with:
title: "Production E2E Canary: daily read-only pack failed"
description: "Production may be broken for users. Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
color: 0xff0000
Loading