From 323b1b6275e71c77b68fe6ea97050dd3800787f7 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 5 Aug 2025 14:52:02 -0500 Subject: [PATCH 1/4] refactor!: swap usage order of parameters in add-team-to-repository script --- gh-cli/add-team-to-repository.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gh-cli/add-team-to-repository.sh b/gh-cli/add-team-to-repository.sh index 594e344..56e661a 100755 --- a/gh-cli/add-team-to-repository.sh +++ b/gh-cli/add-team-to-repository.sh @@ -3,8 +3,8 @@ # Adds a team to a repo function print_usage { - echo "Usage: $0 " - echo "Example: ./add-team-to-repository.sh joshjohanning-org my-repo my-team push" + echo "Usage: $0 " + echo "Example: ./add-team-to-repository.sh joshjohanning-org my-repo push my-team" echo "Valid roles: admin, maintain, push (write), triage, pull (read)" exit 1 } @@ -15,8 +15,8 @@ fi org=$1 repo=$2 -team=$3 -permission=$(echo "$4" | tr '[:upper:]' '[:lower:]') +permission=$(echo "$3" | tr '[:upper:]' '[:lower:]') +team=$4 case "$permission" in "admin" | "maintain" | "push" | "triage" | "pull") From aefaf3fad85e3a0604938fcce27ce40193f4e29a Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 5 Aug 2025 14:52:23 -0500 Subject: [PATCH 2/4] feat: update add-user-to-repository script to include existing invitation check --- gh-cli/add-user-to-repository.sh | 30 +++++++++++++++++++++++++---- gh-cli/invite-user-to-repository.sh | 2 +- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/gh-cli/add-user-to-repository.sh b/gh-cli/add-user-to-repository.sh index 79c8862..06b365c 100755 --- a/gh-cli/add-user-to-repository.sh +++ b/gh-cli/add-user-to-repository.sh @@ -3,9 +3,11 @@ # Adds a user to a repo function print_usage { - echo "Usage: $0 " - echo "Example: ./add-user-to-repository.sh joshjohanning-org my-repo joshjohanning ADMIN" + echo "Usage: $0 [skip_invite_check]" + echo "Example: ./add-user-to-repository.sh joshjohanning-org my-repo ADMIN joshjohanning" + echo "Example: ./add-user-to-repository.sh joshjohanning-org my-repo ADMIN joshjohanning true" echo "Valid roles: ADMIN, MAINTAIN, WRITE, TRIAGE, READ" + echo "skip_invite_check: true to skip checking/canceling pending invitations, defaults to false" exit 1 } @@ -15,8 +17,9 @@ fi org="$1" repo="$2" -user="$3" -permission=$(echo "$4" | tr '[:lower:]' '[:upper:]') +permission=$(echo "$3" | tr '[:lower:]' '[:upper:]') +user="$4" +skip_invite_check="${5:-false}" case "$permission" in "ADMIN" | "MAINTAIN" | "WRITE" | "TRIAGE" | "READ") @@ -26,4 +29,23 @@ case "$permission" in ;; esac +# Check for existing pending invitations (unless skipped) +if [ "$skip_invite_check" != "true" ]; then + echo "Checking for existing invitations for $user..." + pending_invitation=$(gh api "/repos/$org/$repo/invitations" --jq ".[] | select(.invitee.login == \"$user\") | .id" 2>/dev/null) + + if [ -n "$pending_invitation" ]; then + echo "Found pending invitation (ID: $pending_invitation) for $user. Canceling it first..." + gh api -X DELETE "/repos/$org/$repo/invitations/$pending_invitation" + if [ $? -eq 0 ]; then + echo "Successfully canceled pending invitation." + else + echo "Warning: Failed to cancel pending invitation. Proceeding anyway..." + fi + fi +else + echo "Skipping invitation check as requested..." +fi + +echo "Adding/inviting $user to $org/$repo with $permission permission..." gh api -X PUT /repos/$org/$repo/collaborators/$user -f permission=$permission diff --git a/gh-cli/invite-user-to-repository.sh b/gh-cli/invite-user-to-repository.sh index 382bbf5..5a34896 100755 --- a/gh-cli/invite-user-to-repository.sh +++ b/gh-cli/invite-user-to-repository.sh @@ -10,4 +10,4 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Call the add-collaborator-to-repository.sh script with all arguments -exec "$SCRIPT_DIR/add-collaborator-to-repository.sh" "$@" +exec "$SCRIPT_DIR/add-user-to-repository.sh" "$@" From 02a85c96916b6c8d830ca14c7f084a841f66515a Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 5 Aug 2025 15:05:29 -0500 Subject: [PATCH 3/4] fix: correct parameter order in usage examples and add existing invitation check for user addition --- gh-cli/README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gh-cli/README.md b/gh-cli/README.md index e64e16d..e3f4f34 100644 --- a/gh-cli/README.md +++ b/gh-cli/README.md @@ -133,7 +133,7 @@ Adds a team to a repository with a given permission level Example usage: ```shell -./add-team-to-repository.sh joshjohanning-org my-repo my-team push" +./add-team-to-repository.sh joshjohanning-org my-repo push my-team" ``` ### add-user-to-project.sh @@ -144,7 +144,7 @@ Example usage: ```shell ./add-user-to-project.sh -./add-user-to-project.sh joshjohanning-org my-repo 1234 joshjohanning ADMIN" +./add-user-to-project.sh joshjohanning-org my-repo 1234 ADMIN joshjohanning" ``` Example roles: @@ -161,7 +161,14 @@ Adds a user to a repository with a given permission Example usage: ```shell -./add-user-to-repository.sh joshjohanning-org my-repo joshjohanning write" +./add-user-to-repository.sh joshjohanning-org my-repo write joshjohanning" +``` + +This also will attempt to check if there is an existing invitation for this user pending, and if it's expired, cancel it. This can be opted out of by passing in `true` as the 5th parameter, such as + +```shell +# don't check to see if existing invite is present; i.e. if adding existing organization user to repository +./add-user-to-repository.sh joshjohanning-org my-repo write joshjohanning true" ``` ### add-user-to-team.sh @@ -1150,7 +1157,7 @@ Example output: ### invite-user-to-repository.sh -Calls the `./add-collaborator-to-repository.sh` script to add a user to a repository (this is a wrapper script as an alias since `invite == add`. +Calls the `./add-user-to-repository.sh` script to add a user to a repository (this is a wrapper script as an alias since `invite == add`). ### invite-users-to-organization-from-list.sh From 80e1f54161567fd17ce538b4e174fecede958412 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 5 Aug 2025 15:05:51 -0500 Subject: [PATCH 4/4] feat: only re-send expired invitations --- gh-cli/add-user-to-repository.sh | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/gh-cli/add-user-to-repository.sh b/gh-cli/add-user-to-repository.sh index 06b365c..4150be0 100755 --- a/gh-cli/add-user-to-repository.sh +++ b/gh-cli/add-user-to-repository.sh @@ -32,15 +32,24 @@ esac # Check for existing pending invitations (unless skipped) if [ "$skip_invite_check" != "true" ]; then echo "Checking for existing invitations for $user..." - pending_invitation=$(gh api "/repos/$org/$repo/invitations" --jq ".[] | select(.invitee.login == \"$user\") | .id" 2>/dev/null) - - if [ -n "$pending_invitation" ]; then - echo "Found pending invitation (ID: $pending_invitation) for $user. Canceling it first..." - gh api -X DELETE "/repos/$org/$repo/invitations/$pending_invitation" - if [ $? -eq 0 ]; then - echo "Successfully canceled pending invitation." + invitation_data=$(gh api "/repos/$org/$repo/invitations" --jq ".[] | select(.invitee.login == \"$user\") | {id: .id, expired: .expired}" 2>/dev/null) + + if [ -n "$invitation_data" ]; then + invitation_id=$(echo "$invitation_data" | jq -r '.id') + is_expired=$(echo "$invitation_data" | jq -r '.expired') + + if [ "$is_expired" = "true" ]; then + echo "Found expired invitation (ID: $invitation_id) for $user. Canceling it..." + gh api -X DELETE "/repos/$org/$repo/invitations/$invitation_id" + if [ $? -eq 0 ]; then + echo "Successfully canceled expired invitation." + else + echo "Warning: Failed to cancel expired invitation. Proceeding anyway..." + fi else - echo "Warning: Failed to cancel pending invitation. Proceeding anyway..." + echo "Found active invitation (ID: $invitation_id) for $user. Leaving it as is." + echo "Skipping new invitation since an active one already exists." + exit 0 fi fi else