audit-labs/gh-attest
GitHub Audit Evidence Extractor
clone: git clone https://gitbay.org/audit-labs/gh-attest.git
7a25bf40f853eede7bb10c00eede68553636e3d3
verified · cmc
author: Christian Cleberg <hello@cleberg.net> · 2026-08-21T04:37:05Z
.github/dependabot.yml | 5 ++++ .github/workflows/ci.yml | 33 +++++++++++++++++++++++++ .github/workflows/migration-drift.yml | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) @@ -9,3 +9,8 @@ updates: directory: "/" # Location of package manifests schedule: interval: "weekly" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" new file mode 100644 @@ -0,0 +1,33 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: actions/setup-node@v7 + with: + node-version: '26' + cache: npm + + - run: npm ci + + # The engine is TypeScript on Workers types; a type error is a deploy + # that fails in Cloudflare's build rather than here. + - name: Typecheck + run: npm run typecheck + + # Applies every migration to an in-memory SQLite database and diffs the + # resulting control_mappings against docs/framework-mapping.md. The doc + # is what an auditor reads, so drift there is a lie in every export. + - name: Control mappings match the docs + run: npm run test:mappings new file mode 100644 @@ -0,0 +1,45 @@ +name: Migration drift + +# Deploys and migrations are separate actions, so production can run code whose +# schema was never applied — which is exactly what happened with 0008: its code +# shipped, its migration did not, and evidence output was silently wrong until +# someone went looking. Nothing in CI can catch that, because CI has no view of +# the production database. This does. + +on: + schedule: + - cron: '0 9 * * *' + workflow_dispatch: + +permissions: + contents: read + +jobs: + drift: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: actions/setup-node@v7 + with: + node-version: '26' + cache: npm + + - run: npm ci + + - name: Every migration in migrations/ is applied to production + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + run: | + if [ -z "$CLOUDFLARE_API_TOKEN" ]; then + echo "::error::CLOUDFLARE_API_TOKEN is not set — this check cannot see production." + exit 1 + fi + out=$(npx wrangler d1 migrations list DB --remote 2>&1) || true + echo "$out" + if echo "$out" | grep -q "No migrations to apply"; then + echo "Production schema matches migrations/." + else + echo "::error::Production is missing migrations listed above. Run 'npm run db:migrate:remote'." + exit 1 + fi