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
49 changes: 49 additions & 0 deletions .github/workflows/full-dev-path.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Tests that the installed Aztec toolchain works end-to-end.
# Exercises the full developer onboarding path: aztec init -> compile -> test -> start -> codegen -> TS end-to-end test.
name: Full Dev Path Test

on:
workflow_dispatch:
inputs:
version:
description: "Version to install (e.g. latest, nightly, 4.3.0, 4.3.0-nightly.20260420)"
required: true
type: string
push:
tags:
- "v*"

jobs:
full-dev-path:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
VERSION: ${{ github.event.inputs.version || github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Run full dev path test
run: ./aztec-up/test/full-dev-path/run-test.sh

- name: Notify Slack on success
if: success() && github.event_name != 'workflow_dispatch'
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
run: |
export CI=1
./ci3/slack_notify "#team-fairies" \
"Full Dev Path Test passed for version ${VERSION} :white_check_mark:"

- name: Notify Slack and dispatch ClaudeBox on failure
if: failure() && github.event_name != 'workflow_dispatch'
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
GITHUB_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }}
run: |
RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
export CI=1
./ci3/slack_notify_with_claudebox_kickoff "#team-fairies" \
"Full Dev Path Test FAILED (version ${VERSION}): <${RUN_URL}|View Run>" \
"Full dev path test failed for version ${VERSION}. CI run: ${RUN_URL}. Investigate the failure and explain the root cause." \
--link "$RUN_URL"
35 changes: 35 additions & 0 deletions aztec-up/test/full-dev-path/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Full Dev Path Test

Tests that the installed Aztec toolchain works end-to-end. Exercises the complete developer onboarding path:

1. `aztec init` - scaffold a new workspace with a Counter contract and test crate
2. `aztec compile` - compile the scaffolded contract
3. `aztec test` - run the TXE tests from the scaffold's test crate
4. `aztec start --local-network` - start a local sandbox (anvil + aztec node)
5. `aztec codegen` - generate TypeScript bindings from the compiled artifact
6. TS end-to-end test - run a `node --test` suite inside the scaffolded workspace that imports the codegen'd `CounterContract`, stands up an in-process wallet + PXE via `@aztec/wallets/embedded`, deploys Counter, calls `increment`, and reads the value back through the `get_counter` utility function

## Running

With an existing local install (fast inner loop):
```bash
SKIP_INSTALL=1 ./run-test.sh
```

With a fresh install from a specific version:
```bash
VERSION=4.3.0 ./run-test.sh
```

## Environment Variables

| Variable | Description |
|----------|-------------|
| `SKIP_INSTALL` | Set to `1` to skip the installer and use the already-installed toolchain. |
| `VERSION` | Version to install (e.g. `4.3.0` or `v4.3.0`). Required unless `SKIP_INSTALL=1`. |

## Architecture

- **`run-test.sh`** - Bash launcher. Runs the aztec installer (unless skipped), sets up PATH, then `exec node full-dev-path.ts`.
- **`full-dev-path.ts`** - Orchestrator. Runs each CLI step against the installed toolchain and, after codegen, copies `counter.test.ts` into the scaffolded workspace and spawns `node --test` on it. Each phase is wrapped in `step(name, fn)` so failures clearly identify which step broke. Always emits a machine-readable result line for CI/Slack integration: `TEST_RESULT=pass version=...` on success, or `TEST_RESULT=fail step=... version=... error="..."` on failure (with a full banner printed above it).
- **`counter.test.ts`** - The `node:test` suite that drives the deployed Counter end-to-end through the codegen'd bindings. Lives here as a template; copied into the workspace at test time so it can statically `import { CounterContract } from './artifacts/Counter.js'` with real codegen types and resolve `@aztec/*` via the workspace's `node_modules` symlink to the install.
43 changes: 43 additions & 0 deletions aztec-up/test/full-dev-path/counter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// End-to-end test for the scaffolded Counter contract.
//
// Copied into the scaffolded workspace at test time by ../test.ts, then executed with
// `node --test`. Runs from inside the workspace so that:
// - `./artifacts/Counter.js` resolves to the codegen'd bindings (and its types flow).
// - `@aztec/*` imports resolve via the workspace's `node_modules` symlink to the
// installed Aztec toolchain — i.e. the same packages a real user would have.
//
// The test expects an `aztec start --local-network` node reachable at NODE_URL. It uses the
// pre-funded test0 account that local-network already deployed, stands up an in-process
// EmbeddedWallet + PXE, deploys a fresh Counter, and exercises a full round trip through
// the codegen'd bindings (send + simulate).

import test from 'node:test';
import assert from 'node:assert/strict';

import { getInitialTestAccountsData } from '@aztec/accounts/testing';
import { EmbeddedWallet } from '@aztec/wallets/embedded';

import { CounterContract } from './artifacts/Counter.ts';

const NODE_URL = process.env.NODE_URL ?? 'http://localhost:8080';
const INITIAL_COUNTER_VALUE = 0n;

test('Counter deploys and increments through codegen bindings', async () => {
const wallet = await EmbeddedWallet.create(NODE_URL, { ephemeral: true });

const [test0] = await getInitialTestAccountsData();
await wallet.createSchnorrAccount(test0.secret, test0.salt, test0.signingKey);
const owner = test0.address;

const { contract: counter } = await CounterContract.deploy(wallet, INITIAL_COUNTER_VALUE, owner).send({
from: owner,
});

const initial = await counter.methods.get_counter(owner).simulate({ from: owner });
assert.equal(initial.result, INITIAL_COUNTER_VALUE, 'counter value just after deploy');

await counter.methods.increment(owner).send({ from: owner });

const afterIncrement = await counter.methods.get_counter(owner).simulate({ from: owner });
assert.equal(afterIncrement.result, INITIAL_COUNTER_VALUE + 1n, 'counter value after increment');
});
Loading
Loading