mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2026-01-30 06:12:05 +00:00
chore: add forward-port CI for merges into main-next
This commit is contained in:
169
.github/workflows/forward-port.yml
vendored
Normal file
169
.github/workflows/forward-port.yml
vendored
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
name: Forward Port to Next
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: forward-port
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
forward-port:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
DISCORD_WEBHOOK: ${{ secrets.DISCORD_METRICS_WEBHOOK }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Check for existing PR
|
||||||
|
id: check-pr
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
EXISTING_PR=$(gh pr list --base next --head main --state open --json number --jq '.[0].number // empty')
|
||||||
|
if [ -n "$EXISTING_PR" ]; then
|
||||||
|
echo "existing_pr=$EXISTING_PR" >> $GITHUB_OUTPUT
|
||||||
|
echo "PR #$EXISTING_PR already exists for main → next"
|
||||||
|
else
|
||||||
|
echo "existing_pr=" >> $GITHUB_OUTPUT
|
||||||
|
echo "No existing PR found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check if main has changes not in next
|
||||||
|
id: check-diff
|
||||||
|
if: steps.check-pr.outputs.existing_pr == ''
|
||||||
|
run: |
|
||||||
|
git fetch origin next
|
||||||
|
DIFF_COUNT=$(git rev-list --count origin/next..origin/main)
|
||||||
|
echo "diff_count=$DIFF_COUNT" >> $GITHUB_OUTPUT
|
||||||
|
if [ "$DIFF_COUNT" -gt 0 ]; then
|
||||||
|
echo "Found $DIFF_COUNT commit(s) in main not in next"
|
||||||
|
else
|
||||||
|
echo "No new commits to forward port"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for merge conflicts
|
||||||
|
id: check-conflicts
|
||||||
|
if: steps.check-pr.outputs.existing_pr == '' && steps.check-diff.outputs.diff_count != '0'
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
# Try a test merge to detect conflicts
|
||||||
|
git checkout origin/next
|
||||||
|
if git merge --no-commit --no-ff origin/main 2>/dev/null; then
|
||||||
|
echo "has_conflicts=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "No merge conflicts detected"
|
||||||
|
else
|
||||||
|
echo "has_conflicts=true" >> $GITHUB_OUTPUT
|
||||||
|
# Get list of conflicting files
|
||||||
|
CONFLICTING_FILES=$(git diff --name-only --diff-filter=U | head -10)
|
||||||
|
echo "conflicting_files<<EOF" >> $GITHUB_OUTPUT
|
||||||
|
echo "$CONFLICTING_FILES" >> $GITHUB_OUTPUT
|
||||||
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
echo "Merge conflicts detected in: $CONFLICTING_FILES"
|
||||||
|
fi
|
||||||
|
git merge --abort 2>/dev/null || true
|
||||||
|
|
||||||
|
- name: Create forward-port PR
|
||||||
|
id: create-pr
|
||||||
|
if: steps.check-pr.outputs.existing_pr == '' && steps.check-diff.outputs.diff_count != '0'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
# Get the commits being forward-ported for the PR body
|
||||||
|
COMMITS=$(git log origin/next..origin/main --oneline --no-decorate | head -20)
|
||||||
|
COMMIT_COUNT=$(git rev-list --count origin/next..origin/main)
|
||||||
|
|
||||||
|
# Build conflict warning if needed
|
||||||
|
CONFLICT_WARNING=""
|
||||||
|
if [ "${{ steps.check-conflicts.outputs.has_conflicts }}" = "true" ]; then
|
||||||
|
CONFLICT_WARNING="
|
||||||
|
> [!WARNING]
|
||||||
|
> **Merge conflicts detected.** Manual resolution required.
|
||||||
|
>
|
||||||
|
> Conflicting files:
|
||||||
|
> \`\`\`
|
||||||
|
> ${{ steps.check-conflicts.outputs.conflicting_files }}
|
||||||
|
> \`\`\`
|
||||||
|
|
||||||
|
### How to resolve
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
# Option 1: Resolve in a temporary branch (recommended)
|
||||||
|
git fetch origin
|
||||||
|
git checkout -b resolve-forward-port origin/next
|
||||||
|
git merge origin/main
|
||||||
|
# Fix conflicts in your editor, then:
|
||||||
|
git add .
|
||||||
|
git commit
|
||||||
|
git push origin resolve-forward-port
|
||||||
|
# Create PR from resolve-forward-port → next, then close this PR
|
||||||
|
|
||||||
|
# Option 2: Resolve directly on next
|
||||||
|
git checkout next
|
||||||
|
git pull origin next
|
||||||
|
git merge origin/main
|
||||||
|
# Fix conflicts, commit, and push
|
||||||
|
\`\`\`
|
||||||
|
"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create PR body
|
||||||
|
BODY="## Forward Port: main → next
|
||||||
|
|
||||||
|
This PR forward-ports changes from \`main\` to \`next\` to ensure hotfixes and releases are included in the next development branch.
|
||||||
|
$CONFLICT_WARNING
|
||||||
|
### Commits ($COMMIT_COUNT total)
|
||||||
|
\`\`\`
|
||||||
|
$COMMITS
|
||||||
|
\`\`\`
|
||||||
|
$([ "$COMMIT_COUNT" -gt 20 ] && echo "... and $((COMMIT_COUNT - 20)) more")
|
||||||
|
|
||||||
|
---
|
||||||
|
*Auto-generated by forward-port workflow*"
|
||||||
|
|
||||||
|
# Create the PR
|
||||||
|
PR_URL=$(gh pr create \
|
||||||
|
--base next \
|
||||||
|
--head main \
|
||||||
|
--title "chore: forward port main to next" \
|
||||||
|
--label "forward-port" \
|
||||||
|
--label "automated" \
|
||||||
|
--body "$BODY")
|
||||||
|
|
||||||
|
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
|
||||||
|
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||||
|
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
# Add conflict label if needed
|
||||||
|
if [ "${{ steps.check-conflicts.outputs.has_conflicts }}" = "true" ]; then
|
||||||
|
gh pr edit "$PR_NUMBER" --add-label "has-conflicts"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Send Discord notification
|
||||||
|
if: steps.create-pr.outputs.pr_url != '' && env.DISCORD_WEBHOOK != ''
|
||||||
|
uses: sarisia/actions-status-discord@v1
|
||||||
|
with:
|
||||||
|
webhook: ${{ env.DISCORD_WEBHOOK }}
|
||||||
|
status: ${{ steps.check-conflicts.outputs.has_conflicts == 'true' && 'Warning' || 'Success' }}
|
||||||
|
title: "🔄 Forward Port PR Created"
|
||||||
|
description: |
|
||||||
|
**main → next**
|
||||||
|
|
||||||
|
${{ steps.check-conflicts.outputs.has_conflicts == 'true' && '⚠️ **Merge conflicts detected** - manual resolution required' || '✅ No conflicts - ready for review' }}
|
||||||
|
|
||||||
|
**Commits:** ${{ steps.check-diff.outputs.diff_count }}
|
||||||
|
**PR:** ${{ steps.create-pr.outputs.pr_url }}
|
||||||
|
color: ${{ steps.check-conflicts.outputs.has_conflicts == 'true' && '0xFFA500' || '0x58AFFF' }}
|
||||||
|
username: Task Master Bot
|
||||||
|
avatar_url: https://raw.githubusercontent.com/eyaltoledano/claude-task-master/main/images/logo.png
|
||||||
Reference in New Issue
Block a user