From daa543ce2cc2b2eb6d35a7265abcf2a7466e7381 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 5 Sep 2026 08:47:33 +0900 Subject: [PATCH 1/4] chore(ci): bootstrap Product pull-request workflow --- .github/workflows/product.yml | 97 +++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 .github/workflows/product.yml diff --git a/.github/workflows/product.yml b/.github/workflows/product.yml new file mode 100644 index 00000000..f3ae3423 --- /dev/null +++ b/.github/workflows/product.yml @@ -0,0 +1,97 @@ +name: Product + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review, converted_to_draft, closed] + +concurrency: + group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +permissions: + contents: read + +jobs: + rust-quality: + if: ${{ github.event_name != 'pull_request' || (github.event.action != 'closed' && github.event.pull_request.draft == false) }} + runs-on: ubuntu-24.04 + env: + COVERAGE_TOOLCHAIN: nightly-2026-08-20 + steps: + - name: Checkout exact source revision + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + fetch-depth: 0 + persist-credentials: false + + - name: Verify exact source revision + env: + EXPECTED_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + run: test "$(git rev-parse HEAD)" = "$EXPECTED_SHA" + + - name: Validate Product CI contract + run: python3 scripts/check_ci_contract.py + + - name: Show pinned Rust toolchain + run: rustc --version && cargo --version + + - name: Format + run: cargo fmt --all --check + + - name: Clippy + run: cargo clippy --workspace --all-targets -- -D warnings + + - name: Test + run: cargo test --workspace + + - name: Public documentation + env: + RUSTDOCFLAGS: -D warnings + run: cargo doc --workspace --no-deps + + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@1ed6d7be6168f6c9046541087ff549b6bc581fdf # v2.87.2 + with: + tool: cargo-llvm-cov + + - name: Install pinned branch-coverage toolchain + run: rustup toolchain install "$COVERAGE_TOOLCHAIN" --profile minimal --component llvm-tools-preview + + - name: Exact owned coverage + run: ./scripts/check_coverage.sh + + - name: Validate public JSON contract + run: | + npx --yes ajv-cli@5.0.0 compile \ + --spec=draft2020 \ + -s contracts/semantic-candidate.schema.json + npx --yes ajv-cli@5.0.0 test \ + --spec=draft2020 \ + -s contracts/semantic-candidate.schema.json \ + -d contracts/fixtures/semantic-candidate.valid.json \ + --valid + npx --yes ajv-cli@5.0.0 test \ + --spec=draft2020 \ + -s contracts/semantic-candidate.schema.json \ + -d contracts/fixtures/semantic-candidate.invalid-whitespace.json \ + --invalid + npx --yes ajv-cli@5.0.0 test \ + --spec=draft2020 \ + -s contracts/semantic-candidate.schema.json \ + -d contracts/fixtures/semantic-candidate.invalid-published-truth.json \ + --invalid + npx --yes ajv-cli@5.0.0 test \ + --spec=draft2020 \ + -s contracts/semantic-candidate.schema.json \ + -d contracts/fixtures/semantic-candidate.invalid-state-truth-mismatch.json \ + --invalid + + - name: Lockfile freshness + run: | + cargo generate-lockfile --locked + git ls-files --error-unmatch Cargo.lock >/dev/null + test -z "$(git status --porcelain=v1 --untracked-files=all -- Cargo.lock)" + + - name: Clean working tree + run: test -z "$(git status --porcelain=v1 --untracked-files=all)" From a31ae0c2df920f2794f7ddb456795b04797ab472 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 5 Sep 2026 11:13:03 +0900 Subject: [PATCH 2/4] fix(ci): avoid no-op Product workflow events --- .github/workflows/product.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/product.yml b/.github/workflows/product.yml index f3ae3423..d2ccb385 100644 --- a/.github/workflows/product.yml +++ b/.github/workflows/product.yml @@ -2,7 +2,7 @@ name: Product on: pull_request: - types: [opened, synchronize, reopened, ready_for_review, converted_to_draft, closed] + types: [opened, synchronize, reopened, ready_for_review] concurrency: group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }} @@ -13,7 +13,7 @@ permissions: jobs: rust-quality: - if: ${{ github.event_name != 'pull_request' || (github.event.action != 'closed' && github.event.pull_request.draft == false) }} + if: ${{ github.event.pull_request.draft == false }} runs-on: ubuntu-24.04 env: COVERAGE_TOOLCHAIN: nightly-2026-08-20 From db3df99145acb7cdbbafac60489bc420e81784b0 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 8 Sep 2026 16:56:30 +0900 Subject: [PATCH 3/4] fix(ci): use supported lockfile generation command --- .github/workflows/product.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/product.yml b/.github/workflows/product.yml index d2ccb385..4b9eb3f6 100644 --- a/.github/workflows/product.yml +++ b/.github/workflows/product.yml @@ -89,7 +89,7 @@ jobs: - name: Lockfile freshness run: | - cargo generate-lockfile --locked + cargo generate-lockfile git ls-files --error-unmatch Cargo.lock >/dev/null test -z "$(git status --porcelain=v1 --untracked-files=all -- Cargo.lock)" From 22709ec9b4d969bf67ec74db402813e74d11f7ca Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 8 Sep 2026 17:24:58 +0900 Subject: [PATCH 4/4] fix(ci): restore locked lockfile verification --- .github/workflows/product.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/product.yml b/.github/workflows/product.yml index 4b9eb3f6..d2ccb385 100644 --- a/.github/workflows/product.yml +++ b/.github/workflows/product.yml @@ -89,7 +89,7 @@ jobs: - name: Lockfile freshness run: | - cargo generate-lockfile + cargo generate-lockfile --locked git ls-files --error-unmatch Cargo.lock >/dev/null test -z "$(git status --porcelain=v1 --untracked-files=all -- Cargo.lock)"