From 19ce5d94bc2b2b4f7230595a425c612ad98c992f Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Wed, 18 Jun 2025 17:29:44 +0200 Subject: [PATCH 1/5] ci/eval/compare: fix rebuild-stdenv labels Those have not been working since before the migration from OfBorg. Those `rebuildsByKernel` are an attrset of lists coming from `groupByKernel` (also see lengthy comment at the top of the file) - thus we need `lib.elem` instead. --- ci/eval/compare/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/eval/compare/default.nix b/ci/eval/compare/default.nix index 8b609cc8f2c4..302a2df90611 100644 --- a/ci/eval/compare/default.nix +++ b/ci/eval/compare/default.nix @@ -100,7 +100,7 @@ let (getLabels rebuildCountByKernel) # Adds "10.rebuild-*-stdenv" label if the "stdenv" attribute was changed ++ lib.mapAttrsToList (kernel: _: "10.rebuild-${kernel}-stdenv") ( - lib.filterAttrs (_: kernelRebuilds: kernelRebuilds ? "stdenv") rebuildsByKernel + lib.filterAttrs (_: lib.elem "stdenv") rebuildsByKernel ) # Adds the "11.by: package-maintainer" label if all of the packages directly # changed are maintained by the PR's author. (https://github.com/NixOS/ofborg/blob/df400f44502d4a4a80fa283d33f2e55a4e43ee90/ofborg/src/tagger.rs#L83-L88) From 9581b0c55bfab9a42fd12dc1cadfb4cdb5289308 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Wed, 18 Jun 2025 18:19:49 +0200 Subject: [PATCH 2/5] workflows/labels: fix race condition with throttling When we switched to a scheduled workflow, we also changed these lines to take the labels directly from the pull request list we iterate over. At the time it saved us an API request. Meanwhile, we have introduced throttling to the workflow and this causes a potential race condition: When the scheduled or manually triggered workflow is kicked off and empties its reservoir of API requests it might be blocked to wait up to.. an hour! If this happens, the labels taken from the pull request list might already be outdated at the time the workflow continues. This would cause some labels to be reset to their original state, which could be wrong if, for example, another push has happened in the meantime. This will have a much bigger impact after the next commit, where *all* labels are set every time, thus the `before` part must be accurate. Fetching the current labels right before managing them reduces this risk significantly. --- .github/workflows/labels.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 2a632be28b57..9e692f83e4c8 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -186,7 +186,11 @@ jobs: // Get all currently set labels that we manage const before = - pull_request.labels.map(({ name }) => name) + (await github.paginate(github.rest.issues.listLabelsOnIssue, { + ...context.repo, + issue_number: pull_request.number + })) + .map(({ name }) => name) .filter(name => name.startsWith('10.rebuild') || name == '11.by: package-maintainer' || From 8e1f8692618c82a3b5c42d46b41c75b066810e66 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Wed, 18 Jun 2025 18:58:45 +0200 Subject: [PATCH 3/5] workflows/labels: lower API calls reservoir to 500 First data shows, that we're unlikely to need more than 250 within an hour of regular activity. Once this is empty, we'll need to wait until the next hourly refill - thus, we'll rather set this a bit higher to be on the safe side. The hourly limit is at 5000 and we peaked around 3500, so far. We'll certainly have to look into reducing API calls, but this should still work out for now. --- .github/workflows/labels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 9e692f83e4c8..f5a07fd1457e 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -72,8 +72,8 @@ jobs: maxConcurrent: 1, // Hourly limit is at 5000, but other jobs need some, too! // https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api - reservoir: 1000, - reservoirRefreshAmount: 1000, + reservoir: 500, + reservoirRefreshAmount: 500, reservoirRefreshInterval: 60 * 60 * 1000 }) // Pause between mutative requests From 155ea15a381bd7720ad6ac13ab683fdd61f804ae Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Fri, 20 Jun 2025 20:45:56 +0200 Subject: [PATCH 4/5] workflows/pr: run in pull_request context on changed labels.yml When labels.yml is changed the new code is not tested in the PR directly, yet, because we forgot to add labels.yml to the list of pull_request files in pr.yml. This lead to one syntax error merged already. --- .github/workflows/pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 924a60d3752d..599faeda49cc 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -8,6 +8,7 @@ on: - .github/workflows/eval.yml - .github/workflows/lint.yml - .github/workflows/pr.yml + - .github/workflows/labels.yml - .github/workflows/reviewers.yml # needs eval results from the same event type pull_request_target: From d00d3190d6ae913d32bbb2d8133da5558a5cbe07 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Fri, 20 Jun 2025 21:03:45 +0200 Subject: [PATCH 5/5] workflows/labels: fix on older PRs When we made the switch from eval.yml to pr.yml we adjusted the labels job as well - but didn't take into account that we also need to deal with old PRs at the same time. Here, we fallback to another API request to get a run for eval.yml when we can't find one for pr.yml. --- .github/workflows/labels.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index f5a07fd1457e..36877d581c79 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -152,7 +152,17 @@ jobs: status: prEventCondition ? 'in_progress' : 'success', exclude_pull_requests: true, head_sha: pull_request.head.sha - })).data.workflow_runs[0]?.id + })).data.workflow_runs[0]?.id ?? + // TODO: Remove this after 2025-09-17, at which point all eval.yml artifacts will have expired. + (await github.rest.actions.listWorkflowRuns({ + ...context.repo, + // In older PRs, we need eval.yml instead of pr.yml. + workflow_id: 'eval.yml', + event: 'pull_request_target', + status: 'success', + exclude_pull_requests: true, + head_sha: pull_request.head.sha + })).data.workflow_runs[0]?.id // Newer PRs might not have run Eval to completion, yet. We can skip them, because this // job will be run as part of that Eval run anyway.