Skip to content

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

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

leynos merged 2 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.
  • fork_fallback.py reads the combined guard (HOSTED_GUARD) and requires it on the three pull-request lanes; the mutation table the property tests draw from gains dependabot-arm-dropped and actor-instead-of-author. Netsuke is a heavy repository: the measured Dependabot run on ubuntu-latest follows after merge. 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)

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

Gates

pytest tests/workflow_contracts --doctest-modules as make test-workflow-contracts runs it (1321 passed, 3 skipped), ruff@0.16.4 check and format clean, mdtablefix --check clean.

Mutation proof

Mutation Result
ci.yml: user.login replaced by actor (all jobs) killed
ci.yml: Dependabot arm removed (first job) killed
netsukefile-test.yml: user.login replaced by actor (all jobs) killed
netsukefile-test.yml: Dependabot arm removed (first job) killed
contract tests/workflow_contracts/fork_fallback.py: and placement.guard == HOSTED_GUARD -> and placement.guard == FORK_GUARD 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

Route fork and Dependabot pull requests to GitHub-hosted runners while keeping push workflows on Ubicloud.

New Features:

  • Run Dependabot-authored pull requests on GitHub-hosted runners across the applicable CI lanes.

Enhancements:

  • Extend workflow contracts and mutation testing to require the combined fork-or-Dependabot runner guard and validate the pull-request author check.
  • Document runner selection for Dependabot pull requests and the resulting cache behavior.

Tests:

  • Update workflow contract tests and property mutations to cover missing Dependabot routing and incorrect actor-based checks.

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

This PR rolls out the established runner-selection pattern across the pull-request lanes: forked and Dependabot pull requests use GitHub-hosted runners, while other executions retain their lane-specific Ubicloud runners. The workflow contract parser, fixtures, mutation tests, property coverage, and developer documentation are updated to enforce the exact author-based guard and explain its operational tradeoffs.

Sequence diagram for pull request runner selection

sequenceDiagram
    participant GitHub
    participant Workflow as GitHub Actions workflow
    participant Runner
    GitHub->>Workflow: Start pull_request run
    alt fork pull request
        Workflow->>Runner: runs-on ubuntu-latest
    else author is dependabot[bot]
        Workflow->>Runner: runs-on ubuntu-latest
    else other pull request
        Workflow->>Runner: runs-on lane-specific Ubicloud runner
    end
Loading

Flow diagram for push and pull request runner placement

flowchart TD
    A[Workflow run] --> B{Pull request context}
    B -->|"Fork or author is dependabot[bot]"| C[GitHub-hosted ubuntu-latest]
    B -->|Other pull request| D[Lane-specific Ubicloud runner]
    B -->|Push to main| D
Loading

File-Level Changes

Change Details Files
Route Dependabot pull-request jobs to GitHub-hosted runners while preserving Ubicloud for forked/non-PR and main-branch executions.
  • Added a parenthesized fork-or-Dependabot author guard to the three pull-request runner expressions, using pull_request.user.login rather than github.actor.
  • Kept lane-specific hosted images and Ubicloud fallback labels unchanged.
  • Documented hosted-minute rationale, author-versus-actor behavior, and cold-cache implications.
.github/workflows/ci.yml
.github/workflows/netsukefile-test.yml
docs/developers-guide.md
Updated the workflow contract parser and expectations to recognize and require the combined hosted-runner guard.
  • Added reusable guard constants and accepted the combined expression during runner declaration parsing.
  • Changed the three pull-request lane contract checks and doctest fixtures to require the combined guard.
  • Updated checked-in workflow and cache-related contract expectations.
tests/workflow_contracts/fork_fallback.py
tests/workflow_contracts/fork_fallback_test.py
tests/workflow_contracts/setup_rust_sccache_test.py
Extended mutation and property coverage to protect Dependabot routing and author-based identification.
  • Generated valid declarations with the combined guard.
  • Added mutations for dropping the Dependabot arm and replacing the pull-request author with github.actor.
  • Included the new mutations in property-test coverage.
tests/workflow_contracts/runner_placement_mutations.py
tests/workflow_contracts/runner_placement_properties_test.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
Contributor

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: cd1fa046-e407-46de-9c67-64a3f5b156c2
📥 Commits

Reviewing files that changed from the base of the PR and between 051358e and d1b802d.

📒 Files selected for processing: 8
  • .github/workflows/ci.yml
  • .github/workflows/netsukefile-test.yml
  • docs/developers-guide.md
  • tests/workflow_contracts/fork_fallback.py
  • tests/workflow_contracts/fork_fallback_test.py
  • tests/workflow_contracts/runner_placement_mutations.py
  • tests/workflow_contracts/runner_placement_properties_test.py
  • tests/workflow_contracts/setup_rust_sccache_test.py
🔗 Linked repositories identified

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

Included review availability: This review used your included allowance. 0 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-authored and Dependabot-authored pull requests on build-test, kani-smoke and netsukefile to GitHub-hosted runners. Keep pushes and other owned runs on their existing Ubicloud runners.
  • Check github.event.pull_request.user.login for dependabot[bot]. Do not use github.actor, which can differ from the pull request author.
  • Require the combined fork-or-Dependabot guard in the workflow contract. Add mutation cases that reject a missing Dependabot condition and an actor-based check.
  • Document the runner selection and the cold-cache consequence. Keep netsukefile on ubuntu-22.04 because it depends on that image's older glibc.

The author reports 1,321 workflow-contract tests passed and 3 were skipped. Ruff check and format, and mdtablefix --check, were reported clean. The author reports that both new mutation cases were killed. A measured Dependabot run on ubuntu-latest is planned after merge.

Walkthrough

Workflow runner selection now uses hosted runners for pull requests from forks and pull requests authored by dependabot[bot]. The workflow contract checks for this combined guard. Documentation and examples describe the updated condition and push-event behaviour.

Changes

Hosted runner fallback

Layer / File(s) Summary
Combined guard contract
tests/workflow_contracts/fork_fallback.py, tests/workflow_contracts/fork_fallback_test.py, tests/workflow_contracts/runner_placement_mutations.py, tests/workflow_contracts/runner_placement_properties_test.py
The workflow contract now requires the fork-or-Dependabot guard. Mutation cases check for a missing Dependabot condition and use of github.actor instead of the pull-request author.
Runner conditions and examples
.github/workflows/ci.yml, .github/workflows/netsukefile-test.yml, docs/developers-guide.md, tests/workflow_contracts/setup_rust_sccache_test.py
Three workflow jobs select hosted runners for fork or Dependabot-authored pull requests. The guide and test example document the condition. The guide states that pull-request properties are empty strings on pushes.

Possibly related PRs

  • leynos/repovec-appliance#187: Adds the same Dependabot author guard to fork-fallback runner selection and updates related contracts and documentation.

Suggested labels: Issue

Suggested reviewers: codescene-access

Priority: ⬇️ Low

Change: Feature

Merge Risk: ⚪ Minimal · up to d1b80

No current-PR merge-blocking risk is established.

