Skip to content

[Spec] Server Sent Events (scaffold) #3

[Spec] Server Sent Events (scaffold)

[Spec] Server Sent Events (scaffold) #3

Workflow file for this run

name: Spec Post-merge Update
on:
pull_request:
types: [closed]
paths:
- "_specs/**"
permissions:
contents: write
jobs:
postmerge:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Compute TODAY as YYYY-MM-DD using the event's merged_at timestamp if available
- name: Compute TODAY (YYYY-MM-DD)
run: |
set -e
# merged_at looks like: 2025-09-07T11:59:12Z
TS=$(jq -r '.pull_request.merged_at // empty' "$GITHUB_EVENT_PATH" || true)
if [ -n "$TS" ]; then
TODAY="${TS%%T*}"
else
TODAY="$(date -u +%F)"
fi
echo "TODAY=$TODAY" >> "$GITHUB_ENV"
echo "TODAY=$TODAY"
- name: Install yq
run: |
sudo curl -sL https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64 -o /usr/local/bin/yq
sudo chmod +x /usr/local/bin/yq
yq --version
- name: Collect changed spec directories (via API)
id: dirs
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
// List all files changed in the PR
const files = await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
per_page: 100
});
// Keep only _specs/** paths and reduce to _specs/<family>/<version> dirs
const dirs = [...new Set(
files
.map(f => f.filename)
.filter(p => p.startsWith('_specs/'))
.map(p => p.replace(/^(_specs\/[^/]+\/[^/]+)\/.*/, '$1'))
)];
core.info(`Changed spec dirs:\n${dirs.join('\n') || '(none)'}`);
core.setOutput('dirs', dirs.join('\n'));
- name: Determine label-based status policy
id: policy
run: |
set -e
labels='${{ toJson(github.event.pull_request.labels) }}'
# Default: empty TARGET means "auto-activate if currently in-progress"
if echo "$labels" | grep -qi '"name":"spec:deprecated"'; then
echo "TARGET=deprecated" >> $GITHUB_ENV
elif echo "$labels" | grep -qi '"name":"spec:activate"'; then
echo "TARGET=active" >> $GITHUB_ENV
elif echo "$labels" | grep -qi '"name":"keep-draft"\|"name":"spec:draft"'; then
echo "TARGET=in-progress" >> $GITHUB_ENV
else
echo "TARGET=" >> $GITHUB_ENV
fi
- name: Update index.md in affected spaces
if: steps.dirs.outputs.dirs != ''
run: |
set -euo pipefail
CHANGE_TEXT="Merged PR #${PR_NUMBER}: ${PR_TITLE}"
while IFS= read -r dir; do
f="$dir/index.md"
[ -f "$f" ] || continue
# Extract front matter and body
awk 'NR==1&&$0=="---"{in=1;next} in{ if($0=="---"){exit} print }' "$f" > /tmp/fm.yml
awk 'p{print} /^---[ \t]*$/{c++} c==2{p=1}' "$f" > /tmp/body.md
cur_status=$(yq '.status // ""' /tmp/fm.yml)
target="${TARGET:-}"
new_status="$cur_status"
if [ -n "$target" ]; then
new_status="$target"
else
# default: auto-activate if it was in-progress
[ "$cur_status" = "in-progress" ] && new_status="active"
fi
yq -y \
--arg today "$TODAY" \
--arg status "$new_status" \
--arg text "$CHANGE_TEXT" \
'.updated_at = $today
| .status = $status
| .changelog = [{"date": $today, "text": $text}] + (.changelog // [])' \
/tmp/fm.yml > /tmp/fm.new.yml
{ echo '---'; cat /tmp/fm.new.yml; echo '---'; cat /tmp/body.md; } > "$f"
echo "Updated $f (status: $cur_status → $new_status)"
done < <(printf '%s\n' "${{ steps.dirs.outputs.dirs }}")
git config user.name "spec-bot"
git config user.email "[email protected]"
git add _specs
git commit -m "chore(spec): update status/updated_at after merge of #${PR_NUMBER}" || echo "Nothing to commit"
git push