Last active
February 8, 2026 11:50
-
-
Save ufukty/f4e5d1a7e861a2b4973e6bde5a4204c3 to your computer and use it in GitHub Desktop.
Sync labels between repositories
This file contains hidden or 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
| #!/usr/bin/env bash | |
| # run as: ./labels.sh path/to/source/repository path/to/target/repository | |
| # first check if this is sufficient: gh label clone owner/source-repo | |
| # make sure you won't miss the info of issues and PRs attached to the labels the script will delete | |
| PS4='\033[31m$0:$LINENO: \033[0m' | |
| set -eEo pipefail | |
| test $# -eq 2 | |
| test -d "$1" | |
| test -d "$2" | |
| which bash | |
| which comm | |
| which gh | |
| which jq | |
| target="$(cd "$1" && gh label list --json name,description,color)" | |
| current="$(cd "$2" && gh label list --json name,description,color)" | |
| targetTags="$(echo "$target" | jq -r '.[].name' | sort)" | |
| currentTags="$(echo "$current" | jq -r '.[].name' | sort)" | |
| toCreateTags="$(comm -23 <(echo "$targetTags") <(echo "$currentTags"))" | |
| toDeleteTags="$(comm -13 <(echo "$targetTags") <(echo "$currentTags"))" | |
| toUpdateTags="$(comm -12 <(echo "$targetTags") <(echo "$currentTags"))" | |
| if test "$toCreateTags"; then | |
| echo "Will be created:" | |
| echo "$toCreateTags" | |
| echo | |
| fi | |
| if test "$toUpdateTags"; then | |
| echo "Will be checked to update:" | |
| echo "$toUpdateTags" | |
| echo | |
| fi | |
| if test "$toDeleteTags"; then | |
| echo "Will be deleted:" | |
| echo "$toDeleteTags" | |
| echo | |
| fi | |
| read -rn 1 -p "Press any key..." | |
| ( | |
| cd "$2" | |
| # create new | |
| echo "$toCreateTags" | while read -r TAG; do | |
| if test -z "$TAG"; then continue; fi | |
| DESC="$(echo "$target" | jq -jr --arg TAG "$TAG" '.[] | select(.name == $TAG) | .description')" | |
| COLR="$(echo "$target" | jq -jr --arg TAG "$TAG" '.[] | select(.name == $TAG) | .color')" | |
| set -x | |
| gh label create "$TAG" --description "$DESC" --color "$COLR" | |
| set +x | |
| done | |
| # delete irrelevant | |
| echo "$toDeleteTags" | while read -r TAG; do | |
| if test -z "$TAG"; then continue; fi | |
| set -x | |
| gh label delete --yes "$TAG" | |
| set +x | |
| done | |
| # update existing | |
| echo "$toUpdateTags" | while read -r TAG; do | |
| if test -z "$TAG"; then continue; fi | |
| CURRNT_DESC="$(echo "$current" | jq -jr --arg TAG "$TAG" '.[] | select(.name == $TAG) | .description')" | |
| TARGET_DESC="$(echo "$target" | jq -jr --arg TAG "$TAG" '.[] | select(.name == $TAG) | .description')" | |
| if test -z "$CURRNT_DESC"; then CURRNT_DESC=" "; fi | |
| if test -z "$TARGET_DESC"; then TARGET_DESC=" "; fi # gh prevents deleting description | |
| if test "$TARGET_DESC" != "$CURRNT_DESC"; then | |
| set -x | |
| gh label edit "$TAG" --description "$TARGET_DESC" | |
| set +x | |
| fi | |
| CURRNT_COLR="$(echo "$current" | jq -jr --arg TAG "$TAG" '.[] | select(.name == $TAG) | .color')" | |
| TARGET_COLR="$(echo "$target" | jq -jr --arg TAG "$TAG" '.[] | select(.name == $TAG) | .color')" | |
| if test "$TARGET_COLR" != "$CURRNT_COLR"; then | |
| set -x | |
| gh label edit "$TAG" --color "$TARGET_COLR" | |
| set +x | |
| fi | |
| done | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment