chore(deps-dev): update setuptools requirement from >=61.0 to >=82.0.1 #5
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
| name: Branch Lifecycle Automation | |
| on: | |
| issues: | |
| types: [labeled] | |
| pull_request: | |
| types: [opened, synchronize, closed] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| auto-create-branch: | |
| name: Auto-Create Branch from Issue | |
| if: github.event_name == 'issues' && github.event.label.name == 'ready' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create branch from issue | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const issue = context.payload.issue; | |
| const issueNumber = issue.number; | |
| const issueTitle = issue.title; | |
| // Determine branch prefix from labels | |
| let branchPrefix = 'feature'; | |
| const labels = issue.labels.map(l => l.name); | |
| if (labels.includes('bug')) { | |
| branchPrefix = 'fix'; | |
| } else if (labels.includes('documentation')) { | |
| branchPrefix = 'docs'; | |
| } else if (labels.includes('enhancement') || labels.includes('feature')) { | |
| branchPrefix = 'feature'; | |
| } | |
| // Create slug from issue title | |
| const slug = issueTitle | |
| .toLowerCase() | |
| .replace(/[^a-z0-9]+/g, '-') | |
| .replace(/^-|-$/g, '') | |
| .substring(0, 30); | |
| const branchName = `${branchPrefix}-${issueNumber}-${slug}`; | |
| // Check if branch already exists | |
| try { | |
| await github.rest.repos.getBranch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| branch: branchName, | |
| }); | |
| console.log(`Branch ${branchName} already exists, skipping creation`); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| body: `ℹ️ Branch \`${branchName}\` already exists. You can start working on it:\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${branchName}\n\`\`\``, | |
| }); | |
| return; | |
| } catch (error) { | |
| if (error.status !== 404) throw error; | |
| } | |
| // Get dev branch SHA | |
| const { data: devBranch } = await github.rest.repos.getBranch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| branch: 'dev', | |
| }); | |
| // Create new branch from dev | |
| await github.rest.git.createRef({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| ref: `refs/heads/${branchName}`, | |
| sha: devBranch.commit.sha, | |
| }); | |
| console.log(`Created branch: ${branchName}`); | |
| // Add comment to issue | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| body: `✅ Branch created: \`${branchName}\`\n\nYou can start working on this issue:\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${branchName}\n\`\`\`\n\nWhen ready, push your changes and a PR will be automatically created.`, | |
| }); | |
| // Add "in-progress" label | |
| await github.rest.issues.addLabels({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| labels: ['in-progress'], | |
| }); | |
| auto-update-branch: | |
| name: Auto-Update Branch Before Merge | |
| if: github.event_name == 'pull_request' && github.event.action == 'synchronize' && github.event.pull_request.base.ref == 'dev' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.pull_request.head.ref }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Rebase on dev | |
| id: rebase | |
| continue-on-error: true | |
| run: | | |
| git fetch origin dev | |
| # Check if rebase is needed | |
| if git merge-base --is-ancestor origin/dev HEAD; then | |
| echo "Branch is up-to-date with dev" | |
| echo "rebase_needed=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "Rebasing on dev..." | |
| if git rebase origin/dev; then | |
| echo "rebase_needed=true" >> $GITHUB_OUTPUT | |
| echo "rebase_success=true" >> $GITHUB_OUTPUT | |
| git push --force-with-lease | |
| else | |
| echo "rebase_needed=true" >> $GITHUB_OUTPUT | |
| echo "rebase_success=false" >> $GITHUB_OUTPUT | |
| git rebase --abort | |
| fi | |
| - name: Comment on conflict | |
| if: steps.rebase.outputs.rebase_success == 'false' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.payload.pull_request.number, | |
| body: `⚠️ **Merge Conflict Detected**\n\nThis branch has conflicts with \`dev\`. Please resolve them manually:\n\n\`\`\`bash\ngit fetch origin\ngit rebase origin/dev\n# Resolve conflicts\ngit rebase --continue\ngit push --force-with-lease\n\`\`\``, | |
| }); | |
| auto-delete-branch: | |
| name: Auto-Delete Merged Branch | |
| if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Delete merged branch | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const pr = context.payload.pull_request; | |
| const branchName = pr.head.ref; | |
| // Don't delete protected branches | |
| if (['main', 'dev', 'develop', 'master'].includes(branchName)) { | |
| console.log(`Skipping deletion of protected branch: ${branchName}`); | |
| return; | |
| } | |
| try { | |
| await github.rest.git.deleteRef({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| ref: `heads/${branchName}`, | |
| }); | |
| console.log(`Deleted branch: ${branchName}`); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: pr.number, | |
| body: `✅ Branch \`${branchName}\` has been automatically deleted after merge.`, | |
| }); | |
| } catch (error) { | |
| console.log(`Could not delete branch ${branchName}: ${error.message}`); | |
| } | |
| auto-close-issue: | |
| name: Auto-Close Linked Issue | |
| if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Close linked issue | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const pr = context.payload.pull_request; | |
| const branchName = pr.head.ref; | |
| // Extract issue number from branch name (format: {type}-{number}-{slug}) | |
| const match = branchName.match(/^(?:feature|fix|docs|refactor)-(\d+)-/); | |
| if (!match) { | |
| console.log(`No issue number found in branch name: ${branchName}`); | |
| return; | |
| } | |
| const issueNumber = parseInt(match[1], 10); | |
| try { | |
| // Check if issue exists and is open | |
| const { data: issue } = await github.rest.issues.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| }); | |
| if (issue.state === 'open') { | |
| // Close the issue | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| state: 'closed', | |
| }); | |
| // Add comment linking to PR | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| body: `✅ Closed automatically by merging PR #${pr.number}`, | |
| }); | |
| // Remove "in-progress" label and add "completed" | |
| try { | |
| await github.rest.issues.removeLabel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| name: 'in-progress', | |
| }); | |
| } catch (e) { | |
| // Label might not exist | |
| } | |
| await github.rest.issues.addLabels({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issueNumber, | |
| labels: ['completed'], | |
| }); | |
| console.log(`Closed issue #${issueNumber}`); | |
| } | |
| } catch (error) { | |
| console.log(`Could not close issue #${issueNumber}: ${error.message}`); | |
| } |