diff --git a/specs/change/20260704-auto-publish-cli-version-ci/design.md b/specs/change/20260704-auto-publish-cli-version-ci/design.md deleted file mode 100644 index 92f4afa..0000000 --- a/specs/change/20260704-auto-publish-cli-version-ci/design.md +++ /dev/null @@ -1,99 +0,0 @@ -# Design - -## Research - -### Existing System - -- The package is named `zest-dev`, currently version `1.0.0`, and exposes `zest-dev` through `bin.zest-dev = ./bin/zest-dev.js`. Source: `package.json:1-21` -- The package `files` allowlist includes `bin/`, `commands/`, `skills/`, `agents/`, `lib/`, `scripts/`, `plugin/`, `index.js`, `README.md`, and `LICENSE`; these are the package-shipped paths that should count as CLI release-affecting changes. Source: `package.json:22-33` -- The CLI reports `packageJson.version`, so package version bumps drive `zest-dev --version`. Source: `bin/zest-dev.js:127-130` -- Existing npm scripts provide `pnpm test:local` and `pnpm test:package`. Source: `package.json:34-38` -- Package E2E testing packs the repo, installs the tarball into an isolated npm project, and runs `npx zest-dev --version`. Source: `e2e/helpers/package_env.py:29-50` -- Required setup failures and subprocess failures should fail visibly, not be reported as success after partial failure. Source: `e2e/README.md:41-43`, `AGENTS.md:12-41` -- The repository currently has no GitHub workflow files. Source: file search `.github/workflows/*`, 2026-07-04 - -### Design Inputs - -- `pnpm version patch` bumps the package version using the patch bump type. Source: pnpm CLI docs, `pnpm version`, 2026-07-04 -- `pnpm version` normally creates a git commit and tag in a git repo, and `--no-git-tag-version` prevents that commit/tag behavior. Source: pnpm CLI docs, `pnpm version`, 2026-07-04 -- GitHub Actions `pull_request` workflows can filter by activity type, branch, and paths; if branch and path filters are both set, both filters must match. Source: GitHub Actions workflow syntax docs, `pull_request`, 2026-07-04 -- GitHub Actions permissions can be set at workflow or job level, with `read`, `write`, or `none` values; unspecified permissions become `none`. Source: GitHub Actions workflow syntax docs, `permissions`, 2026-07-04 -- `pull_request_target` can grant read/write token permissions even from public forks, which is unnecessary here because fork PR automation is out of scope. Source: GitHub Actions workflow syntax docs, `pull_request_target`, 2026-07-04 - -### Constraints & Dependencies - -- Fork PR automation is out of scope per user decision; workflows should explicitly skip fork PR write-backs. -- Concurrent PRs may bump to the same patch version; this spec catches stale version changes in CI but intentionally does not auto-merge `main` into open PRs. -- npm publish needs repository-side npm authentication or trusted publishing configured by a Human. -- Publishing should skip an already-published version explicitly rather than claiming success for a failed duplicate publish. - -### Key References - -- `package.json:1-47` - package name, version, bin mapping, package files, scripts. -- `bin/zest-dev.js:127-130` - CLI version reads from package metadata. -- `e2e/helpers/package_env.py:29-50` - packaged CLI validation path. -- `e2e/README.md:41-43` and `AGENTS.md:12-41` - fail-fast validation expectations. -- GitHub Actions workflow syntax docs - `pull_request`, `permissions`, `pull_request_target` behavior. -- pnpm CLI docs - `pnpm version patch --no-git-tag-version` behavior. - -## Design Detail - -### Design Decisions - -- Decision: Treat `package.json` version as the single release version source because the CLI reports `packageJson.version`. Source: `package.json:1-3`, `bin/zest-dev.js:127-130` -- Decision: Detect CLI-affecting PRs from the existing package `files` allowlist, excluding version-result files as trigger-only inputs unless implementation needs package metadata changes to count. Source: `package.json:22-33` -- Decision: Use `pnpm version patch --no-git-tag-version` for PR bump commits so the workflow can edit version files without creating release tags during PR validation. Source: pnpm CLI docs, `pnpm version`, 2026-07-04 -- Decision: Add a separate PR CI freshness check that compares PR head version to `main` when a version change exists, failing when head is not greater than main. Source: user requirement; fail-fast policy from `AGENTS.md:12-41` -- Decision: Skip fork PR write-backs rather than using `pull_request_target`, because fork automation is out of scope and `pull_request_target` has broader write-token implications. Source: user requirement; GitHub Actions workflow syntax docs, `pull_request_target`, 2026-07-04 -- Decision: Publish on `main` only when the merged package version is absent from npm; duplicate published versions should be explicit skips or failures, not hidden success. Source: npm package version uniqueness from prior publish spec `specs/change/20260630-publish-to-npm/design.md:21-24`; fail-fast policy from `AGENTS.md:12-41` - -### System Procedure - -```mermaid -flowchart TD - A[PR opened or synchronized] --> B{Same repo PR?} - B -- no --> C[Skip write-back automation] - B -- yes --> D{CLI-shipped files changed?} - D -- no --> E[No bump] - D -- yes --> F{Version already changed?} - F -- no --> G[Patch bump and commit to PR] - F -- yes --> H[Run freshness CI] - G --> H - H --> I{PR version greater than main?} - I -- no --> J[Fail CI; Human resolves conflict/rebase/bump] - I -- yes --> K[PR can merge] - K --> L[main push publish workflow] - L --> M{Version exists on npm?} - M -- yes --> N[Skip with explicit message] - M -- no --> O[Test and publish] -``` - -### Change Scope - -Impact Areas: -- GitHub Actions PR automation and PR CI checks. -- GitHub Actions main-branch npm publish automation. -- Small CI helper scripts for semver comparison, changed-file detection, or npm-version existence checks if YAML-only logic becomes too brittle. -- Maintainer documentation for required npm credentials/trusted publishing and validation workflow. - -Planned File Changes: -- `.github/workflows/` - add PR bump/freshness and main publish workflows. -- `scripts/ci/` or similar - add helper scripts for version comparison and publish checks if useful. -- `package.json` - optionally add script aliases for local CI helper validation. -- `README.md` or release docs - update only if implementation changes maintainer release instructions. - -### Edge Cases - -- Two PRs can both bump to the same next patch version; the later PR should fail freshness CI after `main` advances until it rebases or bumps again. -- A PR may include a manual version bump; automation should not double-bump it, but freshness CI should still validate it against `main`. -- If the bump workflow pushes a commit, it can retrigger PR workflows; skip logic must prevent repeated bumps once version has changed. -- `pnpm-lock.yaml` may or may not change from a version-only bump; the commit step should only commit actual changes. -- npm registry/network/auth failures on publish are required failures unless the version already exists and the workflow explicitly reports a skip. - -### Verification Strategy - -- Add local fixtures or script-level tests for version comparison: behind, equal, and ahead of `main`. -- Run `pnpm test:local` after workflow/script changes. -- Open a real same-repository PR that changes a CLI-shipped file and verify GitHub Actions creates the bump commit and the freshness CI passes. -- Validate the stale case by forcing or simulating a PR version equal to `main`; CI should fail. -- After merge, verify the main publish workflow either publishes the new version or explicitly skips because npm already has it. diff --git a/specs/change/20260704-auto-publish-cli-version-ci/journal.md b/specs/change/20260704-auto-publish-cli-version-ci/journal.md deleted file mode 100644 index 1388a29..0000000 --- a/specs/change/20260704-auto-publish-cli-version-ci/journal.md +++ /dev/null @@ -1,96 +0,0 @@ -# Journal - -## 2026-07-04 - Execution start - -- Created and activated spec `20260704-auto-publish-cli-version-ci`. -- Advanced the spec through research, design, and plan to `planned`. -- Starting implementation from Step 1, following the Plan order. -- Commit policy for this execution: commit after each completed step or meaningful phase progress, with commit messages prefixed by `journal:`. - -## 2026-07-04 - Step 1 complete - -- Added `scripts/ci/check-version-freshness.js` plus a small local test command for ahead, unchanged, behind, and invalid-version cases. -- Added a pull-request CI job in `.github/workflows/ci.yml` that fetches the base branch `package.json` and fails when a PR version change is not greater than base. -- Marked Step 1 complete in the spec progress checklist. - -## 2026-07-04 - Step 2 complete - -- Added `scripts/ci/should-bump-pr-version.js` and a local test command so PR automation can detect package-shipped CLI changes, skip manual version bumps, and avoid version-only rebump loops. -- Extended `.github/workflows/ci.yml` with a same-repo PR patch-bump job that runs `pnpm version patch --no-git-tag-version`, refreshes `pnpm-lock.yaml`, commits the bump, and pushes it back to the PR branch. -- Marked Step 2 complete in the spec progress checklist. - -## 2026-07-04 - Step 3 complete - -- Added `scripts/ci/check-npm-version.js` and a local test command so main-branch CI can distinguish an already-published version from required publish/auth/network failures. -- Extended `.github/workflows/ci.yml` with a push-to-main publish job that waits for the existing test jobs, skips duplicate npm versions explicitly, and runs `npm publish --access public` with `NODE_AUTH_TOKEN`-based auth when publish is required. -- Marked Step 3 complete in the spec progress checklist. - -## 2026-07-04 - Step 4 handoff - -- AFK implementation through Step 3 is complete and committed locally. -- Waiting on Human review, repository secret setup, and PR merge decisions before continuing to real GitHub/npm validation. - -## 2026-07-04 - Step 4 PR created - -- Created PR: https://github.com/nettee/zest-dev/pull/104 -- PR body documents local validation and the required `NPM_TOKEN` repository secret setup. -- The PR patch-bump workflow ran on the PR branch and created `ci: auto bump patch version`, updating `package.json` to `1.0.1`. - -## 2026-07-04 - Step 4 publish auth revised - -- Switched the publish workflow from expiring `NPM_TOKEN` secret auth to npm Trusted Publishing / GitHub OIDC. -- The publish job now requests `id-token: write` and runs `npm publish --access public --provenance` when the version is absent from npm. -- Human setup changed from configuring a repository secret to adding a trusted publisher for repository `nettee/zest-dev` and workflow `ci.yml` in npm package settings. -- Corrected the OIDC `id-token: write` permission so it belongs only to the `publish-npm` job. - -## 2026-07-04 - Step 4 publish workflow split - -- Moved npm publishing out of `.github/workflows/ci.yml` into dedicated `.github/workflows/publish-npm.yml`. -- Trusted Publisher setup should now use workflow filename `publish-npm.yml`, keeping CI and release permissions separate. - -## 2026-07-04 - Step 4 Trusted Publisher configured - -- Human configured npm Trusted Publisher for `nettee/zest-dev` with workflow filename `publish-npm.yml`. -- npm shows publish permissions for the trusted publisher, so no expiring `NPM_TOKEN` secret is needed. - -## 2026-07-04 - Step 5 publish validation failed - -- PR #104 was merged to `main` as merge commit `c65782e`. -- The `Publish npm` workflow ran on `main` and failed in the `npm publish --access public --provenance` step. -- Provenance signing reached npm successfully, but the final registry publish failed with `npm error code E404` and `404 Not Found - PUT https://registry.npmjs.org/zest-dev - Not found`. -- `npm view zest-dev version --json` still reports `1.0.0`, while merged `package.json` is `1.0.1`; publish is not complete. -- `npm owner ls zest-dev` reports package owner `nettee `. -- External research is in progress to identify the exact Trusted Publishing remediation before rerunning the release. - -## 2026-07-04 - Step 5 remediation prepared - -- Prepared a follow-up fix branch after research identified three high-probability causes for misleading Trusted Publishing 404s. -- Removed `registry-url` from `actions/setup-node` in `publish-npm.yml` so GitHub Actions does not inject `_authToken` config that can block OIDC publishing. -- Upgraded the publish workflow runtime to Node `22.14.0` and npm `^11.5.1`, matching current npm Trusted Publishing requirements. -- Normalized `package.json.repository` to `{ type: "git", url: "git+https://github.com/nettee/zest-dev.git" }` so published metadata matches the GitHub repo exactly. - -## 2026-07-04 - Step 5 remediation PR created - -- Created follow-up PR: https://github.com/nettee/zest-dev/pull/105 -- This PR is intended to unblock a rerun of the `Publish npm` workflow so the real release validation can continue. - -## 2026-07-04 - Step 5 publish validation succeeded - -- PR #105 was merged to `main`, and the next `Publish npm` workflow run completed successfully. -- The successful publish log reported `+ zest-dev@1.0.1` after provenance signing. -- `npm view zest-dev version --json` and `npm view zest-dev dist-tags --json` now both confirm `latest = 1.0.1`. - -## 2026-07-04 - Step 6 EAG validated - -- Re-ran the local version-freshness helper tests. -- Confirmed the successful `publish-npm.yml` run executed `pnpm test:local` and `pnpm test:package` before publishing `zest-dev@1.0.1`. - -## 2026-07-04 - Step 7 documentation synced - -- Updated `README.md` so the publish section describes automatic PR patch bumping, version freshness CI, and npm Trusted Publishing via `publish-npm.yml`. - -## 2026-07-04 - Auto-bump policy refined - -- Excluded `README.md` from PR auto-bump trigger detection so docs-only README changes do not count as CLI release changes. -- Updated `ci.yml` so the PR auto-bump job uses repository secret `AUTO_BUMP_TOKEN` when present, falling back to `github.token` otherwise. -- Documented that `AUTO_BUMP_TOKEN` can be used to avoid GitHub's approval gate on follow-up PR runs created by auto-bump commits. diff --git a/specs/change/20260704-auto-publish-cli-version-ci/spec.md b/specs/change/20260704-auto-publish-cli-version-ci/spec.md deleted file mode 100644 index 06715f6..0000000 --- a/specs/change/20260704-auto-publish-cli-version-ci/spec.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: 20260704-auto-publish-cli-version-ci -name: Auto Publish Cli Version Ci -status: planned -created: '2026-07-04' ---- - -## Overview - -Automate the npm release path for the already-published `zest-dev` CLI while keeping unsafe registry setup and final PR/merge judgment visible to a Human. - -Goals: -- On same-repository PRs that modify CLI/package-shipped files, automatically bump the package patch version when the PR has not already changed the version. -- Add CI that fails when a PR includes a version change that is not ahead of `main`, so stale concurrent PR bumps are caught before merge. -- After merge to `main`, publish to npm only when the merged version is not already present on the registry. -- Include implementation, PR, and real validation steps in the plan. - -Scope: -- GitHub Actions workflows and small CI helper scripts for version bump, version freshness checking, and npm publish. -- Same-repository PRs only; fork PR automation is out of scope. -- No automatic merge-from-main handling in this spec. - -Success Criteria: -- CLI-affecting PRs receive a patch version bump commit when needed. -- PR CI rejects version changes that are less than or equal to `main`'s version. -- Merge-to-main publishes a new npm version and skips safely if the version is already published. - -## Research - -See [design.md](./design.md). - -## Design - -### Design Summary - -Use GitHub Actions as the automation boundary. A PR workflow detects package-shipped CLI changes and commits a patch bump back to same-repository PR branches. A separate PR CI check compares the PR version to `main` and fails fast if the PR version is not greater when a version change is present. A main-branch publish workflow validates that the merged version is new on npm before publishing. - -See [design.md](./design.md) for design detail. - -### E2E Acceptance Gate (EAG) - -Acceptance behavior: A version-staleness check fails when a branch's package version is equal to or behind the base version, and passes when it is ahead. - -Verification path: Run the CI helper's local test fixture or command documented by the implementation, plus `pnpm test:local`. - -## Plan - -### Step 1 (AFK): Version Freshness CI - -Goal: Add the required CI check that prevents stale version changes from merging. -Scope: Implement a small script or workflow step that compares `package.json` version on PR head against `main` when the PR contains a version change; fail when head version is less than or equal to main version; wire it into a `pull_request` workflow. -Depends on: None - -### Step 2 (AFK): PR Patch Bump Automation - -Goal: Automatically create the expected patch bump on CLI-affecting same-repository PRs. -Scope: Add a `pull_request` workflow that detects changes under package-shipped CLI paths, skips forks, skips PRs that already changed version, runs `pnpm version patch --no-git-tag-version`, refreshes the lockfile if needed, and commits the bump to the PR branch. -Depends on: Step 1 - -### Step 3 (AFK): Main npm Publish Automation - -Goal: Publish merged versions automatically without hiding duplicate-version failures. -Scope: Add a `push` to `main` workflow that runs tests, compares the merged version against npm, publishes only if the version is absent, and uses the configured npm authentication/provenance path. -Depends on: Step 2 - -### Step 4 (HITL): PR Review and Secret/Publishing Setup - -Goal: Get the automation merged and connect it to authorized npm publishing credentials. -Scope: AI opens or prepares the PR, summarizes changed workflows, required repository secrets/trusted-publishing configuration, and expected CI behavior. Human reviews the PR, configures `NPM_TOKEN` or npm trusted publishing in GitHub/npm, confirms branch protection/check requirements, and merges when satisfied. -Depends on: Step 3 - -### Step 5 (HITL): Real Release Validation - -Goal: Prove the automation works against the real GitHub and npm systems after merge. -Scope: AI creates or guides a minimal CLI-affecting validation PR, watches/interprets workflow results from shared logs, and verifies npm registry output after merge. Human authorizes and merges the validation PR, resolves any version conflict if CI catches staleness, and confirms the actual npm publish result in GitHub/npm if privileged access is required. -Depends on: Step 4 - -### Step 6 (AFK): EAG Validation - -Goal: Validate the completed change against the Spec's EAG before wrap-up work. -Scope: Run the version-staleness helper's local verification fixture or documented command, plus `pnpm test:local`. -Depends on: Step 5 - -### Step 7 (AFK): Documentation Sync - -Goal: Keep project documentation aligned with the implemented automation. -Scope: If implementation changes release workflow, required secrets, branch protection, or maintainer instructions, update the relevant project docs. -Depends on: Step 6 - -## Progress - -- [x] Step 1 (AFK): Version Freshness CI -- [x] Step 2 (AFK): PR Patch Bump Automation -- [x] Step 3 (AFK): Main npm Publish Automation -- [x] Step 4 (HITL): PR Review and Secret/Publishing Setup -- [x] Step 5 (HITL): Real Release Validation -- [x] Step 6 (AFK): EAG Validation -- [x] Step 7 (AFK): Documentation Sync - -## Implementation - -See [steps.md](./steps.md). - -## Deferred Follow-Ups (DFU) - -None. diff --git a/specs/change/20260704-auto-publish-cli-version-ci/steps.md b/specs/change/20260704-auto-publish-cli-version-ci/steps.md deleted file mode 100644 index 9b9e20b..0000000 --- a/specs/change/20260704-auto-publish-cli-version-ci/steps.md +++ /dev/null @@ -1,32 +0,0 @@ -# Steps - -## Step 1 - - - -## Step 2 - -- Added `scripts/ci/should-bump-pr-version.js` plus a local test command to detect package-shipped CLI changes, skip manual version bumps, and avoid version-only loop rebumping. -- Extended `.github/workflows/ci.yml` with a same-repository `pull_request` job that fetches the base branch, decides whether a patch bump is needed, runs `pnpm version patch --no-git-tag-version`, refreshes `pnpm-lock.yaml`, and pushes a single bump commit back to the PR branch. - -## Step 3 - -- Added `scripts/ci/check-npm-version.js` plus a local test command so main-branch automation can detect whether `package.json`'s merged version already exists on npm and only treat 404/not-found as a skip-to-publish case. -- Added `.github/workflows/publish-npm.yml` as a dedicated push-to-main publish workflow that runs local and packaged tests, skips duplicate versions explicitly, and publishes with npm Trusted Publishing / GitHub OIDC provenance when the version is absent. - -## Step 4 - -- Created and merged PR `#104` for the initial automation implementation, then configured npm Trusted Publisher settings for `nettee/zest-dev` with workflow filename `publish-npm.yml`. - -## Step 5 - -- Real publish validation initially failed on `main` with a misleading npm `E404` during trusted publishing, even though provenance signing succeeded. -- Researched the failure, prepared remediation in PR `#105`, merged it, and confirmed the next `Publish npm` run successfully published `zest-dev@1.0.1`. - -## Step 6 - -- Revalidated the version freshness helper locally and relied on the successful `publish-npm.yml` run's `pnpm test:local` execution plus the successful `zest-dev@1.0.1` publish as the EAG completion evidence. - -## Step 7 - -- Updated `README.md` so npm publishing documentation matches the automated PR-bump, version freshness, and Trusted Publishing release flow.