Created
April 10, 2023 00:47
-
-
Save KyMidd/3afee68ce4e65556a125e45485249525 to your computer and use it in GitHub Desktop.
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
# Get all org repos, store in a var | |
get_org_repos() { | |
### | |
### Now that we have more than 1k repos, need to use paginated REST call to get all of them (search API hard limit of 1k) | |
### | |
# Grab Org info to get repo counts | |
curl -sL \ | |
-H "Accept: application/vnd.github+json" \ | |
-H "Authorization: Bearer $GITHUB_TOKEN"\ | |
-H "X-GitHub-Api-Version: 2022-11-28" \ | |
https://api.github.com/orgs/$GH_ORG > org_info.json | |
# Filter org info to get repo counts | |
PRIVATE_REPO_COUNT=$(cat org_info.json | jq -r '.owned_private_repos') | |
PUBLIC_REPO_COUNT=$(cat org_info.json | jq -r '.public_repos') | |
TOTAL_REPO_COUNT=$(($PRIVATE_REPO_COUNT + $PUBLIC_REPO_COUNT)) | |
# Calculate number of pages needed to get all repos | |
REPOS_PER_PAGE=100 | |
PAGES_NEEDED=$(($TOTAL_REPO_COUNT / $REPOS_PER_PAGE)) | |
if [ $(($TOTAL_REPO_COUNT % $REPOS_PER_PAGE)) -gt 0 ]; then | |
PAGES_NEEDED=$(($PAGES_NEEDED + 1)) | |
fi | |
# Get all repos | |
for PAGE_NUMBER in $(seq $PAGES_NEEDED); do | |
echo "Getting repos page $PAGE_NUMBER of $PAGES_NEEDED" | |
# Could replace this with graphql call (would likely be faster, more efficient), but this works for now | |
PAGINATED_REPOS=$(curl -sL \ | |
-H "Accept: application/vnd.github+json" \ | |
-H "Authorization: Bearer $GITHUB_TOKEN"\ | |
-H "X-GitHub-Api-Version: 2022-11-28" \ | |
"https://api.github.com/orgs/$GH_ORG/repos?per_page=$REPOS_PER_PAGE&sort=pushed&page=$PAGE_NUMBER" | jq -r '.[].name') | |
# Combine all pages of repos into one variable | |
# Extra return added since last item in list doesn't have newline (would otherwise combine two repos on one line) | |
ALL_REPOS="${ALL_REPOS}"$'\n'"${PAGINATED_REPOS}" | |
done | |
# Find archived repos | |
ARCHIVED_REPOS=$(gh repo list $GH_ORG -L 1000 --archived | cut -d "/" -f 2 | cut -f 1) | |
ARCHIVED_REPOS_COUNT=$(echo "$ARCHIVED_REPOS" | wc -l | xargs) | |
# Remove archived repos from ALL_REPOS | |
echo "Skipping $ARCHIVED_REPOS_COUNT archived repos, they are read only" | |
for repo in $ARCHIVED_REPOS; do | |
ALL_REPOS=$(echo "$ALL_REPOS" | grep -Ev "^$repo$") | |
done | |
# Remove any empty lines | |
ALL_REPOS=$(echo "$ALL_REPOS" | awk 'NF') | |
# Get repo count | |
ALL_REPOS_COUNT=$(echo "$ALL_REPOS" | wc -l | xargs) | |
# Prepend failing repo name at top to test failure conditions | |
#ALL_REPOS=$(echo "$ALL_REPOS" | sed '1s/^/intentionally-missing-repo-name\n/') | |
} | |
# Create an auto-link reference for a repository | |
create_repo_autolink_reference() { | |
# Map first argument to ticket key | |
TICKET_REF=$1 | |
# If no ticket key provided, skip | |
if [ -z "$TICKET_REF" ]; then | |
echo "☠️ No ticket key provided, skipping" | |
return 0 | |
fi | |
# Create an auto-link reference | |
CREATE_AUTOLINK_REF=$(curl -sL \ | |
-X POST \ | |
-H "Accept: application/vnd.github+json" \ | |
-H "Authorization: Bearer $GITHUB_TOKEN"\ | |
-H "X-GitHub-Api-Version: 2022-11-28" \ | |
https://api.github.com/repos/$GH_ORG/$GH_REPO/autolinks \ | |
-d "{\"key_prefix\":\"${TICKET_REF}-\",\"url_template\":\"https://${YOUR_JIRA_ORG_NAME}.atlassian.net/browse/${TICKET_REF}-<num>\",\"is_alphanumeric\":false}") | |
# If the auto-link reference already exists, skip | |
if [[ $(echo "$CREATE_AUTOLINK_REF" | jq -r '.errors[]?.code' | grep -E 'already_exists') ]]; then | |
#echo "☠️ Auto-link reference already exists for $TICKET_REF, skipping" | |
CREATE_AUTOLINK_REFERENCE_ALREADY_EXIST+=($TICKET_REF) | |
# If created successfully, return success | |
elif [[ $(echo "$CREATE_AUTOLINK_REF" | jq -r '.key_prefix') == "${TICKET_REF}-" ]]; then | |
#echo "💥 Successfully created auto-link reference for $TICKET_REF" | |
CREATE_AUTOLINK_REFERENCE_SUCCESSES+=($TICKET_REF) | |
# If something else happened, return detailed failure message | |
else | |
echo "☠️ Something bad happened creating auto-link reference for $TICKET_REF, please investigate response:" | |
echo "$CREATE_AUTOLINK_REF" | |
CREATE_AUTOLINK_REFERENCE_FAILURES+=($TICKET_REF) | |
fi | |
} | |
# Create auto-link references for all projects | |
create_repo_autolink_references() { | |
# Get existing auto-link references, if any | |
EXISTING_AUTOLINK_REFERENCES=$(curl -sL \ | |
-H "Accept: application/vnd.github+json" \ | |
-H "Authorization: Bearer $GITHUB_TOKEN"\ | |
-H "X-GitHub-Api-Version: 2022-11-28" \ | |
https://api.github.com/repos/$GH_ORG/$GH_REPO/autolinks | jq -r '.[]?.key_prefix' | cut -d '-' -f 1 | awk 'NF') | |
# Set array of project keys to build for this project | |
AUTOLINK_REFERENCES_TO_BUILD=$(echo "$AUTOLINK_JIRA_PROJECT_KEYS" | tr ' ' '\n') | |
# If there are existing auto-link references, remove them from the list of auto-link references to build | |
if [[ $(echo "$EXISTING_AUTOLINK_REFERENCES" | awk 'NF' | wc -l) -gt 0 ]]; then | |
while IFS=$'\n' read -r EXISTING_AUTOLINK_REFERENCE; do | |
AUTOLINK_REFERENCES_TO_BUILD=$(echo "$AUTOLINK_REFERENCES_TO_BUILD" | grep -v "$EXISTING_AUTOLINK_REFERENCE") | |
done <<< "$EXISTING_AUTOLINK_REFERENCES" | |
fi | |
# Create array to store success/failures | |
CREATE_AUTOLINK_REFERENCE_SUCCESSES=() | |
CREATE_AUTOLINK_REFERENCE_ALREADY_EXIST=() | |
CREATE_AUTOLINK_REFERENCE_FAILURES=() | |
# Count length of project keys to build and project key total to build | |
AUTOLINK_REFERENCES_TO_BUILD_LENGTH=$(echo "$AUTOLINK_REFERENCES_TO_BUILD" | awk 'NF' | wc -l | xargs) | |
AUTOLINK_JIRA_PROJECT_KEYS_LENGTH=$(echo "$AUTOLINK_JIRA_PROJECT_KEYS" | awk 'NF' | wc -l | xargs) | |
# If any auto-link references to build, loop through them, create as we go | |
if [[ $(echo "$AUTOLINK_REFERENCES_TO_BUILD" | awk 'NF' | wc -l | xargs) -gt 0 ]]; then | |
while IFS=$'\n' read -r PROJECT_KEY; do | |
create_repo_autolink_reference "$PROJECT_KEY" | |
done <<< "${AUTOLINK_REFERENCES_TO_BUILD[@]}" | |
fi | |
# Create counts vars | |
CREATE_AUTOLINK_REFERENCE_SUCCESSES_LENGTH=${#CREATE_AUTOLINK_REFERENCE_SUCCESSES[@]} | |
CREATE_AUTOLINK_REFERENCE_ALREADY_EXISTS_LENGTH=${#CREATE_AUTOLINK_REFERENCE_ALREADY_EXIST[@]} | |
CREATE_AUTOLINK_REFERENCE_FAILURES_LENGTH=${#CREATE_AUTOLINK_REFERENCE_FAILURES[@]} | |
# If AUTOLINK_REFERENCES_TO_BUILD_LENGTH is 0, then all auto-link references already exist | |
if [[ $AUTOLINK_REFERENCES_TO_BUILD_LENGTH -eq 0 ]]; then | |
echo "ℹ️ All $AUTOLINK_JIRA_PROJECT_KEYS_LENGTH Jira auto-link references already exist, skipping" | |
# If there are failures, print error message | |
elif [[ $CREATE_AUTOLINK_REFERENCE_FAILURES_LENGTH -gt 0 ]]; then | |
echo "ℹ️ $CREATE_AUTOLINK_REFERENCE_SUCCESSES_LENGTH/$AUTOLINK_REFERENCES_TO_BUILD_LENGTH auto-link references created, but some failures ($CREATE_AUTOLINK_REFERENCE_FAILURES_LENGTH/$AUTOLINK_JIRA_PROJECT_KEYS_LENGTH), please investigate" | |
# If there are no failures, print success message | |
else | |
echo "💥 Successfully created $CREATE_AUTOLINK_REFERENCE_SUCCESSES_LENGTH auto-link reference for all $AUTOLINK_JIRA_PROJECT_KEYS_LENGTH configured Jira project keys" | |
fi | |
} | |
# Define the projects to create autolink references for | |
AUTOLINK_JIRA_PROJECT_KEYS=( | |
ABC | |
DEF | |
GHI | |
JKL | |
MNO | |
PQR | |
STU | |
VWY | |
ZYA | |
BCD | |
EFG | |
) | |
AUTOLINK_JIRA_PROJECT_KEYS=$(echo "${AUTOLINK_JIRA_PROJECT_KEYS[@]}" | tr ' ' '\n') | |
echo "########################################" | |
echo Getting All Org Repos | |
echo "########################################" | |
get_org_repos | |
echo "########################################" | |
echo Iterate over repos, create auto-link references | |
echo "########################################" | |
while IFS=$'\n' read -r GH_REPO; do | |
### | |
### Create Repo AutoLink References | |
### | |
# Create repo autolink references to connect ticket strings to Jira tickets via hyperlinks | |
create_repo_autolink_references | |
done <<< "$ALL_REPOS" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment