main
yml 120 lines 4.18 KB
Raw
1 name: Squad Promote
2
3 on:
4 workflow_dispatch:
5 inputs:
6 dry_run:
7 description: 'Dry run show what would happen without pushing'
8 required: false
9 default: 'false'
10 type: choice
11 options: ['false', 'true']
12
13 permissions:
14 contents: write
15
16 jobs:
17 dev-to-preview:
18 name: Promote dev → preview
19 runs-on: ubuntu-latest
20 steps:
21 - uses: actions/checkout@v4
22 with:
23 fetch-depth: 0
24 token: ${{ secrets.GITHUB_TOKEN }}
25
26 - name: Configure git
27 run: |
28 git config user.name "github-actions[bot]"
29 git config user.email "github-actions[bot]@users.noreply.github.com"
30
31 - name: Fetch all branches
32 run: git fetch --all
33
34 - name: Show current state (dry run info)
35 run: |
36 echo "=== dev HEAD ===" && git log origin/dev -1 --oneline
37 echo "=== preview HEAD ===" && git log origin/preview -1 --oneline
38 echo "=== Files that would be stripped ==="
39 git diff origin/preview..origin/dev --name-only | grep -E "^(\.(ai-team|squad|ai-team-templates)|team-docs/|docs/proposals/)" || echo "(none)"
40
41 - name: Merge dev → preview (strip forbidden paths)
42 if: ${{ inputs.dry_run == 'false' }}
43 run: |
44 git checkout preview
45 git merge origin/dev --no-commit --no-ff -X theirs || true
46
47 # Strip forbidden paths from merge commit
48 git rm -rf --cached --ignore-unmatch \
49 .ai-team/ \
50 .squad/ \
51 .ai-team-templates/ \
52 team-docs/ \
53 "docs/proposals/" || true
54
55 # Commit if there are staged changes
56 if ! git diff --cached --quiet; then
57 git commit -m "chore: promote dev → preview (v$(node -e "console.log(require('./package.json').version)"))"
58 git push origin preview
59 echo "✅ Pushed preview branch"
60 else
61 echo "ℹ️ Nothing to commit — preview is already up to date"
62 fi
63
64 - name: Dry run complete
65 if: ${{ inputs.dry_run == 'true' }}
66 run: echo "🔍 Dry run complete — no changes pushed."
67
68 preview-to-main:
69 name: Promote preview → main (release)
70 needs: dev-to-preview
71 runs-on: ubuntu-latest
72 steps:
73 - uses: actions/checkout@v4
74 with:
75 fetch-depth: 0
76 token: ${{ secrets.GITHUB_TOKEN }}
77
78 - name: Configure git
79 run: |
80 git config user.name "github-actions[bot]"
81 git config user.email "github-actions[bot]@users.noreply.github.com"
82
83 - name: Fetch all branches
84 run: git fetch --all
85
86 - name: Show current state
87 run: |
88 echo "=== preview HEAD ===" && git log origin/preview -1 --oneline
89 echo "=== main HEAD ===" && git log origin/main -1 --oneline
90 echo "=== Version ===" && node -e "console.log('v' + require('./package.json').version)"
91
92 - name: Validate preview is release-ready
93 run: |
94 git checkout preview
95 VERSION=$(node -e "console.log(require('./package.json').version)")
96 if ! grep -q "## \[$VERSION\]" CHANGELOG.md 2>/dev/null; then
97 echo "::error::Version $VERSION not found in CHANGELOG.md — update before releasing"
98 exit 1
99 fi
100 echo "✅ Version $VERSION has CHANGELOG entry"
101
102 # Verify no forbidden files on preview
103 FORBIDDEN=$(git ls-files | grep -E "^(\.(ai-team|squad|ai-team-templates)/|team-docs/|docs/proposals/)" || true)
104 if [ -n "$FORBIDDEN" ]; then
105 echo "::error::Forbidden files found on preview: $FORBIDDEN"
106 exit 1
107 fi
108 echo "✅ No forbidden files on preview"
109
110 - name: Merge preview → main
111 if: ${{ inputs.dry_run == 'false' }}
112 run: |
113 git checkout main
114 git merge origin/preview --no-ff -m "chore: promote preview → main (v$(node -e "console.log(require('./package.json').version)"))"
115 git push origin main
116 echo "✅ Pushed main — squad-release.yml will tag and publish the release"
117
118 - name: Dry run complete
119 if: ${{ inputs.dry_run == 'true' }}
120 run: echo "🔍 Dry run complete — no changes pushed."