workflows/bot: allow maintainer merges after committer approval
This allows committers to approve PRs with additional, optional nits that the author-maintainer can either address or merge immediately without these changes. It also allows committers to approve a PR for merge, while still waiting for other maintainers to give their feedback - they can then merge the PR directly instead of passing it back to the committer.
This commit is contained in:
@@ -45,8 +45,9 @@ To ensure security and a focused utility, the bot adheres to specific limitation
|
|||||||
- The PR targets one of the [development branches](#branch-classification).
|
- The PR targets one of the [development branches](#branch-classification).
|
||||||
- The PR only touches packages located under `pkgs/by-name/*`.
|
- The PR only touches packages located under `pkgs/by-name/*`.
|
||||||
- The PR is either:
|
- The PR is either:
|
||||||
- authored by a [committer][@NixOS/nixpkgs-committers],
|
- approved by a [committer][@NixOS/nixpkgs-committers].
|
||||||
- backported via label, or
|
- authored by a [committer][@NixOS/nixpkgs-committers].
|
||||||
|
- backported via label.
|
||||||
- created by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/).
|
- created by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/).
|
||||||
- The user attempting to merge is a member of [@NixOS/nixpkgs-maintainers].
|
- The user attempting to merge is a member of [@NixOS/nixpkgs-maintainers].
|
||||||
- The user attempting to merge is a maintainer of all packages touched by the PR.
|
- The user attempting to merge is a maintainer of all packages touched by the PR.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const { classify } = require('../supportedBranches.js')
|
|||||||
|
|
||||||
function runChecklist({
|
function runChecklist({
|
||||||
committers,
|
committers,
|
||||||
|
events,
|
||||||
files,
|
files,
|
||||||
pull_request,
|
pull_request,
|
||||||
log,
|
log,
|
||||||
@@ -23,11 +24,25 @@ function runChecklist({
|
|||||||
.map((pkg) => new Set(maintainers[pkg]))
|
.map((pkg) => new Set(maintainers[pkg]))
|
||||||
.reduce((acc, cur) => acc?.intersection(cur) ?? cur)
|
.reduce((acc, cur) => acc?.intersection(cur) ?? cur)
|
||||||
|
|
||||||
|
const approvals = new Set(
|
||||||
|
events
|
||||||
|
.filter(
|
||||||
|
({ event, state, commit_id }) =>
|
||||||
|
event === 'reviewed' &&
|
||||||
|
state === 'approved' &&
|
||||||
|
// Only approvals for the current head SHA count, otherwise authors could push
|
||||||
|
// bad code between the approval and the merge.
|
||||||
|
commit_id === pull_request.head.sha,
|
||||||
|
)
|
||||||
|
.map(({ user }) => user.id),
|
||||||
|
)
|
||||||
|
|
||||||
const checklist = {
|
const checklist = {
|
||||||
'PR targets a [development branch](https://github.com/NixOS/nixpkgs/blob/-/ci/README.md#branch-classification).':
|
'PR targets a [development branch](https://github.com/NixOS/nixpkgs/blob/-/ci/README.md#branch-classification).':
|
||||||
classify(pull_request.base.ref).type.includes('development'),
|
classify(pull_request.base.ref).type.includes('development'),
|
||||||
'PR touches only packages in `pkgs/by-name/`.': allByName,
|
'PR touches only packages in `pkgs/by-name/`.': allByName,
|
||||||
'PR is at least one of:': {
|
'PR is at least one of:': {
|
||||||
|
'Approved by a committer.': committers.intersection(approvals).size > 0,
|
||||||
'Authored by a committer.': committers.has(pull_request.user.id),
|
'Authored by a committer.': committers.has(pull_request.user.id),
|
||||||
'Backported via label.':
|
'Backported via label.':
|
||||||
pull_request.user.login === 'nixpkgs-ci[bot]' &&
|
pull_request.user.login === 'nixpkgs-ci[bot]' &&
|
||||||
@@ -246,6 +261,7 @@ async function handleMerge({
|
|||||||
|
|
||||||
const { result, checklist } = runChecklist({
|
const { result, checklist } = runChecklist({
|
||||||
committers,
|
committers,
|
||||||
|
events,
|
||||||
files,
|
files,
|
||||||
pull_request,
|
pull_request,
|
||||||
log,
|
log,
|
||||||
@@ -302,6 +318,7 @@ async function handleMerge({
|
|||||||
|
|
||||||
const { result } = runChecklist({
|
const { result } = runChecklist({
|
||||||
committers,
|
committers,
|
||||||
|
events,
|
||||||
files,
|
files,
|
||||||
pull_request,
|
pull_request,
|
||||||
log,
|
log,
|
||||||
|
|||||||
Reference in New Issue
Block a user