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
2 changes: 1 addition & 1 deletion .agents/skills/mops-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,4 @@ To update tools later: `mops toolchain update moc` or `mops toolchain update` (a

## Editing the mops docs site

Edits go to `docs/docs/` — the in-development 3.x line, served at `docs.mops.one/next/` during the 3.x preview. `docs/versioned_docs/version-2.x/` is the released line, served at the root, and is a frozen snapshot; back-port only correctness fixes for behavior that also exists in 2.x. The two swap back at the 3.0.0 GA.
Edits go to `docs/docs/` — the in-development 3.x line, served at `docs.mops.one/next` during the 3.x preview. `docs/versioned_docs/version-2.x/` is the released line, served at the root, and is a frozen snapshot; back-port only correctness fixes for behavior that also exists in 2.x. The two swap back at the 3.0.0 GA.
7 changes: 3 additions & 4 deletions .github/actions/deploy-canister/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ runs:
done
exit 1

# The custom domain resolves only while the canister serves this file, and
# it is served only because an .ic-assets.json opts dot-directories into the
# upload. Assert the body, not the status: the asset canister answers
# unknown paths with the root index.html at HTTP 200.
# The custom domain resolves only while the canister serves this file.
# Assert the body, not the status: the legacy asset canister still behind
# `cli` answers unknown paths with the root index.html at HTTP 200.
- name: Verify the custom domain still resolves
shell: bash
env:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ jobs:
echo "> published to npm only and are not uploaded to the cli-releases canister."
echo "> Use the npm command above to move between betas."
echo ""
echo "Docs for this line: https://docs.mops.one/next/"
# No trailing slash — the docs canister 307s `/next/` to `/next`.
echo "Docs for this line: https://docs.mops.one/next"
echo ""
} > /tmp/release-notes.md

Expand Down Expand Up @@ -351,7 +352,7 @@ jobs:
# stable-only. Previews are npm-only: no cli-releases artifacts, no cli
# canister upload, so `mops self update` keeps serving the latest 2.x.
# Said so in the notes. The docs deploy itself is deliberately ungated:
# it is what publishes docs.mops.one/next/, which the preview notes
# it is what publishes docs.mops.one/next, which the preview notes
# point 3.x users at.

- name: Generate on-chain release artifacts
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file provides guidance to AI coding agents when working with code in this r

- **Always create a PR.** Never push directly to `main`.
- **CLI design philosophy**: Follow conventions of established package managers (npm, cargo) — naming, flag style, UX patterns. Related commands must stay consistent: if `mops build` works without arguments (all canisters), then `mops check` and `mops check-stable` must too. When changing a command, review its siblings for consistency.
- **Keep docs in sync.** CLI command docs live in `docs/docs/cli/` and config reference in `docs/docs/09-mops.toml.md`. The same feature often appears in both — update all relevant pages. `docs/docs/` is the in-development 3.x line, served at `docs.mops.one/next/` during the 3.x preview; `docs/versioned_docs/version-2.x/` is the released line, served at the site root, and is a frozen snapshot — back-port only correctness fixes for behavior that also exists in 2.x. The two swap back at the 3.0.0 GA.
- **Keep docs in sync.** CLI command docs live in `docs/docs/cli/` and config reference in `docs/docs/09-mops.toml.md`. The same feature often appears in both — update all relevant pages. `docs/docs/` is the in-development 3.x line, served at `docs.mops.one/next` during the 3.x preview; `docs/versioned_docs/version-2.x/` is the released line, served at the site root, and is a frozen snapshot — back-port only correctness fixes for behavior that also exists in 2.x. The two swap back at the 3.0.0 GA.
- **Keep `--help` in sync with the docs.** A command's `--help` should be a concise summary of its doc page: every option and accepted argument (including the `-- <tool flags>` passthrough, via `.addHelpText`) must appear in `--help`, each with a non-empty description. Don't bloat it with prose — link-level detail stays in the docs.
- **Update the changelog.** Add entries under `## Next` in `cli/CHANGELOG.md` for any user-facing CLI changes.
- **Keep skills up to date.** When changing CLI commands or workflows, update `.agents/skills/mops-cli/SKILL.md` to match.
Expand Down Expand Up @@ -91,6 +91,7 @@ Svelte 5 + Vite 8, queries the main canister. Staging canister: `ogp6e-diaaa-aaa
- **Nothing in this repo touches dfx.** Every canister deploy runs on `icp` (config in `icp.yaml`) — local, staging, mainnet and `release.yml` alike — `npm run decl` uses `mops` + `icp-bindgen`, and no workflow installs dfx. Every test replica is PocketIC: `mops.toml` pins `[toolchain] pocket-ic`, which the published 2.x CLI honours over its dfx fallback, so the matrix in `mops-test.yml` needs no dfx either. Keep it that way — if a test starts needing a replica, pin the version, do not reach for dfx.
- **Canister IDs**: icp-cli cannot declare an ID in `icp.yaml`; it reads them from its own store, split by network type. Connected networks live in `.icp/data/mappings/<environment>.ids.json` and **are committed** — that is what lets a fresh checkout deploy without relinking. Managed (local) networks land in `.icp/cache/mappings/`, which is ignored. Add a new mainnet canister with `icp canister link <name> <id> -e ic` and commit the resulting mapping. Mainnet deploys pass `--no-create`, so a missing mapping fails loudly instead of creating a new canister.
- **Deploy environments** are declared explicitly in `icp.yaml`: `ic` excludes `bench`, and `staging` covers only `main` and `assets` because `docs`/`blog`/`cli` have no staging canister of their own.
- **Asset canisters are mid-migration.** `docs` runs dfinity's certified-assets canister (`@dfinity/static-site`); `assets`, `blog`, `play-frontend` and `cli` still run the legacy dfx-era `@dfinity/asset-canister`. Load-bearing differences: legacy serves unknown paths as the root `index.html` at HTTP 200 (so deploy assertions grep bodies, never statuses) and needs an `.ic-assets.json` to upload `.well-known/`; `static-site` returns real 404s, uploads `.well-known/` by default, and canonicalises clean URLs — `docs/docusaurus.config.js` must keep `trailingSlash: false`. Moving a canister between the two is a one-off `icp deploy <name> -e ic --identity mops --no-create -m reinstall` (incompatible wasms; the ID and custom domain survive, assets re-sync). `static-site` is 0.x and a minor bump is breaking by its own policy. `cli` cannot move yet: `static-site` takes a single `dir` and that canister serves two.
- **icp-cli version**: pinned in `.github/workflows/ci.yml`; the `icp.yaml` recipes are pinned by version and sha256, and the local network pins its `icp-cli-network-launcher` `version` (unpinned, every cold start asks api.github.com for the newest release — an anonymous request that gets rate-limited on CI runners, and an unpinned replica under the tests). icp-cli still makes breaking manifest changes between minor versions, so do not unpin anything and do not run `icp network update`. To move versions, bump the CI pin, the recipes and the launcher pin together and re-run the local pipeline.
- **Declarations must be regenerated** after backend changes: `npm run decl` (no replica needed). Two steps per canister: `mops generate candid` writes the `.did` from Motoko source with the pinned `[toolchain] moc`, then [`icp-bindgen`](https://www.npmjs.com/package/@icp-sdk/bindgen) turns it into `*.did.js` / `*.did.d.ts`. The `index.js` / `index.d.ts` actor factories next to them are hand-maintained — nothing regenerates those; add them by hand when adding a canister.
- **API version** in `cli/mops.ts` (`apiVersion`) and `backend/main/main-canister.mo` (`API_VERSION`) must match.
Expand Down
2 changes: 1 addition & 1 deletion cli/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ git tag cli-vX.Y.Z-beta.N <commit-on-v3>
git push origin cli-vX.Y.Z-beta.N
```

`release.yml` detects the prerelease by parsing the version (any prerelease component counts, not a tag pattern) and deviates from a stable release in exactly these ways: npm publish lands under the `next` dist-tag instead of `latest`, the GitHub Release is marked prerelease, and nothing is uploaded to the `cli` canister — so `mops self update` and fresh `install.sh` installs keep serving the latest stable, and no artifacts PR is created. The docs canister still deploys (previews are what publish `docs.mops.one/next/`).
`release.yml` detects the prerelease by parsing the version (any prerelease component counts, not a tag pattern) and deviates from a stable release in exactly these ways: npm publish lands under the `next` dist-tag instead of `latest`, the GitHub Release is marked prerelease, and nothing is uploaded to the `cli` canister — so `mops self update` and fresh `install.sh` installs keep serving the latest stable, and no artifacts PR is created. The docs canister still deploys (previews are what publish `docs.mops.one/next`).

Install a preview with `npm i -g ic-mops@next` or a pinned `ic-mops@X.Y.Z-beta.N`.

Expand Down
5 changes: 5 additions & 0 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ const config = {
// Set the /<baseUrl>/ pathname under which your site is served
// For GitHub pages deployment, it is often '/<projectName>/'
baseUrl: '/',
// Required by the docs canister (`@dfinity/static-site` in `icp.yaml`), which
// canonicalises clean URLs: with Docusaurus's default `<route>/index.html`
// output every deep link would 307 to the trailing-slash form. `false` emits
// `<route>.html` instead, served at the extension-less URLs with no redirect.
trailingSlash: false,

// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
Expand Down
6 changes: 0 additions & 6 deletions docs/static/.ic-assets.json

This file was deleted.

9 changes: 6 additions & 3 deletions icp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ canisters:
dir: frontend/dist
build:
- npm run build-frontend
# dfinity's certified-assets canister, unlike its legacy siblings above. The
# recipe tag pins the canister wasm and its sync plugin as a matched pair,
# `.well-known/` uploads with no opt-in file, and clean URLs are canonicalised
# — `docs/docusaurus.config.js` must keep `trailingSlash: false`. See AGENTS.md.
- name: docs
recipe:
type: "@dfinity/asset-canister@v2.3.0"
sha256: ee41744bd1361593a041d830b06ce50598cae5b21b57209fc727e8f63ae7e906
type: "@dfinity/static-site@v0.3.3"
sha256: d3493c1220b956b04225b84b2921f5a30ef39cbb8a359efb9dd3937de90e9975
configuration:
version: "0.29.1"
dir: docs/build
build:
- npm run build-docs
Expand Down
Loading