Skip to content

Commit caf3ead

Browse files
committed
Merge remote-tracking branch 'origin/main' into better-docker
# Conflicts: # .github/workflows/docker.yml # docker/DOCKER_README.md
2 parents 0aa844b + 478e1b7 commit caf3ead

File tree

3 files changed

+66
-22
lines changed

3 files changed

+66
-22
lines changed

.github/workflows/docker.yml

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@ on:
77
description: "Optional version override (e.g. 5.38.1). Leave blank to use the current version from packages/manifest/package.json."
88
required: false
99
type: string
10+
push:
11+
branches: [main]
12+
paths:
13+
- "docker/DOCKER_README.md"
14+
- ".github/workflows/docker.yml"
1015
pull_request:
1116
branches: [main]
1217
paths:
1318
- "docker/Dockerfile"
1419
- ".dockerignore"
1520
- "docker/docker-compose.yml"
1621
- "docker/.env.example"
17-
- "docker/DOCKER_README.md"
1822
- "docker/install.sh"
1923
- "packages/backend/**"
2024
- "packages/frontend/**"
@@ -115,11 +119,31 @@ jobs:
115119
cosign sign --yes "${tag}@${DIGEST}"
116120
done
117121
118-
- name: Sync README to Docker Hub
119-
uses: peter-evans/dockerhub-description@v4
120-
with:
121-
username: ${{ secrets.DOCKERHUB_USERNAME }}
122-
password: ${{ secrets.DOCKERHUB_TOKEN }}
123-
repository: manifestdotbuild/manifest
124-
short-description: "Smart LLM router for personal AI agents. Self-host with Docker."
125-
readme-filepath: ./docker/DOCKER_README.md
122+
sync-description:
123+
name: Sync Docker Hub description
124+
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
125+
runs-on: ubuntu-latest
126+
steps:
127+
- uses: actions/checkout@v4
128+
129+
- name: Push README to Docker Hub
130+
env:
131+
DOCKER_USER: ${{ secrets.DOCKERHUB_USERNAME }}
132+
DOCKER_PASS: ${{ secrets.DOCKERHUB_TOKEN }}
133+
run: |
134+
# Pinned to immutable digest for supply-chain safety.
135+
# The underlying tool is chko/docker-pushrm:1. When bumping the tag,
136+
# fetch the current digest with:
137+
# TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:chko/docker-pushrm:pull" | jq -r .token)
138+
# curl -sI -H "Authorization: Bearer $TOKEN" \
139+
# -H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
140+
# https://registry-1.docker.io/v2/chko/docker-pushrm/manifests/1 | grep -i docker-content-digest
141+
docker run --rm \
142+
-v "$GITHUB_WORKSPACE/docker/DOCKER_README.md:/data/README.md:ro" \
143+
-e DOCKER_USER \
144+
-e DOCKER_PASS \
145+
chko/docker-pushrm@sha256:812a950e5be7dca26cef33b61eb2076bfcfb6c2a8ec96c126371fc049c3b6608 \
146+
--file /data/README.md \
147+
--short "Smart LLM router for personal AI agents. Cut costs up to 70%." \
148+
--debug \
149+
manifestdotbuild/manifest

CLAUDE.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -506,18 +506,24 @@ Changesets are **not** required on every PR — they're optional and only meanin
506506

507507
1. Merge the pending `chore: version packages` PR to land the version bump in `packages/manifest/package.json`.
508508
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.
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. The `sync-description` job also runs in the same workflow_dispatch and pushes the latest `docker/DOCKER_README.md` to the Docker Hub repo description.
510510

511511
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.
512512

513+
### Docker Hub description
514+
515+
`docker/DOCKER_README.md` is the source of truth for the Docker Hub repo description at [`manifestdotbuild/manifest`](https://hub.docker.com/r/manifestdotbuild/manifest). The `sync-description` job in `docker.yml` pushes it to Docker Hub via the [`chko/docker-pushrm`](https://github.com/christian-korneck/docker-pushrm) container image (standalone `docker run`, no third-party GitHub Action). It uses the same `DOCKERHUB_USERNAME` / `DOCKERHUB_TOKEN` secrets as the publish job — the Docker Hub PAT needs write access to the repo, which the existing token already has for image pushes. Edits to `docker/DOCKER_README.md` are treated as doc-only: they do **not** trigger the PR validate job (no point rebuilding multi-arch images for content changes), and they auto-sync to Docker Hub on merge to main via a dedicated `push:` trigger with a narrow paths filter. The `chko/docker-pushrm` image is pinned to an immutable digest in the workflow — when bumping, re-fetch the digest via `docker manifest inspect chko/docker-pushrm:1` or the registry API (see the inline comment in `docker.yml`).
516+
513517
### Summary of what CI does on each trigger
514518

515519
| Trigger | What happens |
516520
|---------|--------------|
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. |
521+
| PR opened/updated (runtime files) | `ci.yml` runs tests, lint, typecheck, coverage. `docker.yml` validates the Docker build (no push). `changeset-check` warns softly if no changeset is present. |
522+
| PR opened/updated (`docker/DOCKER_README.md` only) | No Docker CI runs — content-only change, nothing to validate. |
518523
| 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. |
524+
| 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 image publish. |
525+
| Merge of a PR that touched `docker/DOCKER_README.md` | `docker.yml` `sync-description` job runs, pushing the new README to Docker Hub via `chko/docker-pushrm`. No image rebuild. |
526+
| Manual `workflow_dispatch` on `Docker` workflow | `publish` job reads `packages/manifest/package.json` and pushes a new image tag to Docker Hub. `sync-description` also runs in parallel and re-syncs the Docker Hub description. This is the **only** path that publishes image artifacts. |
521527

522528
## Code Coverage (Codecov)
523529

docker/DOCKER_README.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
</picture>
77
</p>
88
<p align="center">
9-
<a href="https://github.com/mnfst/manifest/stargazers"><img src="https://img.shields.io/github/stars/mnfst/manifest?style=flat" alt="GitHub stars" /></a>
9+
<a href="https://hub.docker.com/r/manifestdotbuild/manifest"><img src="https://img.shields.io/docker/pulls/manifestdotbuild/manifest?color=2496ED&label=docker%20pulls" alt="Docker pulls" /></a>
1010
&nbsp;
11-
<a href="https://www.npmjs.com/package/manifest"><img src="https://img.shields.io/npm/v/manifest?color=cb3837&label=npm" alt="npm version" /></a>
11+
<a href="https://github.com/mnfst/manifest/stargazers"><img src="https://img.shields.io/github/stars/mnfst/manifest?style=flat" alt="GitHub stars" /></a>
1212
&nbsp;
1313
<a href="https://github.com/mnfst/manifest/blob/main/LICENSE"><img src="https://img.shields.io/github/license/mnfst/manifest?color=blue" alt="license" /></a>
1414
&nbsp;
@@ -17,13 +17,14 @@
1717

1818
## What is Manifest?
1919

20-
Manifest is a smart model router for personal AI agents like OpenClaw, Hermes, or anything speaking the OpenAI-compatible HTTP API. It sits between your agent and your LLM providers, scores each request, and routes it to the cheapest model that can handle it. Simple questions go to fast, cheap models. Hard problems go to expensive ones. You save money without thinking about it.
20+
Manifest is a smart model router for **personal AI agents** like OpenClaw, Hermes, or anything speaking the OpenAI-compatible HTTP API. It sits between your agent and your LLM providers, scores each request, and routes it to the cheapest model that can handle it. Simple questions go to fast, cheap models. Hard problems go to expensive ones. You save money without thinking about it.
2121

22-
- Route requests to the right model: Cut costs up to 70%
23-
- Automatic fallbacks: If a model fails, the next one picks up
24-
- Set limits: Don't exceed your budget
22+
- Route requests to the right model: cut costs up to 70%
23+
- Automatic fallbacks: if a model fails, the next one picks up
24+
- Set limits: don't exceed your budget
25+
- Self-hosted: your requests, your providers, your data
2526

26-
![manifest-gh](https://github.com/user-attachments/assets/7dd74fc2-f7d6-4558-a95a-014ed754a125)
27+
![manifest-gh](https://raw.githubusercontent.com/mnfst/manifest/HEAD/.github/assets/manifest-screenshot.png)
2728

2829
## Table of contents
2930

@@ -35,14 +36,15 @@ Manifest is a smart model router for personal AI agents like OpenClaw, Hermes, o
3536
- [Option 3: One-command install script](#option-3-one-command-install-script)
3637
- [Verifying the image signature](#verifying-the-image-signature)
3738
- [Custom port](#custom-port)
39+
- [Image tags](#image-tags)
3840
- [Upgrading](#upgrading)
3941
- [Backup & persistence](#backup--persistence)
4042
- [Environment variables](#environment-variables)
4143
- [Links](#links)
4244

4345
## Supported providers
4446

45-
Works with 300+ models across OpenAI, Anthropic, Google Gemini, DeepSeek, xAI, Mistral, Qwen, MiniMax, Kimi, Z.ai, GitHub Copilot, OpenRouter, Ollama, and any provider with an OpenAI-compatible API. Reuse an existing paid subscription where supported (ChatGPT Plus/Pro, Claude Max/Pro, Copilot, MiniMax Coding Plan, GLM Coding Plan, Ollama Cloud).
47+
Works with 300+ models across OpenAI, Anthropic, Google Gemini, DeepSeek, xAI, Mistral, Qwen, MiniMax, Kimi, Amazon Nova, Z.ai, OpenRouter, Ollama, and any provider with an OpenAI-compatible API. Connect with an API key, or reuse an existing paid subscription (ChatGPT Plus/Pro, Claude Max/Pro, GLM Coding Plan, etc.) where supported.
4648

4749
## Manifest vs OpenRouter
4850

@@ -51,7 +53,7 @@ Works with 300+ models across OpenAI, Anthropic, Google Gemini, DeepSeek, xAI, M
5153
| Architecture | Your Manifest instance forwards to your providers | Cloud proxy. All traffic goes through their servers |
5254
| Cost | Free | 5% fee on every API call |
5355
| Source code | MIT, fully open | Proprietary |
54-
| Data privacy | Metadata only (Cloud), no middleman (self-hosted) | Prompts and responses pass through a third party |
56+
| Data privacy | Self-hosted — no middleman | Prompts and responses pass through a third party |
5557
| Transparency | Open scoring. You see why a model was chosen | No visibility into routing decisions |
5658

5759
---
@@ -197,6 +199,18 @@ environment:
197199
198200
If you see "Invalid origin" on the login page, `BETTER_AUTH_URL` doesn't match the port you're using.
199201

202+
## Image tags
203+
204+
Every release is published with the following tags:
205+
206+
- `{major}.{minor}.{patch}` — fully pinned (e.g. `5.46.0`)
207+
- `{major}.{minor}` — latest patch within a minor (e.g. `5.46`)
208+
- `{major}` — latest minor+patch within a major (e.g. `5`)
209+
- `latest` — latest stable release
210+
- `sha-<short>` — exact commit for rollback
211+
212+
Images are built for both `linux/amd64` and `linux/arm64`.
213+
200214
## Upgrading
201215

202216
Manifest ships a new image on every release. To upgrade an existing compose install:

0 commit comments

Comments
 (0)