Skip to content

ci: each workflow once per PR commit, and no PR blind to a push path (S37) #875

Open

Description

@gHashTag

Part of #851 (W14, CI pool time).

What

Three ways a workflow's on: block either spends runner time twice or skips a PR. They are classified by speed doubles in the build-speed loop's tooling (pure text, 16 fixtures). The tool lives outside this repo.

class meaning main 57de4a1
DOUBLE_ON_PR push with no branch filter plus pull_request: every commit to a PR branch starts the workflow twice 15
PR_BLIND push on main only, and a push path missing from the pull_request paths: a PR that touches only that path runs nothing before merge 3
DOUBLE_GLOB push on globbed branches (feat/*, fix/**, ...) plus pull_request: twice for PRs from matching branches only 4
PUSH_ALL_ONLY push on every branch, no pull_request 1
OK everything else 99/122

Counted from the Actions API: over 24 h, 351 of 374 push runs on non-main branches came from DOUBLE_ON_PR workflows.

Fix, in two PRs

  • ci: run the nine document gates on push to main only #867 restricts push to main for the nine unfiltered document gates.
  • The S37 PR (branch ci/push-pr-once) handles the six path-filtered DOUBLE_ON_PR workflows and the three that are PR_BLIND on main. Each pull_request path list now holds every push path.

A push: branches: [main] change on its own would have added PR_BLIND workflows. Five of the six listed their own workflow file under push paths only, so the push run on the PR branch was the only run that tested an edit to the workflow. That is the hand-copied-list defect again: two path lists in one file, kept in step by hand.

DOUBLE_ON_PR PR_BLIND OK
main 15 3 99/122
S37 branch 9 (#867's nine) 0 108/122
S37 + #867 (expected; not measured on a merged tree) 0 0 117/122

Deferred

  • A repo-level gate (tools/check_*.py failing on DOUBLE_ON_PR or PR_BLIND) waits until ci: give the 102 push workflows a dispatch-safe concurrency group #870 merges. Both would edit gates-can-fail.yml, and the checker should land on a tree where the count is already 0.
  • DOUBLE_GLOB (brain-ci, codegen, fpga-formal, fpga-formal-comb): whether pushes to feat/* and fix/** should run without a PR is the owner's call.

Not measured

  • Runner minutes saved. The run count is the measured quantity; minutes per run vary by workflow.
  • Whether any external tooling relies on a push run for a non-main branch (a status check required by branch protection on a non-main branch, for instance).

🤖 Generated with Claude Code

Activity

  1. gHashTag commented on Oct 5, 2026

    @gHashTag
    OwnerAuthor

    A measurement for the DOUBLE_GLOB decision, brain-ci only. It is still the owner's call; this is only the cost.

    brain-ci's last 200 runs (2026-10-02 14:47Z to 2026-10-05 03:37Z) covered 146 commits. 45 of them ran twice, once as push and once as pull_request: 44 on fix/* branches, 1 on feat/*. Events: 91 push, 95 pull_request, 13 workflow_dispatch, 1 schedule.

    What each extra run costs:

    The push half of a double tests the branch head, and the pull_request half tests the merge with main. If brain-ci's push were narrowed to [main, 'v*'], a fix/* branch with no PR would get no brain-ci run until a PR is opened or someone dispatches it. workflow_dispatch is already on the workflow.

    🤖 Generated with Claude Code

  2. gHashTag commented on Oct 5, 2026

    @gHashTag
    OwnerAuthor

    The other three DOUBLE_GLOB workflows, measured the same way as brain-ci above: gh run list --workflow <file> --limit 400, then the commits that ran on both push and pull_request.

    workflow runs read window commits run twice wall clock of the push half
    fpga-formal.yml 43 06-29 .. 10-04 10 of 33 (8 fix/, 2 feat/) 235 min
    fpga-formal-comb.yml 11 07-01 .. 10-04 0 of 11 0
    codegen.yml (ralph/dev-*) 400 08-24 .. 10-05 0 of 358 0

    Wall clock includes queue time, so 235 min is an upper bound on runner time, not billed minutes.

    So the glob doubles that cost anything are brain-ci's (45 of 146 commits, earlier comment). fpga-formal.yml is about 2.4 min a day over 97 days. The other two have never doubled in the window read. No change proposed for these three. The brain-ci decision is still the owner's.

    Not measured: whether the push runs on fix/** gave anyone feedback before the PR was opened, which is the reason to keep them.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions