T-75UD-release-ci-dist-repo
Status: closed/obsoleted · Impact: medium · Complexity: medium
D-0014’s private-phase channel is a git-pinned dist repo: release CI
builds the publishable tree and pushes it to a private repo consumers
pin as a git dependency (#vX.Y.Z), riding existing git credentials —
no registry, no .npmrc. Today the repo has no CI at all (no
.github/workflows/), so this task creates both the release pipeline
and the channel it publishes to.
Partial progress — the pipeline is drafted.
.github/workflows/release.yml(tag-triggered build → quality roster →sdlc plugin build-artifact→ plain-Node smoke → push tosksizer/sdlc-dist, with aworkflow_dispatchdry_runpath) and the README “Releasing & the dist channel” section (install forms, consumer read-credential, upgrade + release flow) are in place. Remaining — owner steps that can’t be scripted from here: (1)gh repo create sksizer/sdlc-dist --private; (2) add theSDLC_DIST_DEPLOY_KEYActions secret (write deploy-key private half); (3) cutv0.3.0end to end and verify a scratch-machine install (AC-1/-2/-3 in practice). Keptopen/readyuntil the channel is stood up and a real tag is proven.
| Location | Role today |
|---|---|
plugin/lib/services/plugin/ops/ | home of the plugin ops; T-XTGT adds build-artifact here — the op this pipeline runs and ships |
sdlc.yaml | the quality-check roster a release must be green on |
package.json | version source of truth after T-XTGT’s unification; release tags must agree with it |
README.md | no distribution/consumer-install documentation yet |
No .github/workflows/ directory exists; the dist repo
(sksizer/sdlc-dist) does not exist yet.
Proposed
Section titled “Proposed”Pushing tag vX.Y.Z produces, without manual steps: a quality-gated
build, a commit on the private sksizer/sdlc-dist repo whose tree is
the publishable package (package.json at root), tagged vX.Y.Z there
too. A consumer installs with
bun add git+ssh://git@github.com/sksizer/sdlc-dist#vX.Y.Z (or the
https form under npm) and gets exactly what npm pack would have
produced. Install and CI-credential instructions are documented.
Approach
Section titled “Approach”- Create the private
sksizer/sdlc-distrepo (gh repo create sksizer/sdlc-dist --private); seed a README explaining it is a build-artifact mirror — no hand commits, history is release history, source lives insksizer/dev. - Add
.github/workflows/release.yml, triggered onpush: tags: ['v*']: a. Checkout; install Bun (setup action) and Node ≥20 (both runtimes: Bun to run the toolchain, Node for the artifact smoke). b.bun install; assert tag == rootpackage.jsonversion (fail early on mismatch). c. Run the quality-check roster fromsdlc.yaml(the same commands, verbatim). d.sdlc plugin build-artifact --out dist-pkg/. e. Artifact smoke with Bun removed from PATH:node dist-pkg/plugin/cli/sdlc.js --helpand… project doctor --output json. f. Publish: clonesksizer/sdlc-distwith a deploy key (write) from repo secrets; replace its tree withdist-pkg/contents; commitrelease: vX.Y.Z (<source sha>); tagvX.Y.Z; push branch + tag. - Credentials: generate a write deploy key for
sdlc-dist; store the private half as asksizer/devActions secret; document the consumer-side read credential (a PAT or read deploy key — the default per-repo Actions token cannot fetch other private repos). - Document the channel in
README.md: install commands (bun + npm git forms, tag pinning), the consumer-CI credential requirement, and the upgrade flow (bump the pinned ref; lockfile records the commit sha). - Dry-run path:
workflow_dispatchinputdry_run: trueruns a–e and skips f, so the pipeline is testable without publishing. - Cut
v0.3.0end to end and verify a scratch-machine install from the dist repo tag.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
.github/workflows/release.yml | new | tag-driven build → gate → smoke → push-to-dist pipeline with workflow_dispatch dry-run |
README.md | modify | distribution section: install forms, tag pinning, consumer-CI credential, upgrade flow |
docs/planning/decisions/D-0014-cli-primary-npm-distribution.md | modify | note the concrete dist-repo name and workflow file once live (Migration step 6 fulfilled) |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: pushing tag
vX.Y.Z(matchingpackage.json) yields asksizer/sdlc-distcommit taggedvX.Y.Zwhose root is the publishable package; a tag/version mismatch fails the workflow before building. - AC-2: in a scratch project,
bun add git+ssh://git@github.com/sksizer/sdlc-dist#vX.Y.Zinstalls;bunx sdlc --helpand — with Bun absent —npx sdlc --helpboth exit 0. - AC-3: the workflow’s smoke step runs the staged CLI under Node with Bun stripped from PATH and fails the release when it exits non-zero.
- AC-4:
workflow_dispatchwithdry_run: truecompletes without touchingsdlc-dist. - AC-5: README documents both install forms and the consumer-CI read-credential requirement.
Out of scope
Section titled “Out of scope”- The build op itself (
T-XTGT). - Public npm publishing — the recorded public-phase channel, not now.
- Renovate/automation for consumer-side version bumps — consumers pin refs manually during the private phase.
- General-purpose CI for PRs (quality checks on every push) — worth doing, separate concern; this task ships the release workflow only.
Dependencies
Section titled “Dependencies”T-XTGT(hard, independs_on): the pipeline is a thin shell aroundsdlc plugin build-artifact.T-WGV4transitively, for the Node smoke to pass.
Discovery context
Section titled “Discovery context”- D-0014 Migration step 6 and the Registry-while-private decision (git-pinned dist repo chosen over GitHub Packages; PR #571 review thread).
Depends on
Section titled “Depends on”T-XTGT-publish-build-and-package-reshape