Skip to content

chore(gds): add canonical repository anchor and projections (#22) #264

chore(gds): add canonical repository anchor and projections (#22)

chore(gds): add canonical repository anchor and projections (#22) #264

Workflow file for this run

name: Validate rldyour-opencode
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch: {}
# Least-privilege token (OSSF Scorecard "Token-Permissions" check).
# Validation jobs only need read access to the repository contents.
permissions:
contents: read
# Serialize parallel CI runs on the same ref. Stale PR pushes cancel
# in-flight runs to free runner minutes for the latest revision.
concurrency:
group: validate-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
validate:
strategy:
# Heavy validation remains Ubuntu-only; cross-platform.yml provides
# standard public Ubuntu/Windows/macOS smoke coverage.
fail-fast: false
matrix:
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 15
steps:
# Actions pinned to commit SHA (supply-chain hardening — defends against
# tag hijack on the action repository). Update SHAs in lockstep when
# bumping the major version; verify via `gh api repos/actions/<name>/git/refs/tags/<tag>`.
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Install pytest + PyYAML + jsonschema + referencing (pinned)
# `referencing` is a transitive dependency of jsonschema 4.x; pinning
# it explicitly insulates the validator from a future PyPI resolver
# change that drops the transitive include (integration-review F-1).
run: python3 -m pip install --upgrade pip "pytest==9.1.1" "PyYAML==6.0.3" "jsonschema==4.26.0" "referencing==0.37.0"
- name: Run repo validator (opencode.json + skill/agent/command frontmatter + VERSION)
run: bash scripts/validate_config.sh
- name: Validate opencode.json against vendored JSON Schema (v1.17.18, offline)
# Audit P0-2: schema validator resolves external $refs through a
# vendored Registry (references/models.dev-model-schema.json), so
# this gate never requires network reachability.
run: python3 scripts/validate_opencode_schema.py
- name: Verify baseline consistency (docs/package/lock/workflows on one pin)
# Audit P0-1: hard-fail on plugin SDK / CLI / Bun / pytest pin drift.
run: python3 scripts/validate_opencode_baseline.py
- name: Validate MCP profile graph (mcp-profiles.json + skill.requires_mcp)
# Audit P1-3: every MCP server belongs to exactly one profile and
# every skill.requires_mcp resolves to a declared server.
run: python3 scripts/validate_mcp_profiles.py
- name: Verify skills index is in sync with SKILL.md files
run: python3 scripts/generate_skills_index.py --check --strict
- name: Verify commands index is in sync with command .md files
run: python3 scripts/generate_commands_index.py --check --strict
- name: Verify plugins index is in sync with plugin .ts files
run: python3 scripts/generate_plugins_index.py --check --strict
- name: Verify plugin hook contract
run: python3 scripts/check_plugin_hooks.py
- name: Validate rldyour adapter contract
run: python3 scripts/validate_contract.py
- name: MCP smoke (static — parse only, no spawn, no network)
# Audit P1-4: PR runs always validate the MCP roster statically;
# local-launch + remote-head probes live in dependency-check.yml.
run: python3 scripts/smoke_mcp_capabilities.py --mode static --json
- name: Doctor (Python core, JSON envelope, --total-timeout 30)
# Audit P0-3: deterministic doctor with per-check + wall-clock
# timeouts. Soft-fail (continue-on-error) so a single doctor regression
# never blocks merge, but the JSON envelope is published for triage.
continue-on-error: true
run: python3 scripts/doctor_opencode.py --format json --total-timeout 30 | tee doctor.json
- name: Run validator unit tests
run: python3 -m pytest scripts/tests/ -v
- name: Report project file count
run: |
total=$(find . -type f \( -name '*.md' -o -name '*.json' -o -name '*.yml' -o -name '*.yaml' -o -name '*.sh' -o -name '*.ts' -o -name '*.py' -o -name 'VERSION' -o -name 'LICENSE' -o -name '.gitignore' \) ! -path './.git/*' ! -path './.github/*' | wc -l | tr -d ' ')
echo "Total project files: $total"
shell-strict-mode:
# Tiny linter that asserts every scripts/*.sh begins with the env-bash
# shebang and `set -euo pipefail`.
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- name: Verify shell strictness contract
run: |
python3 - <<'PY'
from pathlib import Path
bad = []
for p in sorted(Path("scripts").glob("*.sh")):
text = p.read_text(encoding="utf-8")
if not text.startswith("#!/usr/bin/env bash"):
bad.append(f"{p}: missing #!/usr/bin/env bash shebang")
if "set -euo pipefail" not in text:
bad.append(f"{p}: missing `set -euo pipefail`")
if bad:
for line in bad:
print("[ERR]", line)
raise SystemExit(1)
print("[OK] all scripts/*.sh start with env-bash and enable strict mode")
PY