merge the vouch scripts

This commit is contained in:
Mitchell Hashimoto
2026-02-03 09:27:43 -08:00
parent c3573fc35b
commit f6b67aa25a
4 changed files with 116 additions and 122 deletions

View File

@@ -1,112 +0,0 @@
#!/usr/bin/env nu
use github.nu
# Vouch gate commands.
#
# Environment variables required:
# GITHUB_TOKEN - GitHub API token with repo access. If this isn't
# set then we'll attempt to read from `gh` if it exists.
def main [] {
print "Usage: vouch-gate <command>"
print ""
print "Commands:"
print " pr Check if a PR author is a vouched contributor"
}
# Check if a PR author is a vouched contributor.
#
# Checks if a PR author is a bot, collaborator with write access,
# or in the vouched contributors list. If not vouched, it closes the PR
# with a comment explaining the process.
#
# Outputs a status to stdout: "skipped", "vouched", or "closed"
#
# Examples:
#
# # Dry run (default) - see what would happen
# ./vouch-gate.nu pr 123
#
# # Actually close an unvouched PR
# ./vouch-gate.nu pr 123 --dry-run=false
#
def "main pr" [
pr_number: int, # GitHub pull request number
--repo (-R): string = "ghostty-org/ghostty", # Repository in "owner/repo" format
--vouched-file: string = ".github/VOUCHED", # Path to vouched contributors file
--dry-run = true, # Print what would happen without making changes
] {
let owner = ($repo | split row "/" | first)
let repo_name = ($repo | split row "/" | last)
# Fetch PR data from GitHub API
let pr_data = github api "get" $"/repos/($owner)/($repo_name)/pulls/($pr_number)"
let pr_author = $pr_data.user.login
let default_branch = $pr_data.base.repo.default_branch
# Skip bots
if ($pr_author | str ends-with "[bot]") or ($pr_author == "dependabot[bot]") {
print $"Skipping bot: ($pr_author)"
print "skipped"
return
}
# Check if user is a collaborator with write access
let permission = try {
github api "get" $"/repos/($owner)/($repo_name)/collaborators/($pr_author)/permission" | get permission
} catch {
""
}
if ($permission in ["admin", "write"]) {
print $"($pr_author) is a collaborator with ($permission) access"
print "vouched"
return
}
# Fetch vouched contributors list from default branch
let file_data = github api "get" $"/repos/($owner)/($repo_name)/contents/($vouched_file)?ref=($default_branch)"
let content = $file_data.content | decode base64 | decode utf-8
let vouched_list = $content
| lines
| each { |line| $line | str trim | str downcase }
| where { |line| ($line | is-not-empty) and (not ($line | str starts-with "#")) }
if ($pr_author | str downcase) in $vouched_list {
print $"($pr_author) is in the vouched contributors list"
print "vouched"
return
}
# Not vouched - close PR with comment
print $"($pr_author) is not vouched, closing PR"
let message = $"Hi @($pr_author), thanks for your interest in contributing!
We ask new contributors to open an issue first before submitting a PR. This helps us discuss the approach and avoid wasted effort.
**Next steps:**
1. Open an issue describing what you want to change and why \(keep it concise, write in your human voice, AI slop will be closed\)
2. Once a maintainer vouches for you with `lgtm`, you'll be added to the vouched contributors list
3. Then you can submit your PR
This PR will be closed automatically. See https://github.com/($owner)/($repo_name)/blob/($default_branch)/CONTRIBUTING.md for more details."
if $dry_run {
print "(dry-run) Would post comment and close PR"
print "closed"
return
}
# Post comment
github api "post" $"/repos/($owner)/($repo_name)/issues/($pr_number)/comments" {
body: $message
}
# Close the PR
github api "patch" $"/repos/($owner)/($repo_name)/pulls/($pr_number)" {
state: "closed"
}
print "closed"
}

View File

