feat(doctor): Phase 5 — doctor §11 + test-debt closure (0.8.0) #19
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| name: Lint shell + JSON templates | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: ShellCheck (scripts + bin) | |
| run: | | |
| # Only lint files that have a shebang we recognize. | |
| set -euo pipefail | |
| mapfile -t targets < <( | |
| find scripts bin -type f \( -name "*.sh" -o ! -name "*.*" \) 2>/dev/null \ | |
| | xargs -I {} sh -c 'head -n1 "{}" | grep -q "^#!.*sh" && echo "{}"' \ | |
| | sort -u | |
| ) | |
| if [ "${#targets[@]}" -eq 0 ]; then | |
| echo "No shell scripts found to lint." | |
| exit 0 | |
| fi | |
| printf ' • %s\n' "${targets[@]}" | |
| # Excluded checks (bstack's defensive shell style accepts these): | |
| # SC1091 — don't follow sourced files. | |
| # SC2155 — declare-and-assign masks return code (intentional). | |
| # SC2034 — unused variable. Several scripts intentionally name | |
| # variables that are only used in conditional branches | |
| # shellcheck can't see. Suppressed at the lint gate; | |
| # per-file SC2034 audit is a follow-up. | |
| shellcheck --severity=warning \ | |
| --exclude=SC1091,SC2155,SC2034 \ | |
| "${targets[@]}" | |
| - name: Validate JSON templates | |
| run: | | |
| set -euo pipefail | |
| shopt -s nullglob | |
| fail=0 | |
| for f in assets/templates/*.snippet; do | |
| if ! jq -e . "$f" >/dev/null 2>&1; then | |
| echo "::error file=$f::invalid JSON shape" | |
| fail=1 | |
| else | |
| echo " • $f — valid JSON" | |
| fi | |
| done | |
| exit "$fail" | |
| doctor: | |
| name: bstack doctor (primitive-contract lint) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Run doctor against templates | |
| run: | | |
| set -euo pipefail | |
| mkdir -p .control | |
| cp assets/templates/CLAUDE.md.template ./CLAUDE.md 2>/dev/null || true | |
| cp assets/templates/AGENTS.md.template ./AGENTS.md 2>/dev/null || true | |
| cp assets/templates/policy.yaml.template .control/policy.yaml 2>/dev/null || true | |
| bash scripts/doctor.sh --quiet | |
| tests: | |
| name: tests/*.test.sh | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Run all tests/*.test.sh | |
| # As of v0.8.0 (Phase 5 of substrate completion) the pre-existing | |
| # tests/template_lockstep.test.sh and tests/onboard.test.sh are | |
| # fixed (case-insensitive lockstep assertion + BSTACK_SKIP_SKILLS=1 | |
| # env override for the bootstrap skill-install loop). The full | |
| # `tests/*.test.sh` suite now runs on every PR — no more vetted | |
| # allowlist. | |
| run: | | |
| set -euo pipefail | |
| shopt -s nullglob | |
| fail=0 | |
| for t in tests/*.test.sh; do | |
| echo "" | |
| echo "=== $t ===" | |
| if ! bash "$t"; then | |
| echo "::error file=$t::test failed" | |
| fail=1 | |
| fi | |
| done | |
| exit "$fail" |