Skip to content

Instantly share code, notes, and snippets.

@cmwylie19
Created October 27, 2025 21:04
Show Gist options
  • Select an option

  • Save cmwylie19/8a0fb983f80b4f55bd845778527e15f5 to your computer and use it in GitHub Desktop.

Select an option

Save cmwylie19/8a0fb983f80b4f55bd845778527e15f5 to your computer and use it in GitHub Desktop.
create issues under epic
#!/usr/bin/env bash
set -euo pipefail
# ========= Config =========
REPO="defenseunicorns/uds-compliance"
SUBISSUE_PARENT=545 # Parent issue to attach sub-issues to
LABEL="Lula2" # Label to apply to created issues
DRY_RUN="${DRY_RUN:-1}" # Override with: DRY_RUN=0 bash issue_creator.sh
# ==========================
# --- Pre-flight checks ---
command -v gh >/dev/null 2>&1 || { echo "Error: gh CLI not found in PATH"; exit 1; }
declare -A control_map
# --- Collect unique acronyms from files in subfolders ---
shopt -s nullglob
for dir in */; do
for file in "$dir"/*; do
[[ -f "$file" ]] || continue
val=$(grep -hE '^control-acronym:' "$file" | awk -F': ' '{print $2}' | xargs || true)
[[ -n "${val:-}" ]] && control_map["$val"]=1
done
done
shopt -u nullglob
# Turn keys into a sorted list
mapfile -t ACRONYMS < <(printf '%s\n' "${!control_map[@]}" | sort)
echo "Found ${#ACRONYMS[@]} unique control acronyms."
create_and_link() {
local acr="$1"
# Skip any acronym that contains parentheses
if [[ "$acr" =~ [\(\)] ]]; then
return 0
fi
local title="eMASS Mappings for ${acr}"
local body=$'Use Lula to map eMASS controls for '"${acr}"$'. Related to #'"${SUBISSUE_PARENT}"
if [[ "$DRY_RUN" -eq 1 ]]; then
printf '\n---- DRY RUN ----\n'
echo "Repo: $REPO"
echo "Title: $title"
echo -e "Body:\n$body"
echo "Would run: gh issue create --repo \"$REPO\" --title \"$title\" --label \"$LABEL\" --body '<...>'"
echo "Then link as sub-issue of #$SUBISSUE_PARENT by POSTing JSON: {\"sub_issue_id\": <new_issue_internal_id>}"
return 0
fi
# Create the issue and capture the URL (gh prints the URL on the last line)
new_url=$(gh issue create --repo "$REPO" --title "$title" --label "$LABEL" --body "$body" | tail -n1)
echo "Created: $new_url"
# Extract number from URL (last path segment)
new_number=${new_url##*/}
# Fetch the internal numeric ID (NOT the number)
new_id=$(gh api "repos/$REPO/issues/$new_number" --jq '.id')
# Ensure we got a numeric ID
if [[ ! "$new_id" =~ ^[0-9]+$ ]]; then
echo "Failed to get numeric issue id for #$new_number (got: $new_id)"
exit 1
fi
# Link it as a sub-issue of SUBISSUE_PARENT (must send JSON; sub_issue_id must be a number)
printf '{"sub_issue_id": %s}\n' "$new_id" | gh api -X POST \
"repos/$REPO/issues/$SUBISSUE_PARENT/sub_issues" \
-H "Accept: application/vnd.github+json" \
-H "Content-Type: application/json" \
--input - >/dev/null
echo "Linked #$new_number as sub-issue of #$SUBISSUE_PARENT"
}
# Process all acronyms
for acr in "${ACRONYMS[@]}"; do
create_and_link "$acr"
done
if [[ "$DRY_RUN" -eq 1 ]]; then
echo
echo "DRY RUN complete. To create and link for real: DRY_RUN=0 bash issue_creator.sh"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment