Skip to content

Instantly share code, notes, and snippets.

@Frikki
Created August 19, 2025 16:51
Show Gist options
  • Select an option

  • Save Frikki/ec06d2ac95ea9e7e3311ab70a535c68a to your computer and use it in GitHub Desktop.

Select an option

Save Frikki/ec06d2ac95ea9e7e3311ab70a535c68a to your computer and use it in GitHub Desktop.
Generate GitHub Labels using GitHub CLI
#!/usr/bin/env bash
# Creates or updates repo labels with color + description.
# Requires: GitHub CLI (gh) authenticated, run at repo root.
set -euo pipefail
labels=(
# name|color|description
"epic|7E57C2|Umbrella for multiple PBIs."
"feature|933396|New user-facing capability."
"bug|D73A4A|Defect/incorrect behavior."
"chore|6A737D|Maintenance/refactor."
"spike|FBCA04|Research/prototype."
"docs|0969DA|Documentation changes."
"test|A2EEEF|Tests/fixtures only."
"front end|FF7B72|Web app/UI work."
"back end|8250DF|API/services/server."
"worker|218BFF|Background jobs/queues."
"api|1B7C83|Public API surface."
"ui|FFC680|Visual/UX changes."
"ingestion|0FB5AE|Gmail/Slack fetching."
"scoring|7A9FFF|Ranking/explanations."
"digest|FFB3AE|Daily summary emails/DMs."
"oauth|8DDBE0|Auth/connect flows."
"database|BFD4F2|Schema/queries/migrations."
"queue|C3E88D|Redis/BullMQ config."
"infra|7057FF|Deploy/config/CI/CD."
"telemetry|B780FF|Metrics/logs/traces."
"security|B60205|Hardening/authz/secrets."
"privacy|0F766E|Data handling/retention."
"a11y|9A6700|Accessibility."
"p0 critical|8B0000|Must fix now."
"p1 high|D93F0B|Top priority."
"p2 medium|F2CC60|Normal priority."
"p3 low|C2E0C6|Nice to have."
"blocked|E4E669|Waiting on dependency."
"needs info|D4C5F9|Clarification required."
)
# Verify dependencies
command -v gh >/dev/null 2>&1 || { echo "❌ GitHub CLI (gh) not installed."; exit 1; }
# Verify we're in a git repo
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { echo "❌ Not inside a git repo."; exit 1; }
# Verify we're authenticated
gh auth status -h github.com >/dev/null 2>&1 || { echo "❌ gh not authenticated."; exit 1; }
# Verify prerequisites and context
command -v gh >/dev/null 2>&1 || { echo "❌ GitHub CLI (gh) not installed."; exit 1; }
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { echo "❌ Not inside a git repo."; exit 1; }
gh auth status -h github.com >/dev/null 2>&1 || { echo "❌ gh not authenticated."; exit 1; }
gh repo view >/dev/null 2>&1 || { echo "❌ Repo not on GitHub (no github.com remote)."; exit 1; }
# Delete all existing labels before recreating
repo_full_name=$(gh repo view --json nameWithOwner --jq .nameWithOwner)
# Prefer gh label list; fall back to gh api
existing_labels=$(gh label list --json name --limit 1000 --jq '.[].name' 2>/dev/null || true)
if [ -z "${existing_labels}" ]; then
existing_labels=$(gh api -H "Accept: application/vnd.github+json" "/repos/${repo_full_name}/labels" --paginate --jq '.[].name' 2>/dev/null || true)
fi
if [ -n "${existing_labels}" ]; then
echo "🧹 Deleting existing labels..."
while IFS= read -r label_name; do
[ -z "${label_name}" ] && continue
if ! gh label delete "${label_name}" --yes >/dev/null 2>&1; then
echo "⚠️ Could not delete: ${label_name}"
else
echo "🗑️ Deleted: ${label_name}"
fi
done <<< "${existing_labels}"
else
echo "ℹ️ No existing labels found."
fi
for entry in "${labels[@]}"; do
IFS='|' read -r name color desc <<< "$entry"
# Try to create; if it exists, update color + description.
if gh label create "$name" --color "$color" --description "$desc" >/dev/null 2>&1; then
echo "✅ Created: $name ($color)"
else
gh label edit "$name" --color "$color" --description "$desc" >/dev/null
echo "♻️ Updated: $name ($color)"
fi
done
echo "🎉 All labels processed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment