Skip to content

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

Merged
leynos merged 2 commits into
mainfrom
dependabot-hosted-runners
Oct 23, 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.
  • runner_placement_policy.py gains DEPENDABOT_GUARD and HOSTED_GUARD; runner_placement_reader.py's RUNNER_EXPRESSION accepts one parenthesised guard; ci_runner_placement_test.py requires the guard to equal HOSTED_GUARD. 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)

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

Gates

make test-workflow-contracts equivalent (pytest tests/workflow_contracts, 253 passed), 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
contract tests/workflow_contracts/runner_placement_policy.py: s/HOSTED_GUARD: typ.Final = f"\(\{FORK_GUARD\} || \{DEPENDABOT_GUARD\}\)"/HOSTED_GUARD: typ.Final = f"({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

Run Dependabot pull requests on GitHub-hosted runners while preserving Ubicloud execution for main-branch pushes.

New Features:

  • Route Dependabot pull-request jobs through GitHub-hosted runners alongside fork pull requests.

Enhancements:

  • Extend workflow placement contracts to validate the combined fork and Dependabot runner guard.
  • Document the runner selection rationale and cold-cache impact for Dependabot builds.

Tests:

  • Update workflow contract parsing and assertions to cover the parenthesized hosted-runner guard.

@sourcery-ai

sourcery-ai Bot commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

The PR mechanically extends the existing fork fallback so Dependabot-authored pull requests use ubuntu-latest, while pushes to main and other Ubicloud workloads remain unchanged. It updates documentation and strengthens the workflow contract to parse and require the exact parenthesized guard, with the stated test and mutation gates covering both the workflow behavior and policy enforcement.

Sequence diagram for Dependabot runner placement

sequenceDiagram
    actor Dependabot
    participant GitHubActions
    participant RunnerSelection
    participant Runner

    Dependabot->>GitHubActions: Open pull request
    GitHubActions->>RunnerSelection: Evaluate runs-on
    alt pull_request.user.login == dependabot[bot]
        RunnerSelection->>Runner: Select ubuntu-latest
    else fork pull request
        RunnerSelection->>Runner: Select ubuntu-latest
    else push to main or other workload
        RunnerSelection->>Runner: Select ubicloud-standard-2
    end
    Runner-->>GitHubActions: Execute workflow
Loading

File-Level Changes

Change Details Files
Route Dependabot pull requests to GitHub-hosted runners alongside fork pull requests.
  • Extend the runs-on fallback guard to match pull requests authored by dependabot[bot].
  • Use github.event.pull_request.user.login rather than the rerun-sensitive github.actor.
  • Document hosted-runner selection and the resulting cold-cache behavior.
.github/workflows/ci.yml
docs/developers-guide.md
Update the workflow contract model and parser for the combined hosted-runner guard.
  • Define Dependabot and combined hosted guards as reviewed policy constants.
  • Allow the runner-expression parser to recognize one parenthesized guard.
  • Require the exact combined guard in runner-placement tests.
tests/workflow_contracts/runner_placement_policy.py
tests/workflow_contracts/runner_placement_reader.py
tests/workflow_contracts/ci_runner_placement_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

@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
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: ba016240-c8f3-473c-9cd3-1df47042ecd3
📥 Commits

Reviewing files that changed from the base of the PR and between 2844d81 and 04d6851.

📒 Files selected for processing: 5
  • .github/workflows/ci.yml
  • docs/developers-guide.md
  • tests/workflow_contracts/ci_runner_placement_test.py
  • tests/workflow_contracts/runner_placement_policy.py
  • tests/workflow_contracts/runner_placement_reader.py
🔗 Linked repositories identified

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

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

Summary

  • Route Dependabot-authored pull requests to ubuntu-latest.
  • Keep other workflows on ubicloud-standard-2.
  • Add DEPENDABOT_GUARD and HOSTED_GUARD to the runner policy.
  • Accept parenthesised guards with spaces in runner_placement_reader.py.
  • Require the combined guard in the CI runner contract.
  • Document the cold-cache consequence in the developers’ guide.
  • Validate with 253 passing workflow-contract tests and a clean mdtablefix --check.

Walkthrough

The CI workflow now selects ubuntu-latest for fork and Dependabot-authored pull requests. Other runs use ubicloud-standard-2. The runner policy, expression reader, workflow contract test, and developer guide reflect this condition.

Changes

Hosted runner selection

Layer / File(s) Summary
Define and validate the hosted runner condition
.github/workflows/ci.yml, tests/workflow_contracts/runner_placement_policy.py, tests/workflow_contracts/runner_placement_reader.py, tests/workflow_contracts/ci_runner_placement_test.py, docs/developers-guide.md
The workflow uses a combined fork-or-Dependabot guard to select ubuntu-latest. The policy checks the Dependabot pull-request author, and the expression reader accepts parenthesised guards. Tests and documentation check the guard and both runner choices.