Pre-merge checks: Passed 15
Check name Status Explanation
Title check Passed The title "Run Dependabot pull requests on GitHub-hosted runners" matches the main change: the workflows and fork-fallback contract now route Dependabot pull requests to ubuntu-latest, while pushes st…
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 16 functions across 5 files. (3 skipped: 3…
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 contract test reads all checked-in runner declarations and requires the exact `(github.event.pull_request.head.repo.fork || github.event.pull_request.user.login == 'de…
User-Facing Documentation Passed PASS: The pull request changes repository CI runner placement for Dependabot and fork pull requests. It does not change Netsuke functionality or behaviour for end users. The change is documented in th…
Developer Documentation Passed Pass. The pull request changes CI runner placement and documents the policy in docs/developers-guide.md at lines 1241-1263 and 1265-1311. The guide records the Dependabot condition, author-versus-ac…
Module-Level Documentation Passed All five changed Python modules have clear module-level docstrings. The docstrings state each module's purpose and use, and describe relationships where needed, including workflow readers, contract te…
Testing (Unit And Behavioural) Passed The PR adds adequate unit and workflow-contract coverage. fork_fallback_test.py reads the checked-in workflow YAML, verifies all direct runner declarations, checks the exact combined HOSTED_GUARD,…
Testing (Property / Proof) Passed PASS. Keep the Hypothesis property test in tests/workflow_contracts/runner_placement_properties_test.py:363-397. It ranges over all fork-fallback mutation kinds, including dependabot-arm-dropped a…
Testing (Compile-Time / Ui) Passed Pass. The pull request changes YAML workflows, Markdown, and Python contract tests only; it adds no Rust or TypeScript compile-time behaviour. The structured runner expressions have focused semantic c…
Unit Architecture Passed PASS — The pull request adds runner-selection expressions and pure workflow-contract parsing only. The workflow changes read explicit GitHub event fields and select a runner; they add no application q…
Domain Architecture Passed Pass this check. The pull request changes only GitHub Actions runner placement, workflow-contract tests, and documentation. It does not change domain logic, domain models, commands, repositories, or a…
Observability Passed PASS: The change alters GitHub Actions runner placement for Dependabot pull requests. It does not alter application or production service behaviour, process boundaries, request throughput, latency, re…
Description check Passed The description matches the changes: it explains routing fork and Dependabot pull requests to GitHub-hosted runners, keeping pushes on Ubicloud, and updating the workflow contracts, tests and document…
Full details: Title check

Explanation

The title "Run Dependabot pull requests on GitHub-hosted runners" matches the main change: the workflows and fork-fallback contract now route Dependabot pull requests to ubuntu-latest, while pushes stay on Ubicloud. The title does not reference a roadmap item or issue number. The title-check requirements call for a roadmap or issue reference only where the description or execplan provides one. The description cites DF12-89, which is a tracker reference rather than a roadmap item number, so no change is required.

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 16 functions across 5 files. (3 skipped: 3 unsupported.)

Full details: Testing (Overall)

Explanation

Accept the testing coverage. The contract test reads all checked-in runner declarations and requires the exact (github.event.pull_request.head.repo.fork || github.event.pull_request.user.login == 'dependabot[bot]') guard, the correct hosted label, and the Ubicloud owned arm (d1b802d, tests/workflow_contracts/fork_fallback_test.py:47-65; .github/workflows/ci.yml:62-65,400-403; .github/workflows/netsukefile-test.yml:35-38). The mutation property test rejects both plausible regressions introduced by this change: dropping the Dependabot arm and using github.actor instead of the pull-request author. It also checks the exact offending lane, so the assertions are not vacuous (d1b802d, tests/workflow_contracts/runner_placement_mutations.py:270-286; runner_placement_properties_test.py:363-397).

Full details: User-Facing Documentation

Explanation

PASS: The pull request changes repository CI runner placement for Dependabot and fork pull requests. It does not change Netsuke functionality or behaviour for end users. The change is documented in the contributor-focused developers' guide, which describes the Dependabot guard, author-versus-actor choice, hosted runner, and push behaviour at docs/developers-guide.md:1239-1263. The users' guide is an end-user reference for authoring and running Netsuke, as stated in docs/contents.md:295-297, so no users' guide update is required.

Full details: Developer Documentation

Explanation

Pass. The pull request changes CI runner placement and documents the policy in docs/developers-guide.md at lines 1241-1263 and 1265-1311. The guide records the Dependabot condition, author-versus-actor choice, push behaviour, lane-specific hosted runners, cache effects, and contract coverage. No new API, roadmap item, ExecPlan, or separate design document is introduced, and no additional locale requires synchronisation.

Full details: Module-Level Documentation

Explanation

All five changed Python modules have clear module-level docstrings. The docstrings state each module's purpose and use, and describe relationships where needed, including workflow readers, contract tests, mutation properties, runner_placement_invariants, and setup-rust. Evidence: tests/workflow_contracts/fork_fallback.py:1-27, fork_fallback_test.py:1-14, runner_placement_mutations.py:1-14, runner_placement_properties_test.py:1-9, and setup_rust_sccache_test.py:1-21 at the reviewed head.

Full details: Testing (Unit And Behavioural)

Explanation

The PR adds adequate unit and workflow-contract coverage. fork_fallback_test.py reads the checked-in workflow YAML, verifies all direct runner declarations, checks the exact combined HOSTED_GUARD, and covers malformed declarations and line-break errors (lines 35-143). The mutation properties reject both a missing Dependabot arm and use of github.actor, while preserving the valid declaration (runner_placement_mutations.py lines 270-326; runner_placement_properties_test.py lines 61-73 and 363-397). The tests therefore exercise the workflow contract boundary, not only private helpers. The changed workflows contain the author-based guard on all three affected lanes (ci.yml lines 62-65 and 400-403; netsukefile-test.yml lines 35-38).

Full details: Testing (Property / Proof)

Explanation

PASS. Keep the Hypothesis property test in tests/workflow_contracts/runner_placement_properties_test.py:363-397. It ranges over all fork-fallback mutation kinds, including dependabot-arm-dropped and actor-instead-of-author, and over all three affected lanes. The mutation helpers in tests/workflow_contracts/runner_placement_mutations.py:270-333 exercise the new invariant and the property asserts the exact offending lane. The invariant therefore has property coverage; no exhaustive proof is introduced or required.

Full details: Testing (Compile-Time / Ui)

Explanation

Pass. The pull request changes YAML workflows, Markdown, and Python contract tests only; it adds no Rust or TypeScript compile-time behaviour. The structured runner expressions have focused semantic coverage in tests/workflow_contracts/fork_fallback_test.py and mutation coverage for the missing Dependabot arm and incorrect actor in tests/workflow_contracts/runner_placement_mutations.py and runner_placement_properties_test.py. This is configuration validation, not UI or generated text output, so snapshot tests are not appropriate.

Full details: Unit Architecture

Explanation

PASS — The pull request adds runner-selection expressions and pure workflow-contract parsing only. The workflow changes read explicit GitHub event fields and select a runner; they add no application query, command, I/O, network client, clock, global state, or hidden dependency. fork_fallback.py keeps parsing as a side-effect-free function with explicit string input and None output on unsupported input (repository leynos/netsuke, commit reviewed, tests/workflow_contracts/fork_fallback.py:137-190). The mutation helpers make their dictionary mutation explicit in their _apply_*_mutation names and return types (same repository and commit, tests/workflow_contracts/runner_placement_mutations.py:230-285). The added cache expectation path delegates to the same pure parser and returns a value from its input (same repository and commit, tests/workflow_contracts/setup_rust_sccache_test.py:153-176). No changed unit combines unrelated responsibilities or makes fallibility or side-effects less visible.

Full details: Domain Architecture

Explanation

Pass this check. The pull request changes only GitHub Actions runner placement, workflow-contract tests, and documentation. It does not change domain logic, domain models, commands, repositories, or adapters. The new Dependabot condition remains in workflow infrastructure and the tests validate that infrastructure policy.

Full details: Observability

Explanation

PASS: The change alters GitHub Actions runner placement for Dependabot pull requests. It does not alter application or production service behaviour, process boundaries, request throughput, latency, retries, or production reliability. The workflows retain existing job status, cache, sccache, and resource summaries, and the developer guide documents the hosted-runner and cold-cache behaviour. No new production metrics, tracing, alerts, or logging are required by this observability check.

Full details: Description check

Explanation

The description matches the changes: it explains routing fork and Dependabot pull requests to GitHub-hosted runners, keeping pushes on Ubicloud, and updating the workflow contracts, tests and documentation.

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

Route forked runs to hosted ground.
Send Dependabot-authored runs there too.
Keep other events on their usual runners.
Check each guard against its contract.
Let clear examples show the path.

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

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 9 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:56:57.002496Z d1b802d Draft marked ready
🔒 Security Review ✅ Completed 2026-10-23T11:57:51.372716Z d1b802d 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.

@coderabbitai coderabbitai Bot added the Issue A pull request originating from an issue label Oct 23, 2026
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.

`fork_fallback.py` reads the combined guard (`HOSTED_GUARD`) and requires it on the three pull-request lanes; the mutation table the property tests draw from gains `dependabot-arm-dropped` and `actor-instead-of-author`. Netsuke is a heavy repository: the measured Dependabot run on `ubuntu-latest` follows after merge. Bespoke contract, so this PR takes the full review gate.
@leynos
leynos force-pushed the dependabot-hosted-runners branch from d1b802d to 2728195 Compare October 23, 2026 23:36
@buzzybee-df12

Copy link
Copy Markdown
Collaborator

Rebased onto main only because the squash merge of a branch whose workflow file diverged from main needs the workflow OAuth scope. Range-diff against the reviewed head (all =):

1:  cbd16dc1 = 1:  5cce9412 Place Dependabot pull requests on GitHub-hosted runners
2:  d1b802d1 = 2:  2728195e Extract the guard test from _split_operands

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

Labels

Issue A pull request originating from an issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants