Skip to content

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

Merged
leynos merged 4 commits into
mainfrom
dependabot-hosted-runners
Oct 19, 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.
  • tests/test_parent_runner_placement.py gains a dependabot origin (hosted) and the parenthesised condition; new cases reject the fork-only form, an actor test and both hosted origins kept on Ubicloud.
  • docs/developers-guide.md records the reason and the cold-cache consequence.

Check script row (before)

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

Gates

make check-fmt, make lint, make test (193 passed, 2 skipped), mdtablefix --check all clean.

Mutation proof

Mutation Result
act-validation.yml: user.login replaced by actor (all jobs) killed
act-validation.yml: Dependabot arm removed (first job) killed
contract tests/test_parent_runner_placement.py: s/"dependabot": HOSTED_LABEL/"dependabot": label/ 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 Dependabot pull requests to GitHub-hosted runners while preserving Ubicloud placement for other eligible runs.

New Features:

  • Run Dependabot pull requests on GitHub-hosted runners while retaining Ubicloud runners for pushes and regular same-repository pull requests.

Enhancements:

  • Extend runner-placement validation to cover Dependabot origins and reject fork-only or actor-based runner expressions.

Documentation:

  • Document Dependabot runner selection and the resulting cold-cache behavior.

Tests:

  • Update runner-placement tests and mutation checks for Dependabot-specific hosted-runner behavior.

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.

`tests/test_parent_runner_placement.py` gains a `dependabot` origin (hosted) and the parenthesised condition; new cases reject the fork-only form, an actor test and both hosted origins kept on Ubicloud.
@sourcery-ai

sourcery-ai Bot commented Oct 19, 2026

Copy link
Copy Markdown

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 3 days and 7 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 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-19T13:15:07.148660Z 6d748cc PR opened
🔒 Security Review ✅ Completed 2026-10-19T13:15:35.535622Z 6d748cc PR opened
ℹ️ 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.

@sourcery-ai

sourcery-ai Bot commented Oct 19, 2026

Copy link
Copy Markdown

Reviewer's Guide

Updates the validation workflow so Dependabot pull requests run on free GitHub-hosted runners in public repositories, using the stable pull-request author identity, while pushes and same-repository pull requests retain Ubicloud placement; the contract tests and developer documentation are updated to enforce and explain the policy.

Sequence diagram for pull request runner selection

sequenceDiagram
    participant GitHub
    participant Workflow
    participant Runner
    GitHub->>Workflow: Trigger act-validation.yml
    Workflow->>Workflow: Read pull_request.head.repo.fork
    Workflow->>Workflow: Read pull_request.user.login
    alt fork pull request or Dependabot author
        Workflow->>Runner: runs-on ubuntu-latest
    else push or same-repository pull request
        Workflow->>Runner: runs-on ubicloud-standard-4
    end
Loading

Flow diagram for validation runner placement

flowchart TD
    Start["Workflow event"] --> PR{"pull_request payload?"}
    PR -->|No, push to main| U["Ubicloud runner\nubicloud-standard-4"]
    PR -->|Yes| Fork{"head.repo.fork?"}
    Fork -->|Yes| H["GitHub-hosted runner\ ubuntu-latest"]
    Fork -->|No| Author{"user.login == dependabot[bot]?"}
    Author -->|Yes| H
    Author -->|No| U
Loading

File-Level Changes

Change Details Files
Route Dependabot pull requests to GitHub-hosted runners while preserving Ubicloud execution for pushes and same-repository pull requests.
  • Extended the workflow runner expression with a parenthesized fork-or-Dependabot-author condition.
  • Used pull request author identity rather than the mutable workflow actor.
  • Kept the existing Ubicloud runner labels, timeout, and cache behavior for pushes to main.
.github/workflows/act-validation.yml
Strengthen the runner-placement contract to validate both hosted origins and reject unsafe expression variants.
  • Added a Dependabot origin and modeled fork and Dependabot as hosted placements.
  • Updated expression parsing and expected placement outcomes for the new condition shape.
  • Added failures for fork-only expressions, actor-based checks, reversed runner arms, and hosted origins assigned to Ubicloud.
tests/test_parent_runner_placement.py
Document the Dependabot runner policy and its cache trade-off for maintainers.
  • Documented why public-repository Dependabot pull requests use hosted minutes.
  • Explained author-versus-actor semantics and the cold hosted-cache consequence.
  • Updated the documented expression and test coverage description.
docs/developers-guide.md

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

@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
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: fe079516-6f3d-45d4-8eaa-b0b93fc44a11
📥 Commits

Reviewing files that changed from the base of the PR and between 8ae9fb1 and 6d748cc.

📒 Files selected for processing: 3
  • .github/workflows/act-validation.yml
  • docs/developers-guide.md
  • tests/test_parent_runner_placement.py

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 1 review per hour.

Summary

  • Route fork and Dependabot-authored pull requests to ubuntu-latest. Keep pushes and same-repository pull requests on ubicloud-standard-4.
  • Check github.event.pull_request.user.login for Dependabot. This keeps runner selection stable when the actor changes on reruns or pushes.
  • Keep pushes to main on Ubicloud so they continue to write the cache. Document that Dependabot builds use a cold hosted cache.
  • Extend runner-placement tests to cover both hosted origins and reject actor-based, incomplete, or incorrectly shaped conditions.
  • Follow the hosted-runner pattern used in the merged pilot.

Validation

The author reports that make check-fmt, make lint, make test (193 passed, 2 skipped), and mdtablefix --check completed cleanly. The author also reports that all three listed mutations were killed.

Walkthrough

The validation workflow now selects ubuntu-latest for fork and Dependabot pull requests. Other cases use ubicloud-standard-4. The placement tests and developer guide describe and check this rule, using the pull request author to identify Dependabot.

Changes

Runner placement

Layer / File(s) Summary
Define the hosted-runner condition
.github/workflows/act-validation.yml, tests/test_parent_runner_placement.py
The workflow and placement model select ubuntu-latest for fork pull requests and pull requests authored by dependabot[bot]. Other cases select ubicloud-standard-4.
Check runner placement
tests/test_parent_runner_placement.py, docs/developers-guide.md
Placement tests cover Dependabot origins and reject missing or incorrect Dependabot conditions, including use of github.actor. The guide documents the rule and the author-versus-actor distinction.

Priority: ⬇️ Low

Change: Feature

Merge Risk: ⚪ Minimal · up to 6d748

Dependabot pull requests will run validation on GitHub-hosted runners, while pushes and same-repository pull requests stay on Ubicloud. No merge-blocking risk was identified.

Pre-merge checks: Passed 13 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Developer Documentation Warning The PR changes the CI runner boundary: Dependabot pull requests now use ubuntu-latest, while pushes and same-repository pull requests use Ubicloud. docs/developers-guide.md documents the expressio… Add an ADR or a logged addendum to the relevant CI design ADR. Record the decision date, origin-to-runner mapping, use of pull_request.user.login instead of github.actor, the cache consequence, and the disk and timeout rationale. Link t…
Observability Warning The change alters runner placement and cache behaviour: Dependabot pull requests now use ubuntu-latest at .github/workflows/act-validation.yml:21-24, while pushes remain on Ubicloud. The workflow … Add bounded-cardinality telemetry at the runner-placement decision and job boundary. Record the selected runner pool (hosted or ubicloud), trigger origin (push, same-repository, fork, or dependabot), duration, and success/failur…
Passed Passed checks: 13 passed
Check name Status Explanation
Title check Passed The title clearly describes the main change: routing Dependabot pull requests to GitHub-hosted runners. No roadmap or GitHub issue number is required because the description does not identify one in t…
Description check Passed The description directly explains the runner-selection change, implementation details, documentation updates, tests, and validation results.
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 5 functions across 1 files. (2 skipped: 2 …
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 The changed runner behaviour has substantive contract tests. test_the_estate_expression_places_each_run covers push, same-repository, fork and Dependabot origins. test_a_misplaced_lane_is_reported…
User-Facing Documentation Passed PASS: The pull request changes the parent repository's act-validation CI runner placement only. It does not change generated-project functionality or a user-facing interface. The operational detail …
Module-Level Documentation Passed The changed Python module, tests/test_parent_runner_placement.py, has a module docstring. It states the module purpose, explains the placement utility, and describes the relationship to parent workf…
Testing (Unit And Behavioural) Passed The change adds meaningful placement coverage. tests/test_parent_runner_placement.py checks push, same-repository, fork, and Dependabot origins. It rejects a missing Dependabot arm, actor-based dete…
Testing (Property / Proof) Passed PASS — Do not recommend a property-based test. The changed invariant has a small, complete table of meaningful origins: push and same-repository runs use ubicloud-standard-4, while fork and Dependab…
Testing (Compile-Time / Ui) Passed Mark this check PASS. The PR changes GitHub Actions YAML, Markdown, and Python tests. It introduces no Rust or TypeScript compile-time behaviour. The placement tests use focused semantic assertions fo…
Unit Architecture Passed The change only updates workflow configuration, documentation, and placement-contract tests. The new runner expression is declarative policy; it adds no query API, command implementation, external dep…
Domain Architecture Passed The pull request changes only GitHub Actions runner placement, developer documentation, and placement-contract tests. It does not change domain logic, commands, repositories, adapters, or domain-facin…
Full details: Title check

Explanation

The title clearly describes the main change: routing Dependabot pull requests to GitHub-hosted runners. No roadmap or GitHub issue number is required because the description does not identify one in the required format.

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

Full details: Testing (Overall)

Explanation

The changed runner behaviour has substantive contract tests. test_the_estate_expression_places_each_run covers push, same-repository, fork and Dependabot origins. test_a_misplaced_lane_is_reported rejects the fork-only expression, github.actor, inverted arms, always-hosted and always-Ubicloud variants. test_every_ubicloud_lane_is_placed_by_the_estate_expression parses the actual workflow and checks the exact job, runner shape, origin placement and timeout. The tests therefore fail for the main plausible incorrect implementations and do not rely on mocks or vacuous assertions.

Full details: User-Facing Documentation

Explanation

PASS: The pull request changes the parent repository's act-validation CI runner placement only. It does not change generated-project functionality or a user-facing interface. The operational detail is documented in docs/developers-guide.md, which matches the contributor audience; docs/users-guide.md is not the applicable document.

Full details: Module-Level Documentation

Explanation

The changed Python module, tests/test_parent_runner_placement.py, has a module docstring. It states the module purpose, explains the placement utility, and describes the relationship to parent workflows, fork pull requests, Dependabot pull requests, and the constructed-expression checks. The pull request only changes a workflow, documentation, and this already documented test module. No changed module lacks the required documentation.

Full details: Testing (Unit And Behavioural)

Explanation

The change adds meaningful placement coverage. tests/test_parent_runner_placement.py checks push, same-repository, fork, and Dependabot origins. It rejects a missing Dependabot arm, actor-based detection, inverted arms, wrong labels, literal runners, and non-string values. It also covers YAML errors, missing workflow directories, runner ceilings, and the exact inventory of real workflow files. The final contract test reads .github/workflows/act-validation.yml, so the tests exercise the workflow configuration boundary rather than only isolated helpers.

Full details: Testing (Property / Proof)

Explanation

PASS — Do not recommend a property-based test. The changed invariant has a small, complete table of meaningful origins: push and same-repository runs use ubicloud-standard-4, while fork and Dependabot pull requests use ubuntu-latest. tests/test_parent_runner_placement.py parameterizes these four cases and adds focused negative cases for a missing Dependabot arm, actor-based detection, inverted arms, and non-estate expressions. The boolean condition and exact author comparison are auditable from this finite table; no introduced lemma or proof assumption requires exhaustive proof.

Full details: Testing (Compile-Time / Ui)

Explanation

Mark this check PASS. The PR changes GitHub Actions YAML, Markdown, and Python tests. It introduces no Rust or TypeScript compile-time behaviour. The placement tests use focused semantic assertions for push, same-repository, fork, and Dependabot origins, and reject the key incorrect expressions. No generated or UI-facing output requires a snapshot; snapshotting the runner expression would add brittle syntax coverage instead of behavioural coverage.

Full details: Unit Architecture

Explanation

The change only updates workflow configuration, documentation, and placement-contract tests. The new runner expression is declarative policy; it adds no query API, command implementation, external dependency, clock, network handle, mutable state, or hidden side-effect. The test additions keep parsing and runner selection as pure functions, with filesystem/YAML access confined to the existing workflow-loading boundary. No new unit is given multiple unrelated responsibilities, and the diff does not make fallibility or state mutation less visible.

Full details: Domain Architecture

Explanation

The pull request changes only GitHub Actions runner placement, developer documentation, and placement-contract tests. It does not change domain logic, commands, repositories, adapters, or domain-facing dependencies. No domain boundary violation or dishonest domain invariant claim is introduced.

Full details: Developer Documentation

Explanation

The PR changes the CI runner boundary: Dependabot pull requests now use ubuntu-latest, while pushes and same-repository pull requests use Ubicloud. docs/developers-guide.md documents the expression and rationale, but the PR changes no design document or ADR. The repository records comparable CI decisions in ADRs, so the new runner-placement decision is not fully recorded.

Resolution

Add an ADR or a logged addendum to the relevant CI design ADR. Record the decision date, origin-to-runner mapping, use of pull_request.user.login instead of github.actor, the cache consequence, and the disk and timeout rationale. Link the record from the developer guide.

Full details: Observability

Explanation

The change alters runner placement and cache behaviour: Dependabot pull requests now use ubuntu-latest at .github/workflows/act-validation.yml:21-24, while pushes remain on Ubicloud. The workflow has diagnostic artefact uploads, but it adds no bounded-cardinality metric or structured decision telemetry for runner pool, origin, cache path, duration, or failure outcome. Repository inspection found no existing metrics facility that covers this workflow. This prevents maintainers from measuring hosted-resource use, cold-cache impact, and degraded placement behaviour without inspecting individual runs.

Resolution

Add bounded-cardinality telemetry at the runner-placement decision and job boundary. Record the selected runner pool (hosted or ubicloud), trigger origin (push, same-repository, fork, or dependabot), duration, and success/failure outcome. Publish a stable metric or equivalent retained workflow telemetry, and add a short diagnostic summary without raw actor names, tokens, request identifiers, or other personal data. Keep the existing Act diagnostic artefacts and verify the new telemetry for every placement branch.

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

Route forked pull requests to hosted ground
Let Dependabot follow that route
Check the author, not the rerun actor
Keep other cases on the Ubicloud runner
Test each branch and document the rule

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

A re-run keeps the original actor (triggering_actor names the re-runner);
what flips the runner is another person pushing to a Dependabot branch.
@leynos
leynos merged commit feacc8c into main Oct 19, 2026
7 checks passed
@leynos
leynos deleted the dependabot-hosted-runners branch October 19, 2026 14:25
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.

1 participant