fix(framework): validate milestone title before provider reads (#1841)
ci/woodpecker/pr/ci Pipeline was successful

Refuse missing or empty creation titles before provider detection while preserving title-free listing. Prove zero-provider usage failures and unchanged synthetic list and creation payload behavior.

Co-Authored-By: GPT-6.1-Sol (Codex) <[email protected]>
This commit is contained in:
code-infra-01andGPT-6.1-Sol committed 2026-11-04 19:41:12 -06:00
1 parent ade6f3d26f
commit de99f7263f
2 files changed
+45 -4

No files matched your search

@@ -80,6 +80,12 @@ while [[ $# -gt 0 ]]; do
esac
done
# Creation usage errors must stop before provider detection or credentials.
# Listing does not require a title.
if [[ "$LIST_ONLY" != true && -z "$TITLE" ]]; then
usage_error "Title is required (-t) for creating milestones"
fi
PLATFORM=$(detect_platform)
if [[ "$LIST_ONLY" == true ]]; then
@@ -106,10 +112,6 @@ if [[ "$LIST_ONLY" == true ]]; then
exit 0
fi
if [[ -z "$TITLE" ]]; then
usage_error "Title is required (-t) for creating milestones"
fi
case "$PLATFORM" in
github)
# GitHub uses the API for milestone creation
@@ -90,6 +90,7 @@ expect_stderr "[Uu]nknown option" "unknown option names itself on stderr"
# 3. Missing required PR number: rc 2, stderr.
expect_rc 2 "missing -t exits 2"
expect_rc 2 "empty title exits 2" -t ""
expect_stderr "Title is required" "missing -t message on stderr"
@@ -129,4 +130,42 @@ done
# the arm above proves only parse acceptance and non-usage classification.
# Parser-failure arms (1-4) remain zero-contact (asserted at 4b).
# Positive provider paths remain real wrapper dispatch with fixture-only gh.
# --list remains legal without a title; ordinary creation retains its JSON body.
GH_REPO="$WORK_DIR/github-fixture"
mkdir -p "$GH_REPO"
git -C "$GH_REPO" init -q
git -C "$GH_REPO" remote add origin https://github.com/fixture/widgets.git
: > "$PROBE_LOG"
PAYLOAD_LOG="$WORK_DIR/payload.json"
export PAYLOAD_LOG
cat > "$BIN_DIR/gh" <<STUB
#!/usr/bin/env bash
echo "gh \$*" >> "$PROBE_LOG"
if [[ "\$*" == "api repos/:owner/:repo/milestones --jq "* ]]; then
printf '7\tfixture-list\topen\t0/0\n'
exit 0
fi
if [[ "\$*" == "api repos/:owner/:repo/milestones --method POST --input -" ]]; then
cat > "\$PAYLOAD_LOG"
printf '{"id":8}\n'
exit 0
fi
exit 99
STUB
chmod +x "$BIN_DIR/gh"
(
cd "$GH_REPO"
PATH="$BIN_DIR:$PATH" "$SCRIPT_DIR/milestone-create.sh" --list
) > "$OUT_FILE" 2> "$ERR_FILE" || fail "list without title failed"
grep -q 'fixture-list' "$OUT_FILE" || fail "list result missing"
(
cd "$GH_REPO"
PATH="$BIN_DIR:$PATH" "$SCRIPT_DIR/milestone-create.sh" -t 'fixture "title"' -d description --due 2030-01-02
) > "$OUT_FILE" 2> "$ERR_FILE" || fail "valid creation failed"
grep -q 'created successfully' "$OUT_FILE" || fail "creation success missing"
jq -e '.title == "fixture \"title\"" and .description == "description" and .due_on == "2030-01-02T00:00:00Z"' "$PAYLOAD_LOG" >/dev/null || fail "creation payload changed"
[[ "$(wc -l < "$PROBE_LOG")" -eq 2 ]] || fail "unexpected positive-path provider contact"
[[ "$(grep -c '^gh api .* --method POST --input -$' "$PROBE_LOG")" -eq 1 ]] || fail "creation did not invoke expected provider method"
echo "milestone-create.sh usage-contract regression passed (R1/R4)"