Skip to content
Draft
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
52 changes: 52 additions & 0 deletions .github/workflows/interface-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Interface Sync Guard

permissions: {}

# Guards the cross-language interface contract:
#
# The frontend SDK bundles generated Candid declarations (idlFactory + types)
# that MUST stay in sync with the canister .did files. This job regenerates the
# declarations from the committed .did using the pinned bindgen version and
# fails if the result differs from what is checked in — i.e. someone changed a
# .did but forgot to regenerate the frontend declarations (or edited the
# generated files by hand).
#
# Note: the Rust <-> Motoko backend interface contract is already enforced
# behaviorally — the Motoko canister is compiled to wasm and the Rust canister's
# integration tests run against it (see backend/mo/canisters/*/Makefile and
# backend-motoko.yml), so this guard deliberately focuses on the
# frontend <-> canister seam, which is otherwise unguarded.

on:
push:
branches:
- main
- master
pull_request:
paths:
- backend/rs/canisters/*/*.did
- frontend/ic_vetkeys/src/declarations/**
- frontend/ic_vetkeys/make_did_bindings.sh
- .github/workflows/interface-sync.yml

jobs:
declarations-in-sync:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
- name: Regenerate frontend declarations from committed .did files
working-directory: frontend/ic_vetkeys
run: SKIP_EXTRACT_CANDID=1 bash make_did_bindings.sh
- name: Fail if declarations are out of sync
run: |
set -eEuo pipefail
if ! git diff --exit-code -- frontend/ic_vetkeys/src/declarations; then
echo "::error::Frontend declarations are out of sync with the canister .did files."
echo "Run 'bash make_did_bindings.sh' in frontend/ic_vetkeys and commit the result."
exit 1
fi
25 changes: 21 additions & 4 deletions frontend/ic_vetkeys/make_did_bindings.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
set -ex

# Pin the bindgen version so regeneration is reproducible. The committed
# declarations under src/declarations were generated with this version; the
# interface-sync CI guard regenerates and diffs against them, so an unpinned
# version (whatever `npx` resolves to) would cause spurious failures whenever a
# newer bindgen ships cosmetic/formatting changes. Bump this deliberately and
# commit the regenerated output together.
BINDGEN_VERSION="0.3.0"

# Set SKIP_EXTRACT_CANDID=1 to regenerate the TS declarations from the existing
# committed .did files without rebuilding them from the Rust source. The
# interface-sync CI guard uses this so the check stays reproducible (it depends
# only on the pinned bindgen version and the committed .did, not on the
# candid-extractor / wasm toolchain).
SKIP_EXTRACT_CANDID="${SKIP_EXTRACT_CANDID:-0}"

function make_and_copy_declarations () {
DIR=$1
NAME=$2
DID_FILE=$3

pushd "$DIR/$NAME"
make extract-candid
popd
if [ "$SKIP_EXTRACT_CANDID" != "1" ]; then
pushd "$DIR/$NAME"
make extract-candid
popd
fi

rm -rf "src/declarations/$NAME"
mkdir -p "src/declarations/$NAME"
npx @icp-sdk/bindgen --did-file "$DIR/$NAME/$DID_FILE" --out-dir "src/declarations/$NAME" --declarations-flat --force
npx "@icp-sdk/bindgen@${BINDGEN_VERSION}" --did-file "$DIR/$NAME/$DID_FILE" --out-dir "src/declarations/$NAME" --declarations-flat --force
}

make_and_copy_declarations "../../backend/rs/canisters/" "ic_vetkeys_manager_canister" "ic_vetkeys_manager_canister.did"
Expand Down
Loading