Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
f425f64
chore: project borg from Mono a5293e119fc2
Oct 10, 2026
21986f7
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 10, 2026
96cf58f
chore: project borg from Mono 3bba595c27f8
Oct 10, 2026
165446f
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 10, 2026
b273b08
chore: project borg from Mono 95eee04b8127
Oct 10, 2026
56f235b
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 10, 2026
cf8a4c5
chore: project borg from Mono d85864165c24
Oct 10, 2026
ff51120
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 10, 2026
df40113
chore: project borg from Mono ef5e513984ed
Oct 10, 2026
122ea41
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 11, 2026
7e22b64
chore: project borg from Mono 7c0e3ee59b04
Oct 11, 2026
20c167b
chore: project borg from Mono b271bbbd34fa
Oct 11, 2026
e3c1d95
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 11, 2026
00e3a20
chore: project borg from Mono 6efbce212025
Oct 11, 2026
1d32694
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 11, 2026
3a4a5d6
chore: project borg from Mono 5af6e0de217f
Oct 11, 2026
be90ea0
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 11, 2026
e20de24
chore: project borg from Mono 7bba3d56ad22
Oct 11, 2026
c53bd9d
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 12, 2026
03f7919
chore: project borg from Mono 459f737d5b9e
Oct 12, 2026
9f49807
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 12, 2026
6fb07e4
chore: project borg from Mono 2e833192cc63
Oct 12, 2026
7ee93e1
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 12, 2026
810c48d
chore: project borg from Mono 6a106187736f
Oct 12, 2026
336d445
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 12, 2026
985a0a0
chore: project borg from Mono e52156fbb589
Oct 12, 2026
43700f4
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 12, 2026
eb79fe9
chore: project borg from Mono 50bb0b080bad
Oct 12, 2026
3242663
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 12, 2026
a74b3af
chore: project borg from Mono fcb4796cdc8e
Oct 12, 2026
0d6fbdf
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 12, 2026
256f424
chore: project borg from Mono 004e0bd914d0
Oct 12, 2026
99c134b
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 16, 2026
1af517a
chore: project borg from Mono 0fd8f678d750
Oct 16, 2026
9ad1940
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 16, 2026
273c4f6
chore: project borg from Mono 4578fdbb3924
Oct 16, 2026
8eedadd
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 16, 2026
a3a4c6d
chore: project borg from Mono 91f10217da2a
Oct 16, 2026
d9a58b7
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 16, 2026
3594dd6
chore: project borg from Mono 296fa1359ec1
Oct 16, 2026
29beea4
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 17, 2026
1824b8d
chore: project borg from Mono 54af7346321a
Oct 17, 2026
4d1d278
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 17, 2026
46f6739
chore: project borg from Mono 6b41db420e1a
Oct 17, 2026
d1bb9d0
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 17, 2026
a1bad3e
chore: project borg from Mono ee64d86fe58c
Oct 17, 2026
03ad971
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 17, 2026
e0ec7c1
chore: project borg from Mono 6077c90a491c
Oct 17, 2026
7d52ff1
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 17, 2026
225f431
chore: project borg from Mono 9604c2352669
Oct 17, 2026
ea2613c
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 18, 2026
1d12608
chore: project borg from Mono 2ba0ca8a9a83
Oct 18, 2026
8bb9571
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 18, 2026
aed2d19
chore: project borg from Mono 9e043be5f33b
Oct 18, 2026
8c7caa2
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 18, 2026
810c6b2
chore: project borg from Mono 0e6e12bf977e
Oct 18, 2026
a35c394
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 18, 2026
54d185b
chore: project borg from Mono 2fbc08e02f94
Oct 18, 2026
a219f79
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 18, 2026
c8aa06d
chore: project borg from Mono faa2360ea605
Oct 18, 2026
68bb067
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 18, 2026
8bd9040
chore: project borg from Mono 7c1c4ccabe91
Oct 18, 2026
1bbee45
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 18, 2026
b2fdd46
chore: project borg from Mono 6aa9d4a0331c
Oct 18, 2026
588f4f1
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 20, 2026
e9bade1
chore: project borg from Mono a83ba9ef50bf
Oct 20, 2026
72a7b89
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 21, 2026
d8e3ab0
chore: project borg from Mono cf74b4784ef9
Oct 21, 2026
42807d8
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 21, 2026
c6d4ecc
chore: project borg from Mono 65eaea1fb12b
Oct 21, 2026
c8a9adf
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 21, 2026
bb28183
chore: project borg from Mono b656cc5c06fd
Oct 21, 2026
d589a1c
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 21, 2026
a619462
chore: project borg from Mono c441bf1b8d50
Oct 21, 2026
9e57cb4
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 21, 2026
edfbc2c
chore: project borg from Mono 6e0e857d148b
Oct 21, 2026
60626eb
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 21, 2026
3c42538
chore: project borg from Mono ed24e352625f
Oct 21, 2026
f981060
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 22, 2026
f169da6
chore: project borg from Mono f3c6715a022f
Oct 22, 2026
b7e4eac
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 22, 2026
9f7facb
chore: project borg from Mono d5ba06afe254
Oct 22, 2026
c872015
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 22, 2026
e993f30
chore: project borg from Mono 105afb45d4fe
Oct 22, 2026
71b6e0a
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 23, 2026
f571328
chore: project borg from Mono 8bcef5bb33b7
Oct 23, 2026
1c6771b
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 23, 2026
cd57777
chore: project borg from Mono 3b5879fc89ae
Oct 23, 2026
a41a0a0
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 23, 2026
30219c2
chore: project borg from Mono cbf7f827e284
Oct 23, 2026
a2f221b
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 23, 2026
c3252f8
chore: project borg from Mono 6d488731feb3
Oct 23, 2026
12adef9
chore: project borg from Mono e87c4cb597ca
Oct 23, 2026
62ef990
chore: project borg from Mono 81345cd61f56
Oct 23, 2026
1a9388f
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 27, 2026
413b2c7
chore: project borg from Mono 2d5c5c6c82d0
Oct 27, 2026
795a5e0
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 27, 2026
7b49c70
chore: project borg from Mono 0cf84f90bfd2
Oct 27, 2026
5a13f76
Merge remote-tracking branch 'origin/main' into sync/mono-projection
github-actions[bot] Oct 27, 2026
d931f1c
chore: project borg from Mono 957fcce869bc
Oct 27, 2026
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
6 changes: 3 additions & 3 deletions .repository-projection.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"projection": "borg",
"projectionSchemaVersion": 1,
"sourceRepository": "dx-corp/mono",
"sourceSha": "0cf84f90bfd2316c7942db9040adf02600a4185f",
"sourceSha": "957fcce869bc4aa2aeca09a23dcb933b23437704",
"destinationRepository": "dx-corp/borg",
"priorProjectedBase": "d9fa852ceaab9c0d87678461edf39376ac996ab5",
"priorProjectedBase": "fca0fb4012d288364bc6dd8a20f28537f4829584",
"definitionDigest": "78ba8d1b5794c261ff0afba6d99abc10b9297ea0dd94be4397fb1cbf63cf0c6e",
"toolDigest": "3236c76d5bddbdab39d448c244f17fb36fa84e10",
"contentDigest": "017dbfc9a5add83f90bc00e037efe2247c8a235c22a751939922c8fa647ba96f",
"contentDigest": "1ea246ccf3856b94f5430e9bb5279ceb192487c91f7388bd972723fd097a3661",
"publicationEligible": true
}
20 changes: 17 additions & 3 deletions src/janitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
//! superseded runs that already started, and `dedupe_same_sha` cancels queued
//! duplicates of a run of the same workflow, commit, event and pull request.
//! Duplicate groups never include `workflow_dispatch` or `merge_group` runs,
//! and a running duplicate is never cancelled. The
//! and a running duplicate is never cancelled, even when its workflow still
//! reads `queued`. An unreadable jobs response also preserves the run. The
//! janitor is opt-in (`supersede_janitor` in the queen config). Cancelling
//! runs needs `actions: write`: the janitor uses the queen's App installation
//! token (minted and refreshed on demand) unless the config names a static
Expand Down Expand Up @@ -97,8 +98,8 @@ pub struct PassReport {
/// Superseded push runs left alone because one of their jobs is running.
/// GitHub shows a run as `queued` while any job waits for a runner.
pub started_push: u32,
/// Runs that changed state between the listing and the cancel and were
/// left alone.
/// Runs left alone when a fresh status, head or active child job
/// contradicted the listing used to select them.
pub raced: u32,
/// Runs whose cancel GitHub answered with 409 (already finished, or stuck
/// in a state GitHub will not cancel).
Expand Down Expand Up @@ -597,6 +598,19 @@ impl Janitor {
report.deferred += 1;
continue;
}
// A waiting sibling can keep the workflow queued after jobs start.
match self.has_running_job(repo, run.id).await {
Ok(false) => {}
Ok(true) => {
report.raced += 1;
continue;
}
Err(e) => {
tracing::warn!("janitor: {repo} run {}: {e}", run.id);
report.errors += 1;
continue;
}
}
let why = format!(
"duplicate of run {kept} (workflow {}, head {})",
run.workflow_id, run.head_sha
Expand Down
58 changes: 58 additions & 0 deletions tests/janitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,64 @@ async fn queued_duplicates_keep_the_lowest_id() {
assert_eq!(r.duplicates, 0, "{r:?}");
}

#[tokio::test]
async fn a_queued_duplicate_with_a_running_job_is_kept() {
// GitHub's workflow stays queued while a sibling job waits for a runner.
// cancel_running must never opt same-head duplicate cleanup into killing it.
for cancel_running in [false, true] {
let h = Harness::start(with(json!({
"dedupe_same_sha": true, "cancel_running": cancel_running
})))
.await;
h.state().pulls.insert(10, "sha".into());
h.add_run(4, "queued", "pull_request", "sha", Some(10));
h.add_run(9, "queued", "pull_request", "sha", Some(10));
h.add_run_job(9, "active", "in_progress", Some("runner-1"));
h.add_run_job(9, "waiting", "queued", None);

let r = h.janitor_pass().await;
assert_eq!(
(r.duplicates, r.dedup_cancelled, r.errors, r.raced),
(1, 0, 0, 1),
"{r:?}"
);
assert!(h.state().cancelled.is_empty());
}
}

#[tokio::test]
async fn an_unreadable_duplicate_job_response_preserves_the_run() {
let h = Harness::start(with(json!({"dedupe_same_sha": true}))).await;
h.state().pulls.insert(10, "sha".into());
h.add_run(4, "queued", "pull_request", "sha", Some(10));
h.add_run(9, "queued", "pull_request", "sha", Some(10));
// An invalid provider response cannot establish that no job is running.
h.state()
.jobs
.push(json!({"id": 90, "run_id": 9, "status": false}));

let r = h.janitor_pass().await;
assert_eq!((r.dedup_cancelled, r.errors), (0, 1), "{r:?}");
assert!(h.state().cancelled.is_empty());
}

#[tokio::test]
async fn keeping_an_active_duplicate_leaves_the_cancel_budget_for_an_idle_one() {
let h = Harness::start(with(json!({
"dedupe_same_sha": true, "max_cancels_per_pass": 1
})))
.await;
h.state().pulls.insert(10, "sha".into());
for id in [4, 6, 9] {
h.add_run(id, "queued", "pull_request", "sha", Some(10));
}
h.add_run_job(6, "active", "in_progress", Some("runner-1"));

let r = h.janitor_pass().await;
assert_eq!((r.dedup_cancelled, r.deferred, r.raced), (1, 0, 1), "{r:?}");
assert_eq!(h.state().cancelled, [9]);
}

#[tokio::test]
async fn a_running_duplicate_is_kept_and_never_cancelled() {
let h = Harness::start(with(json!({"dedupe_same_sha": true}))).await;
Expand Down