Skip to content

Commit 96035c7

Browse files
authored
Merge pull request #1541 from mnfst/chore/manifest-synthetic-package
chore: introduce packages/manifest as canonical release version
2 parents d7df080 + 6ad3aa5 commit 96035c7

File tree

8 files changed

+118
-16
lines changed

8 files changed

+118
-16
lines changed

.changeset/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
"access": "public",
88
"baseBranch": "main",
99
"updateInternalDependencies": "patch",
10-
"ignore": []
10+
"ignore": ["manifest-backend", "manifest-frontend", "manifest-shared"]
1111
}

.github/workflows/docker.yml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ on:
44
workflow_dispatch:
55
inputs:
66
version:
7-
description: "Version to publish (e.g. 5.38.1)"
8-
required: true
7+
description: "Optional version override (e.g. 5.38.1). Leave blank to use the current version from packages/manifest/package.json."
8+
required: false
99
type: string
1010
pull_request:
1111
branches: [main]
@@ -55,6 +55,18 @@ jobs:
5555
steps:
5656
- uses: actions/checkout@v4
5757

58+
- name: Resolve version
59+
id: version
60+
run: |
61+
if [ -n "${{ inputs.version }}" ]; then
62+
VERSION="${{ inputs.version }}"
63+
echo "Using version from workflow input: $VERSION"
64+
else
65+
VERSION=$(jq -r .version packages/manifest/package.json)
66+
echo "Using version from packages/manifest/package.json: $VERSION"
67+
fi
68+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
69+
5870
- uses: docker/setup-qemu-action@v3
5971

6072
- uses: docker/setup-buildx-action@v3
@@ -69,9 +81,9 @@ jobs:
6981
with:
7082
images: manifestdotbuild/manifest
7183
tags: |
72-
type=semver,pattern={{version}},value=${{ inputs.version }}
73-
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.version }}
74-
type=semver,pattern={{major}},value=${{ inputs.version }}
84+
type=semver,pattern={{version}},value=${{ steps.version.outputs.version }}
85+
type=semver,pattern={{major}}.{{minor}},value=${{ steps.version.outputs.version }}
86+
type=semver,pattern={{major}},value=${{ steps.version.outputs.version }}
7587
type=sha
7688
7789
- uses: docker/build-push-action@v6

CLAUDE.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -481,13 +481,43 @@ All pricing comes from a single source:
481481

482482
## Releases
483483

484-
There are **no publishable npm packages** in this repo anymore. `packages/backend`, `packages/frontend`, and `packages/shared` are all `private: true`. Manifest ships exclusively as the Docker image at `manifestdotbuild/manifest` (built from `docker/Dockerfile`).
484+
There are **no publishable npm packages** in this repo. `packages/backend`, `packages/frontend`, `packages/shared`, and `packages/manifest` are all `private: true`. Manifest ships exclusively as the Docker image at `manifestdotbuild/manifest` (built from `docker/Dockerfile`).
485485

486-
Changesets are still installed and wired into the release workflow for internal `CHANGELOG.md` bookkeeping on private packages — they are **not** required on every PR. Use `npx changeset add --empty` if you want to record a changelog entry for a private-package change, otherwise skip it.
486+
### `packages/manifest/` is the canonical version
487487

488-
The Docker image is built and published via `.github/workflows/docker.yml`:
489-
- **PR**: validates the Docker build on changes to `docker/`, `.dockerignore`, `packages/backend/`, `packages/frontend/`, `packages/shared/`, or root `package.json`/`turbo.json`.
490-
- **Manual publish**: `workflow_dispatch` with a `version` input, run by a maintainer when a new image tag should be pushed.
488+
`packages/manifest/` is a **code-free shell package** that exists only to hold the canonical "Manifest version". It has no `src/`, no tests, no dependencies — just `package.json`, `README.md`, and (after the first release) a `CHANGELOG.md`. The real backend and frontend live under `packages/backend/` and `packages/frontend/` as before.
489+
490+
`.changeset/config.json` has `"ignore": ["manifest-backend", "manifest-frontend", "manifest-shared"]`, so when a contributor runs `npx changeset`, **only `manifest` is a selectable target**. Bumps to `manifest-backend` / `manifest-frontend` / `manifest-shared` are silently discarded. Always target `manifest` regardless of which files you actually changed.
491+
492+
### Adding a changeset
493+
494+
```bash
495+
npx changeset
496+
# → select "manifest"
497+
# → choose patch / minor / major
498+
# → write a one-line summary (this becomes the CHANGELOG entry)
499+
```
500+
501+
Commit the generated `.changeset/*.md` file alongside your code. On merge to `main`, `release.yml` runs `changesets/action`, which opens (or updates) a `chore: version packages` PR bumping `packages/manifest/package.json` and appending to `packages/manifest/CHANGELOG.md`.
502+
503+
Changesets are **not** required on every PR — they're optional and only meaningful for changes you want in the changelog. Use `npx changeset add --empty` for purely internal work if you want an explicit "no release" marker.
504+
505+
### Cutting a Docker release
506+
507+
1. Merge the pending `chore: version packages` PR to land the version bump in `packages/manifest/package.json`.
508+
2. Go to **GitHub Actions → Docker → Run workflow**, leave the `version` input blank, click Run.
509+
3. The `publish` job reads `packages/manifest/package.json`, resolves the version automatically, and pushes `manifestdotbuild/manifest:{version}` + `{major}.{minor}` + `{major}` + `sha-<short>` to Docker Hub. The image is multi-arch (amd64 + arm64) and cosign-signed.
510+
511+
To retag an older commit or publish a hotfix version that doesn't match the current `package.json`, pass a semver string in the `version` input and it overrides the package.json lookup.
512+
513+
### Summary of what CI does on each trigger
514+
515+
| Trigger | What happens |
516+
|---------|--------------|
517+
| PR opened/updated | `ci.yml` runs tests, lint, typecheck, coverage. `docker.yml` validates the Docker build (no push) if the PR touches runtime files. `changeset-check` warns softly if no changeset is present. |
518+
| Merge to `main` | `release.yml` runs `changesets/action` to open or update the `chore: version packages` PR. **No auto-publish** — neither npm nor Docker. |
519+
| Merge of `chore: version packages` PR | `release.yml` runs again. Version bump in `packages/manifest/package.json` and the CHANGELOG update land on `main`. Still no publish. |
520+
| Manual `workflow_dispatch` on `Docker` workflow | Reads `packages/manifest/package.json` and pushes a new image tag to Docker Hub. This is the **only** path that publishes anything. |
491521

492522
## Code Coverage (Codecov)
493523

CONTRIBUTING.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,20 @@ The backend runs standalone and OpenClaw talks to it as a regular OpenAI-compati
150150
1. Create a branch from `main` for your change
151151
2. Make your changes in the relevant package(s)
152152
3. Write or update tests as needed
153-
4. Run the test suite to make sure everything passes:
153+
4. Add a changeset if your change should appear in the release notes:
154+
155+
```bash
156+
npx changeset
157+
# → select "manifest"
158+
# → choose patch / minor / major
159+
# → write a one-line summary
160+
```
161+
162+
Always target `manifest` — it's the canonical release version for the whole project, and it's the only package changesets will accept. `manifest-backend`, `manifest-frontend`, and `manifest-shared` are ignored regardless of what you pick. Commit the generated `.changeset/*.md` alongside your code. Changesets are optional for internal/tooling changes; skip this step if the change doesn't need a CHANGELOG entry.
163+
164+
See [`packages/manifest/README.md`](packages/manifest/README.md) for why this package exists.
165+
166+
5. Run the test suite to make sure everything passes:
154167

155168
```bash
156169
npm test --workspace=packages/shared
@@ -159,13 +172,23 @@ npm run test:e2e --workspace=packages/backend
159172
npm test --workspace=packages/frontend
160173
```
161174

162-
5. Verify the production build works:
175+
6. Verify the production build works:
163176

164177
```bash
165178
npm run build
166179
```
167180

168-
6. Open a pull request against `main`
181+
7. Open a pull request against `main`
182+
183+
### Cutting a Docker release
184+
185+
Manifest ships as the Docker image at [`manifestdotbuild/manifest`](https://hub.docker.com/r/manifestdotbuild/manifest). Releases are manual:
186+
187+
1. After merging PRs with changesets, a `chore: version packages` PR will be open on `main` — merge it to land the version bump in `packages/manifest/package.json` and update `packages/manifest/CHANGELOG.md`.
188+
2. Go to **GitHub Actions → Docker → Run workflow**, leave the `version` input blank, click Run.
189+
3. The workflow reads the version from `packages/manifest/package.json` and pushes `manifestdotbuild/manifest:{version}` (plus `{major}.{minor}`, `{major}`, and a `sha-<short>` rollback tag).
190+
191+
If you need to retag an older commit or publish a version that doesn't match the current `package.json`, pass a semver string in the `version` input and it overrides the auto-detected value.
169192

170193
### Commit Messages
171194

package-lock.json

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
"workspaces": [
3030
"packages/shared",
3131
"packages/frontend",
32-
"packages/backend"
32+
"packages/backend",
33+
"packages/manifest"
3334
],
3435
"scripts": {
3536
"dev": "turbo dev",

packages/manifest/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# manifest
2+
3+
This package exists to hold the canonical **Manifest release version**.
4+
5+
It contains no code. The real backend and frontend live in [`../backend`](../backend) and [`../frontend`](../frontend), and shared types in [`../shared`](../shared). The Docker image at [`manifestdotbuild/manifest`](https://hub.docker.com/r/manifestdotbuild/manifest) bundles the built backend + frontend.
6+
7+
## What it's for
8+
9+
- **Changesets target**: `.changeset/config.json` ignores `manifest-backend`, `manifest-frontend`, and `manifest-shared`, so when contributors run `npx changeset` the only selectable package is this one. Always target `manifest` regardless of which files you actually changed — this is the single source of truth for "the version of Manifest as a whole".
10+
- **Docker release version**: `.github/workflows/docker.yml` reads the `version` field from this package's `package.json` via `jq` and uses it to tag the image (`manifestdotbuild/manifest:{version}` + derived `{major}.{minor}` / `{major}` / `sha-<short>` tags).
11+
- **Changelog**: `CHANGELOG.md` here (auto-generated by changesets) is the unified Manifest release history.
12+
13+
## Adding a changeset
14+
15+
```bash
16+
npx changeset
17+
# → select "manifest"
18+
# → choose patch / minor / major
19+
# → write a one-line summary
20+
```
21+
22+
Commit the generated file. On merge to `main`, the release workflow opens a `chore: version packages` PR bumping `version` and appending to `CHANGELOG.md`. Merge that PR to land the version bump, then manually run the Docker workflow (`Actions → Docker → Run workflow` with a blank input) to publish.

packages/manifest/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "manifest",
3+
"version": "5.46.0",
4+
"private": true,
5+
"description": "Canonical release version for the Manifest Docker image. This package holds no code — the real backend and frontend live in ../backend and ../frontend. See README.md for details."
6+
}

0 commit comments

Comments
 (0)