-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add branch protection list checks
adds docs and script for branch protection
- Loading branch information
1 parent
3894d12
commit 5191ded
Showing
2 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Branch protections | ||
|
||
Repos branches are protected through requiring pull requests | ||
and passing workflow jobs. All of the GeoNet repos have some | ||
form of branch protection, whether that be just no write to main | ||
and/or some checks from workflows that are in those repos. | ||
|
||
## Behaviours | ||
|
||
GitHub Actions workflows populate the | ||
_Require status checks to pass before merging_ section of | ||
project settings after they're run, so a new job can't be | ||
required for protection until it's run. | ||
|
||
The search is unhelpful due to it not populating the list of | ||
checks when trying to search without typing. | ||
|
||
## Determine a list of checks | ||
|
||
Use the helper script to get a mostly-concreate set of values | ||
which may be set to provide check-based branch merge protection. | ||
|
||
List checks for all GeoNet repos | ||
|
||
```sh | ||
./hack/list-checks.sh | ||
``` | ||
|
||
List checks for a specific GeoNet repos | ||
|
||
```sh | ||
./hack/list-checks.sh Actions base-images | ||
``` | ||
|
||
Some example output may look like | ||
|
||
```yaml | ||
GeoNet/Actions: | ||
- commit-digest-vet / presubmit-workflow | ||
- conform/commit/commit-body | ||
- conform/commit/conventional-commit | ||
- conform/commit/header-case | ||
- conform/commit/header-last-character | ||
- conform/commit/header-length | ||
- conform/commit/imperative-mood | ||
- conform/commit/spellcheck | ||
- conform / conform | ||
- lint-markdown / markdown-lint | ||
- presubmit-readme-toc / presubmit-readme-toc | ||
- require-actions-run-from-GeoNet-org | ||
- require-jobs-run-steps-have-name | ||
- require-reusable-workflow-is-documented | ||
- t0-basic / build | ||
- t0-basic-check | ||
- t1-use-test / build | ||
- t1-use-test-check | ||
- t2-artifact-pull / build | ||
- t2-artifact-pull-cleanup | ||
- t2-artifact-pull-prepare | ||
- t3-multi-arch / build | ||
- t3-multi-arch-check | ||
- t6-auth-with-geonetci / build | ||
- t6-auth-with-geonetci-check | ||
- t7-use-setup / build | ||
- t8-use-tags / build | ||
- t8-use-tags-check | ||
- t9-no-push / build | ||
- t9-no-push-check | ||
- validate-schema / validate-github-actions | ||
GeoNet/base-images: | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/bin/bash | ||
|
||
set -o errexit | ||
set -o nounset | ||
set -o pipefail | ||
|
||
REPOS="${@}" | ||
|
||
DEBUG=false | ||
__debug_echo() { | ||
if [ ! "$DEBUG" = true ]; then | ||
return | ||
fi | ||
echo "${@}" | ||
} | ||
|
||
get_repos_with_actions() { | ||
repos=($(gh api orgs/GeoNet/repos --jq '.[] | select(.fork==false) | select(.archived==false) | .name' --paginate \ | ||
| sort \ | ||
| tr ' ' '\n' \ | ||
| xargs -I{} \ | ||
sh -c 'gh api "repos/GeoNet/{}/contents/.github/workflows" --jq ". | length | . > 0" 2>&1>/dev/null && echo GeoNet/{}' \ | ||
| grep -E '^GeoNet/.*' | cat)) | ||
echo "${repos[@]}" | ||
} | ||
|
||
get_pull_request_numbers() { | ||
REPO="$1" | ||
PULL_REQUEST_NUMBERS=() | ||
while read NUMBER; do | ||
PULL_REQUEST_NUMBERS+=("$NUMBER") | ||
done < <(gh api -X GET "repos/$REPO/pulls" -f state=all --jq .[0].number) | ||
echo "${PULL_REQUEST_NUMBERS[@]}" | ||
} | ||
|
||
get_head_ref_commit() { | ||
REPO="$1" | ||
NUMBER="$2" | ||
commit="$(gh api "repos/$REPO/pulls/$NUMBER/commits" --jq '.[0].sha')" | ||
echo "$commit" | ||
} | ||
|
||
get_status_checks() { | ||
REPO="$1" | ||
checks=() | ||
for PR in $(get_pull_request_numbers "$REPO"); do | ||
__debug_echo "$REPO/pull/$PR" | ||
COMMIT="$(get_head_ref_commit "$REPO" "$PR")" | ||
__debug_echo " - PR commit: $COMMIT" | ||
while read CONTEXT; do | ||
checks+=("$CONTEXT") | ||
done < <(gh api "repos/$REPO/commits/$COMMIT/status" --jq '.statuses[].context') | ||
done | ||
CHECKS+=("${checks[@]}") | ||
} | ||
|
||
get_workflow_checks() { | ||
REPO="$1" | ||
checks=() | ||
for PR in $(get_pull_request_numbers "$REPO"); do | ||
__debug_echo "$REPO/pull/$PR" | ||
COMMIT="$(get_head_ref_commit "$REPO" "$PR")" | ||
__debug_echo " - PR commit: $COMMIT" | ||
while read SUITE; do | ||
__debug_echo " - Check suite: $SUITE" | ||
while read RUN; do | ||
__debug_echo " - Check run: $RUN" | ||
checks+=("$RUN") | ||
done < <(gh api "repos/$REPO/check-suites/$SUITE/check-runs" --jq .check_runs[].name) | ||
done < <(gh api "repos/$REPO/commits/$COMMIT/check-suites" --jq .check_suites[].id) | ||
done | ||
CHECKS+=("${checks[@]}") | ||
} | ||
|
||
get_checks() { | ||
REPO="$1" | ||
echo "$REPO:" | ||
CHECKS=() | ||
get_status_checks "$REPO" | ||
get_workflow_checks "$REPO" | ||
( | ||
for CHECK in "${CHECKS[@]}"; do | ||
echo " - $CHECK" | ||
done | ||
) | sort | uniq | ||
} | ||
|
||
if [ -n "$REPOS" ]; then | ||
for REPO in $REPOS; do | ||
get_checks "GeoNet/$REPO" | ||
done | ||
exit $? | ||
fi | ||
|
||
for REPO in $(get_repos_with_actions); do | ||
get_checks "$REPO" | ||
done |