-
Notifications
You must be signed in to change notification settings - Fork 62
138 lines (122 loc) · 5.05 KB
/
Copy pathcheck-feature-readmes.yml
File metadata and controls
138 lines (122 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
name: Check feature island READMEs
on:
pull_request:
paths:
- 'src/features/**'
- '!src/features/**/*.stories.tsx'
- '!src/features/**/*.test.*'
- '!src/features/**/*.spec.*'
jobs:
check-readmes:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find islands with changes but no README update
id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
BASE=${{ github.event.pull_request.base.sha }}
HEAD=${{ github.event.pull_request.head.sha }}
changed=$(git diff --name-only "$BASE" "$HEAD" -- 'src/features/**' | grep -v '^$' || true)
stale_islands=""
declare -A seen
while IFS= read -r file; do
# Only process files that are inside a sub-directory of src/features/
# (skip top-level files like src/features/index.ts)
if [[ ! "$file" =~ ^src/features/[^/]+/ ]]; then
continue
fi
# Extract top-level island: src/features/<island>/...
island=$(echo "$file" | sed 's|src/features/\([^/]*\)/.*|\1|')
[[ -z "$island" || -n "${seen[$island]}" ]] && continue
seen[$island]=1
# Check if README.md was also touched in this PR
readme_changed=$(git diff --name-only "$BASE" "$HEAD" -- "src/features/$island/README.md" | wc -l)
if [[ "$readme_changed" -eq 0 ]]; then
stale_islands="$stale_islands\n- \`src/features/$island/README.md\`"
fi
done <<< "$changed"
if [[ -n "$stale_islands" ]]; then
echo "stale_islands<<EOF" >> "$GITHUB_OUTPUT"
echo -e "$stale_islands" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
echo "has_stale=true" >> "$GITHUB_OUTPUT"
else
echo "has_stale=false" >> "$GITHUB_OUTPUT"
fi
- name: Post warning comment
if: steps.check.outputs.has_stale == 'true'
env:
# Pass via env to avoid script injection from untrusted ref names
HEAD_REF: ${{ github.head_ref }}
STALE_ISLANDS: ${{ steps.check.outputs.stale_islands }}
uses: actions/github-script@v7
with:
script: |
const islands = process.env.STALE_ISLANDS;
const headRef = process.env.HEAD_REF;
const body = [
'## ⚠️ Feature island READMEs may need updating',
'',
'This PR modifies files in the following feature islands, but their `README.md` was not touched:',
'',
islands,
'',
'**Action required if your changes:**',
'- Add or remove a sub-feature, page, or route',
'- Change which API (v1/v2) or data layer hooks are used',
'- Alter the permission model or introduce new constraints',
'',
'_No action needed for bug fixes, style changes, or test additions that don\'t change the island\'s structure._',
'',
`See [AGENTS.md](../blob/${headRef}/AGENTS.md) for the full rule.`,
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Feature island READMEs may need updating')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}
- name: Resolve previous warning if READMEs are now updated
if: steps.check.outputs.has_stale == 'false'
uses: actions/github-script@v7
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Feature island READMEs may need updating')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: '## ✅ Feature island READMEs — resolved\n\nAll modified islands have an updated `README.md`. Thank you!',
});
}