Skip to content

Run Dependabot pull requests on GitHub-hosted runners - #646

Merged
leynos merged 4 commits into
mainfrom
dependabot-hosted-runners
Oct 24, 2026
Merged

leynos merged 4 commits into
mainfrom
dependabot-hosted-runners

Conversation

@leynos

@leynos leynos commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Part of DF12-89

Rollout of the pattern in leynos/typos-config-builder#152 (reviewed and merged): Dependabot pull requests on a public repository run on GitHub-hosted runners, not Ubicloud. User decision of 19 October 2026.

Change

Every Ubicloud runs-on that has the fork fallback gains the Dependabot arm, in the pilot's shape:

runs-on: >-
  ${{ (github.event.pull_request.head.repo.fork
  || github.event.pull_request.user.login == 'dependabot[bot]')
  && 'ubuntu-latest' || 'ubicloud-standard-N' }}
  • pull_request.user.login (the author), not github.actor, which changes on a re-run.
  • Pushes to main have no pull_request payload and stay on Ubicloud, so main's caches stay warm.
  • Besides runs-on, the coverage lane's sccache credentials-step guard and backend input were keyed on the fork field alone, so a Dependabot pull request on the hosted arm would have tried the Ubicloud cache proxy and failed closed; both now carry the combined condition. tests/helpers/ci_placement.py reads the combined expression (references: the fork and author fields), test_ci_runner_placement.py and test_ci_compiler_cache_backend.py require it, test_ci_placement_reader.py gains positive and actor-stand-in cases, and test_ci_harness_boundary.py no longer mistakes the 'dependabot[bot]' operand for a runner label. Bespoke contract, so this PR takes the full review gate.
  • docs/developers-guide.md records the reason and the cold-cache consequence.

Check script row (before)

["cuprum", "pending", "8 ubicloud jobs, 7 lacking the arm"] from ~/docs/jm5-dependabot-runners/bin/check.py on origin/HEAD before this change.

Gates

Focused: pytest tests/test_ci_*.py tests/test_*workflow*.py with --noconftest (795 passed; the 49 errors are test_ci_setup_sccache_server_start fixtures that need a built sccache and the 1 failure found was fixed here), yamllint --strict and ruff@0.16.4 check/format on the changed tests clean, mdtablefix --check clean.

Mutation proof

Mutation Result
build-wheels.yml: user.login replaced by actor (all jobs) killed
build-wheels.yml: Dependabot arm removed (first job) killed
ci.yml: user.login replaced by actor (all jobs) killed
ci.yml: Dependabot arm removed (first job) killed
contract tests/helpers/ci_placement.py: frozenset({hosted.group("fork_ref"), hosted.group("author_ref")}) -> frozenset({hosted.group("fork_ref")}) killed

Merge class

Mechanical rollout of the pilot's shape (same expression, same form of contract change, docs paragraph, mutation proof), per the lead's ruling of 19 October.

Overlapping open PRs

These open PRs touch the same kind of files; per the standing rulings they do not hold this PR and are left untouched:

Summary by Sourcery

Run Dependabot pull requests on GitHub-hosted runners while preserving consistent cache handling and CI placement contracts.

New Features:

  • Run Dependabot pull requests from the repository on GitHub-hosted runners across the CI and wheel-building workflows.

Bug Fixes:

  • Keep coverage cache credentials and compiler-cache backend selection aligned with the hosted runner choice for Dependabot pull requests.

Enhancements:

  • Extend CI placement contracts and event modeling to recognize the pull request author while distinguishing it from the triggering actor.
  • Document Dependabot runner placement and its cold-cache behavior.

Documentation:

  • Document the shared hosted-runner condition and cache behavior for fork and Dependabot pull requests.

Tests:

  • Add behavioral and contract coverage for Dependabot runner selection, exact author-field usage, and cache backend behavior.

Selector proof

Selector proof: natural Dependabot runs on ubuntu-latest, all green: https://github.com/leynos/actix-v2a/actions/runs/39958329992, https://github.com/leynos/typos-config-builder/actions/runs/39990740324, https://github.com/leynos/agentland/actions/runs/39965006591; and a main push staying on ubicloud-standard-2: https://github.com/leynos/typos-config-builder/actions/runs/39181228629.

