[Spec] Database (scaffold) #5
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 | |
# Extract front matter and body | |
# Front matter (between the first and second ---), without the --- lines | |
awk 'BEGIN{fm=0} /^---[[:space:]]*$/{fm++; next} fm==1{print}' "$f" > /tmp/fm.yml | |
# Body (after the second ---) | |
awk 'BEGIN{fm=0} /^---[[:space:]]*$/{fm++; next} fm<2{next} {print}' "$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 eval \ | |
--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 |