Skip to content

Commit

Permalink
Check write permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Apr 24, 2024
1 parent 9669ab7 commit b78c63f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

/.github/CODEOWNERS @infinisil @zimbatm
/.github/workflows @infinisil @zimbatm
/scripts @infinisil @zimbatm
/review-body.sh @infinisil @zimbatm

/doc/org-repo.md @infinisil @zimbatm
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
name: Validate codeowners
runs-on: ubuntu-latest
steps:
- uses: cachix/install-nix-action@v26

- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -55,3 +56,12 @@ jobs:

# Specifies whether only teams are allowed as owners of files.
owner_checker_owners_must_be_teams: "false"

# The above validator doesn't currently ensure that people have write access: https://github.com/mszostok/codeowners-validator/issues/157
# So we're doing it manually instead
- name: Check that codeowners have write access
# Important that we run the script from the base branch,
# because otherwise a PR from a fork could change it to extract the secret
run: trusted-base/scripts/unprivileged-owners.sh untrusted-pr ${{ github.repository }}
env:
GH_TOKEN: "${{ secrets.OWNERS_VALIDATOR_GITHUB_SECRET }}"
50 changes: 50 additions & 0 deletions scripts/unprivileged-owners.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash --pure --keep GH_TOKEN -I nixpkgs=channel:nixpkgs-unstable -p codeowners github-cli

set -euo pipefail

tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit

if (( $# != 2 )); then
echo "Usage: $0 PATH OWNER/REPO"
exit 1
fi

root=$1
repo=$2

# Writes all code owners into $tmp/codeowners, one user per line (without @)
while read -r -a fields; do
# The first field is the filename
unset 'fields[0]'
if [[ "${fields[1]}" != "(unowned)" ]]; then
(IFS=$'\n'; echo "${fields[*]##@}")
fi
done < <(cd "$root"; codeowners) |
sort -u > "$tmp/codeowners"

# Get all users with push access
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
--method GET \
-f permission=push \
/repos/"$repo"/collaborators \
-F per_page=100 \
--paginate \
--jq '.[].login' |
sort > "$tmp/collaborators"

# Figure out all the owners that aren't collaborators
readarray -t unprivilegedOwners < <(comm -23 "$tmp/codeowners" "$tmp/collaborators")

if (( "${#unprivilegedOwners[@]}" == 0 )); then
echo "All code owners have write permission"
else
echo "There are code owners that don't have write permission. Either remove them as code owners or give them write permission:"
for handle in "${unprivilegedOwners[@]}"; do
echo "- [ ] @$handle"
done
exit 1
fi

0 comments on commit b78c63f

Please sign in to comment.