-
-
Notifications
You must be signed in to change notification settings - Fork 0
138 lines (132 loc) · 5.57 KB
/
Copy pathmain-selfcheck.yml
File metadata and controls
138 lines (132 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
name: main self-check
# Post-push re-validation of the files touched by THIS push, against the
# khai structural validators.
#
# validate.yml's content validators are diff-scoped: the `setup` job hands
# them only the regions/ + engine/ files a PR changed. That diff scope
# matches the scope of authorship -- a PR is responsible for the files it
# touches. This workflow extends the same scope to integration branches:
# on every push to main / culture/release, re-validate the files the push
# actually delivered (HEAD relative to github.event.before).
#
# Why diff-scoped (not full-content):
# A full-content scan turns every push into a referendum on every legacy
# file in the corpus. Pre-existing rule violations that have nothing to
# do with the current PR then block unrelated merges. The instinct that
# "main should always be self-consistent" is true; the enforcement point
# is the PR that introduced the file, plus this push-time re-check on
# the files actually delivered -- not a corpus-wide alarm.
#
# Loss vs. the previous full-content design:
# If a validator's --khai-files scope is widened, or a rule tightened, in
# a PR that touches only governance paths, the diff-scoped run will not
# re-check legacy regions/ files against the new rule. That gap is
# accepted: such tightenings should be exercised via a deliberate
# corpus-wide audit (workflow_dispatch below), not as a side effect of
# every push. The previous design's "fix-forward immediately" loop, in
# practice, blocked unrelated promotions on unrelated debt.
#
# Manual full-corpus scan:
# workflow_dispatch is wired below. Run it from the Actions UI when
# auditing the corpus after a rule change.
on:
push:
branches: [main, culture/release]
workflow_dispatch:
inputs:
full_corpus:
description: 'Scan the full regions/ + engine/ corpus (ignore push diff)'
type: boolean
default: true
concurrency:
group: main-selfcheck-${{ github.ref_name }}
cancel-in-progress: true
permissions:
contents: read
jobs:
selfcheck:
name: main self-check - khai structural validators
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Need history back to github.event.before so the diff resolves.
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install khai-tests
uses: ./.github/actions/install-khai-tests
with:
token: ${{ secrets.KAIHACKS }}
- name: Collect files in scope for this run
id: files
# Push event: diff regions/+engine/ between github.event.before and
# the current SHA. Pre-existing legacy files are not in scope --
# they were authored by, and reviewed against, earlier rule sets.
#
# workflow_dispatch (full_corpus=true): scan everything. Manual
# audit lane for rule changes.
#
# Corpus-debt filter (piece files lacking ## Yearbook) still
# applies in both modes: it predates this redesign and is still
# the right call for legacy pieces.
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.full_corpus }}" = "true" ]; then
echo "mode: workflow_dispatch full-corpus scan" >&2
CANDIDATES=$(git ls-files 'regions/*.md' 'engine/*.md')
else
BEFORE="${{ github.event.before }}"
AFTER="${{ github.sha }}"
if [ -z "$BEFORE" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then
echo "mode: initial push (no previous SHA); skipping push-diff scan" >&2
echo "files=" >> "$GITHUB_OUTPUT"
exit 0
fi
if ! git cat-file -e "$BEFORE" 2>/dev/null; then
echo "mode: previous SHA $BEFORE not reachable; skipping" >&2
echo "files=" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "mode: push diff $BEFORE..$AFTER" >&2
CANDIDATES=$(git diff --name-only --diff-filter=AM "$BEFORE" "$AFTER" -- 'regions/*.md' 'engine/*.md')
fi
FILES=""
EXCLUDED=0
for f in $CANDIDATES; do
[ -f "$f" ] || continue
case "$f" in
*_piece_*.md)
if ! grep -q '^## Yearbook' "$f"; then
EXCLUDED=$((EXCLUDED+1))
continue
fi
;;
esac
FILES="$FILES$f "
done
FILES=$(echo "$FILES" | sed 's/ *$//')
echo "corpus-debt filter: excluded $EXCLUDED piece file(s) lacking ## Yearbook" >&2
if [ -z "$FILES" ]; then
echo "No regions/ or engine/ markdown in scope for this run." >&2
echo "files=" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "files=$FILES" >> "$GITHUB_OUTPUT"
- name: khai encoding + component validators
if: steps.files.outputs.files != ''
run: |
python -m pytest --pyargs \
khai_tests.test_khai_encoding \
khai_tests.components.test_khai_process \
khai_tests.components.test_khai_position \
khai_tests.components.test_khai_piece \
khai_tests.components.test_khai_place \
khai_tests.components.test_khai_persona \
--khai-files="${{ steps.files.outputs.files }}" -v
- name: cultures section structure
if: steps.files.outputs.files != ''
run: |
python -m pytest tests/test_sections.py \
--khai-files="${{ steps.files.outputs.files }}" -v