docs: publish Azure C3 acceptance evidence (#363) #1441
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
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| name: Lint shell scripts | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install pinned ShellCheck | |
| run: | | |
| set -eu | |
| bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin" | |
| echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" | |
| # Single owner of the lint definition (file set + config + version). Do not | |
| # re-spell the shellcheck command here; keep CI and the pre-push gate on it. | |
| - run: bin/fm-lint.sh | |
| # ShellCheck cannot see the .mjs tools, and nothing else parsed them: a | |
| # syntax error in one reached main green. | |
| - run: bin/fm-lint-node.sh | |
| behavior-test-plan: | |
| name: Behavior test shard plan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Prove complete, disjoint shard coverage | |
| run: bin/fm-behavior-shards.sh --check 8 | |
| behavior-tests: | |
| name: Behavior tests (shard ${{ matrix.shard }}/8) | |
| needs: behavior-test-plan | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5, 6, 7, 8] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install pinned ShellCheck | |
| run: | | |
| set -eu | |
| bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin" | |
| echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" | |
| - name: Require tmux for e2e tests | |
| run: | | |
| set -eu | |
| command -v tmux >/dev/null || { | |
| echo "::error::tmux is required for real afk injection e2e coverage" | |
| exit 1 | |
| } | |
| tmux -V | |
| - name: Install tasks-axi for backlog-handoff delegation | |
| run: | | |
| set -eu | |
| npm install -g tasks-axi | |
| tasks-axi --version | |
| # The Pi credential store is what bin/fm-pi-refresh.mjs holds a lock in | |
| # and writes through. Without Pi here its store contract skipped, and a | |
| # skip that cannot fail is indistinguishable from coverage: two mutations | |
| # of the actuator passed this job green. FM_PI_REQUIRED turns a failed | |
| # install into a red test rather than a silent skip. | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - name: Install Pi for the credential-store contract | |
| run: | | |
| set -eu | |
| npm install -g @earendil-works/pi-coding-agent | |
| # By absolute path: a bare specifier does not resolve from the global | |
| # prefix, and FM_PI_PACKAGE_DIR spares the test a PATH lookup for a | |
| # binary it never runs. | |
| root="$(npm root -g)/@earendil-works/pi-coding-agent" | |
| test -f "$root/dist/core/auth-storage.js" | |
| node -e "console.log(require('$root/package.json').version)" | |
| { | |
| echo "FM_PI_PACKAGE_DIR=$root" | |
| echo "FM_PI_REQUIRED=1" | |
| } >> "$GITHUB_ENV" | |
| - name: Prepare private shard state | |
| run: | | |
| set -eu | |
| shard_root="$RUNNER_TEMP/fm-behavior-${{ matrix.shard }}" | |
| install -d -m 700 "$shard_root/tmp" "$shard_root/tmux" | |
| { | |
| echo "TMPDIR=$shard_root/tmp" | |
| echo "TMP=$shard_root/tmp" | |
| echo "TEMP=$shard_root/tmp" | |
| echo "TMUX_TMPDIR=$shard_root/tmux" | |
| } >> "$GITHUB_ENV" | |
| - name: Run behavior shard ${{ matrix.shard }}/8 | |
| run: | | |
| set -eu | |
| manifest="$RUNNER_TEMP/executed-${{ matrix.shard }}.tsv" | |
| FM_TEST_SKIP_HERDR=1 \ | |
| bin/fm-behavior-shards.sh --run "${{ matrix.shard }}" 8 "$manifest" | |
| - name: Upload executed-test manifest | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: behavior-shard-${{ matrix.shard }} | |
| path: ${{ runner.temp }}/executed-${{ matrix.shard }}.tsv | |
| if-no-files-found: warn | |
| overwrite: true | |
| behavior-tests-complete: | |
| # Preserve the historical required-check name while proving the union of | |
| # what the eight runners actually executed, not only the planned inventory. | |
| name: Behavior tests | |
| needs: behavior-tests | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download executed-test manifests | |
| uses: actions/download-artifact@v4 | |
| continue-on-error: true | |
| with: | |
| pattern: behavior-shard-* | |
| path: ${{ runner.temp }}/behavior-manifests | |
| merge-multiple: true | |
| - name: Verify complete execution union | |
| run: bin/fm-behavior-shards.sh --verify 8 "$RUNNER_TEMP/behavior-manifests" | |
| agent-fleet: | |
| name: Agent Fleet package | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install pinned uv | |
| run: python -m pip install uv==0.9.10 | |
| - name: Verify locked package | |
| working-directory: tools/agent-fleet | |
| run: | | |
| set -eu | |
| uv sync --locked | |
| uv run --locked ruff check . | |
| uv run --locked pytest | |
| uv run --locked python -m compileall -q src | |
| uv build --out-dir "$RUNNER_TEMP/agent-fleet-dist" | |
| invariants: | |
| name: Repo invariants | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Symlinks must stay intact | |
| run: | | |
| set -eu | |
| [ "$(readlink CLAUDE.md)" = "AGENTS.md" ] || { echo "::error::CLAUDE.md must be a symlink to AGENTS.md"; exit 1; } | |
| [ "$(readlink .claude/skills)" = "../.agents/skills" ] || { echo "::error::.claude/skills must be a symlink to ../.agents/skills"; exit 1; } | |
| - name: Personal fleet paths must not be tracked | |
| run: | | |
| set -eu | |
| tracked=$(git ls-files -- data state config projects .no-mistakes) | |
| if [ -n "$tracked" ]; then | |
| echo "::error::Personal fleet paths are tracked in git:" | |
| printf '%s\n' "$tracked" | |
| exit 1 | |
| fi |