# CI and releases

## Pull request gate

Use Conventional Commit PR titles, such as `fix: retain work evidence` or
`feat: improve recall`. Squash merges preserve that title for release automation.

`CI` runs on PRs, pushes to `main`, explicit dispatch and a weekly schedule:

- Node 22.19.0 and Node 24: typecheck, regression/release-policy tests, package and
  automation assertions, and an npm audit that fails on high/critical findings.
- Node 24 with explicit npm 10 and 12: checks, native installation and package builds;
  both npm compatibility lanes are mandatory parts of the gate.
- Node 24: native Pi installation tests and real-host/fake-model integration.
- Workflow syntax checks with a checksum-pinned actionlint binary.
- Build an npm tarball, `SHA256SUMS` and a source-commit/integrity manifest. Pi loads
  TypeScript directly, so building means packaging, not compiling a second runtime.

The final **Quality gate** fails if any prerequisite fails, is cancelled or is skipped.
`main` requires a PR, an up-to-date successful gate and resolved conversations, with
force pushes/deletion blocked. In this single-maintainer repository, the gate does
not require a second person's approval. It does not automatically merge arbitrary
PRs or claim a human code review occurred.

CI uses read-only GitHub tokens, no production credentials and no paid model calls.
Actions are pinned by full commit SHA; checkouts do not persist credentials.
Workflow policy changes still need maintainer review—tests are not a substitute
for reviewing a malicious workflow or dependency change.

## Version and publication flow

1. Merge a checked change into `main`.
2. Release Please maintains a release PR containing `package.json`, lockfile,
   `.release-please-manifest.json` and `CHANGELOG.md` changes.
3. Review and merge that PR. Release Please creates the version tag and GitHub
   Release; the same workflow verifies the exact tagged commit through the full CI.
4. Only after verification succeeds does the `npm` environment publish the built
   archive with npm provenance and verify its public registry integrity.
5. The tarball, checksums and manifest are attached to the GitHub Release.

A GitHub tag/release can exist before npm publication succeeds. Check the **Release**
workflow and npm registry, not just the presence of the tag. Builds are retained as
Actions artifacts for seven days; successful release assets remain attached to the
release. The script never rebuilds between verification and publication.

Release Please uses the built-in `GITHUB_TOKEN`, not a personal GitHub credential.
Because events generated by that token do not start normal push/PR workflows,
it explicitly dispatches CI for its same-repository release PRs. Publication is a
job in the same workflow, not a separate listener waiting for a suppressed event.
GitHub can additionally create a bot-PR run with `action_required`. If that run blocks
PR checks, a maintainer must review the changes and approve that run in Actions;
a successful dispatch alone does not override GitHub's platform approval policy.
The initial rollout required this approval. The workflow does not self-approve or
delete blocked checks to bypass it.

Version behavior follows Conventional Commits. `fix` normally bumps patch, `feat`
bumps minor, and breaking changes before 1.0 bump minor. Visible maintenance/docs/CI
changes can also produce release notes. The bootstrap starts after the already
published 0.2.0 commit; it does not republish 0.1 history.

## Publication credentials

The GitHub environment **npm** accepts deployments from `main` only. No environment
secret is given to the reusable CI jobs or ordinary PR checks. Only the publishing
step receives `NPM_TOKEN` when the repository variable `NPM_AUTH_MODE=token` is set.
No personal GitHub token is stored in Actions.

Prefer npm trusted publishing (OIDC): configure `btnalit/pi-memory-evolution`,
workflow **release.yml**, environment **npm** on the package's npm settings page.
Then set `NPM_AUTH_MODE=oidc`, verify a release, and remove the environment's
`NPM_TOKEN`. `id-token: write` is already granted only to the publication job.

The supplied npm token can publish but cannot configure trust relationships:
npm rejects that account-management operation for granular tokens that bypass 2FA.
Until an account owner completes trusted-publisher setup with supported interactive
authentication, the environment-scoped token is the explicit fallback, not a claim
that OIDC authentication is active. Use a package-scoped, short-lived token and
rotate it before expiry. Do not commit tokens or copy local `key.conf` into CI.

Repository settings must allow Actions to create pull requests. The setting also
mentions approving PRs; this workflow creates them but does not approve them.

## Retrying a release

From Actions, dispatch **Release** on `main` with `tag=vX.Y.Z`, or run:

```bash
gh workflow run release.yml --ref main -f tag=v0.2.1
```

The workflow requires an existing stable GitHub Release whose commit belongs to
`main`, reruns verification and checks the version against the archive manifest.
An already published version is accepted only when npm's integrity matches exactly.
It never overwrites a version or moves `latest` backwards. Existing release assets
must have matching digests; mismatches stop rather than silently using `--clobber`.
Retry the original failed workflow when possible so the original artifact remains
available. Rebuilding with different tooling may legitimately produce different
bytes and require investigation, not bypassing the integrity check.

A cancelled or failed npm call is not proof nothing was published: the registry
check on retry handles that case. After a successful `npm publish` the script waits up
to five minutes for the version to become visible anonymously — npm's propagation lag has
exceeded a minute — and only then attaches release assets; a job that fails after
`+ pi-memory-evolution@x.y.z` was printed has published, and the retry above takes the
already-published branch. Do not delete/recreate tags or edit registry
metadata to disguise a failed release.

## Dependency updates and Pi Gallery

Dependabot checks npm dev dependencies and GitHub Actions weekly. Minor/patch updates
are grouped; majors stay separate. Updates arrive as PRs and must pass the same
gate; no blanket auto-merge is enabled. GitHub vulnerability alerts/security update
PRs complement the scheduled audit. Transitive runtime dependencies are not bundled
just to satisfy host-provided Pi peer APIs.

The package already uses the Pi `pi` manifest and `pi-package` keyword. Distribution
checks retain both, the English npm description/default README, `README.cn.md`,
and a PNG overview referenced by `pi.image`. This provides Gallery discovery and
preview metadata, not an official endorsement or a guarantee of immediate indexing.
The overview is an architecture illustration, not a screenshot of a real user session.

## Local checks

```bash
npm run check
npm run test:install
npm run test:pi
bash scripts/check-workflows.sh  # Linux x86-64; downloads checksum-pinned actionlint
npm run build
```

See [testing](testing.md) for fixture isolation and model-validation boundaries.
