Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions .github/workflows/pr-check-openspec.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,52 @@
name: PR OpenSpec Archive Check

# A change is archived exactly once, when ALL of its work has landed. In a
# stack of PRs, only the tip carries the archived change; the PRs below it still
# carry the in-flight change directory by design. So this check runs only on the
# tip of a stack (or a standalone PR) and is skipped on PRs that still have work
# stacked on top of them. Tip = no other OPEN PR targets this PR's head branch
# as its base.
on:
pull_request:
branches: [main]

permissions:
contents: read
pull-requests: read

jobs:
stack-position:
name: Detect stack position
runs-on: ubuntu-latest
outputs:
is_tip: ${{ steps.detect.outputs.is_tip }}
steps:
- name: Determine whether this PR is the tip of its stack
id: detect
env:
GH_TOKEN: ${{ github.token }}
HEAD_REF: ${{ github.head_ref }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail

# Count OPEN PRs that target this PR's head branch as their base.
# Any such PR means work is still stacked on top → not the tip.
children=$(gh pr list --repo "$REPO" --state open --base "$HEAD_REF" \
--json number --jq 'length' 2>/dev/null || echo 0)
children=${children:-0}

if [ "$children" -gt 0 ]; then
echo "is_tip=false" >> "$GITHUB_OUTPUT"
echo "This PR has $children open PR(s) stacked on top — changes still in flight."
echo "The OpenSpec archive check is skipped until this PR is the tip of the stack."
else
echo "is_tip=true" >> "$GITHUB_OUTPUT"
echo "No PRs are stacked on top — this PR is the tip (or standalone); the archive check will run."
fi

check-openspec-archived:
needs: stack-position
if: needs.stack-position.outputs.is_tip == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
Expand All @@ -28,8 +66,8 @@ jobs:
echo "::error::Unarchived OpenSpec change directories found under openspec/changes/:"
echo "$UNARCHIVED" | sed 's|^| - |'
echo ""
echo "Every change must be moved under openspec/changes/archive/ before merge."
echo "Run the openspec archive workflow (e.g. /openspec-archive-change <name>) and commit the result."
echo "This PR is the tip of its stack (all work landed), so the change must be archived."
echo "Move it under openspec/changes/archive/ (e.g. /openspec-archive-change <name>) and commit."
exit 1
fi

Expand Down
Loading