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
36 changes: 36 additions & 0 deletions .github/workflows/nomination.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: nomination

on:
pull_request_target:
types: [edited, opened, synchronize, reopened]

# We don't need to use the GitHub App for this workflow,
# because it's all localised to this repo
permissions:
issues: write
pull-requests: write

jobs:
process:
name: Check
runs-on: ubuntu-latest
if: ${{ ! contains(github.event.pull_request.labels.*.name, 'nomination') && github.event.pull_request.head.ref != 'create-pull-request/sync' }}
steps:
- name: Fetch source
uses: actions/checkout@v4
- name: Process nomination
run: |
set -o pipefail
gh api "repos/$REPOSITORY/pulls/$PR_NUMBER/files" \
--jq '.[] | "\(.status) \(.filename)"' \
| scripts/nomination.sh members "$REPOSITORY" "$PR_NUMBER" "$ANNOUNCEMENT_ISSUE_NUMBER"
env:
REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
ANNOUNCEMENT_ISSUE_NUMBER: "${{
github.repository_owner == 'NixOS' && 35 ||
github.repository_owner == 'infinisil-test-org' && 30 ||
'NO_ISSUE_NUMBER'
}}"
GH_TOKEN: ${{ github.token }}
PROD: "1"
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ whose members have write access to [Nixpkgs](https://github.com/nixos/nixpkgs).

The [Nixpkgs commit delegators](https://github.com/orgs/NixOS/teams/commit-bit-delegation)
maintain the member list in this repository.
While it's in principle possible to request Nixpkgs commit permissions by creating a PR,
please nominate yourself in [this issue](https://github.com/NixOS/nixpkgs/issues/321665) instead.

## Nominations

To nominate yourself or somebody else:
1. Check [open nominations](/../../issues?q=state%3Aopen%20label%3Anomination) to make sure the user hasn't been nominated already.
1. [Click this link](/../../new/main/members?filename=%3CGITHUB_HANDLE%3E) to create a new file in the [`members` directory](./members).
1. Leave the file contents empty and replace `<GITHUB_HANDLE>` with the handle (without `@`) of the user you'd like to nominate .
1. Click on "Commit changes..." and follow the steps to create a PR.
1. State your motivation for the nomination in the PR description.

Such nominations are also automatically announced in [this issue](/../../issues/35), which you can subscribe to for updates.

## Semi-automatic synchronisation

Expand Down
48 changes: 41 additions & 7 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,41 @@ scripts/sync.sh infinisil-test-org actors members-test

Check that it synchronises the files in the `members-test` directory with the team members of the `actors` team.

## `retire.sh`
## Testing `nomination.sh`

This script does not depend on the current repository, but has some external effects.
For testing, we'll use [PR #33](https://github.com/infinisil-test-org/nixpkgs-committers/pull/33) and [issue #30](https://github.com/infinisil-test-org/nixpkgs-committers/issues/30).

To test:
1. Delete all labels of the PR and reset the title:
```bash
gh api --method DELETE /repos/infinisil-test-org/nixpkgs-committers/issues/33/labels
gh api --method PATCH /repos/infinisil-test-org/nixpkgs-committers/pulls/33 -f title="A non-conforming title"
```
1. Run the script while simulating that a non-nomination PR was opened:
```bash
scripts/nomination.sh members infinisil-test-org/nixpkgs-committers 33 30 <<< "removed members/infinisil"
```

Ensure that it exits with 0 and wouldn't run any effects.
1. Run the script while simulating that multiple users were nominated together:
```bash
scripts/nomination.sh members infinisil-test-org/nixpkgs-committers 33 30 <<< "removed members/foo"$'\n'"added members/bar"
```

Ensure that it exits with non-0 and wouldn't run any effects.
1. Run the script simulating a successful nomination
```bash
scripts/nomination.sh members infinisil-test-org/nixpkgs-committers 33 30 <<< "added members/infinisil"
```

Ensure that it exits with 0 and would run effects to label the PR, change the title and post a comment in the issue.
1. Rerun with effects
```bash
PROD=1 scripts/nomination.sh members infinisil-test-org/nixpkgs-committers 33 30 <<< "added members/infinisil"
```

## Testing `retire.sh`

This script has external effects and as such needs a bit more care when testing.

Expand Down Expand Up @@ -76,7 +110,7 @@ The following sequence tests all code paths:
```

Check that no PR would be opened.
2. Run the script with the `empty` repo argument to simulate CI running with inactive users:
1. Run the script with the `empty` repo argument to simulate CI running with inactive users:

```bash
scripts/retire.sh infinisil-test-org empty nixpkgs-committers members-test 'yesterday 1 month ago' now
Expand All @@ -90,27 +124,27 @@ The following sequence tests all code paths:

Check that it created the PR appropriately, including assigning the "retirement" label.
You can undo this step by closing the PR.
3. Run it again to simulate CI running again later:
1. Run it again to simulate CI running again later:
```bash
PROD=1 scripts/retire.sh infinisil-test-org empty nixpkgs-committers members-test 'yesterday 1 month ago' now
```
Check that no other PR is opened.
4. Run it again with `now` as the notice cutoff date to simulate the time interval passing:
1. Run it again with `now` as the notice cutoff date to simulate the time interval passing:
```bash
PROD=1 scripts/retire.sh infinisil-test-org empty nixpkgs-committers members-test now now
```
Check that it undrafted the previous PR and posted an appropriate comment.
5. Run it again to simulate CI running again later:
1. Run it again to simulate CI running again later:
```bash
PROD=1 scripts/retire.sh infinisil-test-org empty nixpkgs-committers members-test now now
```
Check that no other PR is opened.
6. Reset by marking the PR as a draft again, then run it again with the `active` repo argument to simulate activity during the time interval:
1. Reset by marking the PR as a draft again, then run it again with the `active` repo argument to simulate activity during the time interval:
```bash
PROD=1 scripts/retire.sh infinisil-test-org active nixpkgs-committers members-test now now
```
Check that it gets undrafted with a comment listing the new activity.
8. Close the PR, then run the script again with no activity and for an earlier close cutoff, simulating that the retirement was delayed:
1. Close the PR, then run the script again with no activity and for an earlier close cutoff, simulating that the retirement was delayed:
```bash
PROD=1 scripts/retire.sh infinisil-test-org empty nixpkgs-committers members-test now '1 day ago'
```
Expand Down
24 changes: 24 additions & 0 deletions scripts/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
set -euo pipefail

log() {
echo "$@" >&2
}

trace() {
log "Running:" "${@@Q}"
"$@"
}

effect() {
log -en "\e[33m"
if [[ -z "${PROD:-}" ]]; then
log "Skipping effect:" "${@@Q}"
# If there's stdin, show it
if read -t 0 _; then
sed "s/^/[stdin] /" >&2
fi
else
trace "$@"
fi
log -en "\e[0m"
}
54 changes: 54 additions & 0 deletions scripts/nomination.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash

source "$(dirname -- "${BASH_SOURCE[0]}")"/common.sh

shopt -s nocasematch

usage() {
log "Usage: $0 MEMBERS_DIR REPOSITORY PR_NUMBER ANNOUNCEMENT_ISSUE_NUMBER"
exit 1
}

MEMBERS_DIR=${1:-$(usage)}
REPOSITORY=${2:-$(usage)}
PR_NUMBER=${3:-$(usage)}
ANNOUNCEMENT_ISSUE_NUMBER=${4:-$(usage)}

log "Waiting to get changed files on stdin.."
readarray -t changedFiles
declare -p changedFiles

regex="^added $MEMBERS_DIR/([^/]+)$"

nomineeHandle=
for statusFilename in "${changedFiles[@]}"; do
if [[ "$statusFilename" =~ $regex ]]; then
nomineeHandle=${BASH_REMATCH[1]}
break
fi
done

if [[ -z "$nomineeHandle" ]]; then
log "Not a nomination PR"
exit 0
elif (( "${#changedFiles[@]}" > 1 )); then
log "Only one person can be nominated per PR"
exit 1
fi

effect gh api \
--method PATCH \
"/repos/$REPOSITORY/pulls/$PR_NUMBER" \
-f title="Nominate @$nomineeHandle" \

effect gh api \
--method POST \
"/repos/$REPOSITORY/issues/$ANNOUNCEMENT_ISSUE_NUMBER/comments" \
-F "body=@-" << EOF
The user @$nomineeHandle has been nominated. Endorsements and discussions should be held in the corresponding nomination PR: #$PR_NUMBER
EOF

effect gh api \
--method POST \
"/repos/$REPOSITORY/issues/$PR_NUMBER/labels" \
-f "labels[]=nomination"
25 changes: 2 additions & 23 deletions scripts/retire.sh
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
shopt -s nullglob

log() {
echo "$@" >&2
}
source "$(dirname -- "${BASH_SOURCE[0]}")"/common.sh

trace() {
log "Running:" "${@@Q}"
"$@"
}

effect() {
log -en "\e[33m"
if [[ -z "${PROD:-}" ]]; then
log "Skipping effect:" "${@@Q}"
# If there's stdin, show it
if read -t 0 _; then
sed "s/^/[stdin] /" >&2
fi
else
trace "$@"
fi
log -en "\e[0m"
}
shopt -s nullglob

usage() {
log "Usage: $0 ORG ACTIVITY_REPO MEMBER_REPO DIR NOTICE_CUTOFF CLOSE_CUTOFF"
Expand Down
5 changes: 3 additions & 2 deletions scripts/sync.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail

source "$(dirname -- "${BASH_SOURCE[0]}")"/common.sh

usage() {
echo >&2 "Usage: $0 ORG TEAM DIR"
log "Usage: $0 ORG TEAM DIR"
exit 1
}

Expand Down