Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,10 @@ Tagged commits trigger CI to publish:
- npm (public): [`@o1-labs/mina-archive-node-graphql`](https://www.npmjs.com/package/@o1-labs/mina-archive-node-graphql)
- Docker (GHCR): `ghcr.io/o1-labs/archive-node-api`

Normal releases after `1.0.0` are cut with:

```sh
npm version <major|minor|patch>
git push --follow-tags
```

For the initial `1.0.0` tag and current npm trusted-publishing caveat, see
the [versioning & schema stability policy](./docs/versioning.md#releasing).
A release PR bumps `package.json`, then a maintainer tags its merge commit. Do
not run `npm version` on `main`: `package.json` already carries the version
being released. Steps and the npm trusted-publishing caveat are in the
[versioning & schema stability policy](./docs/versioning.md#releasing).

CI builds, publishes the npm package with provenance once npm trusted
publishing is configured, and pushes Docker tags `1.2.3`, `1.2`, `1`,
Expand Down
2 changes: 1 addition & 1 deletion docs/runbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Recovery semantics to expect:
- Rolling update; `terminationGracePeriodSeconds: 30` lets in-flight requests
drain (the app shuts down gracefully on SIGTERM and flushes traces).
- Readiness gates traffic to new pods until they can reach the DB.
- Roll back within the 1.0.x line — the service is stateless and carries no
- Roll back to any 1.0.0 or later image — the service is stateless and carries no
migrations. Do **not** roll back to a 0.0.x image while readiness targets
`/readiness`: that path 404s, no pod goes Ready, and the Service loses all
endpoints.
105 changes: 78 additions & 27 deletions docs/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ public contract.
Given `MAJOR.MINOR.PATCH`:

- **MAJOR** — a backwards-incompatible change to the public contract (see
"Breaking changes" below). Consumers may need to update queries or config.
"Breaking changes" below), or an alignment major shared with the client SDKs
(see "One major across the server and the SDKs"). Release notes say which;
an alignment major needs no consumer action.
- **MINOR** — backwards-compatible additions: new schema fields/types/arguments,
new optional config, new endpoints. Existing queries keep working.
- **PATCH** — backwards-compatible bug fixes and internal changes.
Expand Down Expand Up @@ -106,7 +108,7 @@ We prefer deprecation over removal:

1. Mark schema elements with the `@deprecated(reason: "…")` directive, pointing to
the replacement and planned removal target, for example
`"Use X. Removed in 2.0.0, no earlier than 2026-11-15."`.
`"Use X. Removed in 3.0.0, no earlier than 2027-03-01."`.
2. Announce the deprecation in the GitHub release notes for the minor that
introduces it. The 90-day clock starts when that release is published.
3. Keep the deprecated element working for **at least one minor release and 90
Expand All @@ -124,16 +126,22 @@ reviewed decision that must be paired with a major version bump.

## Releasing

Releases are cut from `main` by a maintainer:
Releases are cut in two steps:

```sh
npm version <major|minor|patch> # bumps package.json + creates a git tag
git push --follow-tags # tag push triggers the publish pipeline
```
1. A release PR bumps `package.json`/`package-lock.json` (and
`src/schema-version.ts` if the schema moved) and merges to `main`.
2. A maintainer tags that merge commit from a checkout of it, so the tag and
the published version cannot disagree; the tag push triggers the publish
pipeline:

```sh
git checkout <merge-sha>
git tag v$(node -p "require('./package.json').version")
git push origin v$(node -p "require('./package.json').version")
```

For the initial `1.0.0` release only, `package.json` on `main` already carries
the version to release. Tag it directly (`git tag v1.0.0 && git push
--follow-tags`) rather than running `npm version`, which would bump past it.
Do not run `npm version` on `main`: `package.json` already carries the version
being released, and `npm version` would bump past it.

CI then builds and publishes the npm package (with provenance, once npm trusted
publishing is configured for this repository) and the Docker images. Choose the
Expand All @@ -159,21 +167,40 @@ registry logins and `npm publish`. Changing the step order, or reintroducing a
stored credential, undoes both properties — see the ordering comment at the top
of the job.

## Migrating from npm `0.0.6`
## Upgrading to 2.0.0

npm never received 1.0.x (only `0.0.6` is published), so npm consumers go
straight from `0.0.6` to `2.0.0`: apply both lists below. Container users on
1.0.0 need only the second.

Tags `0.0.7` through `0.0.9` existed in git but were not published to npm, so
npm consumers should treat `1.0.0` as an upgrade from `0.0.6`. Review these
operator-visible changes before rolling out:
### From `0.0.6` (changes that shipped in git tag 1.0.0)

- Browser deployments must set `CORS_ORIGIN` deliberately.
- Rate limiting is enabled and depends on the correct `TRUST_PROXY` hop count.
- The supported Node.js runtime moves to Node 22.12 (`engines`); the 1.0.x
container image runs Node 22.
- The supported Node.js runtime moves to Node 22.12 (`engines`).
- Boolean environment variables reject junk values instead of relying on
JavaScript truthiness.
- `actions` result semantics include correctness fixes called out in the release
notes.

### From 1.0.0

2.0.0 is an alignment major (see "One major across the server and the SDKs"):
no query that worked against 1.0.0 changes its result shape. Review:

- The container image runs Node 24 (LTS) and is published for linux/amd64 and
linux/arm64. `engines` is unchanged (`>=22.12.0`).
- License: Apache-2.0 (was ISC).
- New query `schemaVersion`, always served, even when `ENABLED_QUERIES`
restricts the data queries. Listing it in `ENABLED_QUERIES` is accepted.
- New query `zkappCommands`, off unless `ENABLE_ZKAPP_COMMANDS_QUERY=true`;
bounded by `ZKAPP_COMMAND_RANGE_SIZE` (1000) and
`ZKAPP_COMMAND_ACCOUNT_UPDATE_LIMIT` (5000).
- `ENABLED_QUERIES` now accepts `verificationKeyUpdates` (1.0.0 failed startup
on it) and `zkappCommands`.
- Eight list positions declare non-null elements (`[T]` → `[T!]`). Responses
are unchanged; codegen'd clients see stricter element types.

## Schema version

`schema.graphql` carries its own `MAJOR.MINOR` version, served by the
Expand All @@ -186,25 +213,49 @@ package version.
}
```

The server answers `"1.1"` today. Schema 1.1 is the schema that the 1.0.x
releases shipped (1.0), plus two additive changes: the `schemaVersion` query
itself and the `zkappCommands` query with its types. `zkappCommands` is off by
default (`ENABLE_ZKAPP_COMMANDS_QUERY`), but it is part of the contract, so it
moves the MINOR.
The server answers `"2.0"` today. Schema 2.0 has no breaking change against
schema 1.0, which the 1.0.x releases shipped; see "One major across the server
and the SDKs" below for why it is a major. Its changes against 1.0:

- the `schemaVersion` query itself;
- the `zkappCommands` query and its types, off by default
(`ENABLE_ZKAPP_COMMANDS_QUERY`) but part of the contract;
- non-null elements on eight list positions that never carried a null
(`[T]` → `[T!]`), which only strengthens the guarantee.

- The **package** version describes this server: its flags, its defaults, its
behaviour. The list of breaking changes above is about that.
- The **schema** version describes only what a client codes against: the types,
fields and arguments in `schema.graphql`. Its MINOR moves on an additive
change, its MAJOR on one that can break a client.
change, its MAJOR on one that can break a client or on an alignment major
shared with the SDKs.

The two move independently, and that is deliberate. A server release can change
a default or a flag without touching the contract, and a schema can gain a field
without the server's own surface changing.
Their MINOR and PATCH move independently, and that is deliberate; the MAJOR is
shared (see "One major across the server and the SDKs"). A server release can
change a default or a flag without touching the contract, and a schema can gain
a field without the server's own surface changing.

The client SDKs pin the schema version they were built against and compare it
with what `schemaVersion` reports. That is why their package versions do not
track this repository's, and do not track Mina's either — see below.
with what `schemaVersion` reports.

### One major across the server and the SDKs

This package, its schema, and the three client SDKs
([JS](https://github.com/o1-labs/mina-archive-sdk-js),
[Go](https://github.com/o1-labs/mina-archive-sdk-go),
[Rust](https://github.com/o1-labs/mina-archive-sdk-rust)) share one MAJOR.
**Same major means compatible.** A higher server minor only adds what the SDK
does not know about yet.

When any of them takes a major, all of them do, even those with no breaking
change of their own. Semver allows a major without a break; it forbids only a
break without a major. Minors and patches stay independent.

2.0.0 is the first such release: the SDKs needed a major for changes to their
own API, and this server and its schema took one to match. A 1.0.x client
keeps working against it.

Mina versions are separate — see below.

`schemaVersion` is served even when `ENABLED_QUERIES` restricts the data
queries. A compatibility check a deployment can switch off would leave clients
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@o1-labs/mina-archive-node-graphql",
"version": "1.0.1",
"version": "2.0.0",
"description": "A NodeJS GraphQL server for exposing Mina Protocol archive node data for o1js/zkApps",
"repository": {
"type": "git",
Expand Down
5 changes: 3 additions & 2 deletions src/schema-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* same major keeps working.
* - **MAJOR** for a change that can break a client: a removed or renamed field,
* a narrowed type, an argument that becomes required, or a field that becomes
* nullable when clients were entitled to assume it was not.
* nullable when clients were entitled to assume it was not. Also when the
* package or the SDKs take a major: they all share one (docs/versioning.md).
*/
export const SCHEMA_VERSION = '1.1';
export const SCHEMA_VERSION = '2.0';
Loading