[Spec] WebSocket Server (scaffold) #8
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
# --- split front-matter/body (safe awk) --- | |
awk 'BEGIN{fm=0} /^---[[:space:]]*$/{fm++; next} fm==1{print}' "$f" > /tmp/fm.yml | |
awk 'BEGIN{fm=0} /^---[[:space:]]*$/{fm++; next} fm<2{next} {print}' "$f" > /tmp/body.md | |
# current status (yq v4) | |
cur_status=$(yq e '.status // ""' /tmp/fm.yml) | |
# decide new status | |
target="${TARGET:-}" | |
new_status="$cur_status" | |
if [ -n "$target" ]; then | |
new_status="$target" | |
else | |
[ "$cur_status" = "in-progress" ] && new_status="active" | |
fi | |
# export vars so yq can read them via strenv() | |
NEW_STATUS="$new_status" | |
export TODAY NEW_STATUS CHANGE_TEXT | |
# --- yq v4 update (no --arg) --- | |
yq e \ | |
'.updated_at = strenv(TODAY) | |
| .status = strenv(NEW_STATUS) | |
| .changelog = [{"date": strenv(TODAY), "text": strenv(CHANGE_TEXT)}] + (.changelog // [])' \ | |
/tmp/fm.yml > /tmp/fm.new.yml | |
# stitch back | |
{ 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 | |