fraim-framework 1.0.9 β 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/github/phase-change.yml +218 -0
- package/github/status-change.yml +68 -0
- package/github/sync-on-pr-review.yml +66 -0
- package/package.json +1 -1
- package/setup.js +10 -91
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
name: Phase Change Handler
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [labeled]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
issues: write
|
|
9
|
+
pull-requests: write
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
handle-phase-change:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
if: |
|
|
16
|
+
contains(github.event.label.name, 'phase:') ||
|
|
17
|
+
(github.event.action == 'unlabeled' && contains(github.event.label.name, 'phase:'))
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout repository
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
with:
|
|
23
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
24
|
+
fetch-depth: 0
|
|
25
|
+
|
|
26
|
+
- name: Setup Git
|
|
27
|
+
run: |
|
|
28
|
+
git config --global user.name "github-actions[bot]"
|
|
29
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
30
|
+
|
|
31
|
+
- name: Auth GitHub CLI
|
|
32
|
+
run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token
|
|
33
|
+
|
|
34
|
+
- name: Extract issue details
|
|
35
|
+
id: issue-details
|
|
36
|
+
run: |
|
|
37
|
+
ISSUE_NUMBER="${{ github.event.issue.number }}"
|
|
38
|
+
ISSUE_TITLE="${{ github.event.issue.title }}"
|
|
39
|
+
BRANCH_NAME="feature/${ISSUE_NUMBER}-$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')"
|
|
40
|
+
|
|
41
|
+
echo "issue_number=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
|
|
42
|
+
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
|
|
43
|
+
echo "issue_title=$ISSUE_TITLE" >> $GITHUB_OUTPUT
|
|
44
|
+
|
|
45
|
+
- name: Determine current phase
|
|
46
|
+
id: current-phase
|
|
47
|
+
run: |
|
|
48
|
+
LABELS='${{ toJson(github.event.issue.labels) }}'
|
|
49
|
+
CURRENT_PHASE=""
|
|
50
|
+
|
|
51
|
+
# Extract current phase from labels
|
|
52
|
+
for label in $(echo "$LABELS" | jq -r '.[].name'); do
|
|
53
|
+
if [[ $label == phase:* ]]; then
|
|
54
|
+
CURRENT_PHASE=$label
|
|
55
|
+
break
|
|
56
|
+
fi
|
|
57
|
+
done
|
|
58
|
+
|
|
59
|
+
echo "current_phase=$CURRENT_PHASE" >> $GITHUB_OUTPUT
|
|
60
|
+
echo "Current phase: $CURRENT_PHASE"
|
|
61
|
+
|
|
62
|
+
- name: Ensure branch exists and sync
|
|
63
|
+
run: |
|
|
64
|
+
BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
|
|
65
|
+
BASE="master"
|
|
66
|
+
|
|
67
|
+
git fetch origin "$BASE"
|
|
68
|
+
|
|
69
|
+
if git ls-remote --exit-code --heads origin "$BRANCH_NAME" >/dev/null 2>&1; then
|
|
70
|
+
echo "Branch $BRANCH_NAME exists, syncing..."
|
|
71
|
+
git fetch origin "$BRANCH_NAME"
|
|
72
|
+
git switch "$BRANCH_NAME"
|
|
73
|
+
git pull --rebase origin "$BRANCH_NAME"
|
|
74
|
+
else
|
|
75
|
+
echo "Branch $BRANCH_NAME does not exist, creating from $BASE..."
|
|
76
|
+
git switch -c "$BRANCH_NAME" "origin/$BASE"
|
|
77
|
+
git push -u origin "$BRANCH_NAME"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Design: add EMPTY commit to guarantee a diff
|
|
81
|
+
- name: phase:design β ensure empty commit (commit if missing)
|
|
82
|
+
if: steps.current-phase.outputs.current_phase == 'phase:design'
|
|
83
|
+
shell: bash
|
|
84
|
+
env:
|
|
85
|
+
ISSUE: ${{ github.event.issue.number }}
|
|
86
|
+
run: |
|
|
87
|
+
ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
|
|
88
|
+
ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
|
|
89
|
+
BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
|
|
90
|
+
|
|
91
|
+
# Create empty commit to guarantee branch has commits
|
|
92
|
+
git commit --allow-empty -m "Design phase initiated for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
|
|
93
|
+
git push origin "$BRANCH_NAME"
|
|
94
|
+
|
|
95
|
+
# Create or update Design PR
|
|
96
|
+
PR_TITLE="[Design] RFC for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
|
|
97
|
+
PR_BODY="## Design RFC for Issue #$ISSUE_NUMBER
|
|
98
|
+
|
|
99
|
+
This PR contains the design RFC for: $ISSUE_TITLE
|
|
100
|
+
|
|
101
|
+
**Phase:** Design
|
|
102
|
+
**Issue:** #$ISSUE_NUMBER
|
|
103
|
+
**Branch:** \`$BRANCH_NAME\`
|
|
104
|
+
|
|
105
|
+
### RFC Document
|
|
106
|
+
- π [RFC Document]($RFC_FILE)
|
|
107
|
+
|
|
108
|
+
**Note:** This is a Design PR. Implementation will follow in a separate PR after design approval.
|
|
109
|
+
|
|
110
|
+
"
|
|
111
|
+
|
|
112
|
+
# Check if PR already exists
|
|
113
|
+
EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
114
|
+
|
|
115
|
+
if [ -n "$EXISTING_PR" ]; then
|
|
116
|
+
echo "Updating existing PR #$EXISTING_PR"
|
|
117
|
+
gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
|
|
118
|
+
gh pr edit "$EXISTING_PR" --add-label "phase:design" --remove-label "phase:tests" --remove-label "phase:impl"
|
|
119
|
+
else
|
|
120
|
+
echo "Creating new Design PR"
|
|
121
|
+
gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
|
|
122
|
+
# Add labels to the new PR
|
|
123
|
+
sleep 2 # Brief delay to ensure PR is created
|
|
124
|
+
NEW_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number')
|
|
125
|
+
gh pr edit "$NEW_PR" --add-label "phase:design" --remove-label "phase:tests" --remove-label "phase:impl"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
- name: Handle test phase
|
|
129
|
+
if: steps.current-phase.outputs.current_phase == 'phase:tests'
|
|
130
|
+
run: |
|
|
131
|
+
ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
|
|
132
|
+
ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
|
|
133
|
+
BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
|
|
134
|
+
|
|
135
|
+
# Create or update Test Implementation PR
|
|
136
|
+
PR_TITLE="[Testing] Test Cases for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
|
|
137
|
+
PR_BODY="## Test cases for Issue #$ISSUE_NUMBER
|
|
138
|
+
|
|
139
|
+
This PR contains the test cases for: $ISSUE_TITLE
|
|
140
|
+
|
|
141
|
+
**Phase:** Tests
|
|
142
|
+
**Issue:** #$ISSUE_NUMBER
|
|
143
|
+
**Branch:** \`$BRANCH_NAME\`
|
|
144
|
+
|
|
145
|
+
### Test Cases
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
**Note:** This is a Test PR. Implementation will follow after test approval.
|
|
149
|
+
|
|
150
|
+
"
|
|
151
|
+
|
|
152
|
+
# Check if PR already exists
|
|
153
|
+
EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
154
|
+
|
|
155
|
+
if [ -n "$EXISTING_PR" ]; then
|
|
156
|
+
echo "Updating existing PR #$EXISTING_PR"
|
|
157
|
+
gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
|
|
158
|
+
gh pr edit "$EXISTING_PR" --add-label "phase:tests" --remove-label "phase:design" --remove-label "phase:impl"
|
|
159
|
+
else
|
|
160
|
+
echo "Creating new Test Plan PR"
|
|
161
|
+
gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
|
|
162
|
+
# Add labels to the new PR
|
|
163
|
+
sleep 2 # Brief delay to ensure PR is created
|
|
164
|
+
NEW_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number')
|
|
165
|
+
gh pr edit "$NEW_PR" --add-label "phase:tests" --remove-label "phase:design" --remove-label "phase:impl"
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
- name: Handle implementation phase
|
|
169
|
+
if: steps.current-phase.outputs.current_phase == 'phase:impl'
|
|
170
|
+
run: |
|
|
171
|
+
ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
|
|
172
|
+
ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
|
|
173
|
+
BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
|
|
174
|
+
|
|
175
|
+
# Create or update Implementation PR
|
|
176
|
+
PR_TITLE="[Implementation] Fixes for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
|
|
177
|
+
PR_BODY="## Fixes for Issue #$ISSUE_NUMBER
|
|
178
|
+
|
|
179
|
+
This PR contains the fixes for: $ISSUE_TITLE
|
|
180
|
+
|
|
181
|
+
**Phase:** Implementation
|
|
182
|
+
**Issue:** #$ISSUE_NUMBER
|
|
183
|
+
**Branch:** \`$BRANCH_NAME\`
|
|
184
|
+
|
|
185
|
+
### Fixes
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
Closes #$ISSUE_NUMBER
|
|
189
|
+
|
|
190
|
+
"
|
|
191
|
+
|
|
192
|
+
# Check if PR already exists
|
|
193
|
+
EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
194
|
+
|
|
195
|
+
if [ -n "$EXISTING_PR" ]; then
|
|
196
|
+
echo "Updating existing PR #$EXISTING_PR"
|
|
197
|
+
gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
|
|
198
|
+
gh pr edit "$EXISTING_PR" --add-label "phase:impl" --remove-label "phase:design" --remove-label "phase:tests"
|
|
199
|
+
else
|
|
200
|
+
echo "Creating new Implementation PR"
|
|
201
|
+
gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
|
|
202
|
+
# Add labels to the new PR
|
|
203
|
+
sleep 2 # Brief delay to ensure PR is created
|
|
204
|
+
NEW_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number')
|
|
205
|
+
gh pr edit "$NEW_PR" --add-label "phase:impl" --remove-label "phase:design" --remove-label "phase:tests"
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
- name: Normalize ISSUE and PR status to WIP (authoritative)
|
|
209
|
+
run: |
|
|
210
|
+
gh issue edit ${{ github.event.issue.number }} --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
|
|
211
|
+
|
|
212
|
+
# Get the PR number for the current branch and normalize its status
|
|
213
|
+
BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
|
|
214
|
+
PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
215
|
+
|
|
216
|
+
if [ -n "$PR_NUMBER" ]; then
|
|
217
|
+
gh pr edit "$PR_NUMBER" --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
|
|
218
|
+
fi
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Status Change β Flip PR Draft/Ready
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [labeled]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
pull-requests: write
|
|
9
|
+
issues: read
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
# Serialize per ISSUE; last status wins
|
|
13
|
+
concurrency:
|
|
14
|
+
group: status-change-${{ github.event.issue.number }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
status-change:
|
|
19
|
+
if: startsWith(github.event.label.name, 'status:')
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout repository
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
26
|
+
fetch-depth: 0
|
|
27
|
+
|
|
28
|
+
- name: Setup Git
|
|
29
|
+
run: |
|
|
30
|
+
git config --global user.name "github-actions[bot]"
|
|
31
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
32
|
+
|
|
33
|
+
- name: Auth GitHub CLI
|
|
34
|
+
run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token
|
|
35
|
+
|
|
36
|
+
- name: Derive branch + find PR
|
|
37
|
+
id: pr
|
|
38
|
+
shell: bash
|
|
39
|
+
env:
|
|
40
|
+
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
41
|
+
ISSUE_TITLE: ${{ github.event.issue.title }}
|
|
42
|
+
run: |
|
|
43
|
+
set -euo pipefail
|
|
44
|
+
slug=$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g;s/^-+|-+$//g')
|
|
45
|
+
BR="feature/${ISSUE_NUMBER}-${slug}"
|
|
46
|
+
PR=$(gh pr list --state open --head "$BR" --json number --jq '.[0].number')
|
|
47
|
+
echo "pr=$PR" >> $GITHUB_OUTPUT
|
|
48
|
+
echo "label=${{ github.event.label.name }}" >> $GITHUB_OUTPUT
|
|
49
|
+
|
|
50
|
+
- name: Flip PR state (Draft/Ready) based on label
|
|
51
|
+
if: steps.pr.outputs.pr != ''
|
|
52
|
+
shell: bash
|
|
53
|
+
env:
|
|
54
|
+
PR: ${{ steps.pr.outputs.pr }}
|
|
55
|
+
LABEL: ${{ steps.pr.outputs.label }}
|
|
56
|
+
run: |
|
|
57
|
+
set -euo pipefail
|
|
58
|
+
case "$LABEL" in
|
|
59
|
+
status:needs-review)
|
|
60
|
+
gh pr ready "$PR"
|
|
61
|
+
gh pr edit "$PR" --add-label "status:needs-review" --remove-label "status:wip" --remove-label "status:complete" || true
|
|
62
|
+
;;
|
|
63
|
+
status:wip)
|
|
64
|
+
gh pr edit "$PR" --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
|
|
65
|
+
;;
|
|
66
|
+
*)
|
|
67
|
+
echo "No action for label: $LABEL" ;;
|
|
68
|
+
esac
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Sync Issue on PR Review
|
|
2
|
+
on:
|
|
3
|
+
pull_request_review:
|
|
4
|
+
types: [submitted]
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
pull-requests: write
|
|
8
|
+
issues: write
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: review-sync-${{ github.event.pull_request.number }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
sync-on-review:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
# no job-level `if` β we branch inside the script
|
|
18
|
+
env:
|
|
19
|
+
GH_TOKEN: ${{ secrets.PR_AUTOMATION_TOKEN || secrets.GITHUB_TOKEN }}
|
|
20
|
+
REPO: ${{ github.repository }}
|
|
21
|
+
steps:
|
|
22
|
+
- name: Derive review state, issue number, and branch
|
|
23
|
+
id: vars
|
|
24
|
+
shell: bash
|
|
25
|
+
run: |
|
|
26
|
+
set -euo pipefail
|
|
27
|
+
STATE="${{ github.event.review.state }}"
|
|
28
|
+
BR="${{ github.event.pull_request.head.ref }}" # e.g., feature/26-slug
|
|
29
|
+
ISSUE="$(sed -nE 's#^feature/([0-9]+)-.*#\1#p' <<< "$BR" || true)"
|
|
30
|
+
echo "state=$STATE" >> $GITHUB_OUTPUT
|
|
31
|
+
echo "issue=$ISSUE" >> $GITHUB_OUTPUT
|
|
32
|
+
echo "branch=$BR" >> $GITHUB_OUTPUT
|
|
33
|
+
echo "Detected review state: $STATE; branch: $BR; issue: $ISSUE"
|
|
34
|
+
|
|
35
|
+
- name: Handle review states
|
|
36
|
+
if: steps.vars.outputs.issue != ''
|
|
37
|
+
shell: bash
|
|
38
|
+
env:
|
|
39
|
+
STATE: ${{ steps.vars.outputs.state }}
|
|
40
|
+
ISSUE: ${{ steps.vars.outputs.issue }}
|
|
41
|
+
PRNUM: ${{ github.event.pull_request.number }}
|
|
42
|
+
REPO: ${{ env.REPO }}
|
|
43
|
+
run: |
|
|
44
|
+
set -euo pipefail
|
|
45
|
+
case "$STATE" in
|
|
46
|
+
changes_requested)
|
|
47
|
+
# Flip to WIP
|
|
48
|
+
gh issue edit "$ISSUE" --repo "$REPO" \
|
|
49
|
+
--add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
|
|
50
|
+
gh pr edit "$PRNUM" --repo "$REPO" \
|
|
51
|
+
--add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
|
|
52
|
+
;;
|
|
53
|
+
approved)
|
|
54
|
+
# Flip to Complete
|
|
55
|
+
gh issue edit "$ISSUE" --repo "$REPO" \
|
|
56
|
+
--add-label "status:complete" --remove-label "status:wip" --remove-label "status:needs-review" || true
|
|
57
|
+
gh pr edit "$PRNUM" --repo "$REPO" --add-label "status:complete" --remove-label "status:wip" --remove-label "status:needs-review" || true
|
|
58
|
+
;;
|
|
59
|
+
commented)
|
|
60
|
+
# No-op; comments donβt change state
|
|
61
|
+
echo "Review was 'commented' β no state change."
|
|
62
|
+
;;
|
|
63
|
+
*)
|
|
64
|
+
echo "Unknown review state: $STATE"
|
|
65
|
+
;;
|
|
66
|
+
esac
|
package/package.json
CHANGED
package/setup.js
CHANGED
|
@@ -285,98 +285,17 @@ function createLabelsConfigFile() {
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
function createGitHubWorkflows() {
|
|
288
|
-
//
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
on:
|
|
292
|
-
issues:
|
|
293
|
-
types: [labeled, unlabeled]
|
|
294
|
-
|
|
295
|
-
jobs:
|
|
296
|
-
phase-change:
|
|
297
|
-
runs-on: ubuntu-latest
|
|
298
|
-
if: contains(github.event.issue.labels.*.name, 'phase:') || contains(github.event.label.name, 'phase:')
|
|
299
|
-
steps:
|
|
300
|
-
- name: Checkout
|
|
301
|
-
uses: actions/checkout@v4
|
|
302
|
-
|
|
303
|
-
- name: Phase Change Handler
|
|
304
|
-
run: |
|
|
305
|
-
echo "Phase change detected for issue #\${{ github.event.issue.number }}"
|
|
306
|
-
echo "New phase: \${{ github.event.label.name || 'phase removed' }}"
|
|
307
|
-
|
|
308
|
-
- name: Update Issue Status
|
|
309
|
-
if: contains(github.event.label.name, 'phase:')
|
|
310
|
-
run: |
|
|
311
|
-
gh issue edit \${{ github.event.issue.number }} --add-label "status:wip"
|
|
312
|
-
echo "Status updated to WIP for new phase"
|
|
313
|
-
`;
|
|
314
|
-
|
|
315
|
-
// Status change workflow
|
|
316
|
-
const statusChangeWorkflow = `name: Status Change Automation
|
|
317
|
-
|
|
318
|
-
on:
|
|
319
|
-
issues:
|
|
320
|
-
types: [labeled, unlabeled]
|
|
321
|
-
|
|
322
|
-
jobs:
|
|
323
|
-
status-change:
|
|
324
|
-
runs-on: ubuntu-latest
|
|
325
|
-
if: contains(github.event.issue.labels.*.name, 'status:') || contains(github.event.label.name, 'status:')
|
|
326
|
-
steps:
|
|
327
|
-
- name: Checkout
|
|
328
|
-
uses: actions/checkout@v4
|
|
329
|
-
|
|
330
|
-
- name: Status Change Handler
|
|
331
|
-
run: |
|
|
332
|
-
echo "Status change detected for issue #\${{ github.event.issue.number }}"
|
|
333
|
-
echo "New status: \${{ github.event.label.name || 'status removed' }}"
|
|
334
|
-
|
|
335
|
-
- name: Notify Team
|
|
336
|
-
if: contains(github.event.label.name, 'status:needs-review')
|
|
337
|
-
run: |
|
|
338
|
-
echo "Issue ready for review - notifying team"
|
|
339
|
-
`;
|
|
340
|
-
|
|
341
|
-
// Sync on PR review workflow
|
|
342
|
-
const syncOnPRReviewWorkflow = `name: Sync on PR Review
|
|
343
|
-
|
|
344
|
-
on:
|
|
345
|
-
pull_request_review:
|
|
346
|
-
types: [submitted, edited, dismissed]
|
|
347
|
-
|
|
348
|
-
jobs:
|
|
349
|
-
sync-review:
|
|
350
|
-
runs-on: ubuntu-latest
|
|
351
|
-
steps:
|
|
352
|
-
- name: Checkout
|
|
353
|
-
uses: actions/checkout@v4
|
|
354
|
-
|
|
355
|
-
- name: Sync Review Status
|
|
356
|
-
env:
|
|
357
|
-
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
358
|
-
run: |
|
|
359
|
-
PR_NUMBER="\${{ github.event.pull_request.number }}"
|
|
360
|
-
REVIEW_STATE="\${{ github.event.review.state }}"
|
|
361
|
-
|
|
362
|
-
echo "PR #\$PR_NUMBER review state: \$REVIEW_STATE"
|
|
363
|
-
|
|
364
|
-
if [ "\$REVIEW_STATE" = "approved" ]; then
|
|
365
|
-
echo "PR approved - updating status"
|
|
366
|
-
gh pr edit \$PR_NUMBER --add-label "status:approved"
|
|
367
|
-
elif [ "\$REVIEW_STATE" = "changes_requested" ]; then
|
|
368
|
-
echo "Changes requested - updating status"
|
|
369
|
-
gh pr edit \$PR_NUMBER --add-label "status:changes-requested"
|
|
370
|
-
fi
|
|
371
|
-
|
|
372
|
-
echo "Review sync complete"
|
|
373
|
-
`;
|
|
374
|
-
|
|
375
|
-
writeFile('.github/workflows/phase-change.yml', phaseChangeWorkflow);
|
|
376
|
-
writeFile('.github/workflows/status-change.yml', statusChangeWorkflow);
|
|
377
|
-
writeFile('.github/workflows/sync-on-pr-review.yml', syncOnPRReviewWorkflow);
|
|
288
|
+
// Get the directory where this script is located (FRAIM package directory)
|
|
289
|
+
const fraimDir = __dirname;
|
|
378
290
|
|
|
379
|
-
|
|
291
|
+
// Copy actual workflow files from FRAIM/github folder
|
|
292
|
+
const workflowsSrc = path.join(fraimDir, 'github');
|
|
293
|
+
if (fs.existsSync(workflowsSrc)) {
|
|
294
|
+
copyDirectory(workflowsSrc, '.github/workflows');
|
|
295
|
+
logSuccess('GitHub workflows copied from FRAIM/github folder');
|
|
296
|
+
} else {
|
|
297
|
+
logWarning(`github folder not found at ${workflowsSrc}, skipping workflow creation`);
|
|
298
|
+
}
|
|
380
299
|
}
|
|
381
300
|
|
|
382
301
|
function createAgentFolders() {
|