Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
# workflow consumes one automatic job without dropping affected coverage.
test:
runs-on: ubuntu-latest
timeout-minutes: 120
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/cli-package-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
peer-native:
name: Build direct-peer addon (${{ matrix.target }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -132,7 +132,7 @@ jobs:
name: Build immutable tarball
needs: peer-native
runs-on: ubuntu-24.04
timeout-minutes: 60
timeout-minutes: 45
outputs:
release_candidate_artifact_id: ${{ steps.release-candidate.outputs.artifact-id }}
release_candidate_run_attempt: ${{ github.run_attempt }}
Expand Down Expand Up @@ -177,7 +177,7 @@ jobs:
name: Validate installed CLI ${{ matrix.name }}
needs: build
runs-on: ${{ matrix.runner }}
timeout-minutes: 15
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -236,7 +236,7 @@ jobs:
if: github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-24.04
timeout-minutes: 30
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dependency-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ concurrency:
jobs:
audit:
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 45
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/gitoxide-helper-admission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-windows-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ concurrency:
jobs:
package:
runs-on: windows-2025
timeout-minutes: 90
timeout-minutes: 45
defaults:
run:
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/runtime-host-owner-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
matrix:
os: [windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/runtime-host-peer-admission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
test:
name: quality
runs-on: ubuntu-latest
timeout-minutes: 30
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows-recovery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
windows_recovery:
name: windows_recovery
runs-on: windows-latest
timeout-minutes: 30
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows-sandbox-w0.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
protocol:
name: windows_sandbox_w0_protocol
runs-on: windows-2025
timeout-minutes: 25
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
39 changes: 39 additions & 0 deletions scripts/ci-test-plan.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,45 @@ test('pull request triggers stay on an explicit allowlist', () => {
]);
});

test('every pull request lane holds a scarce runner for the same bounded time', () => {
// One tier, not per-lane values. The worst observed successful runs are 19
// minutes (ci.yml) and 20 (release-windows-check), so 45 is about 2.3x the
// slowest lane: enough headroom for a cold cache and a flake retry, and far
// short of the 120 and 90 a hung job used to hold. A lane with no limit at
// all inherits GitHub's 360 and fails here.
// `pull_request` only: a `pull_request_target` lane reads the pull request
// rather than gating it, so it is not competing for a runner the author is
// waiting on and keeps its own tighter limit.
// Granularity is the file, not the job: a job inside a gating workflow that
// opts out of pull requests still carries the tier, because reading a job's
// `if:` would need the YAML parser this file cannot install.
const gates = readdirSync(WORKFLOW_DIR).filter((name) =>
/\bpull_request\b/u.test(triggerBlock(name)),
);
assert.ok(gates.length > 0, 'no pull request lane found');

for (const name of gates) {
// From `jobs:` on, with comment lines stripped, so prose above the triggers
// cannot be read as a job.
const workflow = readWorkflow(name).replaceAll(/^[ \t]*#.*$/gmu, '');
const start = workflow.indexOf('\njobs:');
assert.ok(start >= 0, `${name}: no jobs block`);
const jobs = workflow.slice(start);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] The enforced scope is wider in one direction and narrower in the other than the rule described above. After selecting workflows with a literal pull_request trigger, this scans every runner job below jobs: without evaluating its if, so it forces the cli-package-validation Eval job from 30 to 45 minutes even though that job explicitly cannot run on pull_request. Conversely, copilot-auto-review.yml is deliberately excluded here because it uses pull_request_target, yet this PR still changes its secret-bearing API job from 5 to 45 minutes without a contract covering that exception. The workflow remains trusted-base-only and cancel-in-progress, so this is operational exposure rather than a P0/P1 blocker. Please keep that job at 5 minutes and make the contract enumerate jobs that can actually run on ordinary pull requests.


Posted by an automated review agent operated by @M4n5ter. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.

简体中文

本条评论由 @M4n5ter 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。


const limits = [...jobs.matchAll(/^ {4}timeout-minutes: (\d+)$/gmu)].map((match) => match[1]);
// Counted by `runs-on`, one per job that consumes a runner, rather than by
// job id: a quoted id escapes an id pattern, and a two-space line inside a
// `run: |` block satisfies one.
const runners = [...jobs.matchAll(/^ {4}runs-on:/gmu)].length;
assert.ok(runners > 0, `${name}: no job consumes a runner`);
assert.deepEqual(
limits,
Array.from({ length: runners }, () => '45'),
name,
);
}
});

test('the recovery lane pairs its path filter with a nightly run and a main push', () => {
// Read from the `on:` block with comments stripped, so documenting a trigger
// cannot break its contract.
Expand Down
Loading