diff --git a/README.md b/README.md index 82b78c6..a56f0d9 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,9 @@ See [SECURITY.md](SECURITY.md), the [threat model](docs/architecture/threat-mode | `stellarforge --help` | Display CLI usage/help | Implemented | | `stellarforge --version` | Display CLI version | Implemented | -`stellarforge add`, plugin architecture, remote template registries, and Mainnet deployment are **not implemented** and remain post-v1 or separately reviewed candidates.\n\nSee [Quick Start](docs/guides/quick-start.md), [Command Reference](docs/reference/commands.md), [Configuration](docs/reference/configuration.md), and [Troubleshooting](docs/reference/troubleshooting.md). +`stellarforge add`, plugin architecture, remote template registries, and Mainnet deployment are **not implemented** and remain post-v1 or separately reviewed candidates. + +See [Quick Start](docs/guides/quick-start.md), [Command Reference](docs/reference/commands.md), [Configuration](docs/reference/configuration.md), and [Troubleshooting](docs/reference/troubleshooting.md). --- @@ -201,7 +203,7 @@ stellarforge-cli/ The release strategy uses Semantic Versioning and Changesets. Protected release automation, package validation, cross-platform CI, CodeQL, Dependency Review, and deterministic E2E smoke coverage are implemented. -The source is currently versioned at `0.1.0`, but first public npm publication remains blocked on the one-time REL-001 npm namespace/Trusted Publishing administration. Until that is verified, use the source-checkout instructions in the [Installation Guide](docs/guides/installation.md) rather than assuming registry availability. +The source is currently versioned at `0.1.0`. The npm namespace bootstrap and Trusted Publisher configuration are complete, but the registry contains only the `0.0.0` bootstrap placeholder. The first supported OIDC publication remains intentionally disabled until a release is approved. Until then, use the source-checkout instructions in the [Installation Guide](docs/guides/installation.md). See [ADR-0003](docs/adr/ADR-0003-release-and-versioning-strategy.md) and the [Release Process](docs/contributing/release-process.md). diff --git a/docs/adr/ADR-0003-release-and-versioning-strategy.md b/docs/adr/ADR-0003-release-and-versioning-strategy.md index 4f75c3d..2cd53e7 100644 --- a/docs/adr/ADR-0003-release-and-versioning-strategy.md +++ b/docs/adr/ADR-0003-release-and-versioning-strategy.md @@ -116,6 +116,6 @@ Not selected for the MVP because explicit changeset files make release intent re The repository now includes the Changesets configuration, public package metadata, a protected release workflow, release-policy tests, and release operations documentation. -Production npm publication remains intentionally gated until maintainers complete the one-time namespace bootstrap, configure npm Trusted Publishing for `release.yml`, protect the `npm-release` environment, and explicitly enable `NPM_PUBLISH_ENABLED`. +The one-time namespace bootstrap, npm Trusted Publisher for `release.yml`, and protected `npm-release` environment are configured. Production npm publication remains intentionally dormant while `NPM_PUBLISH_ENABLED=false`; maintainers enable it only for an approved release and verify the resulting npm provenance, tag, and GitHub Release. See `docs/contributing/release-process.md` for the operational checklist, dry-run procedure, rollback guidance, and first-release bootstrap. diff --git a/docs/contributing/release-process.md b/docs/contributing/release-process.md index 27fe016..b2c71b3 100644 --- a/docs/contributing/release-process.md +++ b/docs/contributing/release-process.md @@ -2,7 +2,7 @@ StellarForge CLI uses Semantic Versioning, Changesets, npm Trusted Publishing, and GitHub Releases. -## Safety state before first publication +## Safety state before the first supported publication Release automation is intentionally merged in a non-publishing state. The workflow can create release PRs and validate/pack release artifacts, but the npm publish job runs only when **all** of these controls are in place: @@ -16,7 +16,7 @@ Release automation is intentionally merged in a non-publishing state. The workfl 3. the GitHub `npm-release` environment exists and requires maintainer approval; 4. the repository variable `NPM_PUBLISH_ENABLED` is set to `true`. -Until then, release artifacts are built, tested, inspected, and packed, but publication stops at the protected gate. +The first three controls are configured. `NPM_PUBLISH_ENABLED` deliberately remains `false`, so release artifacts are built, tested, inspected, and packed while publication stops at the protected gate. No long-lived `NPM_TOKEN` is used. @@ -52,31 +52,28 @@ npm run changeset:status This path never publishes. -## First release bootstrap +## Completed namespace bootstrap -The repository is now versioned at `0.1.0` on `main`, but the package remains unpublished until the npm namespace and Trusted Publisher are configured. +The repository is versioned at `0.1.0` on `main`. The `@diginodes/stellarforge-cli` package now exists on npm as the `0.0.0` bootstrap placeholder, and the Trusted Publisher is bound to `DigiNodes/stellarforge-cli`, `release.yml`, and the `npm-release` environment. -npm Trusted Publishing can only be attached after the package exists on npm. Therefore the one-time registry bootstrap must use the reviewed pre-`0.1.0` commit rather than changing `main` back to `0.0.0`. +The bootstrap was intentionally published before enabling routine OIDC releases because npm Trusted Publishing can only be attached after the package exists. It is not a supported end-user release and must never be republished or reused. -The approved bootstrap source is the last pre-release commit: +The published bootstrap source is the reviewed bootstrap commit: ```text -8684d940afc8e2d9e56658061de779429757b780 +8c2cf209eef97349a46cfb1dfb2002834c8e29b6 ``` -From an approved maintainer workstation: - -1. clone `DigiNodes/stellarforge-cli` and check out the bootstrap commit above; -2. run `npm ci --ignore-scripts --no-audit --no-fund`, `npm run build`, and `npm run release:dry-run`; -3. apply the reviewed package-identity patch that changes only the npm package name to `@diginodes/stellarforge-cli` while retaining bootstrap version `0.0.0`; -4. authenticate interactively as an owner of the `diginodes` npm organization, using the required 2FA flow; -5. publish `@diginodes/stellarforge-cli@0.0.0` once with a non-default bootstrap tag, for example `npm publish --access public --tag bootstrap`; -6. configure npm Trusted Publishing on the newly existing `@diginodes/stellarforge-cli` package for organization `DigiNodes`, repository `stellarforge-cli`, workflow `release.yml`, environment `npm-release`, with direct `npm publish` allowed; -7. create/protect the GitHub `npm-release` environment with required maintainer review; -8. set repository Actions variable `NPM_PUBLISH_ENABLED=true`; -9. verify GitHub Dependency Graph keeps the existing Dependency Review workflow enforceable; -10. merge a reviewed release-activation change to `main` (or another approved `main` push) to trigger the protected publish path for the already-versioned `0.1.0` package; -11. approve the `npm-release` environment deployment and verify npm, Git tag, GitHub Release, and provenance all identify `0.1.0`. +The completed administrative record is: + +1. `@diginodes/stellarforge-cli@0.0.0` was published once from a reviewed bootstrap commit using interactive maintainer authentication and 2FA; +2. npm Trusted Publishing is configured for the repository, workflow, and protected environment above; +3. the GitHub `npm-release` environment requires maintainer approval and contains no npm publishing secret; +4. GitHub Dependency Graph is enabled and Dependency Review is healthy; +5. a post-merge release dry run built, tested, and packed `0.1.0` while correctly skipping publication; +6. repository variable `NPM_PUBLISH_ENABLED` remains `false` until an approved release window. + +For the first supported release, maintainers must review the release plan, set `NPM_PUBLISH_ENABLED=true`, merge or trigger the approved release path from `main`, approve the `npm-release` deployment, and verify npm, Git tag, GitHub Release, and provenance all identify the same version. If release approval is withdrawn, leave or restore the variable to `false`. Do **not** republish, rewrite, or downgrade the `0.1.0` commit on `main` merely to bootstrap the npm namespace. diff --git a/docs/guides/installation.md b/docs/guides/installation.md index 8333879..8201753 100644 --- a/docs/guides/installation.md +++ b/docs/guides/installation.md @@ -1,8 +1,8 @@ # Installation -StellarForge CLI has completed its initial MVP implementation and the repository contains protected release automation. The source is versioned at `0.1.0`, but the first public npm publication is still pending the one-time registry and Trusted Publishing setup tracked in REL-001. +StellarForge CLI has completed its initial MVP implementation and the repository contains protected release automation. The source is versioned at `0.1.0`. The npm namespace bootstrap and Trusted Publisher configuration are complete, but the first supported OIDC release has not been approved or published. -Until that publication is verified, use a source checkout for development and evaluation rather than assuming `@diginodes/stellarforge-cli` is available from the npm registry. +The npm registry currently contains `@diginodes/stellarforge-cli@0.0.0` only as a namespace bootstrap placeholder. Do not treat that version as an end-user release. Until a supported version is published and verified, use a source checkout for development and evaluation. ## Contributor prerequisites @@ -15,6 +15,8 @@ The current runtime support contract is: Repository toolchain metadata currently records npm `10.9.2`. +Rust and Cargo are not required for most TypeScript contributions. When Cargo is available, the test suite also validates the generated Smart Contract workspace with `cargo metadata`; that one external-tool validation is skipped when Cargo is absent. Contributors working on Smart Contract or Cargo-specific issues should install a supported Rust toolchain and confirm `cargo --version` succeeds. + See [Platform Support](../reference/platform-support.md). Do not use an end-of-life or unsupported Node release for development or CI. ## Contributor setup @@ -63,9 +65,9 @@ Do not install undocumented global dependencies. Stellar-specific tools required ## Public npm installation -The package metadata is publication-ready (`private: false`), and protected release automation is implemented. However, **registry availability must not be assumed until REL-001 is complete and the first protected OIDC publication has been verified**. +The package metadata is publication-ready (`private: false`), and protected release automation is implemented. However, **the existing `0.0.0` registry entry is a bootstrap placeholder, not a supported release**. -After publication, the public installation instructions should be updated using the verified npm package identity and supported install command. Do not add an npm install example here before that registry verification. +After the first protected OIDC publication is approved and verified, add the supported npm installation command here. Until then, do not direct users to install the bootstrap placeholder. ## Release security state @@ -78,6 +80,6 @@ The release workflow is designed around: - no long-lived `NPM_TOKEN`; - npm provenance where supported. -The remaining one-time administrative work is tracked by REL-001 and includes the npm namespace bootstrap, Trusted Publisher configuration, protected GitHub environment, publication variable, and first protected publication. +The npm namespace, Trusted Publisher, protected GitHub environment, and Dependency Graph are configured. `NPM_PUBLISH_ENABLED` remains `false` as a deliberate kill switch. REL-001 remains open only for the first approved protected OIDC publication and its npm/tag/GitHub Release/provenance verification. See [Release Process](../contributing/release-process.md) for the complete release contract. diff --git a/docs/roadmap/v1-readiness.md b/docs/roadmap/v1-readiness.md index 1cbd48d..ee234d0 100644 --- a/docs/roadmap/v1-readiness.md +++ b/docs/roadmap/v1-readiness.md @@ -41,7 +41,7 @@ A v1.0 release requires all required Automated and Manual items to pass and no r | Subprocesses avoid constructed shell interpolation | process/command tests and code review | Automated + review | | Project configuration rejects secret-bearing fields/raw StrKeys and does not execute code | configuration tests | Automated | | Logs/errors do not intentionally echo secret values | configuration/deploy/E2E tests | Automated | -| npm publishing uses OIDC/Trusted Publishing rather than a long-lived npm token | release workflow + npm publisher configuration | Blocked on REL-001 | +| npm publishing uses OIDC/Trusted Publishing rather than a long-lived npm token | configured publisher + first-release provenance verification | Manual verification on first release | | Security reporting path is documented | `SECURITY.md` | Manual review | Any unresolved security vulnerability affecting the release candidate blocks v1.0 regardless of checklist status. @@ -106,7 +106,7 @@ Before each v0.7–v0.9 release candidate and v1.0: 9. npm package version, Git tag, GitHub Release, and provenance agree for an actual publication. 10. the protected `npm-release` environment and Trusted Publisher are active before publication. -The actual npm publication portion remains blocked until REL-001 is completed. +The release path is configured and has passed its non-publishing dry run. Actual npm publication remains deliberately disabled until maintainers approve the first supported release and set `NPM_PUBLISH_ENABLED=true`. ## 6. Performance and usability targets @@ -153,9 +153,9 @@ The following remain post-v1 candidates unless a new architecture/product decisi ## 9. Current blockers and follow-up policy -### External blocker +### Remaining release activation -- **REL-001** — npm namespace bootstrap, npm Trusted Publisher, protected GitHub `npm-release` environment, publication variable, and first protected OIDC publication. +- **REL-001** — namespace bootstrap, npm Trusted Publisher, protected GitHub `npm-release` environment, and Dependency Graph are complete. The remaining acceptance step is the first approved protected OIDC publication and verification that npm, Git tag, GitHub Release, and provenance agree. ### Gap handling diff --git a/tests/smart-contract-template.test.ts b/tests/smart-contract-template.test.ts index 0237b5e..25fa7ac 100644 --- a/tests/smart-contract-template.test.ts +++ b/tests/smart-contract-template.test.ts @@ -8,9 +8,12 @@ import { withTempDirectory, } from './helpers/index.js'; +const cargoAvailable = + spawnSync('cargo', ['--version'], { shell: false }).status === 0; + describe('Smart Contract template', () => { it( - 'generates a valid Cargo workspace with current Stellar contract guidance and no secrets', + 'generates a workspace with current Stellar contract guidance and no secrets', () => withTempDirectory((root) => { const captured = createCapturedTerminalOutput(); @@ -59,12 +62,32 @@ describe('Smart Contract template', () => { expect(captured.stdoutText()).toContain( 'Created demo.contract from smart-contract', ); + }), + 15_000, + ); + + it.skipIf(!cargoAvailable)( + 'generates a Cargo workspace accepted by cargo metadata', + () => + withTempDirectory((root) => { + const command = createNewCommand({ + cwd: () => root, + output: createCapturedTerminalOutput().output, + }); + + command.parse([ + 'node', + 'new', + 'demo-contract', + '--template', + 'smart-contract', + ]); const metadata = spawnSync( 'cargo', ['metadata', '--no-deps', '--format-version=1'], { - cwd: projectRoot, + cwd: join(root, 'demo-contract'), encoding: 'utf8', shell: false, },