# Copyright (C) 2026 Moko Consulting # # This file is part of a Moko Consulting project. # # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: MokoStandards.Automation # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards-API # PATH: /templates/workflows/shared/auto-dev-issue.yml.template # VERSION: 04.06.00 # BRIEF: Auto-create tracking issue with sub-issues for dev/rc branch workflow # NOTE: Synced via bulk-repo-sync to .github/workflows/auto-dev-issue.yml in all governed repos. name: Dev/RC Branch Issue on: # Auto-create on RC branch creation create: # Manual trigger for dev branches workflow_dispatch: inputs: branch: description: 'Branch name (e.g., dev/my-feature or dev/04.06)' required: true type: string env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true permissions: contents: read issues: write jobs: create-issue: name: Create version tracking issue runs-on: ubuntu-latest if: >- (github.event_name == 'workflow_dispatch') || (github.event.ref_type == 'branch' && (startsWith(github.event.ref, 'rc/') || startsWith(github.event.ref, 'alpha/') || startsWith(github.event.ref, 'beta/'))) steps: - name: Create tracking issue and sub-issues env: GH_TOKEN: ${{ secrets.GA_TOKEN || secrets.GH_TOKEN || github.token }} run: | # For manual dispatch, use input; for auto, use event ref if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then BRANCH="${{ inputs.branch }}" else BRANCH="${{ github.event.ref }}" fi REPO="${{ github.repository }}" ACTOR="${{ github.actor }}" NOW=$(date -u '+%Y-%m-%d %H:%M UTC') # Determine branch type and version if [[ "$BRANCH" == rc/* ]]; then VERSION="${BRANCH#rc/}" BRANCH_TYPE="Release Candidate" LABEL_TYPE="type: release" TITLE_PREFIX="rc" elif [[ "$BRANCH" == beta/* ]]; then VERSION="${BRANCH#beta/}" BRANCH_TYPE="Beta" LABEL_TYPE="type: release" TITLE_PREFIX="beta" elif [[ "$BRANCH" == alpha/* ]]; then VERSION="${BRANCH#alpha/}" BRANCH_TYPE="Alpha" LABEL_TYPE="type: release" TITLE_PREFIX="alpha" else VERSION="${BRANCH#dev/}" BRANCH_TYPE="Development" LABEL_TYPE="type: feature" TITLE_PREFIX="feat" fi TITLE="${TITLE_PREFIX}(${VERSION}): ${BRANCH_TYPE} tracking for ${BRANCH}" # Check for existing issue with same title prefix EXISTING=$(gh api "repos/${REPO}/issues?state=open&per_page=10" \ --jq ".[] | select(.title | startswith(\"${TITLE_PREFIX}(${VERSION})\")) | .number" 2>/dev/null | head -1) if [ -n "$EXISTING" ]; then echo "ℹ️ Issue #${EXISTING} already exists for ${VERSION}" >> $GITHUB_STEP_SUMMARY exit 0 fi # ── Define sub-issues for the workflow ───────────────────────── if [[ "$BRANCH" == rc/* ]]; then SUB_ISSUES=( "RC Testing|Verify all features work on rc branch|type: test,release-candidate" "Regression Testing|Run full regression suite before merge|type: test,release-candidate" "Version Bump|Bump version in README.md and all headers|type: version,release-candidate" "Changelog Update|Update CHANGELOG.md with release notes|documentation,release-candidate" "Merge to Version Branch|Create PR to version/XX|type: release,needs-review" ) elif [[ "$BRANCH" == alpha/* ]] || [[ "$BRANCH" == beta/* ]]; then SUB_ISSUES=( "Testing|Verify features on ${BRANCH_TYPE} branch|type: test,status: in-progress" "Bug Fixes|Fix issues found during ${BRANCH_TYPE} testing|type: bug,status: pending" "Promote to Next Stage|Create PR to promote to next release stage|type: release,needs-review" ) else SUB_ISSUES=( "Development|Implement feature/fix on dev branch|type: feature,status: in-progress" "Unit Testing|Write and pass unit tests|type: test,status: pending" "Code Review|Request and complete code review|needs-review,status: pending" "Version Bump|Bump version in README.md and all headers|type: version,status: pending" "Changelog Update|Update CHANGELOG.md with release notes|documentation,status: pending" "Create RC Branch|Promote dev to rc branch for final testing|type: release,status: pending" "Merge to Main|Create PR from rc/dev to main|type: release,needs-review,status: pending" ) fi # ── Create sub-issues first ─────────────────────────────────────── SUB_LIST="" SUB_NUMBERS="" for SUB in "${SUB_ISSUES[@]}"; do IFS='|' read -r SUB_TITLE SUB_DESC SUB_LABELS <<< "$SUB" SUB_FULL_TITLE="${TITLE_PREFIX}(${VERSION}): ${SUB_TITLE}" SUB_BODY=$(printf '### %s\n\n%s\n\n| Field | Value |\n|-------|-------|\n| **Parent Branch** | `%s` |\n| **Version** | `%s` |\n\n---\n*Sub-issue of the %s tracking issue for `%s`.*' \ "$SUB_TITLE" "$SUB_DESC" "$BRANCH" "$VERSION" "$BRANCH_TYPE" "$BRANCH") SUB_URL=$(gh issue create \ --repo "$REPO" \ --title "$SUB_FULL_TITLE" \ --body "$SUB_BODY" \ --label "${SUB_LABELS}" \ --assignee "jmiller-moko" 2>&1) SUB_NUM=$(echo "$SUB_URL" | grep -oE '[0-9]+$') if [ -n "$SUB_NUM" ]; then SUB_LIST="${SUB_LIST}\n- [ ] ${SUB_TITLE} (#${SUB_NUM})" SUB_NUMBERS="${SUB_NUMBERS} #${SUB_NUM}" fi sleep 0.3 done # ── Create parent tracking issue ────────────────────────────────── PARENT_BODY=$(printf '## %s Branch Created\n\n| Field | Value |\n|-------|-------|\n| **Branch** | `%s` |\n| **Version** | `%s` |\n| **Type** | %s |\n| **Created by** | @%s |\n| **Created at** | %s |\n| **Repository** | `%s` |\n\n## Workflow Sub-Issues\n\n%b\n\n---\n*Auto-created by [auto-dev-issue.yml](.github/workflows/auto-dev-issue.yml) on branch creation.*' \ "$BRANCH_TYPE" "$BRANCH" "$VERSION" "$BRANCH_TYPE" "$ACTOR" "$NOW" "$REPO" "$SUB_LIST") PARENT_URL=$(gh issue create \ --repo "$REPO" \ --title "$TITLE" \ --body "$PARENT_BODY" \ --label "${LABEL_TYPE},version" \ --assignee "jmiller-moko" 2>&1) PARENT_NUM=$(echo "$PARENT_URL" | grep -oE '[0-9]+$') # ── Link sub-issues back to parent ──────────────────────────────── if [ -n "$PARENT_NUM" ]; then for SUB in "${SUB_ISSUES[@]}"; do IFS='|' read -r SUB_TITLE _ _ <<< "$SUB" SUB_FULL_TITLE="${TITLE_PREFIX}(${VERSION}): ${SUB_TITLE}" SUB_NUM=$(gh api "repos/${REPO}/issues?state=open&per_page=20" \ --jq ".[] | select(.title == \"${SUB_FULL_TITLE}\") | .number" 2>/dev/null | head -1) if [ -n "$SUB_NUM" ]; then gh api "repos/${REPO}/issues/${SUB_NUM}" -X PATCH \ -f body="$(gh api "repos/${REPO}/issues/${SUB_NUM}" --jq '.body' 2>/dev/null) > **Parent Issue:** #${PARENT_NUM}" --silent 2>/dev/null || true fi sleep 0.2 done fi # ── Create or update prerelease for alpha/beta/rc ──────────────── if [[ "$BRANCH" == rc/* ]] || [[ "$BRANCH" == alpha/* ]] || [[ "$BRANCH" == beta/* ]]; then case "$BRANCH_TYPE" in Alpha) RELEASE_TAG="alpha" ;; Beta) RELEASE_TAG="beta" ;; "Release Candidate") RELEASE_TAG="release-candidate" ;; esac EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true) if [ -z "$EXISTING" ]; then gh release create "$RELEASE_TAG" \ --title "${RELEASE_TAG} (${VERSION})" \ --notes "## ${BRANCH_TYPE} ${VERSION}\n\nBranch: \`${BRANCH}\`\nTracking issue: ${PARENT_URL}" \ --prerelease \ --target main 2>/dev/null || true echo "${BRANCH_TYPE} release created: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY else gh release edit "$RELEASE_TAG" \ --title "${RELEASE_TAG} (${VERSION})" --prerelease 2>/dev/null || true echo "${BRANCH_TYPE} release updated: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY fi fi # ── Summary ─────────────────────────────────────────────────────── echo "## Dev Workflow Issues Created" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Item | Issue |" >> $GITHUB_STEP_SUMMARY echo "|------|-------|" >> $GITHUB_STEP_SUMMARY echo "| **Parent** | ${PARENT_URL} |" >> $GITHUB_STEP_SUMMARY echo "| **Sub-issues** |${SUB_NUMBERS} |" >> $GITHUB_STEP_SUMMARY