From 4e8d851b499f1cefb167920036a31e2982fc9d41 Mon Sep 17 00:00:00 2001 From: Aarnav Tale Date: Sun, 1 Mar 2026 11:21:53 -0500 Subject: [PATCH] chore: add triage and release lifecycle workflows Amp-Thread-ID: https://ampcode.com/threads/T-019ca7cb-cefa-714f-94da-9f8dc14bdf24 Co-authored-by: Amp --- .github/workflows/lifecycle.yaml | 87 ++++++++++++++++++++++++++++++++ .github/workflows/triage.yaml | 20 ++++++++ 2 files changed, 107 insertions(+) create mode 100644 .github/workflows/lifecycle.yaml create mode 100644 .github/workflows/triage.yaml diff --git a/.github/workflows/lifecycle.yaml b/.github/workflows/lifecycle.yaml new file mode 100644 index 00000000..a92e1cf6 --- /dev/null +++ b/.github/workflows/lifecycle.yaml @@ -0,0 +1,87 @@ +name: Release Lifecycle +on: + push: + tags: + - "v*" + +permissions: + issues: write + +jobs: + beta: + name: Beta Release + if: contains(github.ref_name, '-') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Label and comment on referenced issues + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG="${GITHUB_REF_NAME}" + PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + + if [ -z "$PREV_TAG" ]; then + echo "No previous tag found, skipping" + exit 0 + fi + + echo "Processing issues referenced between ${PREV_TAG} and ${TAG}" + ISSUES=$(git log --format="%B" "${PREV_TAG}..HEAD" | grep -oE '#[0-9]+' | sort -u | tr -d '#') + + for ISSUE in $ISSUES; do + [ -z "$ISSUE" ] && continue + + STATE=$(gh issue view "$ISSUE" --json state --jq '.state' \ + --repo "${{ github.repository }}" 2>/dev/null || echo "") + [ "$STATE" != "OPEN" ] && continue + + echo "Labeling and commenting on #${ISSUE}" + gh issue edit "$ISSUE" --add-label "In Beta" \ + --repo "${{ github.repository }}" 2>/dev/null || true + gh issue comment "$ISSUE" \ + --body "🧪 Available in [\`${TAG}\`](https://github.com/${{ github.repository }}/releases/tag/${TAG})" \ + --repo "${{ github.repository }}" 2>/dev/null || true + done + + stable: + name: Stable Release + if: ${{ !contains(github.ref_name, '-') }} + runs-on: ubuntu-latest + steps: + - name: Close milestone issues + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG="${GITHUB_REF_NAME}" + VERSION="${TAG#v}" + + MILESTONE_NUMBER=$(gh api "repos/${{ github.repository }}/milestones" \ + --jq ".[] | select(.title == \"${VERSION}\") | .number" 2>/dev/null || echo "") + + if [ -z "$MILESTONE_NUMBER" ]; then + echo "No milestone found for ${VERSION}, skipping" + exit 0 + fi + + echo "Processing milestone ${VERSION} (#${MILESTONE_NUMBER})" + gh api "repos/${{ github.repository }}/issues?milestone=${MILESTONE_NUMBER}&state=open&per_page=100" \ + --paginate --jq '.[].number' 2>/dev/null | while IFS= read -r ISSUE; do + [ -z "$ISSUE" ] && continue + + echo "Closing #${ISSUE}" + gh issue edit "$ISSUE" --remove-label "In Beta" \ + --repo "${{ github.repository }}" 2>/dev/null || true + gh issue comment "$ISSUE" \ + --body "✅ Released in [\`${TAG}\`](https://github.com/${{ github.repository }}/releases/tag/${TAG})" \ + --repo "${{ github.repository }}" 2>/dev/null || true + gh issue close "$ISSUE" \ + --repo "${{ github.repository }}" 2>/dev/null || true + done + + echo "Closing milestone ${VERSION}" + gh api -X PATCH "repos/${{ github.repository }}/milestones/${MILESTONE_NUMBER}" \ + -f state=closed 2>/dev/null || true diff --git a/.github/workflows/triage.yaml b/.github/workflows/triage.yaml new file mode 100644 index 00000000..5b52e6f2 --- /dev/null +++ b/.github/workflows/triage.yaml @@ -0,0 +1,20 @@ +name: Triage +on: + issues: + types: [milestoned] + +permissions: + issues: write + +jobs: + remove-triage: + name: Remove Needs Triage + runs-on: ubuntu-latest + steps: + - name: Remove Needs Triage label + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh issue edit ${{ github.event.issue.number }} \ + --remove-label "Needs Triage" \ + --repo ${{ github.repository }} 2>/dev/null || true