@sourcery-ai

sourcery-ai Bot commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

The PR mechanically rolls out the established fork-runner pattern so Dependabot pull requests use ubuntu-latest rather than Ubicloud, while keeping main pushes on Ubicloud. It synchronizes coverage cache behavior, placement parsing, contract tests, harness handling, and documentation around the exact pull-request author condition, with mutation-backed tests guarding against actor-based or incomplete expressions.

Sequence diagram for Dependabot runner and coverage cache selection

sequenceDiagram
    participant GitHub
    participant Workflow
    participant Coverage
    participant Cache

    GitHub->>Workflow: pull_request event
    Workflow->>Workflow: github.event.pull_request.user.login
    alt fork or Dependabot author
        Workflow->>Workflow: select ubuntu-latest
        Workflow->>Coverage: skip export-ubicloud-cache-credentials
        Coverage->>Cache: use backend local
        Cache-->>Coverage: compile cold
    else owned pull request
        Workflow->>Workflow: select ubicloud-standard-2
        Workflow->>Coverage: run export-ubicloud-cache-credentials
        Coverage->>Cache: use backend gha
    end
Loading

File-Level Changes

Change Details Files
Route Dependabot-authored pull requests to GitHub-hosted runners alongside fork pull requests.
  • Extended fork-fallback runner expressions in the wheel-build and CI workflows with an exact pull-request author check for dependabot[bot].
  • Used the combined condition for coverage cache-credential gating and the sccache backend, preventing hosted jobs from accessing the Ubicloud cache proxy.
  • Documented hosted-runner selection, actor-versus-author semantics, and cold-cache behavior.
.github/workflows/build-wheels.yml
.github/workflows/ci.yml
docs/ci-cache-ownership.md
docs/developers-guide.md
Update CI placement contracts and test infrastructure to understand and enforce the expanded runner expression.
  • Added parsing for fork-or-Dependabot conditional placements while preserving fork-only compatibility and recording both expression references.
  • Updated runner and compiler-cache contracts to require the fork and author fields, including tests that reject github.actor substitutions.
  • Adjusted the local harness to exclude dependabot[bot] from runner-label extraction and added positive placement-reader coverage.
tests/helpers/ci_placement.py
tests/helpers/ci_runners.py
tests/test_ci_compiler_cache_backend.py
tests/test_ci_harness_boundary.py
tests/test_ci_placement_reader.py
tests/test_ci_runner_placement.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-access[bot]

This comment was marked as outdated.

@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: 0301c71c-b1b6-420a-a985-ab361a9276b1
📥 Commits

Reviewing files that changed from the base of the PR and between 9c90083 and 4da3a8e.

📒 Files selected for processing: 11
  • .github/workflows/build-wheels.yml
  • .github/workflows/ci.yml
  • cuprum/unittests/test_benchmark_gate_ci_contract.py
  • docs/ci-cache-ownership.md
  • docs/developers-guide.md
  • tests/helpers/ci_placement.py
  • tests/helpers/ci_runners.py
  • tests/test_ci_compiler_cache_backend.py
  • tests/test_ci_harness_boundary.py
  • tests/test_ci_placement_reader.py
  • tests/test_ci_runner_placement.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.

Summary

  • Route fork pull requests and pull requests authored by dependabot[bot] to GitHub-hosted ubuntu-latest runners. Use the pull request author field, not github.actor, so reruns do not change runner placement.
  • Keep non-fork, non-Dependabot runs on ubicloud-standard-2. Pushes to main have no pull-request payload and remain on Ubicloud.
  • Apply the same fork-or-Dependabot condition to the coverage job’s sccache credential guard and backend selection. These jobs skip Ubicloud cache credentials and use the local backend.
  • Update the CI placement reader and workflow, cache, and harness contract tests to check the combined condition and author-versus-actor distinction.
  • Document runner placement and the cold-cache consequence in the developers’ guide and cache-ownership guide. This follows the reviewed and merged pilot change.

Validation

The author reports 795 tests passed, 49 fixture errors because test_ci_setup_sccache_server_start requires a built sccache, and one failure that was fixed. They also report clean yamllint --strict, Ruff check and format, and mdtablefix --check results, plus successful mutation checks for the runner expressions and CI placement contract.

Walkthrough

CI runner conditions now send fork and Dependabot pull requests to ubuntu-latest. Coverage skips Ubicloud cache credentials and uses the local sccache backend for these pull requests. Placement checks and CI documentation reflect the updated conditions.

Changes

Pull-request runner placement and cache handling

Layer / File(s) Summary
Recognise the author-based runner condition
tests/helpers/ci_placement.py, tests/helpers/ci_runners.py, tests/test_ci_placement_reader.py, tests/test_ci_harness_boundary.py
The placement helper recognises fork-only and fork-or-Dependabot conditions. It records the condition fields and runner labels. Tests check the parsed fields and labels.
Route Dependabot jobs to the hosted runner
.github/workflows/build-wheels.yml, .github/workflows/ci.yml, cuprum/unittests/test_benchmark_gate_ci_contract.py, tests/test_ci_runner_placement.py
The wheel and CI jobs use ubuntu-latest for fork or Dependabot pull requests. Other cases retain ubicloud-standard-2. Runner tests check the author condition.
Align coverage cache handling
.github/workflows/ci.yml, tests/test_ci_compiler_cache_backend.py, docs/ci-cache-ownership.md, docs/developers-guide.md
Coverage skips cache credential export and selects the local sccache backend for fork or Dependabot pull requests. Tests and documentation describe these conditions.

Suggested labels: Issue

Priority: ⬇️ Low

Change: Feature

Merge Risk: ⚪ Minimal · up to 4da3a

The Dependabot runner change appears mergeable after normal checks; no concrete merge-blocking issue is established.

Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

Failed Failed checks: 1 error · 1 warning