@@ -2,27 +2,133 @@
use github.nu
# Vouch for a contributor by adding them to the VOUCHED file.
#
# This script checks if a comment matches "lgtm", verifies the commenter has
# write access, and adds the issue author to the vouched list if not already
# present.
# Vouch - contributor trust management.
#
# Environment variables required:
# GITHUB_TOKEN - GitHub API token with repo access. If this isn't
# set then we'll attempt to read from `gh` if it exists.
def main [] {
print "Usage: vouch <command>"
print ""
print "Commands:"
print " check-pr Check if a PR author is a vouched contributor"
print " approve-by-issue Vouch for a contributor via issue comment"
}
# Check if a PR author is a vouched contributor.
#
# Checks if a PR author is a bot, collaborator with write access,
# or in the vouched contributors list. If not vouched, it closes the PR
# with a comment explaining the process.
#
# Outputs a status to stdout: "skipped", "vouched", or "closed"
#
# Examples:
#
# # Dry run (default) - see what would happen
# ./vouch.nu check-pr 123
#
# # Actually close an unvouched PR
# ./vouch.nu check-pr 123 --dry-run=false
#
def "main check-pr" [
pr_number: int, # GitHub pull request number
--repo (-R): string = "ghostty-org/ghostty", # Repository in "owner/repo" format
--vouched-file: string = ".github/VOUCHED", # Path to vouched contributors file
--dry-run = true, # Print what would happen without making changes
] {
let owner = ($repo | split row "/" | first)
let repo_name = ($repo | split row "/" | last)
# Fetch PR data from GitHub API
let pr_data = github api "get" $"/repos/($owner)/($repo_name)/pulls/($pr_number)"
let pr_author = $pr_data.user.login
let default_branch = $pr_data.base.repo.default_branch
# Skip bots
if ($pr_author | str ends-with "[bot]") or ($pr_author == "dependabot[bot]") {
print $"Skipping bot: ($pr_author)"
print "skipped"
return
}
# Check if user is a collaborator with write access
let permission = try {
github api "get" $"/repos/($owner)/($repo_name)/collaborators/($pr_author)/permission" | get permission
} catch {
""
}
if ($permission in ["admin", "write"]) {
print $"($pr_author) is a collaborator with ($permission) access"
print "vouched"
return
}
# Fetch vouched contributors list from default branch
let file_data = github api "get" $"/repos/($owner)/($repo_name)/contents/($vouched_file)?ref=($default_branch)"
let content = $file_data.content | decode base64 | decode utf-8
let vouched_list = $content
| lines
| each { |line| $line | str trim | str downcase }
| where { |line| ($line | is-not-empty) and (not ($line | str starts-with "#")) }
if ($pr_author | str downcase) in $vouched_list {
print $"($pr_author) is in the vouched contributors list"
print "vouched"
return
}
# Not vouched - close PR with comment
print $"($pr_author) is not vouched, closing PR"
let message = $"Hi @($pr_author), thanks for your interest in contributing!
We ask new contributors to open an issue first before submitting a PR. This helps us discuss the approach and avoid wasted effort.
**Next steps:**
1. Open an issue describing what you want to change and why \(keep it concise, write in your human voice, AI slop will be closed\)
2. Once a maintainer vouches for you with `lgtm`, you'll be added to the vouched contributors list
3. Then you can submit your PR
This PR will be closed automatically. See https://github.com/($owner)/($repo_name)/blob/($default_branch)/CONTRIBUTING.md for more details."
if $dry_run {
print "(dry-run) Would post comment and close PR"
print "closed"
return
}
# Post comment
github api "post" $"/repos/($owner)/($repo_name)/issues/($pr_number)/comments" {
body: $message
}
# Close the PR
github api "patch" $"/repos/($owner)/($repo_name)/pulls/($pr_number)" {
state: "closed"
}
print "closed"
}
# Vouch for a contributor by adding them to the VOUCHED file.
#
# This checks if a comment matches "lgtm", verifies the commenter has
# write access, and adds the issue author to the vouched list if not already
# present.
#
# Outputs a status to stdout: "skipped", "already", or "added"
#
# Examples:
#
# # Dry run (default) - see what would happen
# ./vouch.nu 123 456789
# ./vouch.nu approve-by-issue 123 456789
#
# # Actually vouch for a contributor
# ./vouch.nu 123 456789 --dry-run=false
# ./vouch.nu approve-by-issue 123 456789 --dry-run=false
#
def main [
def "main approve-by-issue" [
issue_id: int, # GitHub issue number
comment_id: int, # GitHub comment ID
--repo (-R): string = "ghostty-org/ghostty", # Repository in "owner/repo" format

View File

@@ -29,7 +29,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
nix develop -c nu .github/scripts/vouch-gate.nu pr \
nix develop -c nu .github/scripts/vouch.nu check-pr \
-R ${{ github.repository }} \
${{ github.event.pull_request.number }} \
--dry-run=false

View File

@@ -30,7 +30,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
status=$(nix develop -c nu .github/scripts/vouch.nu \
status=$(nix develop -c nu .github/scripts/vouch.nu approve-by-issue \
-R ${{ github.repository }} \
${{ github.event.issue.number }} \
${{ github.event.comment.id }} \