chore: release v1.7.2 (#502) #1085
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 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| checks: write | |
| # NOTE: intentionally no `paths:` filter. These jobs (test/lint/audit/spec-check) | |
| # are the branch-protection required status checks β a required check that is | |
| # skipped by a path filter never reports, which blocks the PR forever (e.g. a | |
| # docs-only PR). Running the gate on every PR/push is the cost of enforcing it. | |
| # See issue #451. Do not re-add path filters here without also removing these | |
| # jobs from the required-checks list. | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| # Never cancel in-progress runs on main: every merged commit must get a | |
| # completed CI verdict (for bisection and post-merge signal). PR branches | |
| # keep fast-cancel on new pushes. | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| test: | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo test --verbose --locked | |
| lint: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo fmt --check | |
| - run: cargo clippy -- -D warnings | |
| audit: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - run: cargo generate-lockfile | |
| - uses: rustsec/audit-check@v2.0.0 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| integration: | |
| name: Integration (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| needs: [test] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Build fledge | |
| run: cargo build --release --locked | |
| - name: Add fledge to PATH (unix) | |
| if: runner.os != 'Windows' | |
| run: echo "${{ github.workspace }}/target/release" >> $GITHUB_PATH | |
| - name: Add fledge to PATH (windows) | |
| if: runner.os == 'Windows' | |
| run: echo "${{ github.workspace }}/target/release" >> $env:GITHUB_PATH | |
| - name: Verify fledge runs | |
| run: fledge --version | |
| - name: Run lanes (check) | |
| run: fledge lanes run check | |
| - name: Install default plugins | |
| run: fledge plugins install --defaults --non-interactive | |
| continue-on-error: true | |
| - name: List installed plugins | |
| run: fledge plugins list | |
| - name: Run default plugin - github (smoke test) | |
| run: fledge github --help | |
| continue-on-error: true | |
| - name: Run default plugin - deps (smoke test) | |
| run: fledge deps --help | |
| continue-on-error: true | |
| - name: Run default plugin - metrics | |
| run: fledge metrics | |
| continue-on-error: true | |
| spec-check: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| outputs: | |
| body: ${{ steps.specsync.outputs.body }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Build the branch Fledge CLI | |
| run: cargo build --locked | |
| - name: Add the branch Fledge CLI to PATH | |
| run: echo "${{ github.workspace }}/target/debug" >> "$GITHUB_PATH" | |
| - name: Run spec-sync | |
| id: specsync | |
| uses: CorvidLabs/spec-sync@342bd053d410211c16fcd041a9eb94ed53012fe2 # v5.2.0 | |
| with: | |
| version: 5.2.0 | |
| strict: true | |
| comment: false | |
| # Enforce reverse coverage: every production source file must be | |
| # claimed by a spec (test-only + template CI files are excluded in | |
| # .specsync/config.toml). Fails CI if an unclaimed file is added (#448). | |
| require-coverage: 100 | |
| lifecycle-enforce: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Enforce SpecSync change workspaces | |
| run: specsync change check --strict --require-coverage 100 | |
| corvid-pet: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| if: github.event_name == 'pull_request' && always() | |
| needs: [test, lint, audit, spec-check, integration] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Determine combined status | |
| id: status | |
| env: | |
| CHECK_TEST: "Tests (3 OS)=${{ needs.test.result }}" | |
| CHECK_INTEGRATION: "Integration (3 OS)=${{ needs.integration.result }}" | |
| CHECK_LINT: "Lint (fmt + clippy)=${{ needs.lint.result }}" | |
| CHECK_SPEC: "Spec Validation=${{ needs.spec-check.result }}" | |
| CHECK_AUDIT: "Dependency Audit=${{ needs.audit.result }}" | |
| REPORT_SPEC: ${{ needs.spec-check.outputs.body }} | |
| run: | | |
| OVERALL="success" | |
| TABLE="| Check | Status |\n|-------|--------|\n" | |
| DETAILS="" | |
| while IFS= read -r line; do | |
| VAR_NAME="${line%%=*}" | |
| VAR_VALUE="${!VAR_NAME}" | |
| LABEL="${VAR_VALUE%%=*}" | |
| RESULT="${VAR_VALUE##*=}" | |
| if [ "$RESULT" = "success" ]; then | |
| ICON="β Passed" | |
| else | |
| ICON="β ${RESULT}" | |
| OVERALL="failure" | |
| fi | |
| TABLE+="| **${LABEL}** | ${ICON} |\n" | |
| SUFFIX="${VAR_NAME#CHECK_}" | |
| REPORT_VAR="REPORT_${SUFFIX}" | |
| REPORT_VALUE="${!REPORT_VAR}" | |
| if [ -n "$REPORT_VALUE" ]; then | |
| DETAILS+="\n<details>\n<summary>π ${LABEL} Details</summary>\n\n${REPORT_VALUE}\n\n</details>\n" | |
| fi | |
| done < <(env | grep '^CHECK_' | sort) | |
| echo "result=${OVERALL}" >> "$GITHUB_OUTPUT" | |
| { | |
| echo "context<<CONTEXT_EOF" | |
| echo "### CI Summary" | |
| echo "" | |
| echo -e "$TABLE" | |
| if [ -n "$DETAILS" ]; then | |
| echo -e "$DETAILS" | |
| fi | |
| echo "CONTEXT_EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - uses: CorvidLabs/corvid-pet@v1.0.0 | |
| with: | |
| mode: pr-comment | |
| event: auto | |
| pet-name: Corvin | |
| review-on-pr: "true" | |
| context: ${{ steps.status.outputs.context }} | |
| job-status: ${{ steps.status.outputs.result }} | |
| attest: | |
| name: Record attestation | |
| runs-on: ubuntu-latest | |
| needs: [test, lint, audit, spec-check, integration] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| # contents: write lets the step push refs/notes/attest. | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # After the gates pass, record a provenance attestation on this commit and | |
| # push it to refs/notes/attest, so fledge builds a trust ledger (and its | |
| # /trust/ attest pip lights). attest ships a public Linux binary | |
| # (checksum-verified), so no token is needed; the step is additive and | |
| # best-effort, so a hiccup logs a warning and never fails CI. | |
| - name: Record attestation (attest) | |
| env: | |
| ATTEST_VERSION: v0.5.0 | |
| run: | | |
| base="https://github.com/CorvidLabs/attest/releases/download/${ATTEST_VERSION}" | |
| bin="${RUNNER_TEMP}/attest"; sum="${bin}.sha256" | |
| retry="--retry 5 --retry-connrefused --retry-delay 1" | |
| if curl -fsSL $retry "${base}/attest-linux-x86_64" -o "$bin" \ | |
| && curl -fsSL $retry "${base}/attest-linux-x86_64.sha256" -o "$sum" \ | |
| && want="$(awk '{print $1}' "$sum")" && [ -n "$want" ] \ | |
| && printf '%s %s\n' "$want" "$bin" | sha256sum -c - ; then | |
| chmod +x "$bin" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git config user.name "github-actions[bot]" | |
| git fetch origin "+refs/notes/attest:refs/notes/attest" 2>/dev/null || true | |
| if "$bin" sign --commit HEAD --reviewer agent:ci --confidence 0.9 --tests-passed \ | |
| --verdict proceed --note "CI: tests + integration + lint + audit + spec-check green" \ | |
| && git push origin refs/notes/attest ; then | |
| echo "attestation recorded for $(git rev-parse --short HEAD)" | |
| else | |
| echo "::warning::attest sign/push failed; provenance not recorded this run" | |
| fi | |
| else | |
| echo "::warning::attest download/verify failed; provenance not recorded this run" | |
| fi |