Skip to content

Commit d909a97

Browse files
Merge branch 'main' into spofford/locks
2 parents b6cd08b + 808506a commit d909a97

File tree

15 files changed

+871
-3266
lines changed

15 files changed

+871
-3266
lines changed

.github/workflows/release.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Publish
2+
3+
# We have to use gtar on macOS because apple's tar is literally broken.
4+
# Yes, I know how stupid that sounds. But it's true:
5+
# https://github.com/actions/virtual-environments/issues/2619
6+
7+
on:
8+
push:
9+
tags:
10+
- 'v[0-9]+.[0-9]+.[0-9]+'
11+
- 'v[0-9]+.[0-9]+.[0-9]+-[A-Za-z]+.[0-9]+'
12+
pull_request:
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.ref }}
16+
cancel-in-progress: true
17+
18+
env:
19+
# When getting Rust dependencies, retry on network error:
20+
CARGO_NET_RETRY: 10
21+
22+
jobs:
23+
build_icp:
24+
runs-on: ${{ matrix.os }}
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
target: [ x86_64-apple-darwin, aarch64-apple-darwin, x86_64-unknown-linux-gnu ]
29+
# target: [ x86_64-apple-darwin, aarch64-apple-darwin, x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu ] Waiting for repo to be public
30+
include:
31+
- os: macos-14-large
32+
target: x86_64-apple-darwin
33+
binary_path: target/x86_64-apple-darwin/release
34+
name: x86_64-darwin
35+
tar: gtar
36+
- os: macos-14
37+
target: aarch64-apple-darwin
38+
binary_path: target/aarch64-apple-darwin/release
39+
name: aarch64-darwin
40+
tar: gtar
41+
- os: ubuntu-22.04
42+
target: x86_64-unknown-linux-gnu
43+
binary_path: target/x86_64-unknown-linux-gnu/release
44+
name: x86_64-linux
45+
tar: tar
46+
# - os: ubuntu-22.04-arm
47+
# target: aarch64-unknown-linux-gnu
48+
# binary_path: target/aarch64-unknown-linux-gnu/release
49+
# name: aarch64-linux
50+
# tar: tar
51+
steps:
52+
- uses: actions/checkout@v4
53+
54+
- name: Setup environment variables
55+
run: |
56+
echo "RUSTFLAGS=--remap-path-prefix=${GITHUB_WORKSPACE}=/builds/dfinity" >> $GITHUB_ENV
57+
58+
- name: Set names (tag only)
59+
if: github.ref_type == 'tag'
60+
run: |
61+
REF_NAME_SANITIZED=$(echo "$GITHUB_REF_NAME" | tr '/' '-')
62+
echo "TARBALL_FILENAME=icp-cli-$REF_NAME_SANITIZED-${{ matrix.name }}.tar.gz" >> $GITHUB_ENV
63+
echo "SHA256_FILENAME=icp-cli-$REF_NAME_SANITIZED-${{ matrix.name }}.tar.gz.sha256" >> $GITHUB_ENV
64+
65+
- name: Cache Cargo
66+
uses: actions/cache@v4
67+
with:
68+
path: |
69+
~/.cargo/bin/
70+
~/.cargo/registry/index/
71+
~/.cargo/registry/cache/
72+
~/.cargo/git/db/
73+
~/.rustup/
74+
target/
75+
key: ${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain.toml') }}-publish-1
76+
77+
- name: Build
78+
run: |
79+
cargo clean --target ${{ matrix.target }} --release
80+
cargo build --target ${{ matrix.target }} --locked --release
81+
82+
- name: Strip binaries
83+
run: |
84+
cd ${{ matrix.binary_path }}
85+
sudo chown -R $(whoami) .
86+
strip icp
87+
if: contains(matrix.os, 'ubuntu')
88+
89+
- name: Create tarball of binaries and sha256 of tarball
90+
if: github.ref_type == 'tag'
91+
run: |
92+
${{ matrix.tar }} -zcC ${{ matrix.binary_path }} -f ${{ env.TARBALL_FILENAME }} icp
93+
shasum -a 256 ${{ env.TARBALL_FILENAME }} > ${{ env.SHA256_FILENAME }}
94+
shasum -c ${{ env.SHA256_FILENAME }}
95+
96+
- name: Upload Artifacts
97+
if: github.ref_type == 'tag'
98+
uses: actions/upload-artifact@v4
99+
with:
100+
name: icp-artifacts-${{ hashFiles('rust-toolchain.toml') }}-${{ matrix.name }}
101+
path: |
102+
${{ env.TARBALL_FILENAME }}
103+
${{ env.SHA256_FILENAME }}
104+
105+
aggregate:
106+
name: publishable:required
107+
if: ${{ always() }}
108+
needs: [build_icp]
109+
runs-on: ubuntu-latest
110+
steps:
111+
- name: check build result
112+
if: ${{ needs.build_icp.result != 'success' }}
113+
run: exit 1
114+
115+
publish:
116+
runs-on: ubuntu-latest
117+
if: github.ref_type == 'tag'
118+
needs: build_icp
119+
permissions:
120+
contents: write
121+
strategy:
122+
fail-fast: false
123+
matrix:
124+
name: [ 'x86_64-darwin', 'aarch64-darwin', 'x86_64-linux']
125+
# name: [ 'x86_64-darwin', 'aarch64-darwin', 'x86_64-linux', 'aarch64-linux' ]
126+
steps:
127+
- uses: actions/checkout@v4
128+
129+
- name: Setup environment variables
130+
run: echo "VERSION=$GITHUB_REF_NAME" >> $GITHUB_ENV
131+
132+
- name: Download Artifacts
133+
uses: actions/download-artifact@v4
134+
with:
135+
name: icp-artifacts-${{ hashFiles('rust-toolchain.toml') }}-${{ matrix.name }}
136+
137+
- name: Upload tarball and sha256
138+
uses: svenstaro/upload-release-action@v2
139+
with:
140+
repo_token: ${{ secrets.GITHUB_TOKEN }}
141+
file: icp-*.tar.*
142+
file_glob: true
143+
tag: ${{ env.VERSION }}
144+
prerelease: true
145+
make_latest: false

examples/icp-frontend-environment-variables/README.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,27 @@ This example demonstrates how to pass environment variables from the asset canis
77
This project consists of two canisters:
88

99
- [backend](./backend/): a pre-built Hello World canister, together with its [`backend.did`](./backend/dist/hello_world.did) file.
10-
- [frontend](./frontend/): a [Vite](https://vite.dev/) webapp deployed in a [custom asset canister](./frontend/canister/assetstorage.wasm.gz), built specifically for this example.
10+
- [frontend](./frontend/): a [Vite](https://vite.dev/) webapp deployed in an asset canister.
1111

1212
### Bindings Generation
1313

1414
The [`@icp-sdk/bindgen`](https://npmjs.com/package/@icp-sdk/bindgen) library offers a plugin for Vite that generates the TypeScript Candid bindings from the [`backend.did`](./backend/dist/hello_world.did) file. The bindings are generated at build time by Vite and are saved in the [`frontend/app/src/backend/api/`](./frontend/app/src/backend/api/) folder.
1515

1616
The plugin supports hot module replacement, so you can run the frontend in development mode (by running `npm run dev` in the [`frontend/app/`](./frontend/app/) folder) and make changes to the Candid declaration file to see the bindings being updated in real time.
1717

18-
The plugin also supports additional features, such as the ability to generate a TypeScript declaration file for the environment variables that are available to the frontend. The [`canister-env.d.ts`](./frontend/app/src/backend/api/canister-env.d.ts) file is generated automatically by the plugin and is used to type the environment variables in the frontend code. See the [Environment Variables](#environment-variables) section for more details.
19-
2018
See the [`vite.config.ts`](./frontend/app/vite.config.ts) file for how the plugin is used.
2119

2220
### Environment Variables
2321

2422
The project is configured to pass the backend's canister ID to the frontend using a [cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies). The environment variables are made available to the frontend JS code that runs in the browser by following this flow:
2523

2624
1. During deployment, the `icp` CLI sets the backend's canister ID in the frontend canister's (asset canister) environment variables
27-
2. The asset canister (built specifically for this example, its Wasm can be found in the [`frontend/canister/`](./frontend/canister/) folder) sets a specific cookie (named `ic_env`) that contains some environment variables when the assets are uploaded
25+
2. The asset canister sets a specific cookie (named `ic_env`) that contains some environment variables when the assets are uploaded
2826
3. The asset canister serves the frontend assets with the cookie set
29-
4. The frontend JS code uses the [`@icp-sdk/canister-env`](./frontend/libs/canister-env/) library to parse the cookie and extract the environment variables
27+
4. The frontend JS code uses the [`@icp-sdk/core/agent/canister-env`](https://js.icp.build/core/latest/canister-env/) module to parse the cookie and extract the environment variables
3028

3129
In the [`App.tsx`](./frontend/app/src/App.tsx) file, you can see how the frontend can obtain the backend's canister ID from the environment variables and use it to create an actor for the backend canister.
3230

33-
The [Bindings Generation](#bindings-generation) process is also configured to generate a TypeScript declaration file for the environment variables served by the asset canister, in order to make the frontend code more type-safe.
34-
35-
> Note: the `@icp-sdk/canister-env` library is only available in this repository. It will soon be extracted into a separate repo and NPM package.
36-
3731
## Prerequisites
3832

3933
Before you begin, ensure that you have the following installed:

examples/icp-frontend-environment-variables/frontend/app/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111
"preview": "vite preview"
1212
},
1313
"dependencies": {
14-
"@icp-sdk/canister-env": "*",
15-
"@icp-sdk/core": "^4.0.5",
14+
"@icp-sdk/core": "^4.2.1",
1615
"react": "^19.1.1",
1716
"react-dom": "^19.1.1"
1817
},
1918
"devDependencies": {
2019
"@eslint/js": "^9.33.0",
21-
"@icp-sdk/bindgen": "^0.1.0",
20+
"@icp-sdk/bindgen": "^0.2.0",
2221
"@types/react": "^19.1.10",
2322
"@types/react-dom": "^19.1.7",
2423
"@vitejs/plugin-react": "^5.0.0",

examples/icp-frontend-environment-variables/frontend/app/src/App.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
import { useState } from "react";
22
import { createActor } from "./backend/api/hello_world";
3-
import { getCanisterEnv } from "@icp-sdk/canister-env";
3+
import { getCanisterEnv } from "@icp-sdk/core/agent/canister-env";
44
import "./App.css";
55

6+
// Here we define the environment variables that the asset canister serves.
7+
// By default, the CLI sets all the canister IDs in the environment variables of the asset canister
8+
// using the `PUBLIC_CANISTER_ID:<canister-name>` format.
9+
// For this reason, we can expect the `PUBLIC_CANISTER_ID:backend` environment variable to be set.
610
interface CanisterEnv {
711
readonly "PUBLIC_CANISTER_ID:backend": string;
812
}
913

14+
// We only want to access the environment variables when serving the frontend from the asset canister.
15+
// In development mode, we use a fixed canister ID for the backend canister.
1016
const canisterEnv = getCanisterEnv<CanisterEnv>();
1117
const canisterId = canisterEnv["PUBLIC_CANISTER_ID:backend"];
1218

19+
// We want to fetch the root key from the replica when developing locally.
1320
const helloWorldActor = createActor(canisterId, {
1421
agentOptions: {
15-
rootKey: !import.meta.env.DEV ? canisterEnv.IC_ROOT_KEY : undefined,
22+
rootKey: !import.meta.env.DEV ? canisterEnv!.IC_ROOT_KEY : undefined,
1623
shouldFetchRootKey: import.meta.env.DEV,
1724
},
1825
});
@@ -26,9 +33,7 @@ function App() {
2633
"name"
2734
) as HTMLInputElement;
2835

29-
helloWorldActor.greet(nameInput.value).then((greeting) => {
30-
setGreeting(greeting);
31-
});
36+
helloWorldActor.greet(nameInput.value).then(setGreeting);
3237
return false;
3338
}
3439

examples/icp-frontend-environment-variables/frontend/app/src/backend/api/declarations/hello_world.did.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// @ts-nocheck
44

5-
// This file was automatically generated by @icp-sdk/bindgen@0.1.0.
5+
// This file was automatically generated by @icp-sdk/bindgen@0.2.0.
66
// You should NOT make any changes in this file as it will be overwritten.
77
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
88

@@ -21,7 +21,5 @@ export interface _SERVICE {
2121
*/
2222
'greet' : ActorMethod<[string], string>,
2323
}
24-
export declare const idlService: IDL.ServiceClass;
25-
export declare const idlInitArgs: IDL.Type[];
2624
export declare const idlFactory: IDL.InterfaceFactory;
2725
export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[];

examples/icp-frontend-environment-variables/frontend/app/src/backend/api/declarations/hello_world.did.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@
22

33
// @ts-nocheck
44

5-
// This file was automatically generated by @icp-sdk/bindgen@0.1.0.
5+
// This file was automatically generated by @icp-sdk/bindgen@0.2.0.
66
// You should NOT make any changes in this file as it will be overwritten.
77
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
88

99
import { IDL } from '@icp-sdk/core/candid';
1010

11-
export const idlService = IDL.Service({
12-
'greet' : IDL.Func([IDL.Text], [IDL.Text], ['query']),
13-
});
14-
15-
export const idlInitArgs = [];
16-
1711
export const idlFactory = ({ IDL }) => {
1812
return IDL.Service({ 'greet' : IDL.Func([IDL.Text], [IDL.Text], ['query']) });
1913
};

examples/icp-frontend-environment-variables/frontend/app/src/backend/api/hello_world.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// @ts-nocheck
44

5-
// This file was automatically generated by @icp-sdk/bindgen@0.1.0.
5+
// This file was automatically generated by @icp-sdk/bindgen@0.2.0.
66
// You should NOT make any changes in this file as it will be overwritten.
77
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
88

examples/icp-frontend-environment-variables/frontend/app/vite.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import { defineConfig } from "vite";
22
import react from "@vitejs/plugin-react";
33
import { icpBindgen } from "@icp-sdk/bindgen/plugins/vite";
44

5+
// Change these values to match your local replica.
6+
// The `icp network run` command will print the root key
7+
// and the `icp deploy` command will print the backend canister id.
8+
const IC_ROOT_KEY_HEX =
9+
"308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008b52b4994f94c7ce4be1c1542d7c81dc79fea17d49efe8fa42e8566373581d4b969c4a59e96a0ef51b711fe5027ec01601182519d0a788f4bfe388e593b97cd1d7e44904de79422430bca686ac8c21305b3397b5ba4d7037d17877312fb7ee34";
10+
const BACKEND_CANISTER_ID = "txyno-ch777-77776-aaaaq-cai";
11+
512
// https://vite.dev/config/
613
export default defineConfig({
714
plugins: [
@@ -11,4 +18,17 @@ export default defineConfig({
1118
outDir: "./src/backend/api",
1219
}),
1320
],
21+
server: {
22+
headers: {
23+
"Set-Cookie": `ic_env=${encodeURIComponent(
24+
`ic_root_key=${IC_ROOT_KEY_HEX}&PUBLIC_CANISTER_ID:backend=${BACKEND_CANISTER_ID}`
25+
)}; SameSite=Lax;`,
26+
},
27+
proxy: {
28+
"/api": {
29+
target: "http://127.0.0.1:8000",
30+
changeOrigin: true,
31+
},
32+
},
33+
},
1434
});

examples/icp-frontend-environment-variables/frontend/libs/canister-env/package.json

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)