This repository publishes three language SDKs plus a Node-only CLI from one shared webhook contract and one shared API contract.
- Node SDK:
@primitivedotdev/sdk - Node CLI:
primitive(also mirrored asprimcliand the legacy scoped@primitivedotdev/cli) - Python:
primitivedotdev - Go:
github.com/primitivedotdev/sdks/sdk-go
Use this process when cutting a release for one or more packages.
Releases are automated from main.
- If a PR merges with a new
sdk-node/package.jsonversion, GitHub Actions publishes the Node SDK. - If a PR merges with a new
cli-node/package.jsonversion, GitHub Actions publishes the CLI. - If a PR merges with a new
sdk-python/pyproject.tomlversion, GitHub Actions publishes the Python SDK. - If a PR merges with a new
sdk-go/VERSIONvalue, GitHub Actions creates the Go module tag and GitHub release.
- Confirm the working tree is clean.
- Update the relevant SDK version metadata in a release PR.
- If the webhook contract or API contract changed, regenerate artifacts for each affected SDK.
- Ensure the release PR passes the required
SDK Checksworkflow. - Review the SDK README and changelog notes for any public API changes.
- Merge the release PR into
main.
- Open a PR that bumps
sdk-node/package.jsonto the target version. - Merge that PR into
main. - The
Node Releaseworkflow verifies the version bump, publishes to npm through trusted publishing/OIDC, and creates thesdk-node/vX.Y.Ztag plus a GitHub release. - Verify the package contents with
npm view @primitivedotdev/sdk version. - Confirm the packed artifact exposes
@primitivedotdev/sdk,@primitivedotdev/sdk/webhook,@primitivedotdev/sdk/api,@primitivedotdev/sdk/openapi,@primitivedotdev/sdk/contract, and@primitivedotdev/sdk/parser, and that it does NOT install aprimitivebin (the CLI lives in the separateprimitivepackage).
- Open a PR that bumps
cli-node/package.jsonto the target version. - Merge that PR into
main. - The
CLI Releaseworkflow verifies the version bump, publishes to npm through trusted publishing/OIDC, and creates thecli-node/vX.Y.Ztag plus a GitHub release. - Verify the package contents with
npm view primitive version. - Confirm the packed artifact exposes the
primitivebin and thatprimitive list-operationssucceeds in a fresh install.
The same workflow also publishes the CLI under two mirror names (via scripts/cli-mirror-publish.sh): primcli and the legacy scoped @primitivedotdev/cli (kept so existing scoped installs keep receiving releases). Each mirror is the identical build with only the package name changed, locked to the same version, so npm install -g primitive, npm install -g primcli, and npm install -g @primitivedotdev/cli are interchangeable. The mirror publishes are no-ops when that version already exists, so a re-run is safe. After a release, verify with npm view primcli version and npm view @primitivedotdev/cli version.
The unscoped name primcli is used because npm normalizes package names by stripping -/_/. before checking for collisions, so an all-one-word primitivecli collides with the unrelated existing primitive-cli and is rejected at publish.
Coordinate Node SDK and CLI releases when both ship in the same cycle: cut the SDK first (so its npm version is available), then bump CLI's @primitivedotdev/sdk dep range if needed and ship CLI.
Both npm packages use npm trusted publishing from GitHub Actions. Do not add npm API tokens; configure npmjs trusted publishers for @primitivedotdev/sdk with .github/workflows/node-release.yml and primitive with .github/workflows/cli-release.yml.
Each mirror (primcli and @primitivedotdev/cli) needs its own npm trusted publisher (same .github/workflows/cli-release.yml). All three names already have trusted publishers configured for this workflow (each published from it before or after the rename), so no npm-side changes are needed; the workflow keeps the mirrors in lockstep. For any future new mirror name: npm trusted publishing requires the package to already exist, so claim the name with a one-time manual npm publish first (primcli was claimed at primcli@1.2.0).
- Open a PR that bumps
sdk-python/pyproject.tomlto the target version. - Merge that PR into
main. - The
Python Releaseworkflow verifies the version bump, publishes to PyPI, and creates thesdk-python/vX.Y.Ztag plus a GitHub release. - Verify the release on PyPI.
- Ensure the
sdk-go/module contents are ready to tag. - Open a PR that updates
sdk-go/VERSIONto the target version, for example0.1.0. - Merge that PR into
main. - The
Go Releaseworkflow creates the subdirectory-prefixedsdk-go/vX.Y.Ztag plus a GitHub release. - Verify the subdirectory-prefixed tag resolves correctly through the Go module proxy.
The repository initializes sdk-go/VERSION with unreleased so the first automation PR does not publish a Go tag. The first real Go release happens when that file changes to a semantic version.
If a release includes schema or shared-fixture changes:
- Update
json-schema/email-received-event.schema.json. - Regenerate SDK artifacts.
- Update
test-fixtures/if the behavioral contract changed. - Ensure the PR passes
SDK Checksagain before merging.
If a release includes API spec changes:
- Update
openapi/primitive-api.yaml. - Regenerate the Node, Python, and Go API clients.
- Ensure the PR passes
SDK Checksagain before merging.