From 20ca66ac687a6f2b5350ad972fbeba5678322431 Mon Sep 17 00:00:00 2001 From: Aliaksandr Date: Thu, 22 Jan 2026 01:31:04 +0200 Subject: [PATCH 1/5] ci(bot): add token fallback for labeler actions Use github.token when app token is not available (in forks). --- .github/workflows/bot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml index 9eb5911aadb5c..44198e2e2735a 100644 --- a/.github/workflows/bot.yml +++ b/.github/workflows/bot.yml @@ -97,7 +97,7 @@ jobs: github.event_name == 'pull_request_target' && !contains(fromJSON(inputs.headBranch).type, 'development') with: - repo-token: ${{ steps.app-token.outputs.token }} + repo-token: ${{ steps.app-token.outputs.token || github.token }} configuration-path: .github/labeler.yml # default sync-labels: true @@ -107,7 +107,7 @@ jobs: github.event_name == 'pull_request_target' && !contains(fromJSON(inputs.headBranch).type, 'development') with: - repo-token: ${{ steps.app-token.outputs.token }} + repo-token: ${{ steps.app-token.outputs.token || github.token }} configuration-path: .github/labeler-no-sync.yml sync-labels: false @@ -120,7 +120,7 @@ jobs: github.event_name == 'pull_request_target' && contains(fromJSON(inputs.headBranch).type, 'development') with: - repo-token: ${{ steps.app-token.outputs.token }} + repo-token: ${{ steps.app-token.outputs.token || github.token }} configuration-path: .github/labeler-development-branches.yml sync-labels: true From 0557411308fa3914d23a120b2b0c74b654c0223c Mon Sep 17 00:00:00 2001 From: Aliaksandr Date: Thu, 22 Jan 2026 01:31:49 +0200 Subject: [PATCH 2/5] ci(bot): add fork compatibility for maintainer map In forks without merge-group history, return empty maintainer map instead of throwing an error. --- ci/github-script/bot.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ci/github-script/bot.js b/ci/github-script/bot.js index f0155e8edd1c4..415593c7aec49 100644 --- a/ci/github-script/bot.js +++ b/ci/github-script/bot.js @@ -9,6 +9,9 @@ module.exports = async ({ github, context, core, dry }) => { const artifactClient = new DefaultArtifactClient() + // Detect if running in a fork (not NixOS/nixpkgs) + const isFork = context.repo.owner !== 'NixOS' + async function downloadMaintainerMap(branch) { let run @@ -68,9 +71,18 @@ module.exports = async ({ github, context, core, dry }) => { // We get here when none of the 10 commits we looked at contained a maintainer map. // For the master branch, we don't have any fallback options, so we error out. - // For other branches, we select a suitable fallback below. - if (branch === 'master') throw new Error('No maintainer map found.') + // In forks without merge-group history, return empty map to allow testing. + if (branch === 'master') { + if (isFork) { + core.warning( + 'No maintainer map found. Using empty map (expected in forks without merge-group history).', + ) + return {} + } + throw new Error('No maintainer map found.') + } + // For other branches, we select a suitable fallback below. const { stable, version } = classify(branch) const release = `release-${version}` From 033eccc028fb63d3537d3383041d7009b3466ec3 Mon Sep 17 00:00:00 2001 From: Aliaksandr Date: Thu, 22 Jan 2026 01:32:17 +0200 Subject: [PATCH 3/5] ci(bot): add fork compatibility for team lookups Forks don't have NixOS teams, return empty list to avoid 404. --- ci/github-script/bot.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci/github-script/bot.js b/ci/github-script/bot.js index 415593c7aec49..f812df3c565f6 100644 --- a/ci/github-script/bot.js +++ b/ci/github-script/bot.js @@ -121,6 +121,11 @@ module.exports = async ({ github, context, core, dry }) => { return [] } + // Forks don't have NixOS teams, return empty list + if (isFork) { + return [] + } + if (!members[team_slug]) { members[team_slug] = github.paginate(github.rest.teams.listMembersInOrg, { org: context.repo.owner, From bb0ec76b447f21063beb0448b61cd54d85096735 Mon Sep 17 00:00:00 2001 From: Aliaksandr Date: Thu, 22 Jan 2026 01:45:07 +0200 Subject: [PATCH 4/5] ci(bot): auto-label new package PRs with '8.has: package (new)' Checks all PR commit messages for ': init at' pattern and requires eval to report added packages (attrdiff.added). --- ci/github-script/bot.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/ci/github-script/bot.js b/ci/github-script/bot.js index f812df3c565f6..ba53aded5e374 100644 --- a/ci/github-script/bot.js +++ b/ci/github-script/bot.js @@ -321,9 +321,28 @@ module.exports = async ({ github, context, core, dry }) => { expectedHash: artifact.digest, }) - const evalLabels = JSON.parse( + const changedPaths = JSON.parse( await readFile(`${pull_number}/changed-paths.json`, 'utf-8'), - ).labels + ) + const evalLabels = changedPaths.labels + + // Fetch all PR commits to check their messages for package patterns + const prCommits = await github.paginate(github.rest.pulls.listCommits, { + ...context.repo, + pull_number, + per_page: 100, + }) + const commitMessages = prCommits.map((c) => c.commit.message) + + // Label new package PRs: "packagename: init at X.Y.Z" + // Exclude NixOS module commits like "nixos/timekpr: init at 0.5.8" + const newPackagePattern = /(? 0 + const commitsIndicateNewPackage = commitMessages.some((msg) => + newPackagePattern.test(msg), + ) + evalLabels['8.has: package (new)'] = + hasNewPackages && commitsIndicateNewPackage // TODO: Get "changed packages" information from list of changed by-name files // in addition to just the Eval results, to make this work for these packages From bf5645a0edffd6d7bfe8048a023b8255427cdb71 Mon Sep 17 00:00:00 2001 From: Aliaksandr Date: Thu, 22 Jan 2026 01:45:41 +0200 Subject: [PATCH 5/5] ci(bot): auto-label package updates with '8.has: package (update)' Checks all PR commit messages for version update pattern like 'packagename: X.Y.Z -> A.B.C'. Matches: 1.2.3, 0-unstable-2024-01-15, 1.3rc1, alpha, unstable --- ci/github-script/bot.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ci/github-script/bot.js b/ci/github-script/bot.js index ba53aded5e374..b3c3af8ec389d 100644 --- a/ci/github-script/bot.js +++ b/ci/github-script/bot.js @@ -344,6 +344,15 @@ module.exports = async ({ github, context, core, dry }) => { evalLabels['8.has: package (new)'] = hasNewPackages && commitsIndicateNewPackage + // Label package update PRs: "packagename: X.Y.Z -> A.B.C" + // Matches versions like: 1.2.3, 0-unstable-2024-01-15, 1.3rc1, alpha, unstable + // Exclude NixOS module commits like "nixos/ncps: types.str -> types.path" + const updatePackagePattern = /(?|→) [\w.-]+/ + const commitsIndicateUpdate = commitMessages.some((msg) => + updatePackagePattern.test(msg), + ) + evalLabels['8.has: package (update)'] = commitsIndicateUpdate + // TODO: Get "changed packages" information from list of changed by-name files // in addition to just the Eval results, to make this work for these packages // when Eval results have expired as well.