Fix authentication when (older) identities have devices without a cre… #13572
This file contains 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
# This describes all the tests we run on the canister code (various builds, | |
# integration tests, e2e tests). The canister code is built in docker and the | |
# wasm is then reused by subsequent build steps. We build various flavors of | |
# the code, see `docker-build-...` for more info. | |
name: Canister tests | |
on: | |
push: | |
jobs: | |
##################### | |
# The docker builds # | |
##################### | |
# The image shared by all builds, containing pre-built rust deps | |
docker-build-base: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
# We use buildx and its GitHub Actions caching support `type=gha`. For | |
# more information, see | |
# https://github.com/docker/build-push-action/issues/539 | |
- name: Set up docker buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build base Docker image | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: Dockerfile | |
cache-from: type=gha,scope=cached-stage | |
cache-to: type=gha,scope=cached-stage,mode=max | |
outputs: type=cacheonly | |
target: deps | |
docker-build-ii: | |
runs-on: ubuntu-latest | |
needs: docker-build-base | |
strategy: | |
# NOTE: the 'name' in the matrix should match the asset filename, because it is used in | |
# .github/actions/release to figure out the job ID. | |
# | |
# NOTE: if you modify the flavors, update the #flavors table in README.md | |
matrix: | |
include: | |
# The production build | |
- name: internet_identity_production.wasm.gz | |
II_FETCH_ROOT_KEY: 0 | |
II_DUMMY_CAPTCHA: 0 | |
II_DUMMY_AUTH: 0 | |
II_DEV_CSP: 0 | |
# No captcha and fetching the root key, used in (our) tests, backend and | |
# e2e. | |
- name: internet_identity_test.wasm.gz | |
II_FETCH_ROOT_KEY: 1 | |
II_DUMMY_CAPTCHA: 1 | |
II_DUMMY_AUTH: 0 | |
II_DEV_CSP: 0 | |
# Everything disabled, used by third party developers who only care | |
# about the login flow | |
- name: internet_identity_dev.wasm.gz | |
II_FETCH_ROOT_KEY: 1 | |
II_DUMMY_CAPTCHA: 1 | |
II_DUMMY_AUTH: 1 | |
II_DEV_CSP: 1 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Infer version | |
id: version | |
run: | | |
version="$(./scripts/version)" | |
echo "Inferred version: '$version'" | |
echo "version=$version" >> "$GITHUB_OUTPUT" | |
- name: Set up docker buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build ${{ matrix.name }} | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: Dockerfile | |
build-args: | | |
II_FETCH_ROOT_KEY=${{ matrix.II_FETCH_ROOT_KEY }} | |
II_DUMMY_AUTH=${{ matrix.II_DUMMY_AUTH }} | |
II_DUMMY_CAPTCHA=${{ matrix.II_DUMMY_CAPTCHA }} | |
II_DEV_CSP=${{ matrix.II_DEV_CSP }} | |
II_VERSION=${{ steps.version.outputs.version }} | |
cache-from: type=gha,scope=cached-stage | |
# Exports the artefacts from the final stage | |
outputs: ./out | |
target: scratch_internet_identity | |
- run: mv out/internet_identity.wasm.gz ${{ matrix.name }} | |
- run: sha256sum ${{ matrix.name }} | |
- name: "Upload ${{ matrix.name }}" | |
uses: actions/upload-artifact@v4 | |
with: | |
# name is the name used to display and retrieve the artifact | |
name: ${{ matrix.name }} | |
# path is the name used as the file to upload and the name of the | |
# file when downloaded | |
path: ${{ matrix.name }} | |
docker-build-archive: | |
runs-on: ubuntu-latest | |
needs: docker-build-base | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up docker buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build Archive Canister | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: Dockerfile | |
cache-from: type=gha,scope=cached-stage | |
# Exports the artefacts from the final stage | |
outputs: ./out | |
target: scratch_archive | |
- run: mv out/archive.wasm.gz archive.wasm.gz | |
- run: sha256sum archive.wasm.gz | |
- name: "Upload archive.wasm.gz" | |
uses: actions/upload-artifact@v4 | |
with: | |
# name is the name used to display and retrieve the artifact | |
name: archive.wasm.gz | |
# path is the name used as the file to upload and the name of the | |
# downloaded file | |
path: archive.wasm.gz | |
wasm-size: | |
runs-on: ubuntu-latest | |
needs: docker-build-ii | |
steps: | |
- uses: actions/checkout@v4 | |
- name: "Download wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_production.wasm.gz | |
path: . | |
- id: record-size | |
uses: ./.github/actions/file-size | |
with: | |
file: internet_identity_production.wasm.gz | |
save: ${{ github.ref == 'refs/heads/main' }} | |
- name: "Check canister size" | |
run: | | |
max_size=2097152 # maximum canister size, in bytes | |
actual_size=${{ steps.record-size.outputs.size }} | |
if (( actual_size > max_size )) | |
then | |
echo "Canister size too big" | |
echo "($actual_size > $max_size)" | |
exit 1 | |
fi | |
vc_demo_issuer-build: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/cache@v4 | |
with: | |
path: | | |
~/.cargo/registry | |
~/.cargo/git | |
demos/vc_issuer/target | |
key: ${{ runner.os }}-cargo-${{ hashFiles('demos/vc_issuer/Cargo.lock', 'rust-toolchain.toml') }} | |
- uses: ./.github/actions/bootstrap | |
- uses: ./.github/actions/setup-node | |
- run: npm ci | |
- name: "Build VC issuer canister" | |
working-directory: demos/vc_issuer | |
run: ./build.sh | |
- run: sha256sum vc_demo_issuer.wasm.gz | |
working-directory: demos/vc_issuer | |
- name: "Upload VC issuer" | |
uses: actions/upload-artifact@v4 | |
with: | |
# name is the name used to display and retrieve the artifact | |
name: vc_demo_issuer.wasm.gz | |
# path is the name used as the file to upload and the name of the | |
# downloaded file | |
path: ./demos/vc_issuer/vc_demo_issuer.wasm.gz | |
test-app-build: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/cache@v4 | |
with: | |
path: | | |
~/.cargo/registry | |
~/.cargo/git | |
demos/test-app/target | |
key: ${{ runner.os }}-cargo-${{ hashFiles('demos/test-app/Cargo.lock', 'rust-toolchain.toml') }} | |
- uses: ./.github/actions/bootstrap | |
- uses: ./.github/actions/setup-node | |
- run: npm ci | |
- name: "Build test app canister" | |
working-directory: demos/test-app | |
run: ./build.sh | |
- name: "Upload test app" | |
uses: actions/upload-artifact@v4 | |
with: | |
# name is the name used to display and retrieve the artifact | |
name: test_app.wasm | |
# path is the name used as the file to upload and the name of the | |
# downloaded file | |
path: ./demos/test-app/test_app.wasm | |
##################################### | |
# The Rust vc issuer canister tests # | |
##################################### | |
vc-issuer-test: | |
runs-on: ubuntu-latest | |
needs: [docker-build-ii, vc_demo_issuer-build] | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/cache@v4 | |
with: | |
path: | | |
~/.cargo/registry | |
~/.cargo/git | |
demos/vc_issuer/target | |
key: ${{ runner.os }}-cargo-vc-tests-${{ hashFiles('demos/vc_issuer/Cargo.lock', 'rust-toolchain.toml') }} | |
- uses: ./.github/actions/bootstrap | |
- name: "Download VC issuer wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: vc_demo_issuer.wasm.gz | |
path: demos/vc_issuer | |
- name: "Download II wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_test.wasm.gz | |
path: . | |
- run: mv internet_identity_test.wasm.gz internet_identity.wasm.gz | |
- name: Install PocketIC | |
run: | | |
curl -sL -o pocket-ic.gz https://github.com/dfinity/pocketic/releases/download/6.0.0/pocket-ic-x86_64-linux.gz | |
gzip -d pocket-ic.gz | |
chmod +x pocket-ic | |
- name: "Run VC issuer canister tests" | |
working-directory: demos/vc_issuer | |
run: | | |
# create dummy assets | |
mkdir dist | |
touch dist/index.{html,css,js} | |
touch dist/index2.js | |
cargo test | |
########################### | |
# The Rust canister tests # | |
########################### | |
# Run the tests, user the output of the docker build as Wasm module | |
# (note: this runs _all_ cargo tests) | |
canister-tests-build: | |
runs-on: ${{ matrix.os }} | |
strategy: | |
matrix: | |
os: [ubuntu-latest, macos-latest] | |
steps: | |
- uses: actions/checkout@v4 | |
# Attempt to restore the pre-built test binaries from cache. | |
# The test binaries are only dependent on rust code, because the front-end code is bundled in the `wasm` file | |
# that is loaded by the test binaries. | |
# If the binary can be restored from cache, we skip the build step, including even setting up the toolchain etc. | |
- uses: actions/cache@v4 | |
id: cache-test-archive | |
with: | |
path: /tmp/test-archive | |
key: ${{ runner.os }}-rust-test-archive-${{ hashFiles('src/**/*.rs', 'Cargo.*', 'src/*/*.toml', 'rust-toolchain.toml') }} | |
- uses: ./.github/actions/bootstrap | |
if: steps.cache-test-archive.outputs.cache-hit != 'true' | |
- uses: actions/cache@v4 | |
if: steps.cache-test-archive.outputs.cache-hit != 'true' | |
with: | |
path: | | |
~/.cargo | |
target | |
key: ${{ runner.os }}-rust-test-cache-${{ hashFiles('Cargo.toml', 'rust-toolchain.toml', 'Cargo.lock') }} | |
- name: Install nextest | |
if: steps.cache-test-archive.outputs.cache-hit != 'true' | |
run: | | |
curl -LsSf https://get.nexte.st/latest/${{ matrix.os == 'macos-latest' && 'mac' || 'linux' }} | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin | |
# Rustup only installs cargo on the first call, so we use a dedicated step to get a good idea of how | |
# time is spent in each step separately | |
- if: steps.cache-test-archive.outputs.cache-hit != 'true' | |
run: cargo check --help | |
- name: Create dummy assets | |
if: steps.cache-test-archive.outputs.cache-hit != 'true' | |
run: | | |
mkdir dist | |
touch dist/index.html | |
# Build the tests | |
- name: Build test archive | |
if: steps.cache-test-archive.outputs.cache-hit != 'true' | |
run: | | |
git checkout ${{ steps.git_info.outputs.commit_now }} | |
cargo nextest archive --archive-file canister-tests-${{ matrix.os }}.tar.zst --release | |
mkdir -p /tmp/test-archive/ | |
cp canister-tests-${{ matrix.os }}.tar.zst /tmp/test-archive | |
- name: Restore test archive | |
if: steps.cache-test-archive.outputs.cache-hit == 'true' | |
run: | | |
mv /tmp/test-archive/canister-tests-${{ matrix.os }}.tar.zst . | |
- name: "Upload canister test archive" | |
uses: actions/upload-artifact@v4 | |
with: | |
# name is the name used to display and retrieve the artifact | |
name: canister-tests-${{ matrix.os }}.tar.zst | |
# path is the name used as the file to upload and the name of the | |
# downloaded file | |
path: ./canister-tests-${{ matrix.os }}.tar.zst | |
canister-tests-run: | |
runs-on: ${{ matrix.os }} | |
needs: [canister-tests-build, cached-build, docker-build-archive] | |
strategy: | |
matrix: | |
os: [ubuntu-latest, macos-latest] | |
partition: ["1/3", "2/3", "3/3"] | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Download nextest | |
run: | | |
set -euo pipefail | |
curl -LsSf https://get.nexte.st/latest/${{ matrix.os == 'macos-latest' && 'mac' || 'linux' }} | tar zxf - | |
- name: "Download nextest test archive" | |
uses: actions/download-artifact@v4 | |
with: | |
name: canister-tests-${{ matrix.os }}.tar.zst | |
path: . | |
- name: Install PocketIC | |
run: | | |
curl -sL -o pocket-ic.gz https://github.com/dfinity/pocketic/releases/download/6.0.0/pocket-ic-x86_64-${{ matrix.os == 'macos-latest' && 'darwin' || 'linux' }}.gz | |
gzip -d pocket-ic.gz | |
chmod +x pocket-ic | |
- name: "Download II wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_test_cached.wasm.gz | |
path: . | |
- name: "Download archive wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: archive.wasm.gz | |
path: . | |
- name: Run PocketIc | |
run: ./pocket-ic --port-file pocket-ic-port & | |
- name: Run Tests | |
run: | | |
mv internet_identity_test.wasm.gz internet_identity.wasm.gz | |
# NOTE: Here we download changing assets (i.e. the latest release) meaning that in some rare cases (after a new release) | |
# PRs that used to be green may become red (if the new release broke something). While this is not CI best practice, it's | |
# a relatively small price to pay to make sure PRs are always tested against the latest release. | |
curl -sSL https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_test.wasm.gz -o internet_identity_previous.wasm.gz | |
curl -sSL https://github.com/dfinity/internet-identity/releases/latest/download/archive.wasm.gz -o archive_previous.wasm.gz | |
# We are using --partition hash instead of count, because it makes sure that the tests partition is stable across runs | |
# even if tests are added or removed. The tradeoff is that the balancing might be slightly worse, but we have enough | |
# tests that it should not be a big issue. | |
./cargo-nextest nextest run --archive-file canister-tests-${{ matrix.os }}.tar.zst --partition hash:${{ matrix.partition }} | |
env: | |
RUST_BACKTRACE: 1 | |
test-canisters-script: | |
needs: [cached-build, docker-build-archive] | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/cache@v4 | |
id: cache | |
with: | |
path: | | |
~/.cargo | |
target | |
key: ${{ runner.os }}-test-canisters-script-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock', '.node-version', 'package-lock.json') }} | |
- name: "Download II wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_test_cached.wasm.gz | |
path: . | |
- name: "Download archive wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: archive.wasm.gz | |
path: . | |
- name: Move wasms | |
run: mv internet_identity_test.wasm.gz internet_identity.wasm.gz | |
- name: Create dummy assets | |
run: | | |
mkdir dist | |
touch dist/index.html | |
- name: Run tests | |
# should_keep_new_anchor_across_rollback uses previous II wasm | |
# should_issue_same_principal_after_restoring_backup uses a stable memory backup | |
# should_keep_entries_across_rollback uses previous archive wasm | |
# should_report_daily_active_anchors tests stats | |
# should_get_different_id_alias_for_different_relying_parties tests VCs | |
# should_get_valid_delegation tests II core functionality | |
run: | | |
./scripts/test-canisters.sh --no-build should_keep_new_anchor_across_rollback | |
./scripts/test-canisters.sh --no-build should_issue_same_principal_after_restoring_backup | |
./scripts/test-canisters.sh --no-build should_keep_entries_across_rollback | |
./scripts/test-canisters.sh --no-build should_report_daily_active_anchors | |
./scripts/test-canisters.sh --no-build should_get_different_id_alias_for_different_relying_parties | |
./scripts/test-canisters.sh --no-build should_get_valid_delegation | |
###################### | |
# The end-to-end tests # | |
###################### | |
e2e: | |
runs-on: ubuntu-latest | |
needs: [cached-build, test-app-build, vc_demo_issuer-build] | |
strategy: | |
matrix: | |
device: ["desktop", "mobile"] | |
# We run the integration tests on both the official and legacy domains, to make sure | |
# the webapp (routes, csp, etc) works on both. Captchas are statically enabled on one | |
# domain and disabled on the other. | |
# Both settings are combined in one single matrix variable as otherwise there would be | |
# excessively many combinations to be run and it would be questionable how much more of | |
# a signal we would get from that. | |
settings: | |
[ | |
{ | |
domain: "https://identity.internetcomputer.org", | |
captcha: "enabled", | |
}, | |
{ domain: "https://identity.ic0.app", captcha: "disabled" }, | |
] | |
# Specify some shards for jest (a jest instance will only run a subset of files | |
# based on the shard assigned to it) | |
# The jest parameter is actually 1/N, 2/N etc but we use a artifact-friendly | |
# version here (with underscore). | |
shard: ["1_6", "2_6", "3_6", "4_6", "5_6", "6_6"] | |
# Make sure that one failing test does not cancel all other matrix jobs | |
fail-fast: false | |
env: | |
# Suffix used for tagging artifacts | |
artifact_suffix: ${{ contains(matrix.settings.domain, 'internetcomputer') && 'current' || 'legacy' }}-${{ matrix.device }}-captcha_${{ matrix.settings.captcha }}-${{ matrix.shard }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/setup-node | |
# npm ci is a slow operation that mostly involves downloading packages, so we run | |
# it in the background while we set up the replica | |
- name: Kickstart npm ci | |
run: '{ npm ci --no-audit --no-fund; echo "$?" > ~/npm-ci-status; } &' | |
- uses: dfinity/setup-dfx@e50c04f104ee4285ec010f10609483cf41e4d365 | |
# Helps with debugging | |
- name: Show versions | |
run: | | |
echo dfx --version | |
dfx --version | |
echo node --version | |
node --version | |
- name: "Run dfx" | |
run: dfx start --background --artificial-delay 0 | |
- name: "Download II wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_test_cached.wasm.gz | |
path: . | |
- name: "Download test app wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: test_app.wasm | |
path: demos/test-app | |
- name: "Download VC issuer wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: vc_demo_issuer.wasm.gz | |
path: demos/vc_issuer | |
- name: Create Canisters | |
run: dfx canister create --all | |
- name: Deploy canisters | |
run: | | |
captcha_flag="${{ matrix.settings.captcha }}" | |
# Build the "CaptchaEnabled" / "CaptchaDisabled" variants from the matrix captcha value | |
# (i.e. capitalize the first letter) | |
captcha_variant="Captcha$(tr '[:lower:]' '[:upper:]' <<< ${captcha_flag:0:1})${captcha_flag:1}" | |
# NOTE: dfx install will run the postinstall scripts from dfx.json | |
dfx canister install internet_identity --wasm internet_identity_test.wasm.gz --argument "(opt record { captcha_config = opt record { max_unsolved_captchas= 50:nat64; captcha_trigger = variant {Static = variant { $captcha_variant }}}})" | |
dfx canister install test_app --wasm demos/test-app/test_app.wasm | |
dfx canister install issuer --wasm demos/vc_issuer/vc_demo_issuer.wasm.gz | |
# Check the return code of npm ci | |
- name: Check on npm ci | |
# make sure we don't wait too long if for some unlikely reason the npm status file doesn't get created | |
timeout-minutes: 5 | |
run: | | |
until [ -f ~/npm-ci-status ]; do sleep 1; done | |
exit $(cat ~/npm-ci-status) | |
- name: Run dev server | |
id: dev-server-start | |
run: | | |
TLS_DEV_SERVER=1 NO_HOT_RELOAD=1 npm run dev | tee -a > dev-server-logs.txt & | |
dev_server_pid=$! | |
echo "dev_server_pid=$dev_server_pid" >> "$GITHUB_OUTPUT" | |
# run unit tests & e2e tests | |
# NOTE: we run chrome in headless mode because that's the only thing that works in GHA | |
# NOTE: the last bit (tr) replaces 1_N with 1/N | |
- run: | | |
II_URL=${{ matrix.settings.domain }} \ | |
SCREEN=${{ matrix.device }} \ | |
II_E2E_CHROME_OPTS="--headless" \ | |
II_CAPTCHA=${{ matrix.settings.captcha }} \ | |
npm run test:e2e -- --shard=$(tr <<<'${{ matrix.shard }}' -s _ /) | |
- name: Stop dfx | |
if: ${{ always() }} | |
run: dfx stop | |
- name: Stop dev server | |
if: ${{ always() }} | |
run: kill ${{ steps.dev-server-start.outputs.dev_server_pid }} | |
- name: Archive dev server logs | |
if: ${{ always() }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: dev-server-logs-${{ env.artifact_suffix }} | |
path: dev-server-logs.txt | |
if-no-files-found: ignore | |
- name: Archive test failures | |
if: ${{ always() }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: e2e-test-failures-${{ env.artifact_suffix }} | |
path: test-failures/* | |
if-no-files-found: ignore | |
# Aggregate all e2e matrix jobs, used in branch protection | |
e2e-all: | |
runs-on: ubuntu-latest | |
needs: e2e | |
steps: | |
- run: echo e2e ok | |
using-dev-build: | |
runs-on: ubuntu-latest | |
needs: docker-build-ii | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/setup-node | |
- uses: dfinity/setup-dfx@e50c04f104ee4285ec010f10609483cf41e4d365 | |
# Helps with debugging | |
- name: Show versions | |
run: | | |
echo dfx --version | |
dfx --version | |
- name: Start replica | |
run: | | |
dfx start --background --artificial-delay 0 | |
- name: "Download wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_dev.wasm.gz | |
path: . | |
- name: Deploy II and run tests | |
run: | | |
set -euo pipefail | |
# Copy example to make sure it does not rely on living inside the II repo | |
builddir=$(mktemp -d) | |
cp -r ./demos/using-dev-build/. "$builddir" | |
ii_wasm="$PWD/internet_identity_dev.wasm.gz" | |
ii_did="$PWD/src/internet_identity/internet_identity.did" | |
pushd "$builddir" | |
# Install npm deps | |
npm ci | |
sed -i "s;https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_dev.wasm.gz;$ii_wasm;" ./dfx.json | |
sed -i "s;https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did;$ii_did;" ./dfx.json | |
dfx deploy --no-wallet | |
npm run test | |
popd | |
rm -rf "$builddir" | |
- name: Stop replica | |
run: | | |
dfx stop | |
# This deploys the production build to mainnet (to a canister that we use for release testing) alongside | |
# some other canisters useful for testing & playing with II. | |
deploy: | |
runs-on: ubuntu-latest | |
if: startsWith(github.ref, 'refs/tags/release-') | |
needs: | |
[ | |
docker-build-ii, | |
docker-build-archive, | |
test-app-build, | |
vc_demo_issuer-build, | |
] | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dfinity/setup-dfx@e50c04f104ee4285ec010f10609483cf41e4d365 | |
- name: "Download II wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_production.wasm.gz | |
path: . | |
- name: "Download archive wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: archive.wasm.gz | |
path: . | |
- name: "Install key" | |
env: | |
DFX_DEPLOY_KEY: ${{ secrets.DFX_DEPLOY_KEY }} | |
run: | | |
key_pem=$(mktemp) | |
printenv "DFX_DEPLOY_KEY" > "$key_pem" | |
dfx identity import --disable-encryption --force default "$key_pem" | |
rm "$key_pem" | |
- name: "Deploy II" | |
run: | | |
wallet="cvthj-wyaaa-aaaad-aaaaq-cai" | |
sha=$(shasum -a 256 ./archive.wasm.gz | cut -d ' ' -f1 | sed 's/../\\&/g') | |
dfx canister --network ic --wallet "$wallet" install --mode upgrade \ | |
--argument "(opt record {archive_config = record { module_hash = blob \"$sha\"; entries_buffer_limit = 10000:nat64; entries_fetch_limit = 1000:nat16; polling_interval_ns = 60000000000:nat64}; canister_creation_cycles_cost = opt (1000000000000:nat64); })" \ | |
--wasm internet_identity_production.wasm.gz \ | |
fgte5-ciaaa-aaaad-aaatq-cai | |
- name: "Download test app wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: test_app.wasm | |
path: . | |
- name: "Deploy test app" | |
run: | | |
wallet="cvthj-wyaaa-aaaad-aaaaq-cai" | |
dfx canister --network ic --wallet "$wallet" install --mode upgrade \ | |
--wasm ./test_app.wasm \ | |
vt36r-2qaaa-aaaad-aad5a-cai | |
- name: "Download VC issuer wasm" | |
uses: actions/download-artifact@v4 | |
with: | |
name: vc_demo_issuer.wasm.gz | |
path: . | |
- name: "Deploy Issuer" | |
run: | | |
wallet="cvthj-wyaaa-aaaad-aaaaq-cai" | |
dfx canister --network ic --wallet "$wallet" install --mode upgrade \ | |
--wasm vc_demo_issuer.wasm.gz \ | |
v2yvn-myaaa-aaaad-aad4q-cai | |
./demos/vc_issuer/provision \ | |
--ii-canister-id fgte5-ciaaa-aaaad-aaatq-cai \ | |
--dfx-network ic \ | |
--issuer-canister v2yvn-myaaa-aaaad-aad4q-cai \ | |
--wallet "$wallet" | |
- name: "Deploy archive" | |
run: scripts/deploy-archive --wasm archive.wasm.gz --canister-id fgte5-ciaaa-aaaad-aaatq-cai --network ic | |
# This prepares all the files necessary for a release (all flavors of Wasm, release notes). | |
# On release tags, a new release is created and the assets are uploaded. | |
release: | |
runs-on: ubuntu-latest | |
needs: [docker-build-ii, docker-build-archive, vc_demo_issuer-build] | |
steps: | |
- uses: actions/checkout@v4 | |
- name: "Download test build" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_test.wasm.gz | |
path: . | |
- name: "Download dev build" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_dev.wasm.gz | |
path: . | |
- name: "Download production build" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_production.wasm.gz | |
path: . | |
- name: "Download archive" | |
uses: actions/download-artifact@v4 | |
with: | |
name: archive.wasm.gz | |
path: . | |
- name: "Download issuer" | |
uses: actions/download-artifact@v4 | |
with: | |
name: vc_demo_issuer.wasm.gz | |
path: . | |
- name: "Get GHA job IDs" | |
uses: actions/github-script@v7 | |
id: pipeline-jobs | |
with: | |
script: | | |
return (await github.paginate("GET /repos/dfinity/internet-identity/actions/runs/${{ github.run_id }}/jobs")) | |
.map(job => { | |
return { | |
id: job.id, | |
name: job.name, | |
steps: job.steps.map(step => { | |
return {name: step.name, number: step.number} | |
}), | |
html_url: job.html_url} | |
}); | |
- name: "Get latest release" | |
uses: actions/github-script@v7 | |
id: latest-release-tag | |
with: | |
result-encoding: string | |
script: return (await github.rest.repos.getLatestRelease({owner:"dfinity", repo:"internet-identity"})).data.tag_name; | |
# NOTE: we create the release notes ourselves, instead of letting GitHub do it with | |
# 'generate_release_notes: true', here we can actually specify the release range. When doing | |
# it on its own, GitHub is really bad at figuring which tag to use as the previous tag (for | |
# listing contributions since). | |
# https://github.com/github/feedback/discussions/5975 | |
- name: "Generate CHANGELOG" | |
uses: actions/github-script@v7 | |
id: changelog | |
with: | |
result-encoding: string | |
script: | | |
return (await github.rest.repos.generateReleaseNotes({ | |
owner: "dfinity", | |
repo: "internet-identity", | |
tag_name: "${{ github.ref }}", | |
previous_tag_name: "${{ steps.latest-release-tag.outputs.result }}", | |
})).data.body; | |
- name: Print prepare-release-inputs | |
env: | |
# use an env variable so that the GitHub templating does not cause issues with string escaping | |
# see: https://github.com/orgs/community/discussions/32012 | |
CHANGELOG: ${{ steps.changelog.outputs.result }} | |
run: | | |
echo -e 'pipeline jobs:\n${{ steps.pipeline-jobs.outputs.result }}' | |
echo "latest-release-tag: ${{ steps.latest-release-tag.outputs.result }}" | |
echo -e "changelog:\n$CHANGELOG" | |
- name: Prepare release | |
uses: ./.github/actions/release | |
id: prepare-release | |
with: | |
assets: | | |
internet_identity_production.wasm.gz | |
internet_identity_dev.wasm.gz | |
internet_identity_test.wasm.gz | |
archive.wasm.gz | |
vc_demo_issuer.wasm.gz | |
production_asset: internet_identity_production.wasm.gz | |
changelog: ${{ steps.changelog.outputs.result }} | |
workflow_jobs: ${{ steps.pipeline-jobs.outputs.result }} | |
- name: Release notes | |
run: cat ${{ steps.prepare-release.outputs.notes-file }} | |
# Create a sha file for dfx pull, referenced by the metadata set in the build | |
- name: Create sha for dfx pull | |
run: | | |
shasum -a 256 \ | |
./internet_identity_dev.wasm.gz > \ | |
./internet_identity_dev.wasm.gz.sha256 | |
- name: Publish release | |
if: startsWith(github.ref, 'refs/tags/release-') | |
run: | | |
./scripts/release \ | |
--tag ${{ github.ref }} \ | |
--notes-file ${{ steps.prepare-release.outputs.notes-file }} \ | |
-- \ | |
internet_identity_production.wasm.gz \ | |
internet_identity_dev.wasm.gz \ | |
internet_identity_dev.wasm.gz.sha256 \ | |
internet_identity_test.wasm.gz \ | |
src/internet_identity/internet_identity.did \ | |
archive.wasm.gz \ | |
vc_demo_issuer.wasm.gz | |
env: | |
# populated by GitHub Actions | |
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# Bump the version in the download links and create A Pull Request | |
- name: Update README | |
env: | |
PREVIOUS_RELEASE_TAG: ${{ steps.latest-release-tag.outputs.result }} | |
NEW_RELEASE_TAG: ${{ github.ref_name }} | |
run: | | |
echo "II release: $PREVIOUS_RELEASE_TAG -> $NEW_RELEASE_TAG" | |
sed -i "s|$PREVIOUS_RELEASE_TAG|$NEW_RELEASE_TAG|g" ./README.md | |
cat ./README.md | |
- name: Create Pull Request | |
if: startsWith(github.ref, 'refs/tags/release-') | |
uses: peter-evans/create-pull-request@v6 | |
with: | |
token: ${{ secrets.GIX_BOT_PAT }} | |
base: main | |
add-paths: ./README.md | |
commit-message: Update release in README | |
committer: GitHub <noreply@github.com> | |
author: gix-bot <gix-bot@users.noreply.github.com> | |
branch: bot-release-readme-update | |
delete-branch: true | |
title: "Update release in README" | |
# Since this may be triggered on tag push, a failure won't be shown on any | |
# PR status. To notify the team, we send a message to our Slack channel on failure. | |
- name: Notify Slack on failure | |
uses: ./.github/actions/slack | |
if: ${{ startsWith(github.ref, 'refs/tags/') && failure() }} | |
with: | |
WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
MESSAGE: "Release creation failed" | |
# A native, fast cached build. We use the produced test assets to run the canister & e2e tests. | |
# The asset's checksum is compared against that of the (slower) docker build. | |
cached-build: | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/cache@v4 | |
id: cache | |
with: | |
path: | | |
~/.cargo | |
target | |
key: ${{ runner.os }}-cached-build-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock', '.node-version', 'package-lock.json') }} | |
- uses: ./.github/actions/bootstrap | |
- uses: ./.github/actions/setup-node | |
# run the build | |
# NOTE: npm ci is only ~2s slower than an offline install (npm i --offline), so we use npm ci to have | |
# a Clean Install | |
- run: npm ci --no-audit --no-fund | |
- name: Build test flavor | |
env: | |
II_FETCH_ROOT_KEY: 1 | |
II_DUMMY_CAPTCHA: 1 | |
II_DUMMY_AUTH: 0 | |
II_DEV_CSP: 0 | |
run: ./scripts/build | |
- run: mv internet_identity.wasm.gz internet_identity_test.wasm.gz | |
- name: "Upload test build" | |
uses: actions/upload-artifact@v4 | |
with: | |
# name is the name used to display and retrieve the artifact | |
name: internet_identity_test_cached.wasm.gz | |
# path is the name used as the file to upload and the name of the | |
# file when downloaded | |
path: internet_identity_test.wasm.gz | |
# Make sure that the asset we're testing is the same as that produced by the (slower) docker builds | |
cached-build-check: | |
runs-on: ubuntu-22.04 | |
needs: [docker-build-ii, cached-build] | |
steps: | |
- uses: actions/checkout@v4 | |
- name: "Download docker build" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_test.wasm.gz | |
path: . | |
- run: mv internet_identity_test.wasm.gz docker.wasm.gz | |
- name: "Download native cached build" | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_test_cached.wasm.gz | |
path: . | |
- run: mv internet_identity_test.wasm.gz native.wasm.gz | |
- run: | | |
native_sha256=$(shasum -a 256 ./native.wasm.gz | cut -d ' ' -f1) | |
docker_sha256=$(shasum -a 256 ./docker.wasm.gz | cut -d ' ' -f1) | |
echo "shas: native '$native_sha256', docker '$docker_sha256'" | |
if [ "$native_sha256" == "$docker_sha256" ] | |
then | |
echo output sha256 matches expected | |
else | |
echo "sha mismatch" | |
exit 1 | |
fi | |
clean-build: | |
runs-on: ${{ matrix.os }} | |
strategy: | |
matrix: | |
# On main, we run the checks across all platforms. On other branches, in order to speed up checks (on PRs) we skip most platforms | |
# (in particular the slow macos builds). A single ubuntu build is not long and gives us some signal. | |
# XXX: GHA does not support proper if/else so we implement a workaround: https://github.com/actions/runner/issues/409 | |
# XXX: GHA fails if we return the matrix object directly, so we have to pretend it's JSON | |
os: ${{ github.ref == 'refs/heads/main' && fromJson('[ "ubuntu-22.04", "ubuntu-20.04", "macos-13", "macos-14" ]') || fromJson('[ "ubuntu-22.04" ]') }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/check-build | |
- run: mv internet_identity.wasm.gz internet_identity_clean_build_${{ matrix.os }}.wasm.gz | |
- name: "Upload clean build" | |
uses: actions/upload-artifact@v4 | |
with: | |
# name is the name used to display and retrieve the artifact | |
name: internet_identity_clean_build_${{ matrix.os }}.wasm.gz | |
# path is the name used as the file to upload and the name of the | |
# file when downloaded | |
path: internet_identity_clean_build_${{ matrix.os }}.wasm.gz | |
verify-clean-build-hash: | |
needs: ["clean-build", "docker-build-ii"] | |
runs-on: ${{ matrix.os }} | |
strategy: | |
matrix: | |
# On main, we run the hash check across all platforms where the non-dockerized build is reproducible (i.e. not mac-os). | |
# On other branches, in order to speed up checks (on PRs) we skip most platforms. A single ubuntu build is not long and gives us some signal. | |
# XXX: GHA does not support proper if/else so we implement a workaround: https://github.com/actions/runner/issues/409 | |
# XXX: GHA fails if we return the matrix object directly, so we have to pretend it's JSON | |
os: ${{ github.ref == 'refs/heads/main' && fromJson('[ "ubuntu-22.04", "ubuntu-20.04"]') || fromJson('[ "ubuntu-22.04" ]') }} | |
steps: | |
- name: Download internet_identity_clean_build_${{ matrix.os }}.wasm.gz | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_clean_build_${{ matrix.os }}.wasm.gz | |
path: . | |
- name: Download internet_identity_production.wasm.gz | |
uses: actions/download-artifact@v4 | |
with: | |
name: internet_identity_production.wasm.gz | |
path: . | |
- name: Check hashes | |
run: | | |
clean_build_sha256=$(shasum -a 256 ./internet_identity_clean_build_${{ matrix.os }}.wasm.gz | cut -d ' ' -f1) | |
echo got clean build sha "$clean_build_sha256" | |
prod_build_sha256=$(shasum -a 256 ./internet_identity_production.wasm.gz | cut -d ' ' -f1) | |
echo got prod build sha "$prod_build_sha256" | |
if [ "$clean_build_sha256" == "$prod_build_sha256" ] | |
then | |
echo output clean build sha256 matches prod build sha256 | |
else | |
echo "sha mismatch: clean build '$clean_build_sha256' /= prod build '$prod_build_sha256'" | |
exit 1 | |
fi | |
interface-compatibility: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/setup-didc | |
- name: "Check canister interface compatibility" | |
run: | | |
curl -sSL https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did -o internet_identity_previous.did | |
didc check src/internet_identity/internet_identity.did internet_identity_previous.did | |
sig-verifier-js: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/setup-node | |
- run: npm ci | |
- name: Build sig-verifier | |
run: npm run --workspace ./src/sig-verifier-js build | |
- name: Run sig-verifier tests | |
run: npm run --workspace ./src/sig-verifier-js test |