Skip to content

feat(ci): Phase 0 D1 — publish shape schema + portable validator - #274

Merged
ChrisonSimtian merged 1 commit into
mainfrom
feat/phase0-publish-validator
Jul 20, 2026
Merged

feat(ci): Phase 0 D1 — publish shape schema + portable validator#274
ChrisonSimtian merged 1 commit into
mainfrom
feat/phase0-publish-validator

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

Phase 0, Deliverable 1 of the stack-extraction epic (#272) — per ADR-0008. This is the foundation everything else depends on.

What

Publishes the shape contract and a portable validator so standalone Homelab.Stacks.* repos can validate their shapes in CI without the full engine build.

  • build/Build.csPublishValidator target. Publishes the C# engine as a self-contained linux-x64 single-file binary with shape.schema.json beside it (mirrors the existing PublishPowerOrchestrator). Same engine → ADR-0001's one validator, made portable: no .NET SDK, no private feeds, no self-hosted runner needed to run it.
  • .github/workflows/publish-schema.yml. Builds the validator on the self-hosted runner (needs the cross-org package feeds, exactly like validate-shapes.yml), then publishes two release assets on ubuntu-latest:
    • shape.schema.json (the contract, for humans/tools)
    • homelab-validate-linux-x64.tar.gz (the portable validator)
  • .gitignorepublish/ + dist/.

Versioning

Tracks the shapes' apiVersion: homelab/v1:

  • schema-v1 — a moving channel refreshed on every relevant main push. Consumers pin @schema-v1 (breaking contract change → schema-v2).
  • workflow_dispatch version — optional immutable point release (e.g. schema-v1.0.0).

Why this shape

The engine's validate is a pure, offline command (only converge touches the cluster) and the csproj already copies the schema beside the binary, resolved from AppContext.BaseDirectory — so a self-contained publish is self-sufficient. Reusing the engine (rather than a second JSON-Schema checker) keeps the one-validator principle from ADR-0001.

Validation

  • Workflow YAML + Build.cs target verified locally; the self-contained publish + release runs in CI on merge (can't exercise GH Actions locally).
  • Next: D2 (opt-in reusable validate workflow that consumes @schema-v1), then D3 (submodule auto-bump PR bot).

Refs #272.

🤖 Generated with Claude Code

…-0008)

Publishes the shape contract and a portable validator so standalone
Homelab.Stacks.* repos can validate their own shapes in CI — the first
Phase 0 deliverable that unlocks stack extraction (#272).

- build: new Fallout PublishValidator target — publishes the C# engine as a
  self-contained linux-x64 single-file binary with shape.schema.json beside it
  (mirrors PublishPowerOrchestrator). Same engine, ADR-0001's one validator,
  made portable: runs with no .NET SDK / private feeds / self-hosted runner.
- ci: publish-schema.yml — builds the validator on the self-hosted runner
  (needs the cross-org package feeds, like validate-shapes.yml), then releases
  shape.schema.json + homelab-validate-linux-x64.tar.gz on ubuntu.
  Versioning tracks apiVersion homelab/v1: a moving `schema-v1` channel
  (consumers pin @schema-v1) refreshed on relevant main pushes, plus an
  optional immutable point release via workflow_dispatch.
- gitignore: publish/ + dist/ (self-contained output + packaged assets).

Refs #272.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian
ChrisonSimtian merged commit 8413dcf into main Jul 20, 2026
6 checks passed
@ChrisonSimtian
ChrisonSimtian deleted the feat/phase0-publish-validator branch July 20, 2026 05:51
ChrisonSimtian added a commit that referenced this pull request Jul 20, 2026
**Phase 0, Deliverable 2** of the stack-extraction epic (#272), per
[ADR-0008](docs/adr/ADR-0008-stack-extraction-meta-repo.md). Builds on
D1 (#274), whose `schema-v1` release is now live.

## What

`.github/workflows/_validate-shapes.yml` — a **reusable, opt-in**
workflow a standalone `Homelab.Stacks.*` repo calls from its own PR
pipeline. It downloads the pinned **portable validator** from the
Homelab `schema-v1` release and runs the **same C# engine `validate`**
over the repo's shapes on `ubuntu-latest` — no .NET SDK, no private
feeds, no self-hosted runner.

Caller example (added to each stack repo during Phase 1 extraction):
```yaml
jobs:
  shapes:
    uses: Chrison-dev/Homelab/.github/workflows/_validate-shapes.yml@main
    secrets:
      schema-token: ${{ secrets.SCHEMA_RO_PAT }}   # contents:read on Chrison-dev/Homelab
```

## Correctness notes

- The engine's `validate` has an **`apiVersion: homelab/v1` gate**
(`ShapeValidator.IsHomelabShape`), so it skips
`.github/workflows/*.yml`, `compose.yml`, `.env`, etc. — pointing it at
the repo root is safe.
- `validate <dir>` recurses (as proven by the superproject's `validate
stacks/`), so shapes at the repo root **and** in service subdirs are all
covered.
- The tarball ships `homelab-infra` + `schema/shape.schema.json`; the
engine resolves the schema from `AppContext.BaseDirectory` (verified
with a `test -f`).

## Design

This is the **lightweight, early-feedback mirror**; the superproject's
`validate-shapes.yml` (`./build.sh ValidateShapes`) remains the
full-fidelity gate. One validator (ADR-0001), made portable — not a
second implementation.

Also adds a `#275` breadcrumb to `publish-schema.yml` (the hand-rolled
release steps are interim pending native Fallout publish).

## Note
No stack repo consumes this yet — the first caller lands with the
SmartHome extraction (Phase 1). Requires an org/repo secret
`SCHEMA_RO_PAT` on consumers.

Refs #272.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisonSimtian added a commit that referenced this pull request Jul 20, 2026
**Phase 0, Deliverable 3** (final) of the stack-extraction epic (#272),
per [ADR-0008](docs/adr/ADR-0008-stack-extraction-meta-repo.md).

## What

`.github/workflows/bump-stack-submodules.yml` — a weekly (+
`workflow_dispatch`) bot that advances every `stacks/*` submodule
pointer to its remote default-branch HEAD and opens **one** PR with the
bumps.

- Turns **submodule drift into a reviewable PR** — the exact
stale-pointer trap we hit by hand this session.
- Removes the manual **"second PR"** after a stack repo merges its own
change.
- The bump PR touches `stacks/**`, so **`validate-shapes.yml` gates**
the newly-pinned shapes in the superproject before merge.

## Tokens & idempotency

- `SUBMODULES_RO_PAT` fetches the private `Homelab.Stacks.*` repos
(`--remote`); the default `GITHUB_TOKEN` (contents + pull-requests
write) pushes the branch + opens the PR.
- Fixed `automation/bump-stack-submodules` branch → one open PR,
force-updated each run.

## Phase 0 status — complete
| | Deliverable | PR |
|---|---|---|
| D1 | Schema + portable validator | #274 ✅ merged |
| D2 | Opt-in reusable validate action | #276 |
| D3 | Submodule auto-bump bot | this |

With these merged, Phase 0 is done and stack extraction (SmartHome,
BuildLab — Phase 1) is unblocked. Also filed #275 (move the interim
hand-rolled release to native Fallout publish).

Refs #272.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant