From 497f11f091d3cd8d0fe66ebd97ae9d7a5c909cf8 Mon Sep 17 00:00:00 2001 From: Waren Gonzaga Date: Tue, 6 Oct 2026 19:24:27 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20setup:=20restore=20def?= =?UTF-8?q?ault=20development=20package=20builds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-flow.yml | 6 +++--- AGENTS.md | 4 ++-- CONTRIBUTING.md | 2 +- README.md | 6 ++++-- docs/RELEASING.md | 36 ++++++++++++++++++++------------ 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-flow.yml b/.github/workflows/build-flow.yml index b018bfa..281d0cf 100644 --- a/.github/workflows/build-flow.yml +++ b/.github/workflows/build-flow.yml @@ -41,12 +41,12 @@ jobs: package-manager: bun release-package-manager: bun - # Only an eligible main push may publish packages and a GitHub Release. - publish-dev-artifacts: false + # Use Build Flow's default dev publishing; PR/manual runs validate only. publish-pr-artifacts: false publish-manual-artifacts: false # The pinned workflow gates publication on CI/security and requires both # registries plus successful package-job completion before GitHub Release. - package-publish-enabled: true + # The pinned policy also treats manual runs on dev as dev events. + package-publish-enabled: ${{ github.event_name == 'push' }} release-create: true diff --git a/AGENTS.md b/AGENTS.md index 57bc2cc..c818de6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -80,7 +80,7 @@ with: release-package-manager: bun ``` -The caller is [.github/workflows/build-flow.yml](.github/workflows/build-flow.yml). It pins released Build Flow v1.0.0 at immutable commit `f8263c388160a62f4a0e72ed888e56c8e9159469`. The package primitive is the released v2.3.0. Do not claim OIDC is active from an action release or a validation run alone. Package publication and GitHub Release creation are enabled for eligible pushes to `main`; dev, PR, and manual artifact publication are disabled. Promoting a PR to `main` can publish a release, so require explicit merge/release authorization and follow [docs/RELEASING.md](docs/RELEASING.md). +The caller is [.github/workflows/build-flow.yml](.github/workflows/build-flow.yml). It pins released Build Flow v1.0.0 at immutable commit `f8263c388160a62f4a0e72ed888e56c8e9159469`. The package primitive is the released v2.3.0. Do not claim OIDC is active from an action release or a validation run alone. Omit `publish-dev-artifacts` to inherit Build Flow's `true` default: eligible `dev` pushes publish `-dev.` packages with the `dev` dist-tag to both registries. Development builds are the project standard; do not disable them without an explicit request. Eligible `main` pushes publish regular packages and a GitHub Release; PR and manual artifact publication remain disabled. Merging into `dev` or `main` can publish packages, so honor the authorized merge/release scope and follow [docs/RELEASING.md](docs/RELEASING.md). Use explicit Bun install/lint/typecheck/test/coverage/build commands supported by the package. The inspected `node-bun` defaults contain npm fallbacks; a failed Bun check must not turn into a successful fallback. Keep required security checks and run the Node package smoke check under each configured Node matrix version as part of the build gate. Do not claim that a parallel CodeQL job gates release unless its dependencies enforce that. @@ -88,7 +88,7 @@ Use one compatible package identity/version for both registries: `@wgtechlabs/md The first npm publication needs a one-time bootstrap if the package is absent. Use the preserved validated `0.1.0` tarball tied to the existing `v0.1.0` tag at finalized commit `3975075b4dee44806012e71d80e858ddcf2b39a9`; follow the verification and maintainer-authentication procedure in [docs/RELEASING.md](docs/RELEASING.md). Never rewrite the tag, duplicate an existing registry version, or blindly rerun a partial publication. Future eligible releases use automatic OIDC after the trusted publisher and workflow adoption are verified. -Required sequencing: validate source → finalize release source/version → build package → confirm successful publication to BOTH registries → publish GitHub Release. Partial registry publication is incomplete and must not unlock release. Do not silently change existing primitive defaults; document consumer policy overrides such as non-main artifact publishing. +Required sequencing on `main`: validate source → finalize release source/version → build package → confirm successful publication to BOTH registries → publish GitHub Release. Development builds validate and publish from the triggering commit without release finalization or a GitHub Release. Partial registry publication is incomplete and must not unlock release. Do not silently change existing primitive defaults; document consumer policy overrides such as non-main artifact publishing. ### Release gate contract diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fc6f507..513ef41 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,4 +15,4 @@ Use Clean Commit messages: ` : ` or ` Labels are managed through [GHLT](https://github.com/warengonzaga/github-labels-template). Routine template updates use `ghlt apply --repo wgtechlabs/mdd-engine`; a destructive `migrate` requires explicit authorization. The initial migration has already been completed. -Do not publish packages or create releases from ordinary feature work. Follow [the release prerequisites](docs/RELEASING.md); eligible pushes to `main` publish to npm and GitHub Packages before creating a GitHub Release. +Follow [the release prerequisites](docs/RELEASING.md): eligible pushes to `dev` automatically publish development packages with the `dev` dist-tag to npm and GitHub Packages. Eligible pushes to `main` publish regular packages before creating a GitHub Release. Feature branches and PRs do not publish packages. diff --git a/README.md b/README.md index 1f478c8..b176aae 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The headless Markdown documentation compiler behind mdd. Give it a local project Built with TypeScript and Bun. Runs on Node.js 22, 24, and 26 without Bun. The default is the latest Node LTS, currently pinned to **24.21.0**. -> Initial implementation. Publishing to npm and GitHub Packages is configured for eligible pushes to `main`. Verify the first release before using registry installation instructions. See [releasing](docs/RELEASING.md). +> Build Flow is configured to publish development packages from `dev` with the `dev` dist-tag and regular releases from `main` to npm and GitHub Packages. See [releasing](docs/RELEASING.md). ## A documentation project @@ -38,7 +38,9 @@ All settings are optional. Custom paths are relative to `mdd/config.json` and mu ## Compile without a website -After installing a locally packed copy of `@wgtechlabs/mdd-engine` in your Node project: +Install the regular package with `bun add @wgtechlabs/mdd-engine`. Once the first development build is published, use `bun add @wgtechlabs/mdd-engine@dev` to try the development version. You can also install a locally packed copy. + +In your Node project: ```js import { compileProject } from '@wgtechlabs/mdd-engine'; diff --git a/docs/RELEASING.md b/docs/RELEASING.md index d8c6c7b..2ade5a0 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -1,20 +1,30 @@ # Releasing mdd-engine -## Automatic publication on main +## Automatic publication channels -[Build Flow](../.github/workflows/build-flow.yml) enables package publication and GitHub Release creation for eligible pushes to `main`. It publishes `@wgtechlabs/mdd-engine` to both npm (`registry.npmjs.org`) and GitHub Packages (`npm.pkg.github.com`). This package does not publish a container image to GHCR. +[Build Flow](../.github/workflows/build-flow.yml) enables development package publication from `dev` and regular package publication with a GitHub Release from `main`. It publishes `@wgtechlabs/mdd-engine` to both npm (`registry.npmjs.org`) and GitHub Packages (`npm.pkg.github.com`). This package does not publish a container image to GHCR. The workflow pins released [Build Flow v1.0.0](https://github.com/wgtechlabs/build-flow-action/releases/tag/v1.0.0) at immutable commit [`f8263c388160a62f4a0e72ed888e56c8e9159469`](https://github.com/wgtechlabs/build-flow-action/commit/f8263c388160a62f4a0e72ed888e56c8e9159469). It uses the released [Package Build Flow v2.3.0](https://github.com/wgtechlabs/package-build-flow-action/releases/tag/v2.3.0). Workflow validation does not prove npm trust configuration or publication. -PRs, pushes to `dev`, and manual runs validate changes without publishing artifacts. Promoting this configuration to `main` enables the release path. Use a regular merge commit for the `dev` → `main` promotion and obtain explicit merge/release authorization. +Development builds are standard: the caller omits `publish-dev-artifacts` to inherit Build Flow's `true` default. PR and manual publication are explicitly disabled. The caller also requires a `push` event for `package-publish-enabled`, because the pinned orchestrator classifies manual runs on `dev` as development events too. + +| Trigger | Package version / dist-tag | GitHub Release | +|---|---|---| +| Eligible push to `dev` | `-dev.` / `dev` | None | +| Eligible push to `main` | Planned regular version / `latest` | After both registries succeed | +| Pull request or manual run | Validation only | None | + +For example, base version `0.1.0` produces `0.1.0-dev.`. After the first successful development publication, install it with `bun add @wgtechlabs/mdd-engine@dev`. Development publication does not move `latest`. Commit-type filtering is disabled by default, so setup or documentation changes are eligible too; the existing bot-actor detection can still suppress publication. + +Merging into `dev` can publish a development package. Use a regular merge commit for the `dev` → `main` promotion, which can publish a regular release. Both operations must stay within the authorized merge/release scope. ## Required sequence 1. CI runs the Bun checks and packed-package smoke check on Node 22, 24, and 26. Dependency auditing and Gitleaks must pass. 2. Enabled CodeQL analysis must succeed before source finalization or publication. -3. Build Flow finalizes the planned version, source commit, changelog, and tag once. -4. The package job checks out that exact finalized commit, builds the package, and publishes to both registries. -5. Both registry results must report success and the complete package job must succeed before Build Flow creates the GitHub Release. +3. On `main`, Build Flow finalizes the planned version, source commit, changelog, and tag once. Development builds skip release finalization and use the triggering commit. +4. The package job checks out that source commit, builds the package with the appropriate version/dist-tag, and publishes to both registries. +5. For `main`, both registry results must report success and the complete package job must succeed before Build Flow creates the GitHub Release. Development builds do not create a GitHub Release. The package primitive's `artifact-published` output means at least one registry published. Build Flow checks complete publication separately; the aggregate flag alone is insufficient. Failure of either registry, a later package step, or required security analysis must prevent the GitHub Release. Preserve these guarantees when upgrading the workflow pin. @@ -45,7 +55,7 @@ Trust the calling workflow in this repository, even though reusable Build Flow w After setup, eligible future releases publish automatically without an npm publish token or a per-version promotion step. Saving the trusted publisher does not verify it; confirm a successful OIDC publication before considering migration complete. -Create the trusted-publisher configuration shortly before an authorized promotion to `main`: it must complete its first successful publish within **48 hours of creation**. That successful publish validates the configuration and removes its expiry. If it expires before publication, recreate it to start a new 48-hour window; ordinary edits do not reset the deadline. Changing the repository or project identity requires a new trust relationship and validation window. See [npm's validation-window announcement](https://github.blog/changelog/2026-10-02-unvalidated-npm-trusted-publishing-configurations-now-expire/). The deadline does not replace the bootstrap, merge-authorization, or release-verification requirements below. +The same trusted publisher supports both `dev` and `main` through `build-flow.yml`. Create the configuration shortly before an authorized publication: it must complete its first successful publish within **48 hours of creation**. That successful publish validates the configuration and removes its expiry. If it expires before publication, recreate it to start a new 48-hour window; ordinary edits do not reset the deadline. Changing the repository or project identity requires a new trust relationship and validation window. See [npm's validation-window announcement](https://github.blog/changelog/2026-10-02-unvalidated-npm-trusted-publishing-configurations-now-expire/). The deadline does not replace the bootstrap, merge-authorization, or release-verification requirements below. ## Bootstrap the first npm version @@ -57,7 +67,7 @@ Verify the npm result, configure the trusted publisher, and complete the missing ## Verify a release -After the main workflow completes, verify the actual version in both registries, package contents and integrity, GitHub package visibility, and the GitHub Release tag/commit. GitHub Packages may initially be private; confirm the intended public visibility. Successful validation or an accepted workflow run does not prove publication. +After a `dev` or `main` workflow completes, verify the actual version and dist-tag in both registries, package contents and integrity, and GitHub package visibility. For a regular release from `main`, also verify the GitHub Release tag/commit. Development builds must update `dev` without moving `latest`. GitHub Packages may initially be private; confirm the intended public visibility. Successful validation or an accepted workflow run does not prove publication. The packed package must contain runtime JavaScript, TypeScript declarations, README, and LICENSE, while excluding tests, credentials, caches, and development files. Before the first release or a compatibility change, verify current Node 22/24/26 and the lowest version claimed by `engines.node`. @@ -65,13 +75,13 @@ The packed package must contain runtime JavaScript, TypeScript declarations, REA Registry publication is not atomic. If one registry succeeds and the other fails, the GitHub Release must remain unpublished. Do not delete the published version or blindly rerun the whole workflow: the primitive attempts both registries again and does not treat an existing version as a successful retry. -1. Record the finalized tag/commit, exact package version, successful registry, and failed job logs. Correct the failed registry's access issue: npm trusted-publisher identity/OIDC permissions (recreate an expired configuration) or GitHub package permissions, as applicable. -2. Retrieve the published tarball from the successful registry and verify its identity, version, metadata, integrity, and contents against the finalized source. Preserve those package bytes for recovery. -3. With explicit publication authorization, publish that verified tarball only to the missing registry using authentication accepted by that registry. Do not rebuild a different artifact, change the released version, or rewrite the finalized tag. -4. Verify the same version and package contents in both registries and all required checks on the finalized source. Only then create the GitHub Release for the existing verified tag with explicit release authorization. +1. Record the source commit, finalized tag if applicable, exact package version/dist-tag, successful registry, and failed job logs. Correct the failed registry's access issue: npm trusted-publisher identity/OIDC permissions (recreate an expired configuration) or GitHub package permissions, as applicable. +2. Retrieve the published tarball from the successful registry and verify its identity, version, metadata, integrity, and contents against that source. Preserve those package bytes for recovery. +3. With explicit publication authorization, publish that verified tarball only to the missing registry using authentication accepted by that registry and the recorded dist-tag. For development recovery, explicitly use `--tag dev` so the upload cannot move `latest`. Do not rebuild a different artifact, change the released version, or rewrite the finalized tag. +4. Verify the same version, dist-tag, and package contents in both registries and all required checks on that source. For a regular release from `main`, only then create the GitHub Release for the existing verified tag with explicit release authorization. Development package recovery does not create a GitHub Release. This is a manual recovery procedure, not automatic retry support. No live partial-publication recovery has been exercised for mdd-engine. ## Normal delivery -Work on a short-lived branch from `dev`, squash its PR into `dev`, and promote `dev` to `main` through a regular merge commit with a meaningful `🚀 release:` title. See [AGENTS.md](../AGENTS.md) and [CONTRIBUTING.md](../CONTRIBUTING.md). +Work on a short-lived branch from `dev` and squash its PR into `dev` to enable an eligible development package build. Promote `dev` to `main` through a regular merge commit with a meaningful `🚀 release:` title for a regular release. See [AGENTS.md](../AGENTS.md) and [CONTRIBUTING.md](../CONTRIBUTING.md). From e9dc270f546248295cdede674da5cb0b44b69c9c Mon Sep 17 00:00:00 2001 From: Waren Gonzaga Date: Tue, 6 Oct 2026 19:58:37 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20setup:=20inherit=20def?= =?UTF-8?q?ault=20package=20publishing=20channels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-flow.yml | 19 ++------------ AGENTS.md | 14 +++------- CONTRIBUTING.md | 2 +- README.md | 4 +-- docs/RELEASING.md | 45 +++++++++++++++++++------------- 5 files changed, 36 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build-flow.yml b/.github/workflows/build-flow.yml index 281d0cf..1fe2ee8 100644 --- a/.github/workflows/build-flow.yml +++ b/.github/workflows/build-flow.yml @@ -21,10 +21,9 @@ jobs: uses: wgtechlabs/build-flow-action/.github/workflows/app.yml@f8263c388160a62f4a0e72ed888e56c8e9159469 # v1.0.0 secrets: inherit with: - ci-profile: node-bun + # The Bun lockfile selects the default node-bun profile/package manager. # JavaScript/TypeScript CodeQL analyzes source without a compiler build. codeql-build-mode: none - ci-runtime-version: '24.21.0' ci-matrix-versions: '["22","24","26"]' # setup-bun reads packageManager: bun@1.3.10 from package.json. ci-setup-command: test "$(bun --version)" = '1.3.10' @@ -35,18 +34,4 @@ jobs: ci-coverage-command: bun run coverage ci-build-command: bun run build && bun run smoke && bun audit enable-package: true - enable-release: true - package-registry: both - package-npm-auth-method: oidc - package-manager: bun - release-package-manager: bun - - # Use Build Flow's default dev publishing; PR/manual runs validate only. - publish-pr-artifacts: false - publish-manual-artifacts: false - - # The pinned workflow gates publication on CI/security and requires both - # registries plus successful package-job completion before GitHub Release. - # The pinned policy also treats manual runs on dev as dev events. - package-publish-enabled: ${{ github.event_name == 'push' }} - release-create: true + # Inherit dev/PR/manual publishing, both registries, npm OIDC, and releases. diff --git a/AGENTS.md b/AGENTS.md index c818de6..653008e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,29 +66,23 @@ Use GHLT for authorized Clean Labels template setup. Preserve existing labels; a ## Build, package, and release policy -Use `wgtechlabs/build-flow-action` reusable workflows rather than inventing a new release pipeline. Package and release flows must be enabled for this repository, with both npm and GitHub Packages selected: +Use `wgtechlabs/build-flow-action` reusable workflows rather than inventing a new release pipeline. Enable the package flow explicitly; inherit the pinned defaults for releases, both npm and GitHub Packages, OIDC, and development/PR/manual publication. Keep project-specific validation inputs in the caller: ```yaml with: - ci-profile: node-bun ci-matrix-versions: '["22","24","26"]' enable-package: true - enable-release: true - package-registry: both - package-npm-auth-method: oidc - package-manager: bun - release-package-manager: bun ``` -The caller is [.github/workflows/build-flow.yml](.github/workflows/build-flow.yml). It pins released Build Flow v1.0.0 at immutable commit `f8263c388160a62f4a0e72ed888e56c8e9159469`. The package primitive is the released v2.3.0. Do not claim OIDC is active from an action release or a validation run alone. Omit `publish-dev-artifacts` to inherit Build Flow's `true` default: eligible `dev` pushes publish `-dev.` packages with the `dev` dist-tag to both registries. Development builds are the project standard; do not disable them without an explicit request. Eligible `main` pushes publish regular packages and a GitHub Release; PR and manual artifact publication remain disabled. Merging into `dev` or `main` can publish packages, so honor the authorized merge/release scope and follow [docs/RELEASING.md](docs/RELEASING.md). +The caller is [.github/workflows/build-flow.yml](.github/workflows/build-flow.yml). It pins released Build Flow v1.0.0 at immutable commit `f8263c388160a62f4a0e72ed888e56c8e9159469`. The package primitive is the released v2.3.0. Do not claim OIDC is active from an action release or a validation run alone. Omit `publish-dev-artifacts`, `publish-pr-artifacts`, `publish-manual-artifacts`, and `package-publish-enabled` to inherit their `true` defaults. Development and preview builds are the project standard; do not disable them without an explicit request. Eligible PRs targeting `dev` use `pr`, dev pushes and promotion PRs use `dev`, other PRs targeting `main` use `patch`, and manual runs use `wip`. Eligible `main` pushes publish regular packages and a GitHub Release. Updating a PR can publish a preview; merging into `dev` or `main` can publish packages too. Honor the authorized delivery scope and follow [docs/RELEASING.md](docs/RELEASING.md). Use explicit Bun install/lint/typecheck/test/coverage/build commands supported by the package. The inspected `node-bun` defaults contain npm fallbacks; a failed Bun check must not turn into a successful fallback. Keep required security checks and run the Node package smoke check under each configured Node matrix version as part of the build gate. Do not claim that a parallel CodeQL job gates release unless its dependencies enforce that. -Use one compatible package identity/version for both registries: `@wgtechlabs/mdd-engine`. Confirm license, registry access, package contents, and public visibility before publishing. The npm authentication is Trusted Publishing with OIDC, using npm CLI >=11.5.1 on the pinned Node 24.21.0 runtime. Retain `package-npm-auth-method: oidc` when upgrading the orchestrator. Configure npm to trust `wgtechlabs/mdd-engine` / `build-flow.yml`, allow direct `npm publish`, and preserve `id-token: write` through the reusable workflow chain. OIDC publishing must not require or fall back to `NPM_TOKEN`. GitHub Packages still uses the separate built-in `GITHUB_TOKEN` with `packages: write`, and GitHub Releases require `contents: write`. Never hardcode or log tokens; retain permissions required by enabled comments or security features. +Use one compatible package identity/version for both registries: `@wgtechlabs/mdd-engine`. Confirm license, registry access, package contents, and public visibility before publishing. The npm authentication is Trusted Publishing with OIDC, using npm CLI >=11.5.1 on the pinned Node 24.21.0 runtime. Verify the inherited `package-npm-auth-method: oidc` default when upgrading the orchestrator. Configure npm to trust `wgtechlabs/mdd-engine` / `build-flow.yml`, allow direct `npm publish`, and preserve `id-token: write` through the reusable workflow chain. OIDC publishing must not require or fall back to `NPM_TOKEN`. GitHub Packages still uses the separate built-in `GITHUB_TOKEN` with `packages: write`, and GitHub Releases require `contents: write`. Never hardcode or log tokens; retain permissions required by enabled comments or security features. The first npm publication needs a one-time bootstrap if the package is absent. Use the preserved validated `0.1.0` tarball tied to the existing `v0.1.0` tag at finalized commit `3975075b4dee44806012e71d80e858ddcf2b39a9`; follow the verification and maintainer-authentication procedure in [docs/RELEASING.md](docs/RELEASING.md). Never rewrite the tag, duplicate an existing registry version, or blindly rerun a partial publication. Future eligible releases use automatic OIDC after the trusted publisher and workflow adoption are verified. -Required sequencing on `main`: validate source → finalize release source/version → build package → confirm successful publication to BOTH registries → publish GitHub Release. Development builds validate and publish from the triggering commit without release finalization or a GitHub Release. Partial registry publication is incomplete and must not unlock release. Do not silently change existing primitive defaults; document consumer policy overrides such as non-main artifact publishing. +Required sequencing on `main`: validate source → finalize release source/version → build package → confirm successful publication to BOTH registries → publish GitHub Release. Preview builds validate and publish from the triggering commit without release finalization or a GitHub Release. Partial registry publication is incomplete and must not unlock release. Preserve default bot detection and GitHub's fork-PR permission restrictions; never use `pull_request_target` to run contributor code with publishing credentials. Do not silently change existing primitive defaults; document the reason for any necessary consumer override. ### Release gate contract diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 513ef41..03a3f2d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,4 +15,4 @@ Use Clean Commit messages: ` : ` or ` Labels are managed through [GHLT](https://github.com/warengonzaga/github-labels-template). Routine template updates use `ghlt apply --repo wgtechlabs/mdd-engine`; a destructive `migrate` requires explicit authorization. The initial migration has already been completed. -Follow [the release prerequisites](docs/RELEASING.md): eligible pushes to `dev` automatically publish development packages with the `dev` dist-tag to npm and GitHub Packages. Eligible pushes to `main` publish regular packages before creating a GitHub Release. Feature branches and PRs do not publish packages. +Follow [the release prerequisites and build channels](docs/RELEASING.md): eligible PRs targeting `dev` publish `pr` previews; pushes to `dev` and `dev` → `main` PRs publish `dev` previews. Other PRs targeting `main` publish `patch` previews, and manual runs publish `wip` previews. Eligible pushes to `main` publish regular packages before creating a GitHub Release. Both npm and GitHub Packages are enabled through Build Flow defaults. Pushing to an open PR can publish a new preview; a feature-branch push without an eligible PR does not trigger this workflow. diff --git a/README.md b/README.md index b176aae..b57a062 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The headless Markdown documentation compiler behind mdd. Give it a local project Built with TypeScript and Bun. Runs on Node.js 22, 24, and 26 without Bun. The default is the latest Node LTS, currently pinned to **24.21.0**. -> Build Flow is configured to publish development packages from `dev` with the `dev` dist-tag and regular releases from `main` to npm and GitHub Packages. See [releasing](docs/RELEASING.md). +> Build Flow's default channels publish development, PR, and manual preview packages alongside regular releases to npm and GitHub Packages. See [build channels and releasing](docs/RELEASING.md). ## A documentation project @@ -38,7 +38,7 @@ All settings are optional. Custom paths are relative to `mdd/config.json` and mu ## Compile without a website -Install the regular package with `bun add @wgtechlabs/mdd-engine`. Once the first development build is published, use `bun add @wgtechlabs/mdd-engine@dev` to try the development version. You can also install a locally packed copy. +Install the regular package with `bun add @wgtechlabs/mdd-engine`. After a successful preview publication, use `bun add @wgtechlabs/mdd-engine@dev` for development builds or `bun add @wgtechlabs/mdd-engine@pr` for PRs targeting `dev`. Preview tags track the most recently published package in their channel; install an exact version to test a particular PR. You can also install a locally packed copy. In your Node project: diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 2ade5a0..7dd351d 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -2,29 +2,38 @@ ## Automatic publication channels -[Build Flow](../.github/workflows/build-flow.yml) enables development package publication from `dev` and regular package publication with a GitHub Release from `main`. It publishes `@wgtechlabs/mdd-engine` to both npm (`registry.npmjs.org`) and GitHub Packages (`npm.pkg.github.com`). This package does not publish a container image to GHCR. +[Build Flow](../.github/workflows/build-flow.yml) uses its default development, pull-request, and manual preview publication channels, plus regular package publication with a GitHub Release from `main`. It publishes `@wgtechlabs/mdd-engine` to both npm (`registry.npmjs.org`) and GitHub Packages (`npm.pkg.github.com`). This package does not publish a container image to GHCR. The workflow pins released [Build Flow v1.0.0](https://github.com/wgtechlabs/build-flow-action/releases/tag/v1.0.0) at immutable commit [`f8263c388160a62f4a0e72ed888e56c8e9159469`](https://github.com/wgtechlabs/build-flow-action/commit/f8263c388160a62f4a0e72ed888e56c8e9159469). It uses the released [Package Build Flow v2.3.0](https://github.com/wgtechlabs/package-build-flow-action/releases/tag/v2.3.0). Workflow validation does not prove npm trust configuration or publication. -Development builds are standard: the caller omits `publish-dev-artifacts` to inherit Build Flow's `true` default. PR and manual publication are explicitly disabled. The caller also requires a `push` event for `package-publish-enabled`, because the pinned orchestrator classifies manual runs on `dev` as development events too. +The caller enables the package flow and inherits the pinned defaults for publication, both registries, npm OIDC, and releases. It does not override `publish-dev-artifacts`, `publish-pr-artifacts`, `publish-manual-artifacts`, or `package-publish-enabled`; all default to `true`. -| Trigger | Package version / dist-tag | GitHub Release | -|---|---|---| -| Eligible push to `dev` | `-dev.` / `dev` | None | -| Eligible push to `main` | Planned regular version / `latest` | After both registries succeed | -| Pull request or manual run | Validation only | None | +| Eligible trigger | Package version | Install tag | GitHub Release | +|---|---|---|---| +| Push to `dev` | `-dev.` | `dev` | None | +| PR targeting `dev` | `-pr.` | `pr` | None | +| PR from `dev` to `main` | `-dev.` | `dev` | None | +| Other PR targeting `main` | `-patch.` | `patch` | None | +| Manual run (`workflow_dispatch`) | `-wip.` | `wip` | None | +| Push to `main` with a planned version bump | Planned regular version | `latest` | After both registries succeed | -For example, base version `0.1.0` produces `0.1.0-dev.`. After the first successful development publication, install it with `bun add @wgtechlabs/mdd-engine@dev`. Development publication does not move `latest`. Commit-type filtering is disabled by default, so setup or documentation changes are eligible too; the existing bot-actor detection can still suppress publication. +`` is the version in `package.json`; `` is the first seven characters of the workflow's commit SHA. PR runs build GitHub's test-merge commit, not just the source-branch head. For example, a PR targeting `dev` can publish `0.1.0-pr.abcdef1`. -Merging into `dev` can publish a development package. Use a regular merge commit for the `dev` → `main` promotion, which can publish a regular release. Both operations must stay within the authorized merge/release scope. +After a successful publication, install a channel with `bun add @wgtechlabs/mdd-engine@dev` or `bun add @wgtechlabs/mdd-engine@pr`. Install an exact version to test a particular PR: the `pr` tag is shared across PRs, and `dev` is shared by dev pushes and promotion PRs. Each tag follows the most recently published package in its channel. Preview publication does not move `latest`. The package action's default PR comment provides installation instructions after successful publication. + +Commit-type filtering is disabled by default, so setup or documentation changes can publish previews too. Default bot detection can suppress publication. Fork PRs cannot be assumed publishable: GitHub restricts write permissions and credentials on those runs. Keep those platform restrictions; do not use `pull_request_target` to run contributor code with publishing credentials. + +The caller listens to pushes and PRs for `dev`/`main`, plus manual dispatch. Feature-branch pushes without an eligible PR do not run it. The standalone primitive's unplanned-main `staging` flow is not used here: the orchestrator plans and finalizes regular versions before main publication. Do not add a `release: published` trigger to republish a version already handled by the orchestrator. + +Updating a PR can publish a preview immediately. Merging into `dev` can publish a development package. Use a regular merge commit for the `dev` → `main` promotion, which can publish a regular release. These operations must stay within the authorized delivery scope. ## Required sequence 1. CI runs the Bun checks and packed-package smoke check on Node 22, 24, and 26. Dependency auditing and Gitleaks must pass. 2. Enabled CodeQL analysis must succeed before source finalization or publication. -3. On `main`, Build Flow finalizes the planned version, source commit, changelog, and tag once. Development builds skip release finalization and use the triggering commit. +3. On `main`, Build Flow finalizes the planned version, source commit, changelog, and tag once. Preview builds skip release finalization and use the triggering commit. 4. The package job checks out that source commit, builds the package with the appropriate version/dist-tag, and publishes to both registries. -5. For `main`, both registry results must report success and the complete package job must succeed before Build Flow creates the GitHub Release. Development builds do not create a GitHub Release. +5. For `main`, both registry results must report success and the complete package job must succeed before Build Flow creates the GitHub Release. Preview builds do not create a GitHub Release. The package primitive's `artifact-published` output means at least one registry published. Build Flow checks complete publication separately; the aggregate flag alone is insufficient. Failure of either registry, a later package step, or required security analysis must prevent the GitHub Release. Preserve these guarantees when upgrading the workflow pin. @@ -35,7 +44,7 @@ The package primitive's `artifact-published` output means at least one registry - The OIDC publishing job requires npm CLI 11.5.1 or newer and Node 22.14.0 or newer; use the pinned Node 24.21.0 runtime. These publishing-tool requirements do not change the package's consumer runtime range. - Explicit CI overrides propagate failures. The build check includes `bun audit` before publication; the primitive's own audit runs after publishing and is not a substitute for this gate. - CodeQL uses `codeql-build-mode: none` for JavaScript/TypeScript source analysis. -- The caller selects `package-npm-auth-method: oidc`. npm publishing requires no `NPM_TOKEN` and must not fall back to a long-lived publish token. +- The caller inherits `package-npm-auth-method: oidc`. npm publishing requires no `NPM_TOKEN` and must not fall back to a long-lived publish token. - GitHub Packages uses its separate built-in `GITHUB_TOKEN` with `packages: write`; GitHub Release creation requires `contents: write`. npm OIDC does not replace these GitHub permissions. Preserve the caller's other required permissions and allow the authorized release commit/tag on `main`. - Retain the MIT `LICENSE` in the package and the repository metadata linking it to `wgtechlabs/mdd-engine`. @@ -51,11 +60,11 @@ Once the package exists on npm, add a GitHub Actions trusted publisher in its np | Environment | Leave empty unless the publishing job declares one | | Allowed actions | Enable **npm publish** for direct automatic publication | -Trust the calling workflow in this repository, even though reusable Build Flow workflows perform the upload. Grant `id-token: write` through the caller and called workflows, use GitHub-hosted runners, and retain `package-npm-auth-method: oidc` when upgrading Build Flow. Keep both registries enabled. See [npm's trusted-publishing guide](https://docs.npmjs.com/trusted-publishers/) for the platform requirements and settings. +Trust the calling workflow in this repository, even though reusable Build Flow workflows perform the upload. Grant `id-token: write` through the caller and called workflows, use GitHub-hosted runners, and verify the inherited `package-npm-auth-method: oidc` default when upgrading Build Flow. Keep both registries enabled. See [npm's trusted-publishing guide](https://docs.npmjs.com/trusted-publishers/) for the platform requirements and settings. After setup, eligible future releases publish automatically without an npm publish token or a per-version promotion step. Saving the trusted publisher does not verify it; confirm a successful OIDC publication before considering migration complete. -The same trusted publisher supports both `dev` and `main` through `build-flow.yml`. Create the configuration shortly before an authorized publication: it must complete its first successful publish within **48 hours of creation**. That successful publish validates the configuration and removes its expiry. If it expires before publication, recreate it to start a new 48-hour window; ordinary edits do not reset the deadline. Changing the repository or project identity requires a new trust relationship and validation window. See [npm's validation-window announcement](https://github.blog/changelog/2026-10-02-unvalidated-npm-trusted-publishing-configurations-now-expire/). The deadline does not replace the bootstrap, merge-authorization, or release-verification requirements below. +The trusted publisher identifies the caller `build-flow.yml` for all eligible channels; verify each publishing path against the registries rather than assuming a configured channel has succeeded. Create the configuration shortly before an authorized publication: it must complete its first successful publish within **48 hours of creation**. That successful publish validates the configuration and removes its expiry. If it expires before publication, recreate it to start a new 48-hour window; ordinary edits do not reset the deadline. Changing the repository or project identity requires a new trust relationship and validation window. See [npm's validation-window announcement](https://github.blog/changelog/2026-10-02-unvalidated-npm-trusted-publishing-configurations-now-expire/). The deadline does not replace the bootstrap, merge-authorization, or release-verification requirements below. ## Bootstrap the first npm version @@ -67,7 +76,7 @@ Verify the npm result, configure the trusted publisher, and complete the missing ## Verify a release -After a `dev` or `main` workflow completes, verify the actual version and dist-tag in both registries, package contents and integrity, and GitHub package visibility. For a regular release from `main`, also verify the GitHub Release tag/commit. Development builds must update `dev` without moving `latest`. GitHub Packages may initially be private; confirm the intended public visibility. Successful validation or an accepted workflow run does not prove publication. +After a publishing workflow completes, verify the actual version and dist-tag in both registries, package contents and integrity, and GitHub package visibility. For a regular release from `main`, also verify the GitHub Release tag/commit. Preview builds must update their expected channel tag without moving `latest`. For PRs, also verify the published version matches the test-merge commit and the installation comment is accurate. GitHub Packages may initially be private; confirm the intended public visibility. Successful validation or an accepted workflow run does not prove publication. The packed package must contain runtime JavaScript, TypeScript declarations, README, and LICENSE, while excluding tests, credentials, caches, and development files. Before the first release or a compatibility change, verify current Node 22/24/26 and the lowest version claimed by `engines.node`. @@ -77,11 +86,11 @@ Registry publication is not atomic. If one registry succeeds and the other fails 1. Record the source commit, finalized tag if applicable, exact package version/dist-tag, successful registry, and failed job logs. Correct the failed registry's access issue: npm trusted-publisher identity/OIDC permissions (recreate an expired configuration) or GitHub package permissions, as applicable. 2. Retrieve the published tarball from the successful registry and verify its identity, version, metadata, integrity, and contents against that source. Preserve those package bytes for recovery. -3. With explicit publication authorization, publish that verified tarball only to the missing registry using authentication accepted by that registry and the recorded dist-tag. For development recovery, explicitly use `--tag dev` so the upload cannot move `latest`. Do not rebuild a different artifact, change the released version, or rewrite the finalized tag. -4. Verify the same version, dist-tag, and package contents in both registries and all required checks on that source. For a regular release from `main`, only then create the GitHub Release for the existing verified tag with explicit release authorization. Development package recovery does not create a GitHub Release. +3. With explicit publication authorization, publish that verified tarball only to the missing registry using authentication accepted by that registry and the recorded dist-tag. For preview recovery, explicitly use the recorded `--tag dev`, `--tag pr`, `--tag patch`, or `--tag wip` so the upload cannot move `latest`. Do not rebuild a different artifact, change the released version, or rewrite the finalized tag. +4. Verify the same version, dist-tag, and package contents in both registries and all required checks on that source. For a regular release from `main`, only then create the GitHub Release for the existing verified tag with explicit release authorization. Preview package recovery does not create a GitHub Release. This is a manual recovery procedure, not automatic retry support. No live partial-publication recovery has been exercised for mdd-engine. ## Normal delivery -Work on a short-lived branch from `dev` and squash its PR into `dev` to enable an eligible development package build. Promote `dev` to `main` through a regular merge commit with a meaningful `🚀 release:` title for a regular release. See [AGENTS.md](../AGENTS.md) and [CONTRIBUTING.md](../CONTRIBUTING.md). +Work on a short-lived branch from `dev`, use its eligible PR preview for testing, and squash the PR into `dev` for a development package build. Promote `dev` to `main` through a regular merge commit with a meaningful `🚀 release:` title for a regular release. See [AGENTS.md](../AGENTS.md) and [CONTRIBUTING.md](../CONTRIBUTING.md).