Skip to content

fix: eliminate page freeze from unstable getUser/getToken in useEffect deps #32

fix: eliminate page freeze from unstable getUser/getToken in useEffect deps

fix: eliminate page freeze from unstable getUser/getToken in useEffect deps #32

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'
continue-on-error: 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'
continue-on-error: true
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!',
});
}