Skip to content

Bootstrap CI: test matrix and AI code review workflows - #2

Merged
erubboli merged 2 commits into
mainfrom
ci-bootstrap
Sep 17, 2026
Merged

erubboli merged 2 commits into
mainfrom
ci-bootstrap

Conversation

@nullPointerEnjoyer

Copy link
Copy Markdown
Contributor

Adds the CI workflows to main so that pull_request events (including #1 from the fork) can trigger them — fork PRs only pick up workflow definitions that exist on the base branch.

@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown

🔍 OpenCodeReview found 6 issue(s) in this PR.

  • ✅ Successfully posted inline: 2 comment(s)
  • 📋 Routed to summary by policy: 3 comment(s)
  • ⏭️ Skipped (overlap with history): 1 comment(s)

maintainability · low

📄 .github/workflows/ci.yml (L15-L16)

⚠️ GitHub could not post this as an inline comment: Routed to summary (severity low · category maintainability)

This workflow has no concurrency group, so rapid successive pushes to main or PR updates can stack redundant full CI runs (6 clippy + 6 test + 3 platform legs). Adding a concurrency group with cancel-in-progress: true (as done in code-review.yml) avoids wasted runner time.

💡 Suggested Change

Before:

env:
  CARGO_TERM_COLOR: always

After:

concurrency:
  group: ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

bug · low

📄 .github/workflows/code-review.yml (L25-L25)

⚠️ GitHub could not post this as an inline comment: Routed to summary (severity low · category bug)

secrets.OCR_LLM_TOKEN is not defined or documented anywhere in the repository. If the secret is missing (or named differently), non-fork PRs will pass the if: gate but fail at runtime with an auth error rather than skipping cleanly. Consider guarding the job (e.g., if: secrets.OCR_LLM_TOKEN != '' via an env check) or documenting the required secret in the README.


maintainability · low

📄 .github/workflows/ci.yml (L44-L47)

⚠️ GitHub could not post this as an inline comment: Routed to summary (severity low · category maintainability)

The cache key interpolates the full features string, which contains spaces (e.g. --no-default-features --features node). Spaces in cache keys are error-prone and can produce confusing cache entries. Consider a sanitized key, e.g. key: ${{ hashFiles('Cargo.lock') }}-${{ matrix.features }} normalized to ${{ replace(matrix.features, ' ', '-') }}, so cache keys are stable and unambiguous.

💡 Suggested Change

Before:

      - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
        with:
          key: ${{ matrix.features }}
      - run: cargo clippy ${{ matrix.features }} --all-targets --locked -- -D warnings

After:

      - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
        with:
          key: ${{ replace(matrix.features, ' ', '-') }}
      - run: cargo clippy ${{ matrix.features }} --all-targets --locked -- -D warnings

Comment thread .github/workflows/ci.yml
Comment on lines +6 to +10
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

performance · medium
There is no dependency caching (no actions/cache or Swatinem/rust-cache) and no concurrency group. Every push/PR triggers six parallel jobs each doing a full cold cargo build of the dependency graph, and multiple runs for the same PR are not cancelled. Adding rust-cache and a concurrency group would significantly cut runner minutes.

Suggestion:

Suggested change
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always

Comment thread .github/workflows/ci.yml
Comment on lines +9 to +12
env:
CARGO_TERM_COLOR: always

jobs:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security · medium
This workflow defines six jobs but has no top-level permissions: block, so every job runs with the default (potentially broad) GITHUB_TOKEN permissions. All these jobs only need to check out code and run cargo; contents: read is sufficient. Add a least-privilege permissions block.

Suggestion:

Suggested change
env:
CARGO_TERM_COLOR: always
jobs:
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
jobs:

Comment thread .github/workflows/ci.yml
Comment on lines +13 to +16
fmt:
name: Format
runs-on: ubuntu-latest
steps:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maintainability · medium
None of the six jobs set timeout-minutes, so a hung cargo build or a blocking test (e.g., on windows-latest) can consume runner time indefinitely. The companion code-review.yml sets 40 minutes; apply a similar job-level timeout here (GitHub's default 360 minutes is far too long for CI).

Suggestion:

Suggested change
fmt:
name: Format
runs-on: ubuntu-latest
steps:
fmt:
name: Format
runs-on: ubuntu-latest
timeout-minutes: 30
steps:

Comment thread .github/workflows/ci.yml Outdated
Comment on lines +18 to +20
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug · medium
The fmt job uses dtolnay/rust-toolchain@stable while every other job pins 1.92.0, and there is no rust-toolchain.toml in the repo to normalize the version. rustfmt formatting rules can differ between stable and 1.92.0, causing CI failures on code formatted with one version and checked with the other. Pin fmt to the same toolchain for consistency.

Suggestion:

Suggested change
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- uses: dtolnay/rust-toolchain@1.92.0
with:
components: rustfmt

Comment thread .github/workflows/ci.yml Outdated
Comment on lines +18 to +20
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security · medium
dtolnay/rust-toolchain is a third-party action referenced by mutable tag (@stable, @1.92.0). Tags can be repointed, so a compromise of the action's repo would execute arbitrary code in CI with access to the GITHUB_TOKEN. Pin the action to a full commit SHA (e.g., uses: dtolnay/rust-toolchain@<sha> with toolchain: 1.92.0 passed via with:). Applies to all five clippy/test/platform/doc jobs and the fmt job.

Suggestion:

Suggested change
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- uses: dtolnay/rust-toolchain@<full-commit-sha>
with:
toolchain: 1.92.0
components: rustfmt

Comment thread .github/workflows/ci.yml
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./scripts/check-license.sh

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug · high
The license job runs ./scripts/check-license.sh, but no scripts/ directory or check-license.sh file exists in the repository. This job will always fail with an unclear runner error. Either commit the script (with the executable bit set) in this change, or remove the job until the script lands.

Suggestion:

Suggested change
- run: ./scripts/check-license.sh
- name: Check license headers
shell: bash
run: |
test -x ./scripts/check-license.sh || { echo "scripts/check-license.sh missing or not executable"; exit 1; }
./scripts/check-license.sh

Comment thread .github/workflows/ci.yml
on:
push:
branches: [main]
paths-ignore: [".github/**"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security · medium
paths-ignore: [".github/**"] on both push and pull_request excludes the workflow's own file, so changes to ci.yml (or other CI configuration) will never trigger CI. A broken or misconfigured workflow would go unnoticed until an unrelated code change happens. Consider removing .github/** from the ignore list, or at least keeping ci.yml itself in scope.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged tradeoff: workflow-only PRs would previously have failed all 18 crate jobs with "could not find Cargo.toml" (there is no crate on the bootstrap branch this PR touches). The workflows themselves are exercised on every code-touching PR, and a broken ci.yml surfaces on the next code change. If we want workflow-only changes validated too, the options are a dorny/paths-filter job-level setup or accepting a full 3-platform matrix run on CI-only PRs — happy to switch if preferred.

Comment thread .github/workflows/ci.yml
# The default path blows past the Windows MAX_PATH limit inside the
# mintlayer-core git checkouts (same reason mintlayer-core's own
# build.yml does this).
run: echo "CARGO_HOME=C:\crg" >> "$GITHUB_ENV"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug · medium
The Windows step sets CARGO_HOME=C:\crg before Swatinem/rust-cache runs. rust-cache by default caches the cargo home and target directories based on the effective environment, so an override here changes cache paths; also this custom CARGO_HOME persists into the cargo build/test steps. Verify rust-cache handles the overridden CARGO_HOME (or pass explicit workspaces/cache-directories inputs) so Windows legs don't silently skip caching and rebuild from scratch every run.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional: the override is set for all subsequent steps precisely so that rust-cache and cargo resolve the same short CARGO_HOME on Windows (registry/target under C:\crg), keeping the cache path consistent across runs. rust-cache v2 derives the cargo home from the effective environment, so caching is active — just relocated. If we ever see silent cache misses on the Windows leg we can pin cache-directories explicitly.

@erubboli
erubboli merged commit 4387941 into main Sep 17, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants