Skip to content

Commit 8e339e7

Browse files
locus313Copilot
andcommitted
feat: add SKIP_ARCHIVED option to github-add-repo-permissions
Skips granting maintain/push/triage/pull permissions on archived repos when SKIP_ARCHIVED=true. Admin permissions are still applied on archived repos so owning teams retain settings access after archival. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d33af13 commit 8e339e7

4 files changed

Lines changed: 39 additions & 6 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ export REPO_NAME_FILTER="my-service-"
168168

169169
# Optional: skip specific repos for a given permission level (space-separated repo names)
170170
export REPO_PULL_EXCLUDE="secret-repo internal-tools" # These repos won't get pull access
171+
172+
# Optional: skip maintain/push/triage/pull on archived repos (admin is still applied)
173+
export SKIP_ARCHIVED="true"
171174
```
172175

173176
**Usage:**
@@ -182,6 +185,7 @@ cd org-admin/github-add-repo-permissions
182185
- Grants permissions to specified teams based on permission level
183186
- Supports multiple teams per permission level (space-separated)
184187
- Skips repos listed in the matching `REPO_<LEVEL>_EXCLUDE` variable for that permission level only
188+
- Optionally skips maintain/push/triage/pull permissions on archived repos when `SKIP_ARCHIVED=true` (admin permissions are still applied on archived repos)
185189
- Processes all five GitHub permission levels: admin, maintain, push, triage, pull
186190
- Includes 5-second delays between repos to avoid rate limits
187191

org-admin/github-add-repo-permissions/action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ inputs:
5151
description: 'Space-separated repo names to skip for pull access'
5252
required: false
5353
default: ''
54+
skip-archived:
55+
description: 'Set to "true" to skip maintain/push/triage/pull permissions on archived repos (admin is still applied)'
56+
required: false
57+
default: 'false'
5458
api-url-prefix:
5559
description: 'GitHub API base URL'
5660
required: false
@@ -74,5 +78,6 @@ runs:
7478
REPO_PUSH_EXCLUDE: ${{ inputs.repo-push-exclude }}
7579
REPO_TRIAGE_EXCLUDE: ${{ inputs.repo-triage-exclude }}
7680
REPO_PULL_EXCLUDE: ${{ inputs.repo-pull-exclude }}
81+
SKIP_ARCHIVED: ${{ inputs.skip-archived }}
7782
API_URL_PREFIX: ${{ inputs.api-url-prefix }}
7883
run: ${{ github.action_path }}/github-add-repo-permissions.sh

org-admin/github-add-repo-permissions/github-add-repo-permissions.sh

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
# GITHUB_TOKEN Required. PAT with admin:org scope
1919
# ORG Required. GitHub organization name
2020
# REPO_NAME_FILTER Optional. Prefix filter for repository names (default: all repos)
21+
# SKIP_ARCHIVED Optional. Set to "true" to skip maintain/push/triage/pull permissions on
22+
# archived repositories; admin permissions are still applied (default: false)
2123
# REPO_ADMIN Optional. Space-separated team slugs to grant admin access
2224
# REPO_MAINTAIN Optional. Space-separated team slugs to grant maintain access
2325
# REPO_PUSH Optional. Space-separated team slugs to grant push access
@@ -50,6 +52,7 @@ GITHUB_TOKEN=${GITHUB_TOKEN:-''}
5052
ORG=${ORG:-''}
5153
API_URL_PREFIX=${API_URL_PREFIX:-'https://api.github.com'}
5254
REPO_NAME_FILTER=${REPO_NAME_FILTER:-''}
55+
SKIP_ARCHIVED=${SKIP_ARCHIVED:-'false'}
5356

5457
# Permission-specific team variables (space-separated team slugs)
5558
REPO_ADMIN=${REPO_ADMIN:-''}
@@ -80,6 +83,9 @@ print_status "Organization: ${ORG}"
8083
if [ -n "${REPO_NAME_FILTER}" ]; then
8184
print_status "Repository filter: ${REPO_NAME_FILTER}*"
8285
fi
86+
if [ "${SKIP_ARCHIVED}" = "true" ]; then
87+
print_status "Skipping non-admin permissions on archived repositories"
88+
fi
8389

8490
is_excluded () {
8591
local REPO_NAME=$1
@@ -146,19 +152,26 @@ process_repos () {
146152
err "$(echo "${repos_json}" | jq -r '.message // "unknown error"')"
147153
fi
148154

149-
while IFS= read -r REPO; do
155+
while IFS=$'\t' read -r REPO ARCHIVED; do
150156
[ -z "${REPO}" ] && continue
151157
print_status "Processing repo ${REPO}"
152158

159+
# Admin access is always granted, even on archived repos (e.g. so
160+
# platform teams retain settings access after archival).
153161
apply_level "${REPO}" "admin" "${REPO_ADMIN}" "${REPO_ADMIN_EXCLUDE}"
154-
apply_level "${REPO}" "maintain" "${REPO_MAINTAIN}" "${REPO_MAINTAIN_EXCLUDE}"
155-
apply_level "${REPO}" "push" "${REPO_PUSH}" "${REPO_PUSH_EXCLUDE}"
156-
apply_level "${REPO}" "triage" "${REPO_TRIAGE}" "${REPO_TRIAGE_EXCLUDE}"
157-
apply_level "${REPO}" "pull" "${REPO_PULL}" "${REPO_PULL_EXCLUDE}"
162+
163+
if [ "${SKIP_ARCHIVED}" = "true" ] && [ "${ARCHIVED}" = "true" ]; then
164+
print_status " Skipping non-admin permissions on ${REPO} (archived)"
165+
else
166+
apply_level "${REPO}" "maintain" "${REPO_MAINTAIN}" "${REPO_MAINTAIN_EXCLUDE}"
167+
apply_level "${REPO}" "push" "${REPO_PUSH}" "${REPO_PUSH_EXCLUDE}"
168+
apply_level "${REPO}" "triage" "${REPO_TRIAGE}" "${REPO_TRIAGE_EXCLUDE}"
169+
apply_level "${REPO}" "pull" "${REPO_PULL}" "${REPO_PULL_EXCLUDE}"
170+
fi
158171

159172
# Add delay to prevent hitting GitHub rate limit
160173
sleep 5
161-
done < <(echo "${repos_json}" | jq -r --arg filter "${REPO_NAME_FILTER}" 'sort_by(.name) | .[] | select(.name | startswith($filter)) | .name')
174+
done < <(echo "${repos_json}" | jq -r --arg filter "${REPO_NAME_FILTER}" 'sort_by(.name) | .[] | select(.name | startswith($filter)) | [.name, (.archived // false | tostring)] | @tsv')
162175
done
163176
}
164177

tests/test_script_validation.bats

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@ _run_script() {
115115
[[ "$output" == *"Applied pull to read-team on repo-skip"* ]]
116116
}
117117

118+
@test "github-add-repo-permissions: skips non-admin permissions but still applies admin on archived repos when SKIP_ARCHIVED is true" {
119+
cp "${BATS_TEST_DIRNAME}/mock_curl_permissions.sh" "$MOCK_BIN/curl"
120+
chmod +x "$MOCK_BIN/curl"
121+
_run_script "${REPO_ROOT}/org-admin/github-add-repo-permissions/github-add-repo-permissions.sh" \
122+
"export GITHUB_TOKEN=fake; export ORG=test; export REPO_ADMIN=owner-team; export REPO_PULL=read-team; export SKIP_ARCHIVED=true; export MOCK_REPOS_JSON='[{\"name\":\"repo-keep\",\"archived\":false},{\"name\":\"repo-old\",\"archived\":true}]';"
123+
[ "$status" -eq 0 ]
124+
[[ "$output" == *"Applied pull to read-team on repo-keep"* ]]
125+
[[ "$output" == *"Applied admin to owner-team on repo-old"* ]]
126+
[[ "$output" != *"pull to read-team on repo-old"* ]]
127+
}
128+
118129
# ═══════════════════════════════════════════════════════════════════════════════
119130
# org-admin/github-archive-old-repos
120131
# ═══════════════════════════════════════════════════════════════════════════════

0 commit comments

Comments
 (0)