yadflow 2.14.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/bin/yad.mjs +19 -5
- package/cli/artifact-status.mjs +102 -0
- package/cli/doctor.mjs +14 -1
- package/cli/epic-state.mjs +1 -1
- package/cli/gate.mjs +121 -58
- package/cli/manifest.mjs +2 -0
- package/cli/platform.mjs +44 -6
- package/package.json +1 -1
- package/skills/yad-checks/SKILL.md +7 -0
- package/skills/yad-checks/references/check-gates.md +25 -7
- package/skills/yad-checks/templates/checks/ledger-guard.sh +117 -0
- package/skills/yad-checks/templates/checks/verified-commits.sh +9 -1
- package/skills/yad-checks/templates/github/yad-hub-checks.yml +28 -6
- package/skills/yad-checks/templates/gitlab/yad-hub-checks.gitlab-ci.yml +18 -5
- package/skills/yad-hub-bridge/SKILL.md +41 -14
- package/skills/yad-hub-bridge/references/bridge.md +93 -51
- package/skills/yad-hub-bridge/templates/github/yad-gate-sync.yml +85 -35
- package/skills/yad-hub-bridge/templates/gitlab/yad-gate-sync.gitlab-ci.yml +63 -32
- package/skills/yad-pr-template/templates/checks/pr-template.sh +53 -10
- package/skills/yad-pr-template/templates/checks/pr-title.sh +55 -18
- package/skills/yad-review-gate/SKILL.md +12 -10
|
@@ -5,22 +5,39 @@
|
|
|
5
5
|
# period (config.yaml build.pr_title_style: same_as_commit_subject; one task = one PR, the title is
|
|
6
6
|
# the squash-merge subject). Keep <type> in sync with cli/manifest.mjs COMMIT_TYPES.
|
|
7
7
|
# --profile hub — a front-half artifact-review title "review: <artifact> (EP-<slug>)", the shape
|
|
8
|
-
# `yad gate open` creates (cli/gate.mjs).
|
|
8
|
+
# `yad gate open` creates (cli/gate.mjs) — BUT only for review/EP-* head branches. Every other
|
|
9
|
+
# hub PR is a tooling/code change to the hub itself and follows the code convention; pass the
|
|
10
|
+
# head ref via --head so the gate can tell the two apart (a tooling PR has no EP artifact to
|
|
11
|
+
# review). With no --head, the hub profile stays strict (requires the review shape).
|
|
12
|
+
# Branch name is not enough on its own: a non-review head that actually changes front-half
|
|
13
|
+
# artifacts (epics/**) would otherwise slip past the review workflow with a plain code title.
|
|
14
|
+
# Pass the PR's changed paths via --changed <file> (one path per line); when they touch epics/**
|
|
15
|
+
# on a non-review head the gate FAILS — artifact changes must go through a review/EP-* PR.
|
|
9
16
|
# The title is passed as the (single) positional arg; CI injects it from the event payload
|
|
10
17
|
# (GitHub: github.event.pull_request.title; GitLab: $CI_MERGE_REQUEST_TITLE).
|
|
11
18
|
set -euo pipefail
|
|
12
19
|
|
|
13
20
|
PROFILE=code
|
|
21
|
+
HEADREF=""
|
|
22
|
+
CHANGED=""
|
|
14
23
|
ARGS=()
|
|
15
24
|
while [ $# -gt 0 ]; do
|
|
16
25
|
case "$1" in
|
|
17
26
|
--profile) PROFILE="${2:-code}"; shift 2 ;;
|
|
18
27
|
--profile=*) PROFILE="${1#*=}"; shift ;;
|
|
28
|
+
--head) HEADREF="${2:-}"; shift 2 ;;
|
|
29
|
+
--head=*) HEADREF="${1#*=}"; shift ;;
|
|
30
|
+
--changed) CHANGED="${2:-}"; shift 2 ;;
|
|
31
|
+
--changed=*) CHANGED="${1#*=}"; shift ;;
|
|
19
32
|
*) ARGS+=("$1"); shift ;;
|
|
20
33
|
esac
|
|
21
34
|
done
|
|
22
35
|
case "$PROFILE" in code|hub) ;; *) echo "FAIL [pr-title]: unknown --profile '$PROFILE' (code|hub)."; exit 1 ;; esac
|
|
23
36
|
|
|
37
|
+
# True when the PR changes a front-half artifact (anything under epics/**). Reads the --changed list
|
|
38
|
+
# of paths CI computed from the PR diff; with no list (direct caller / test) it reports false.
|
|
39
|
+
artifact_changed() { [ -n "$CHANGED" ] && [ -f "$CHANGED" ] && grep -qE '^epics/' "$CHANGED"; }
|
|
40
|
+
|
|
24
41
|
TITLE="${ARGS[0]:-}"
|
|
25
42
|
if [ -z "$TITLE" ]; then
|
|
26
43
|
echo "FAIL [pr-title]: empty title — pass the PR/MR title as the argument."
|
|
@@ -29,23 +46,43 @@ fi
|
|
|
29
46
|
|
|
30
47
|
TYPES='feat|fix|docs|refactor|test|perf|build|ci|chore|revert'
|
|
31
48
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
# Conventional-Commits subject (optional scope + breaking `!`), no trailing period. Used by the code
|
|
50
|
+
# profile and by hub tooling PRs (any head branch that is not review/EP-*).
|
|
51
|
+
check_code_title() {
|
|
52
|
+
if ! printf '%s' "$TITLE" | grep -qE "^(${TYPES})(\([a-z0-9._-]+\))?!?: .+"; then
|
|
53
|
+
echo "FAIL [pr-title]: '${TITLE}' is not '<type>(<scope>)?!?: <description>' (type one of: ${TYPES//|/, })."
|
|
54
|
+
exit 1
|
|
37
55
|
fi
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
56
|
+
if printf '%s' "$TITLE" | grep -qE '\.$'; then
|
|
57
|
+
echo "FAIL [pr-title]: '${TITLE}' must not end with a period."
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
echo "PASS [pr-title]: '${TITLE}' (profile: ${PROFILE}, tooling/code)"
|
|
61
|
+
exit 0
|
|
62
|
+
}
|
|
41
63
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
if [ "$PROFILE" = hub ]; then
|
|
65
|
+
# review/EP-* head branch (or unknown head ref) => front-half artifact-review PR: 'review: <artifact> (EP-<slug>)'.
|
|
66
|
+
case "$HEADREF" in
|
|
67
|
+
review/EP-*|"")
|
|
68
|
+
if printf '%s' "$TITLE" | grep -qE '^review: .+ \(EP-[a-z0-9-]+\)$'; then
|
|
69
|
+
echo "PASS [pr-title]: '${TITLE}' (profile: hub, artifact-review)"
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
echo "FAIL [pr-title]: '${TITLE}' is not a hub review title 'review: <artifact> (EP-<slug>)'."
|
|
73
|
+
exit 1
|
|
74
|
+
;;
|
|
75
|
+
*)
|
|
76
|
+
# Any other hub PR is a tooling/code change to the hub itself — UNLESS it changes front-half
|
|
77
|
+
# artifacts (epics/**), which must go through a review/EP-* PR. Without this guard a non-review
|
|
78
|
+
# head could carry an artifact change past the front-half review with only a code title.
|
|
79
|
+
if artifact_changed; then
|
|
80
|
+
echo "FAIL [pr-title]: head '${HEADREF}' changes front-half artifacts (epics/**) but is not a review/EP-* branch — artifact changes must go through a review PR."
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
# tooling only — fall through to the code convention.
|
|
84
|
+
;;
|
|
85
|
+
esac
|
|
50
86
|
fi
|
|
51
|
-
|
|
87
|
+
|
|
88
|
+
check_code_title
|
|
@@ -165,21 +165,23 @@ If the predicate **passes**:
|
|
|
165
165
|
now `ready-for-build`, with `test-cases` running in parallel).
|
|
166
166
|
|
|
167
167
|
### PR-driven automation (the `yad gate` CLI)
|
|
168
|
-
When the hub has a platform, the
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
When the hub has a platform, **CI is the sole writer of the ledger**. `yad gate open` opens the review
|
|
169
|
+
PR only; CI (`yad gate ci`) writes the `.sdlc/` + `reviews/` records this skill describes. The skill's
|
|
170
|
+
job is the human half: presenting the artifact, helping the owner address comments, and narrating the
|
|
171
|
+
gate. Local `yad gate sync` is advisory in bridge mode (reads the platform, prints status, writes
|
|
172
|
+
nothing); a human must never commit gate-state files (the `ledger-guard` check rejects it).
|
|
173
173
|
|
|
174
174
|
Under that CLI the gate **advances on merge**: a review PR/MR whose reviewer rule is satisfied, whose
|
|
175
175
|
comment threads are **all resolved**, and which has been **merged** auto-marks the step `done` and
|
|
176
176
|
unblocks the next step. (Until those three hold, the step stays `in_review`.)
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
178
|
+
The flow is **merge-driven** (wired by `yad-hub-bridge` `wire`): during review CI writes nothing — the
|
|
179
|
+
platform PR/MR is the source of truth (native approvals + threads), and CI never touches the review
|
|
180
|
+
branch (so an in-flight approval is never dismissed and required checks never strand). On the human
|
|
181
|
+
**merge** CI re-reads approvals, advances the step, and flips the artifact `status:` on the **default
|
|
182
|
+
branch**. After a merge, `git checkout <default> && git pull` to see it. The predicate and the human
|
|
183
|
+
merge are unchanged — CI never approves and never merges. File-only mode (no platform) keeps the local
|
|
184
|
+
write path.
|
|
183
185
|
|
|
184
186
|
### Hard rules (build plan §1, §5)
|
|
185
187
|
- **The merge click is the human approval act.** A front step advances only when a human merges the
|