Priority: ⬇️ Low

Change: Feature

Merge Risk: ⚪ Minimal · up to 04d68

The intended runner selection is consistently implemented, so the change is mergeable.

Pre-merge checks: Passed 15
Check name Status Explanation
Title check Passed The title accurately summarises the main change: routing Dependabot pull requests to GitHub-hosted runners. The description references DF12-89 but does not identify an existing GitHub issue by number …
Description check Passed The description directly explains the runner change, implementation details, tests, documentation updates, and rollout context. It is related to the changeset.
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 1 functions across 3 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 Pass the testing check. The changed behaviour is guarded by substantive workflow-contract tests. test_the_runner_expression_is_exactly_the_reviewed_one reads the parsed ci.yml value and requires t…
User-Facing Documentation Passed Pass the user-facing documentation check. The pull request changes GitHub Actions runner placement for fork and Dependabot pull requests, not Wireframe's library API or end-user behaviour. The require…
Developer Documentation Passed Pass the developer documentation check. Update docs/developers-guide.md with the Dependabot runner decision, the exact runs-on guard, the author-versus-actor rule, and the hosted-pool cold-cache r…
Module-Level Documentation Passed All three changed Python modules carry clear module-level docstrings. ci_runner_placement_test.py explains the assertions and its relationship to the policy and reader modules (lines 1–7). `runner_p…
Testing (Unit And Behavioural) Passed Accept the testing coverage. The workflow contract reads the parsed .github/workflows/ci.yml job and checks the single-line expression, the exact combined HOSTED_GUARD, and both runner arms in `te…
Testing (Property / Proof) Passed PASS. The change adds one reviewed runner expression and a bounded parser form. The contract compares the parsed guard and both runner arms to exact constants in `tests/workflow_contracts/ci_runner_pl…
Testing (Compile-Time / Ui) Passed Pass. The pull request changes GitHub Actions YAML, Markdown, and Python workflow-contract code. It introduces no Rust or TypeScript compile-time behaviour, so trybuild or an equivalent compile-time t…
Unit Architecture Passed Keep the change as submitted. The pull request adds declarative workflow policy, documentation, policy constants, and a pure regular-expression parser update. It adds no commands, writes, network call…
Domain Architecture Passed Pass. Keep the change as infrastructure-only. The pull request changes .github/workflows/ci.yml runner selection, developer documentation, and workflow-contract tests. It does not change domain mode…
Observability Passed PASS — The change alters GitHub Actions runner placement only. It does not alter production request handling, service state, queues, or runtime resource behaviour. The workflow records the selected ru…
Full details: Title check

Explanation

The title accurately summarises the main change: routing Dependabot pull requests to GitHub-hosted runners. The description references DF12-89 but does not identify an existing GitHub issue by number that the title must include.

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

Full details: Testing (Overall)

Explanation

Pass the testing check. The changed behaviour is guarded by substantive workflow-contract tests. test_the_runner_expression_is_exactly_the_reviewed_one reads the parsed ci.yml value and requires the complete HOSTED_GUARD, ubuntu-latest arm, and ubicloud-standard-2 arm. This rejects fork-only guards, github.actor, incorrect author fields, a removed Dependabot arm, and incorrect runner labels. runner_placement_reader_test.py also exercises the expression reader and rejects unsupported expression forms. The tests therefore check the changed behaviour, not only mock calls or coverage.

Full details: User-Facing Documentation

Explanation

Pass the user-facing documentation check. The pull request changes GitHub Actions runner placement for fork and Dependabot pull requests, not Wireframe's library API or end-user behaviour. The required audience is therefore repository developers, and docs/developers-guide.md documents the hosted-runner guard, author check, runner arms, and cold-cache effect at lines 7-45. docs/users-guide.md remains an API consumer guide for assembling Wireframe applications at lines 1-6, and no user-facing functionality changed.

Full details: Developer Documentation

Explanation

Pass the developer documentation check. Update docs/developers-guide.md with the Dependabot runner decision, the exact runs-on guard, the author-versus-actor rule, and the hosted-pool cold-cache rationale (lines 27–45). No new API, tooling requirement, roadmap completion, or execplan is introduced by this pull request, and no additional design document is required for this scoped workflow decision.

Full details: Module-Level Documentation

Explanation

All three changed Python modules carry clear module-level docstrings. ci_runner_placement_test.py explains the assertions and its relationship to the policy and reader modules (lines 1–7). runner_placement_policy.py explains the reviewed decisions and its enforcement relationship (lines 1–13). runner_placement_reader.py explains its parsing utility and its relationship to the policy and test modules (lines 1–11). The pull request adds no module without documentation.

Full details: Testing (Unit And Behavioural)

Explanation

Accept the testing coverage. The workflow contract reads the parsed .github/workflows/ci.yml job and checks the single-line expression, the exact combined HOSTED_GUARD, and both runner arms in tests/workflow_contracts/ci_runner_placement_test.py (lines 239-285). This rejects github.actor and a missing Dependabot arm. The reader tests cover valid runner forms plus malformed expressions, null values, invalid mappings, sequences, and duplicate declarations in tests/workflow_contracts/runner_placement_reader_test.py (lines 47-158). The tests therefore exercise the workflow contract boundary and the changed parser behaviour. make test-workflow-contracts runs the complete workflow-contract suite through the Makefile target (lines 102-104).

Full details: Testing (Property / Proof)

Explanation

PASS. The change adds one reviewed runner expression and a bounded parser form. The contract compares the parsed guard and both runner arms to exact constants in tests/workflow_contracts/ci_runner_placement_test.py, and existing parameterized tests cover accepted and rejected runs-on forms. The meaningful input set is small and explicit, so a property test would not improve confidence. No lemma or proof assumption is introduced.

Full details: Testing (Compile-Time / Ui)

Explanation

Pass. The pull request changes GitHub Actions YAML, Markdown, and Python workflow-contract code. It introduces no Rust or TypeScript compile-time behaviour, so trybuild or an equivalent compile-time test is not required. The runner expression uses focused semantic assertions for its guard and both runner arms, plus parameterized reader tests for expression handling. This is more stable and meaningful than a snapshot of YAML or diagnostic text. No UI or user-facing output changes require snapshot coverage.

Full details: Unit Architecture

Explanation

Keep the change as submitted. The pull request adds declarative workflow policy, documentation, policy constants, and a pure regular-expression parser update. It adds no commands, writes, network calls, clocks, global mutable state, or hidden dependencies. The existing workflow reader keeps file parsing at the test boundary, and the changed tests compare parsed values with explicit policy constants. No unit-architecture failure condition is introduced.

Full details: Domain Architecture

Explanation

Pass. Keep the change as infrastructure-only. The pull request changes .github/workflows/ci.yml runner selection, developer documentation, and workflow-contract tests. It does not change domain models, commands, repositories, adapters, or production business logic. The new HOSTED_GUARD and RUNNER_EXPRESSION parse and enforce GitHub Actions runner policy, so they do not introduce transport, persistence, or vendor concerns into domain code.

Full details: Observability

Explanation

PASS — The change alters GitHub Actions runner placement only. It does not alter production request handling, service state, queues, or runtime resource behaviour. The workflow records the selected runner and job result, while .github/workflows/ci.yml:58-64 and docs/developers-guide.md document the Dependabot condition and cold-cache effect. No new production logging, metrics, tracing, or alert is required by this change.

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

A fork arrives; the runner shifts its place
Dependabot’s author joins the guarded case
Other runs keep their established lane
The contract checks the choice again
Clear rules guide the workflow train

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

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 21, 2026 22:47
@sourcery-ai

sourcery-ai Bot commented Oct 21, 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 21 hours and 12 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 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 ⚠️ Failed 2026-10-21T22:47:44.714025Z
We couldn’t complete this review. Comment @codex review to try again.
04d6851 Draft marked ready
🔒 Security Review ⚠️ Failed 2026-10-21T22:47:51.671731Z
We couldn’t complete this review. Comment @codex security review to try again.
04d6851 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

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@chatgpt-codex-connector

Copy link
Copy Markdown

The account paying for this security review has reached its Codex usage limits. The payer can check the Codex usage dashboard. For personal accounts, using credits requires enabling “Use credits for security reviews” in Code review settings. If you do not manage the paying account, contact this repository's admins.

@wafflecat-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
leynos force-pushed the dependabot-hosted-runners branch from 04d6851 to 8361012 Compare October 22, 2026 13:22
@pandalump

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:

1:  ed3e150 = 1:  780f319 Place Dependabot pull requests on GitHub-hosted runners
2:  04d6851 = 2:  8361012 Spell parenthesized as the en-GB-oxendict gate requires

codescene-access[bot]

This comment was marked as outdated.

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.

`runner_placement_policy.py` gains `DEPENDABOT_GUARD` and `HOSTED_GUARD`; `runner_placement_reader.py`'s `RUNNER_EXPRESSION` accepts one parenthesised guard; `ci_runner_placement_test.py` requires the guard to equal `HOSTED_GUARD`. Bespoke contract, so this PR takes the full review gate.
@leynos
leynos force-pushed the dependabot-hosted-runners branch from 8361012 to 61044ff Compare October 23, 2026 11:54
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.

3 participants