Skip to content

ci: add static validation pipeline and v1 JSON schemas (Phase 1+1A)#2

Open
arnaudlh wants to merge 4 commits intomainfrom
feat/ci-static-validation-and-schemas
Open

ci: add static validation pipeline and v1 JSON schemas (Phase 1+1A)#2
arnaudlh wants to merge 4 commits intomainfrom
feat/ci-static-validation-and-schemas

Conversation

@arnaudlh
Copy link
Copy Markdown
Owner

@arnaudlh arnaudlh commented May 6, 2026

Implements Phase 1 (static lint pipeline) and Phase 1A (strict JSON schemas) from the broader maximize-E2E-coverage plan. Tracked at Azure#55.

What lands here

Schemas (schemas/git-ape/<artifact>/v1.json)

JSON Schema draft 2020-12, one major.minor per artifact:

  • _defs/v1.json — canonical shared types (deploymentId, azureSubscription, armResourceId, iso8601DateTime, cafAbbreviation, environmentTier, deploymentStatus, softDeletableType)
  • state/v1.json — runtime deployment state (matches website/docs/deployment/state.md)
  • metadata/v1.json — planning-time deployment metadata
  • security-gate/v1.jsoncount form only; the legacy boolean form (criticalPassed: true) is rejected at v1.0
  • requirements/v1.json, cost-estimate/v1.json, policy-recommendations/v1.json
  • plugin/v1.json — validates plugin.json (the chat-agents-plugin manifest)

schemas/README.md documents the registry layout, versioning policy (per-artifact schemaVersion, shared $defs as a release train), strictness rules (additionalProperties: false on top level only, transition window for nested objects), and a known-follow-ups list.

Tooling

  • scripts/validate-schemas.sh — bulk validator. Walks .azure/deployments/**/*.json and tests/fixtures/**/*.json, picks the schema by base filename, surfaces per-file pass/fail. Skips _invalid/ paths (covered by negative bats tests).
  • .yamllint.yml — repo-wide config; advisory in this PR.

CI workflow (.github/workflows/git-ape-ci.yml)

Five parallel jobs, all tools pinned to specific versions:

Job Tool Version Status
lint-shell shellcheck 0.10.0 strict on scripts/+tests/; error-only on .github/ (legacy)
lint-yaml yamllint 1.38.0 advisory
lint-markdown markdownlint-cli 0.45.0 advisory
validate-schemas check-jsonschema 0.37.2 gating
bats-tests bats-core 1.11.1 gating

Existing workflows (git-ape-actionlint.yml, git-ape-docs-check.yml, git-ape-plugin-version-check.yml) are deliberately left untouched.

Tests

  • tests/fixtures/ — valid sample per artifact + two negative samples in _invalid/
  • tests/bash/schema-validation.bats — 13 assertions, including:
    • state.json missing required field → MUST be rejected
    • security-gate.json boolean form → MUST be rejected at v1.0
  • tests/README.md and tests/fixtures/README.md document how to extend

Local verification (all passing)

$ bash scripts/validate-schemas.sh
scanned: 8  skipped: 0  failures: 0

$ bats tests/bash/schema-validation.bats
1..13
ok 1..13

actionlint, yamllint, and shellcheck --severity=style are clean on every file added or modified.

Out of scope (deliberate)

  • state.json/metadata.json emission paths in deploy-stack.sh/deploy-stack.ps1 — those scripts arrive in Leverage Deployment Stacks for idempotent operations Azure/git-ape#44 on upstream main. Phase 2 emitter parity tests are deferred until that lands.
  • ARM template static checks (Checkov, ARM-TTK, PSRule for Azure, MSDO templateanalyzer)
  • Real-Azure sandbox E2E
  • Auto-generated artifact field-reference docs

Acceptance criteria from Azure#55

  • git-ape-ci.yml runs jobs in parallel and gates the PR
  • 8 schema files committed under schemas/git-ape/
  • Shared $defs registry exists at _defs/v1.json (cross-file $ref deduplication is a documented follow-up)
  • scripts/validate-schemas.sh invokable locally and from CI
  • Negative-test fixtures (security-gate boolean form, state missing required field) cause CI to fail
  • plugin.json itself validates against schemas/git-ape/plugin/v1.json
  • All tools pinned to versions
  • tests/fixtures/README.md documents how to add a new fixture

arnaudlh and others added 4 commits May 5, 2026 14:04
Without 'declare -A', SECTION_TITLES=([feat]=...) is parsed as an
indexed array, so bash evaluates the keys as arithmetic expressions.
Under 'set -u' the lookup of unset names like 'feat' fails with
'unbound variable' and the workflow exits 1 before generating release
notes.

Also collapse 'declare -A SECTIONS' + reassignment into a single
'declare -A SECTIONS=(...)' for symmetry with SECTION_TITLES.

Verified locally on bash 5.3.9 (homebrew):
- Original form: 'feat: unbound variable' under set -euo pipefail.
- Fixed form: parses sample 'feat(plugin): ...' commit and emits
  '### Features' with the formatted bullet line.

Repro of the failure: https://github.com/Azure/git-ape/actions/runs/25362438095
On workflow_dispatch with versions already aligned, the prior
'Commit version bump' step is skipped and the tag is never created
locally. The release-notes step then ran 'git log v0.0.1' against a
non-existent ref, silently producing an empty changelog.

Verified locally with act:
  act workflow_dispatch -W .github/workflows/git-ape-release.yml \
    -e event.json -s GITHUB_TOKEN=... \
    -P ubuntu-latest=catthehacker/ubuntu:act-latest

After the fix, the release notes step emits the full conventional-
commit-grouped changelog walking from the first commit through HEAD.
…itles

fix(release): declare SECTION_TITLES as associative array
Introduces a parallel static-validation CI workflow and the first set of
strict JSON Schemas (draft 2020-12) for every artifact Git-Ape emits per
deployment.

Schemas under schemas/git-ape/<artifact>/v1.json:
- _defs/v1.json (canonical shared types)
- state/v1.json
- metadata/v1.json
- security-gate/v1.json (count form only; boolean form rejected at v1.0)
- requirements/v1.json
- cost-estimate/v1.json
- policy-recommendations/v1.json
- plugin/v1.json (validates the chat-agents-plugin manifest at repo root)

Tooling:
- scripts/validate-schemas.sh — bulk validator selecting schema by base
  filename for every JSON under .azure/deployments/ and tests/fixtures/
- .yamllint.yml — repo-wide YAML lint config (advisory in this PR)
- .github/workflows/git-ape-ci.yml — new workflow with five parallel jobs
  (shellcheck, yamllint, markdownlint, validate-schemas, bats) all pinned
  to specific tool versions

Tests:
- tests/fixtures/ — valid samples for every artifact + two negative
  fixtures asserting the migration contract (state.json missing required
  fields; security-gate.json boolean form)
- tests/bash/schema-validation.bats — 13 positive + negative assertions

Phase 2 reduced: bash<->PowerShell emitter parity tests are deferred to
a follow-up PR after Azure#44 (deploy-stack scripts) lands on main.

Existing CI (actionlint, docs-check, plugin-version-check) is intentionally
left in place; this workflow extends rather than duplicates them.

Refs: Azure#55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants