feat: migrate hello_world and who_am_i to icp-cli, add Codespaces and CI support#1346
Draft
marc0olo wants to merge 52 commits into
Draft
feat: migrate hello_world and who_am_i to icp-cli, add Codespaces and CI support#1346marc0olo wants to merge 52 commits into
marc0olo wants to merge 52 commits into
Conversation
Updates both Motoko and Rust who_am_i examples to use GitHub Codespaces instead of ICP Ninja for the one-click browser experience. devcontainer.json changes: - Image: marc0olo/icp-dev-env-motoko:dev / icp-dev-env-rust:dev - workspaceFolder: opens VS Code directly in the example directory - Port 8000 (icp-cli gateway) replaces port 4943 (dfx) - postStartCommand: icp network start -d (auto-starts on every resume) - postCreateCommand: mops install (Motoko only) - Adds stateful.runme extension for interactive README buttons README changes: - Replaces ICP Ninja badge with Open in GitHub Codespaces badge - Adds note that authentication uses production id.ai (PocketIC accepts mainnet signatures, so no local II needed) - Adds Runme action buttons: deploy, frontend, reset-deploy, info - Removes icp network stop (lifecycle handled by Codespace suspension) - Adds mainnet guidance section See #1345 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds `"postAttachCommand": "code README.md"` to both who_am_i devcontainer configs so the README with Runme action buttons opens automatically every time a Codespace is attached. Also adds a resume note to the Motoko README pointing users to github.com/codespaces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Clarifies that returning users should look for the "Open existing codespace" banner on the creation page, and adds the github.com/codespaces link to the Rust README (was already in Motoko). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
workspaceFolder doesn't scope the Explorer in Codespaces; code -r reopens the current window rooted at the example folder, fixing both the sidebar view and the terminal working directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GitHub Codespaces only discovers devcontainer.json under .devcontainer/ at the repo root — per-example subdirectory .devcontainer/ folders are silently ignored, causing the devcontainer_path URL param to be discarded. Adds root-level .devcontainer/motoko-who-am-i/ and /rust-who-am-i/ configs and updates the Codespaces badge URLs in both READMEs accordingly. The per-example .devcontainer/ files are kept for local dev container use. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Removes code -r (caused double window reload since workspaceFolder now works correctly once devcontainer is properly discovered) - Opens README.md on attach so Runme buttons are immediately visible - Suppresses port 7865 (PocketIC internal port) auto-forward notification - Sets git.openRepositoryInParentFolders=always to avoid parent-repo prompt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root-level .devcontainer/<name>/ configs handle both Codespaces and local dev container use. Per-example configs are redundant and create maintenance overhead across 46+ examples. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix ICP gateway rejecting API calls from Codespaces: override origin header in Vite proxy to localhost:8000 so the network launcher accepts requests from non-localhost forwarded domains - Add "Show URLs" Runme cell that constructs correct Codespaces-aware frontend and Candid UI URLs using $CODESPACE_NAME - Rename "Local development" section to "Codespace actions" and remove redundant "Install dependencies" cell (handled by postCreateCommand) - Set workbench.editorAssociations to open .md files in Runme directly, preventing the double README tab (preview + notebook) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- actor.js: detect .app.github.dev and route API calls directly to the port-8000 forwarded URL, bypassing the Vite proxy host check - README: reorder Codespace actions (Show URLs before dev server), use ?canisterId= query-param routing (works with Codespaces port forwarding), derive Candid UI URL from icp network status --json, remove icp environment cell Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add postAttach.sh scripts for both who_am_i devcontainers: - deploys canisters on first attach (guarded by canister status check, skipped on reconnects) - prints Frontend + Candid UI URLs to terminal - opens frontend in browser via `code --open-url` - opens README in editor Update README to reflect automatic deploy/open behaviour; simplify Codespace actions section accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add clear echo output at each stage: network confirmation, deploy progress (with timing hint), deployment complete/skipped, URL building, and browser open notification. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
URLs are printed to the terminal and are clickable via Cmd/Ctrl+click. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
actor.js: create HttpAgent explicitly and call fetchRootKey() when accessed via the ICP gateway directly (no ic_env cookie). Extend isLocalNetwork() to cover .app.github.dev so Codespaces URLs are treated as local. Make createBackendActor async accordingly. App.jsx: await createBackendActor. postAttach.sh: capture icp network status --json into a variable before piping to jq to avoid the broken-pipe panic; add __Candid_UI fallback for candid_ui_principal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The asset canister serves the ic_env cookie (containing the root key) when the frontend is loaded directly from the ICP gateway, so the agent already has the correct root key. The explicit fetchRootKey call and async createBackendActor were unnecessary. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows the ICP HTTP gateway to accept requests with Codespaces forwarded Host headers. If the gateway doesn't support wildcards, we'll need a dynamic postStart.sh approach instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fig.js getNetworkHost() and the origin header override were workarounds for the gateway rejecting non-localhost Host headers. The root cause is now fixed via gateway.domains in icp.yaml, so these are no longer needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The wildcard *.app.github.dev caused the gateway to hang (PocketIC
doesn't support wildcards). Replace with a postStart.sh script that
injects the exact ${CODESPACE_NAME}-8000.app.github.dev domain into
icp.yaml before starting the network. The modification is workspace-
local and not committed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move postStart.sh and postAttach.sh to .devcontainer/scripts/ (shared by all examples); both devcontainer.json files now reference them directly - postStart.sh: generic gateway domain injection — handles both ii:true and non-ii icp.yaml layouts - postAttach.sh: fully generic via `icp project show` + jq — detects frontend vs backend canisters by recipe/sync type, shows correct URLs for each (frontend URL or Candid UI link) - Add .devcontainer/CODESPACE.md with Show URLs / Redeploy / Reset cells; symlinked into motoko/who_am_i and rust/who_am_i - Scope workbench.editorAssociations to CODESPACE.md only (not *.md) - Remove postCreateCommand (mops install) from motoko devcontainer - Use icp deploy --mode reinstall -y for reset instead of network restart Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move URL detection logic from postAttach.sh and CODESPACE.md into a dedicated script. All three cells in CODESPACE.md are now one-liners. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove incorrect "open existing codespace" claim, drop Codespace actions (moved to CODESPACE.md), and remove em-dashes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…itations - Remove stateful.runme extension from both devcontainer configs - Remove workbench.editorAssociations (no longer needed) - Add workbench.startupEditor: none to suppress auto-opening README.md - CODESPACE.md is now plain markdown: warns that icp deploy URLs do not work in Codespaces and explains the ?canisterId= limitation for non-SPA frontends Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Open CODESPACE.md immediately on attach (before deploy) and in preview mode - Always run icp deploy on attach (idempotent, accurate for both first start and resume) - Add setup-in-progress disclaimer to CODESPACE.md - Move non-SPA note to bottom, rename Redeploy section to Deploy / Redeploy - Replace invalid workbench.commandPalette.showAskInChat with editorAssociations for markdown preview Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Uses the combined Motoko + Rust image for contributors and explorers who clone the full repo. No lifecycle scripts — intended for local Dev Containers use, not Codespaces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace dfx install instructions with icp-cli - Document GitHub Codespaces (per-example badges) and root Dev Container - Remove Gitpod reference - Fix all docs URLs to docs.internetcomputer.org - Demote ICP Ninja to a brief mention Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove ICP Ninja reference (NINJA_CONTRIBUTING.md deleted) - Replace dfx references with icp-cli - Add Codespaces devcontainer guidance for new examples Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add devcontainer configs for motoko-hello-world and rust-hello-world - Add CODESPACE.md symlinks - Replace ICP Ninja sections with Codespaces badge in both READMEs - Remove dfx.json, BUILD.md, and old .devcontainer from each example - Add hello_world.yml CI workflow using icp-cli - Remove hello_world entries from ninja_pr_checks.yml - Fix security best practices and icp-cli URLs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ho_am_i hello_world: tests default greeting, setGreeting/set_greeting + updated output who_am_i: tests whoami returns a principal and is deterministic Creates who_am_i.yml CI workflow; removes hello_world and who_am_i from ninja_pr_checks.yml to avoid duplicate runs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… guide - Add .github/workflow-template.yml as canonical starting point for new examples - Remove mops install from who_am_i CI (handled by icp deploy) - Separate npm run dev from deploy steps in who_am_i READMEs with explanation - Update ADDING_AN_EXAMPLE.md to reference template and Makefile pattern Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fall back to appending a network block when neither ii: true nor mode: managed is present. Fixes gateway injection for examples like hello_world that have no network section in their icp.yaml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The icp.yaml schema expects 'networks' (plural) with named entries, not a top-level 'network' field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Includes the port 5173 forwarded domain so the ICP gateway accepts requests proxied through the Vite dev server in Codespaces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a defensive icp network start -d before deploy so the Codespace recovers if postStart.sh failed or the network process didn't survive. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
icp network start -d returns immediately but the replica takes a moment to be ready. Poll localhost:8000/api/v2/status until it responds before running icp deploy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
postStartCommand completes before postAttachCommand runs, so the network is guaranteed ready by postStart.sh. The band-aid was masking errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
icp network start -d may return before the replica is ready to accept connections. Poll /api/v2/status so postStartCommand only completes once the network is actually up, guaranteeing postAttach can deploy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
icp network start -d already blocks until the network is ready. set -e ensures failures are visible immediately rather than silently continuing to the next command. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename internet_identity_app_backend → backend and internet_identity_app_frontend → frontend in both Motoko and Rust who_am_i examples, including src directories, .did files, icp.yaml, Cargo.toml, Makefile, vite.config.js, actor.js, package.json, .gitignore, and README. Also removes ICP Ninja artifacts (dfx.json, BUILD.md) and simplifies vite.config.js by dropping the dfx fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… branch - moc 1.5.1 → 1.8.2, core 2.4.0 → 2.5.0 - Add --default-persistent-actors to moc args so the persistent keyword is no longer needed in main.mo - Pin Motoko recipe to fix/motoko-mops-moc-args branch until dfinity/icp-cli-recipes#26 merges and a stable release is cut Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AGENTS.md is the primary source of agent instructions covering: canonical example layout, icp.yaml / mops.toml / Cargo.toml patterns, Makefile requirements, devcontainer and CI workflow templates, README structure, dfx→icp-cli migration checklist, and pending items (images, Motoko recipe version). CLAUDE.md delegates to AGENTS.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a Skills section at the top of AGENTS.md pointing to the live skills registry at skills.internetcomputer.org. Lists the relevant skills (icp-cli, icp-cli/dfx-migration, motoko, mops-cli, internet-identity, asset-canister) and establishes that skills take precedence over general knowledge where they overlap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without a paths filter, changing the workflow file (e.g. removing hello_world and who_am_i which now use icp-cli) triggers the run_all_examples self-trigger, causing all ninja examples to run on unrelated PRs. Enumerating the exact ninja-managed paths ensures the workflow only fires when relevant example code or the workflow file itself changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR migrates
hello_worldandwho_am_i(Motoko + Rust) from dfx to icp-cli and lays the groundwork for migrating all remaining examples. ICP Ninja support is intentionally dropped — it does not support icp-cli yet.dfx.jsonreplaced withicp.yaml, canister names simplified tobackend/frontend,dfx deploy→icp deploy,dfx start→icp network start -d.devcontainer/, shared lifecycle scripts,CODESPACE.mdwelcome document; root devcontainer for local multi-example developmenthello_world.yml,who_am_i.yml) using container images; workflow template for new examples; ninja PR checks scoped to ninja-managed paths onlytesttarget for both examples, exercised in CIdfx.json,BUILD.md, ICP Ninja references from READMEs,ADDING_AN_EXAMPLE.md, andCONTRIBUTING.md; updated all docs to advertise icp-cliAGENTS.md(canonical) +CLAUDE.mdcovering example structure, migration checklist, and ICP skills registry integrationPending before merge
1. Switch to official icp-dev-env images
All devcontainer configs and CI workflows currently reference images from a personal fork:
Once published under the
dfinityorg, update every occurrence to:Affected files:
.devcontainer/devcontainer.json.devcontainer/motoko-hello-world/devcontainer.json.devcontainer/rust-hello-world/devcontainer.json.devcontainer/motoko-who-am-i/devcontainer.json.devcontainer/rust-who-am-i/devcontainer.json.github/workflows/hello_world.yml.github/workflows/who_am_i.yml2. Switch Motoko recipe to stable release
motoko/who_am_i/icp.yamlpins a fix-branch URL to pick up[moc] argssupport frommops.tomlbefore the fix ships in a stable release:Tracked in: dfinity/icp-cli-recipes#26
Once that PR merges and a new
@dfinity/motokoversion is released, update both:motoko/who_am_i/icp.yamlmotoko/hello_world/icp.yaml(currently still on@dfinity/motoko@v4.1.0)Test plan
motoko-hello-world,rust-hello-world,motoko-who-am-i,rust-who-am-i) and verify the network starts, canisters deploy, and the frontend is accessibleCODESPACE.mdopens automatically in preview mode on attachmake testlocally in all four exampleshello_worldandwho_am_iCI workflows pass🤖 Generated with Claude Code