feat(workflows): cascade PR retargeting + bounded review/resolve loop #142
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Quality gates only. No image build, no release. | |
| # | |
| # Triggers: | |
| # - pull_request: fast feedback on every PR | |
| # - push to main: post-merge sanity (catches squash-regressions; release is manual) | |
| # - workflow_call: invoked by dev-release.yml and release.yml so an image | |
| # is never published without these checks passing. | |
| name: CI | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| workflow_call: | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint-and-test: | |
| name: Lint & Test | |
| # `head_commit.message` is only present on `push` events. On | |
| # `pull_request` and `workflow_call` it is null and contains() against | |
| # null can behave unexpectedly. Restrict the skip-ci optimization to | |
| # push events so PRs always run CI. | |
| if: ${{ github.event_name != 'push' || | |
| !contains(github.event.head_commit.message, 'skip ci') }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout source code | |
| uses: actions/checkout@v6 | |
| with: | |
| # Full history kept for parity with dev-release/release workflows | |
| # and to give semantic-release accurate diff context when this | |
| # workflow is invoked via workflow_call. Secret scanning lives | |
| # in .github/workflows/secrets-scan.yml now. | |
| fetch-depth: 0 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - name: Cache Bun install dir | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Typecheck | |
| run: bun run typecheck | |
| - name: Lint | |
| run: bun run lint | |
| - name: Format check | |
| run: bun run format | |
| - name: Dockerfile base-sync guard | |
| run: bun run check:dockerfile-base-sync | |
| - name: Docs-sync guard (bot workflows, FR-019) | |
| if: github.event_name == 'pull_request' | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: bun run check:docs-sync | |
| - name: Dependency audit | |
| # Wraps `bun audit --json` to gate on severity. `bun audit` itself | |
| # exits 1 on ANY advisory regardless of --audit-level, so the | |
| # wrapper restores severity-based gating + an inline GHSA allowlist. | |
| run: bun run audit:ci | |
| - name: Test | |
| run: bun run test | |
| - name: Build | |
| run: bun run build |