Check name Status Explanation Resolution
Testing (Unit And Behavioural) Error Add behavioural coverage for the new Dependabot runner path. The PR adds static YAML and parser checks, but it does not exercise the externally observable workflow selection for a Dependabot pull requ… Add a Dependabot event fixture with a non-fork pull request and user.login == 'dependabot[bot]'. Update the event evaluator to resolve the combined fork-or-author expression. Add a behavioural scenario that reads the real composed workflo…
Testing (Property / Proof) Warning The change adds a generic hosted-expression parser and a positional invariant over two references, two runner arms, and variable whitespace (tests/helpers/ci_placement.py:92-99,249-259). The new exa… Add a Hypothesis property in tests/test_ci_placement_properties.py for the combined expression. Generate valid fork and author references, both arm labels, and inner whitespace. Assert that parsing preserves the fork arm, owned arm, and b…
Passed Passed checks: 13 passed
Check name Status Explanation
Title check Passed The title "Run Dependabot pull requests on GitHub-hosted runners" matches the main change: the diff routes Dependabot-authored pull requests to ubuntu-latest in build-wheels.yml and ci.yml, alongside …
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 7 files. (4 skipped: 4…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Testing (Overall) Passed Accept the testing coverage. The changed runner declarations are guarded by test_fork_reachable_lanes_fall_back_by_position, which checks the hosted and Ubicloud arms and requires both FORK_FIELD …
User-Facing Documentation Passed The pull request changes internal GitHub Actions runner placement and cache handling for Dependabot pull requests. It does not change Cuprum's user-facing Python or Rust API. The authoritative diff ha…
Developer Documentation Passed Pass. The CI tooling and runner-placement change is documented in docs/developers-guide.md: the fork-arm section records the Dependabot condition, the author-versus-actor rule, the coverage creden…
Module-Level Documentation Passed All seven modified Python modules retain module-level docstrings in the reviewed head. The docstrings describe each module's purpose and testing or helper role, with component relationships stated whe…
Testing (Compile-Time / Ui) Passed PASS. The reviewed range changes YAML workflows, Python contract tests/helpers, and Markdown only. It adds no Rust or TypeScript compile-time behaviour, so a trybuild or equivalent test is not applica…
Unit Architecture Passed Pass this check. The pull request changes only GitHub Actions expressions, documentation, and test contracts. The new _conditional_placement function in tests/helpers/ci_placement.py is a pure par…
Domain Architecture Passed PASS: The pull request changes only CI workflow expressions, CI contract tests and helpers, and CI documentation. The reviewed diff has no production domain code or domain boundary changes. Therefore,…
Observability Passed Pass this check. The change only alters GitHub Actions runner and cache routing. GitHub exposes the selected runner on each job, while the affected CI jobs already record cache keys and hit status in …
Description check Passed Pass the description check. The description directly explains the Dependabot runner changes, cache handling, contract tests, documentation updates, and validation results.
Full details: Title check

Explanation

The title "Run Dependabot pull requests on GitHub-hosted runners" matches the main change: the diff routes Dependabot-authored pull requests to ubuntu-latest in build-wheels.yml and ci.yml, alongside fork pull requests. The title does not include a roadmap item or issue number, but the description references DF12-89, and the requirements only mandate those references where a roadmap task or issue is referenced in the PR description; this is a judgement call that the author should confirm.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 7 files. (4 skipped: 4 unsupported.)

Full details: Testing (Overall)

Explanation

Accept the testing coverage. The changed runner declarations are guarded by test_fork_reachable_lanes_fall_back_by_position, which checks the hosted and Ubicloud arms and requires both FORK_FIELD and AUTHOR_FIELD for every affected job (tests/test_ci_runner_placement.py:66-96). Synthetic reader tests exercise the combined expression and distinguish github.event.pull_request.user.login from github.actor (tests/test_ci_placement_reader.py:106-130). Cache tests require the combined condition for both the local/gha backend choice and the credentials-step guard (tests/test_ci_compiler_cache_backend.py:138-155, 221-242). The benchmark-gate contract also asserts the complete changes runner expression (cuprum/unittests/test_benchmark_gate_ci_contract.py:149-171). These assertions fail for the main plausible regressions: fork-only logic, actor-based logic, swapped runner arms, missing Dependabot cache handling, and an incorrect benchmark-gate expression.

Full details: User-Facing Documentation

Explanation

The pull request changes internal GitHub Actions runner placement and cache handling for Dependabot pull requests. It does not change Cuprum's user-facing Python or Rust API. The authoritative diff has no change to docs/users-guide.md; that guide targets package users and documents command execution and installation (docs/users-guide.md:1-14). The relevant maintainer-facing behaviour is documented in docs/developers-guide.md, including the Dependabot hosted-runner condition and coverage cache behaviour. Therefore the user-facing documentation requirement does not apply.

Full details: Developer Documentation

Explanation

Pass. The CI tooling and runner-placement change is documented in docs/developers-guide.md: the fork-arm section records the Dependabot condition, the author-versus-actor rule, the coverage credentials and sccache effects, and the cold-cache consequence (lines 181-226). The cache design document records the corresponding fork-or-Dependabot cache behaviour (docs/ci-cache-ownership.md, lines 178-182). No roadmap item or new execplan is changed in the reviewed range. The operational decision is therefore recorded in the relevant maintainer and cache design documentation.

Full details: Module-Level Documentation

Explanation

All seven modified Python modules retain module-level docstrings in the reviewed head. The docstrings describe each module's purpose and testing or helper role, with component relationships stated where needed, for example in tests/helpers/ci_placement.py and tests/test_ci_runner_placement.py. No changed file introduces a module without the required documentation.

Full details: Testing (Compile-Time / Ui)

Explanation

PASS. The reviewed range changes YAML workflows, Python contract tests/helpers, and Markdown only. It adds no Rust or TypeScript compile-time behaviour, so a trybuild or equivalent test is not applicable. The structured CI expression is covered with focused semantic assertions: tests/test_ci_placement_reader.py:108-130 checks both condition references, runner arms, and actor rejection; tests/helpers/ci_placement.py:249-269 parses the supported variants; and the benchmark contract checks the exact normalised expression. This is a source-level CI contract, not user-facing or UI output, so a snapshot would add brittleness without improving coverage.

Full details: Unit Architecture

Explanation

Pass this check. The pull request changes only GitHub Actions expressions, documentation, and test contracts. The new _conditional_placement function in tests/helpers/ci_placement.py is a pure parser with explicit input and output. It adds no I/O, network calls, clock access, process execution, mutation, or hidden dependency. Existing workflow reading remains at the placement boundary. The updated tests use existing injected monkeypatch seams and add no side effects. No production Python, Rust, or configuration entity gains a mixed responsibility.

Full details: Domain Architecture

Explanation

PASS: The pull request changes only CI workflow expressions, CI contract tests and helpers, and CI documentation. The reviewed diff has no production domain code or domain boundary changes. Therefore, it does not introduce a Domain Architecture failure.

Full details: Observability

Explanation

Pass this check. The change only alters GitHub Actions runner and cache routing. GitHub exposes the selected runner on each job, while the affected CI jobs already record cache keys and hit status in GITHUB_STEP_SUMMARY and publish sccache effectiveness statistics. The resource sampler also records peak memory and disk use. The workflow comments and updated documentation state the expected Dependabot hosted-runner and cold-cache behaviour. No new service boundary, production data path, alert, or unbounded metric label was introduced.

Full details: Testing (Unit And Behavioural)

Explanation

Add behavioural coverage for the new Dependabot runner path. The PR adds static YAML and parser checks, but it does not exercise the externally observable workflow selection for a Dependabot pull request. tests/helpers/ci_events.py:141-142 selects the hosted arm only from event["fork"], and tests/features/ci_runner_selection.feature:11-53 has no Dependabot event. Therefore the new github.event.pull_request.user.login == 'dependabot[bot]' branch in .github/workflows/ci.yml:76-77 and build-wheels.yml:173-174 can be wrong while the new tests still pass.

Resolution

Add a Dependabot event fixture with a non-fork pull request and user.login == 'dependabot[bot]'. Update the event evaluator to resolve the combined fork-or-author expression. Add a behavioural scenario that reads the real composed workflows, including the reusable wheel workflow, and asserts that every fork-reachable job selects ubuntu-latest. Exercise the coverage credentials guard and cache backend at the workflow boundary as well, asserting that Dependabot skips Ubicloud credentials and selects the local backend.

Full details: Testing (Property / Proof)

Explanation

The change adds a generic hosted-expression parser and a positional invariant over two references, two runner arms, and variable whitespace (tests/helpers/ci_placement.py:92-99,249-259). The new example tests cover one canonical expression and one github.actor mutation (tests/test_ci_placement_reader.py:108-131). The existing Hypothesis property covers only the fork-only grammar (tests/test_ci_placement_properties.py:95-125), so it does not exercise the new grammar across meaningful fields, labels, spacing, and arm orderings.

Resolution

Add a Hypothesis property in tests/test_ci_placement_properties.py for the combined expression. Generate valid fork and author references, both arm labels, and inner whitespace. Assert that parsing preserves the fork arm, owned arm, and both references by position. Add cases that verify the exact dependabot[bot] literal and reject or distinguish github.actor.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Route the pull requests to hosted ground
Keep Ubicloud runners for other rounds
Let cache credentials stay away
Choose local sccache for the day
Check each condition on its way

Comment @coderabbitai help to get the list of available commands.

GitHub-hosted minutes cost nothing on a public repository, so a pull request
authored by dependabot[bot] now falls back to ubuntu-latest like a fork's.
The expression tests pull_request.user.login rather than github.actor, which
changes when someone re-runs or pushes. A push to main has no pull_request
payload and stays on Ubicloud, so main still writes the cache.

Besides `runs-on`, the `coverage` lane's sccache credentials-step guard and `backend` input were keyed on the fork field alone, so a Dependabot pull request on the hosted arm would have tried the Ubicloud cache proxy and failed closed; both now carry the combined condition. `tests/helpers/ci_placement.py` reads the combined expression (references: the fork and author fields), `test_ci_runner_placement.py` and `test_ci_compiler_cache_backend.py` require it, `test_ci_placement_reader.py` gains positive and actor-stand-in cases, and `test_ci_harness_boundary.py` no longer mistakes the `'dependabot[bot]'` operand for a runner label. Bespoke contract, so this PR takes the full review gate.
@leynos
leynos force-pushed the dependabot-hosted-runners branch from 1f488f4 to 19f2110 Compare October 21, 2026 22:33
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review October 23, 2026 11:55
@sourcery-ai

sourcery-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Sorry @leynos, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 6 days and 10 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T11:57:54.608940Z 4da3a8e Draft marked ready
🔒 Security Review ✅ Completed 2026-10-23T11:57:36.867372Z 4da3a8e Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4da3a8e661

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/helpers/ci_placement.py
@coderabbitai coderabbitai Bot added the Issue label Oct 23, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pre-merge checks failed. Please resolve the failing checks before merging.

codescene-access[bot]

This comment was marked as outdated.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai The latest pre-merge table shows an error row (Testing (Unit And Behavioural)) asking for a workflow-level end-to-end test. Please assess this argument and say whether the error row is cleared at the current head.

GitHub Actions evaluates runs-on expressions only on GitHub's own runners, so no in-repository test can run the real event contexts. The placement contract (tests/helpers/ci_placement.py and tests/test_ci_runner_placement.py, with the compiler-cache backend contract) reads the checked-in workflow files and requires the exact combined fork-or-Dependabot-author condition, with the hosted arm first and the Ubicloud arm second, and refuses the fork-only form and a github.actor stand-in. The PR body lists the mutations that were killed. The end-to-end evidence is a real Dependabot run on ubuntu-latest and a main push on Ubicloud, recorded by the pilot (leynos/typos-config-builder#152). A self-dispatching proof workflow would add a paid job to assert what the Actions run page already records.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
git rev-parse HEAD
fd -H '^(AGENTS\.md|ci_placement\.py|test_ci_runner_placement\.py|test_ci_compiler_cache_backend\.py|test_ci_placement_reader\.py)$' .
for f in tests/helpers/ci_placement.py tests/test_ci_runner_placement.py tests/test_ci_compiler_cache_backend.py tests/test_ci_placement_reader.py; do
  ast-grep outline "$f"
done
gh pr view 646 --repo leynos/cuprum --json headRefOid,body,statusCheckRollup
gh api repos/leynos/cuprum/issues/646/comments --paginate --jq '.[] | {id,user:.user.login,body}'
gh pr view 152 --repo leynos/typos-config-builder --json body,state,mergedAt,comments

Length of output: 94599


🏁 Script executed:

#!/bin/bash
cat AGENTS.md
sed -n '40,135p' tests/helpers/ci_placement.py
sed -n '245,335p' tests/helpers/ci_placement.py
sed -n '50,145p' tests/test_ci_runner_placement.py
sed -n '20,32p' tests/test_ci_placement_reader.py
sed -n '105,147p' tests/test_ci_placement_reader.py
sed -n '35,110p' tests/test_ci_compiler_cache_backend.py
sed -n '135,260p' tests/test_ci_compiler_cache_backend.py
ast-grep outline tests/helpers/ci_events.py
sed -n '1,210p' tests/helpers/ci_events.py
cat tests/features/ci_runner_selection.feature
rg -n -C 4 'runs-on:|dependabot|export-ubicloud-cache-credentials|backend:' .github/workflows/ci.yml .github/workflows/build-wheels.yml
git diff 4da3a8e661004faf4ea91a900e8ecb906f57c1b1 HEAD --stat
gh api repos/leynos/typos-config-builder/issues/152/comments --paginate --jq '.[] | select(.body | test("actions/runs/")) | {html_url,body}'

Length of output: 72058


🤖 web_search executed:

Official GitHub Actions documentation contexts runs-on expression evaluated before job sent to runner workflow_dispatch pull_request event context

Length of output: 16225


@pandalump Keep the Testing (Unit And Behavioural) error open at head 4189fcd. Accept the argument against a self-dispatching proof workflow, but distinguish that from the local behavioural test requested by the current row.

The current table requests a Dependabot event fixture and a scenario through the existing composed-workflow evaluator. It does not require a paid GitHub Actions job.

The source inspection confirms two separate facts:

  • The placement contracts enforce the intended expression. They check the combined fork-or-Dependabot-author condition, both runner arms, and the coverage cache configuration. Withdraw the row’s claim that an incorrect selector can pass those contracts without identifying a concrete surviving mutation.
  • The behavioural evaluator still models only forks. In tests/helpers/ci_events.py, _select() uses only bool(event.get("fork")). A non-fork Dependabot event would therefore select Ubicloud in this model. tests/features/ci_runner_selection.feature has no Dependabot scenario.

AGENTS.md explicitly requires relevant behavioural coverage. The static contracts provide strong regression protection, but they do not update the existing behavioural model to match the changed workflow.

Correct one premise: GitHub evaluates runner selection before routing the job, not on a GitHub-hosted runner. See the GitHub contexts documentation. A local test cannot prove GitHub’s implementation, but it can exercise the repository’s event model against the checked-in composed workflows.

Close the remaining gap without adding a proof workflow:

  • Add a non-fork Dependabot event to the existing evaluator and behavioural scenarios.
  • Assert hosted placement through the reusable wheel workflow.
  • Cover the coverage credentials guard and local backend for that event.

Keep live-run evidence separate. The retrieved pilot discussion accepts contract coverage and describes the real runs as pending post-merge validation. I found no linked completed selector runs in its comments, so I cannot confirm that part of the argument.

This is a source-based assessment, not a test execution result. It does not change the displayed table or the PR’s approval status.

You are interacting with an AI system.

@wafflecat-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai Following your assessment, the existing behavioural model now has a Dependabot event: DEPENDABOT_PULL_REQUEST in tests/helpers/ci_events.py (_select takes the hosted arm for a fork or the Dependabot author), a scenario "Dependabot's pull request selects only hosted runners" in tests/features/ci_runner_selection.feature asserting no paid lane and the hosted fallback on every fork-reachable lane through the reusable wheel workflow, and a dependabot row in the schedulable-label outline. Removing the author clause from _select fails the new scenario. The credentials guard and local backend are covered by tests/test_ci_compiler_cache_backend.py. Please say whether the Testing (Unit And Behavioural) error row is cleared at the current head.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
git rev-parse HEAD
gh pr view 646 --repo leynos/cuprum --json headRefOid
fd -H '^AGENTS\.md$' .
cat AGENTS.md
for f in tests/helpers/ci_events.py tests/features/ci_runner_selection.feature tests/test_ci_compiler_cache_backend.py; do
  ast-grep outline "$f"
done
rg -n -C 3 'DEPENDABOT_PULL_REQUEST|ci_runner_selection\.feature|Dependabot.s pull request selects only hosted runners|schedulable|dependabot' tests --glob '*.py' --glob '*.feature'

Length of output: 50923


🏁 Script executed:

#!/bin/bash
ast-grep outline tests/behaviour/test_ci_runner_selection.py
sed -n '1,210p' tests/helpers/ci_events.py
cat tests/features/ci_runner_selection.feature
sed -n '1,190p' tests/behaviour/test_ci_runner_selection.py
sed -n '260,320p' tests/behaviour/test_ci_runner_selection.py
sed -n '15,105p' tests/test_ci_compiler_cache_backend.py
sed -n '135,260p' tests/test_ci_compiler_cache_backend.py
rg -n -C 3 'runs-on:|dependabot|export-ubicloud-cache-credentials|backend:' .github/workflows/ci.yml .github/workflows/build-wheels.yml

Length of output: 39391


🏁 Script executed:

#!/bin/bash
sed -n '190,223p' tests/behaviour/test_ci_runner_selection.py
git rev-parse HEAD

Length of output: 1738


@wafflecat-df12 Treat the Testing (Unit And Behavioural) error row as cleared at head 66d4f02. Source inspection confirms that the changes close the specific behavioural coverage gap from my previous assessment.

  • tests/helpers/ci_events.py defines a non-fork Dependabot event. _select() selects the hosted arm from the pull request author.
  • The Dependabot scenario has a pytest-bdd binding. It rejects every Ubicloud selection and requires every fork-reachable lane to be present and select ubuntu-latest.
  • The evaluator follows the reusable wheel workflow with the same event. The hosted-placement assertion checks the composed schedule.
  • The schedulable-label outline includes dependabot.
  • tests/test_ci_compiler_cache_backend.py requires the combined fork-or-Dependabot-author condition for the local backend and the credentials-step exclusion.

Keep this verdict separate from test execution and PR approval. I did not run repository tests or reproduce the reported mutation check. This reply does not update the displayed table or change the provider’s approval status. No self-dispatching proof workflow is needed to close this finding.

You are interacting with an AI system.

@leynos
leynos merged commit 87aed4e into main Oct 24, 2026
22 checks passed
@leynos
leynos deleted the dependabot-hosted-runners branch October 24, 2026 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants