diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..84a5deb6 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,74 @@ +# Harpocrates Development Container Dockerfile +# Pinned versions match: +# - Noir & Barretenberg: zk/toolchain.lock.json (nargo 1.0.0-beta.9, bb 0.87.0) +# - Node.js: package.json engines / CI pinned version (v22.x) +# - Python: backend / devx / zk runtime (3.12) +# - Rust: contracts workspace (1.85.0 stable with wasm32-unknown-unknown target) +# - Stellar CLI: contracts compilation and testing + +FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 + +ARG DEBIAN_FRONTEND=noninteractive + +# Pin toolchain versions +ENV NODE_MAJOR=22 \ + RUST_VERSION=1.85.0 \ + NARGO_VERSION=1.0.0-beta.9 \ + BB_VERSION=0.87.0 \ + STELLAR_CLI_VERSION=22.5.0 + +# Base dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + curl \ + git \ + gnupg \ + jq \ + libssl-dev \ + pkg-config \ + python3 \ + python3-dev \ + python3-pip \ + python3-venv \ + sudo \ + tar \ + unzip \ + wget \ + && rm -rf /var/lib/apt/lists/* + +# Install Node.js 22.x +RUN mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ + apt-get update && apt-get install -y --no-install-recommends nodejs && \ + rm -rf /var/lib/apt/lists/* + +# Install Rust toolchain for vscode user +USER vscode +ENV RUSTUP_HOME=/home/vscode/.rustup \ + CARGO_HOME=/home/vscode/.cargo \ + NARGO_HOME=/home/vscode/.nargo \ + BB_HOME=/home/vscode/.bb \ + PATH=/home/vscode/.cargo/bin:/home/vscode/.nargo/bin:/home/vscode/.bb:$PATH + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain ${RUST_VERSION} \ + && rustup target add wasm32-unknown-unknown wasm32v1-none \ + && rustup component add clippy rustfmt llvm-tools-preview + +# Install Stellar CLI +USER root +RUN curl -fsSL https://github.com/stellar/stellar-cli/releases/latest/download/stellar-cli-ubuntu-x86_64.tar.gz \ + | tar -xz -C /usr/local/bin stellar \ + && chmod +x /usr/local/bin/stellar + +# Install Nargo and Barretenberg for vscode user +USER vscode +RUN curl -L https://raw.githubusercontent.com/noir-lang/noirup/refs/heads/main/install | bash \ + && /home/vscode/.nargo/bin/noirup --version ${NARGO_VERSION} + +RUN curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/master/barretenberg/bbup/install | bash \ + && /home/vscode/.bb/bbup --version ${BB_VERSION} + +USER vscode +WORKDIR /workspace diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..de9267d3 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,24 @@ +{ + "name": "Harpocrates Dev Container", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + "remoteUser": "vscode", + "customizations": { + "vscode": { + "settings": { + "python.defaultInterpreterPath": "${workspaceFolder}/backend/.venv/bin/python", + "python.testing.pytestEnabled": true, + "editor.formatOnSave": true + }, + "extensions": [ + "rust-lang.rust-analyzer", + "dbaeumer.vscode-eslint", + "ms-python.python", + "ms-python.vscode-pylance" + ] + } + }, + "postCreateCommand": "bash .devcontainer/post-create.sh" +} diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100644 index 00000000..6005fb0b --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "=== Running post-create setup ===" + +# 1. Install frontend npm dependencies +if [ -d "frontend" ] && [ -f "frontend/package.json" ]; then + echo "Installing frontend dependencies..." + (cd frontend && npm ci) +fi + +# 2. Install cli npm dependencies +if [ -d "cli" ] && [ -f "cli/package.json" ]; then + echo "Installing cli dependencies..." + (cd cli && npm ci) +fi + +# 3. Create backend virtual environment and install dependencies +if [ -d "backend" ] && [ -f "backend/requirements.txt" ]; then + echo "Setting up backend virtual environment..." + python3 -m venv backend/.venv + backend/.venv/bin/pip install --upgrade pip + backend/.venv/bin/pip install -r backend/requirements.txt + if [ -f "backend/requirements-dev.txt" ]; then + backend/.venv/bin/pip install -r backend/requirements-dev.txt + fi +fi + +# 4. Verify dependency pins +if [ -f "devx/check_dependency_pins.py" ]; then + echo "Checking repository dependency pins..." + python3 devx/check_dependency_pins.py +fi + +echo "=== Post-create setup complete ===" diff --git a/.github/workflows/devcontainer-ci.yml b/.github/workflows/devcontainer-ci.yml new file mode 100644 index 00000000..b49bc2d7 --- /dev/null +++ b/.github/workflows/devcontainer-ci.yml @@ -0,0 +1,109 @@ +name: Devcontainer CI + +on: + pull_request: + paths: + - ".devcontainer/**" + - ".github/workflows/devcontainer-ci.yml" + - "zk/toolchain.lock.json" + push: + branches: + - main + paths: + - ".devcontainer/**" + - ".github/workflows/devcontainer-ci.yml" + - "zk/toolchain.lock.json" + schedule: + # Run weekly on Sunday at midnight UTC + - cron: "0 0 * * 0" + +permissions: + contents: read + +concurrency: + group: devcontainer-ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-and-smoke: + name: Build Devcontainer and Smoke Test + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Check out repository + uses: actions/checkout@v7 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Devcontainer image (build-only job) + uses: docker/build-push-action@v5 + with: + context: . + file: .devcontainer/Dockerfile + tags: harpocrates-devcontainer:test + load: true + push: false + + - name: Smoke test toolchain versions inside container + run: | + docker run --rm harpocrates-devcontainer:test bash -c ' + set -euo pipefail + + echo "=== Checking toolchains ===" + node --version + npm --version + python3 --version + rustc --version + cargo --version + stellar --version + + echo "=== Checking Noir and Barretenberg pinned versions ===" + nargo --version + bb --version + + EXPECTED_NARGO="1.0.0-beta.9" + EXPECTED_BB="0.87.0" + + ACTUAL_NARGO="$(nargo --version 2>/dev/null | grep -oE "[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.]+)?")" + ACTUAL_BB="$(bb --version 2>/dev/null | grep -oE "[0-9]+\.[0-9]+\.[0-9]+")" + + if [[ "$ACTUAL_NARGO" != *"$EXPECTED_NARGO"* ]]; then + echo "Error: nargo version ($ACTUAL_NARGO) does not match expected ($EXPECTED_NARGO)" + exit 1 + fi + + if [[ "$ACTUAL_BB" != *"$EXPECTED_BB"* ]]; then + echo "Error: bb version ($ACTUAL_BB) does not match expected ($EXPECTED_BB)" + exit 1 + fi + + echo "All toolchains verified successfully." + ' + + - name: Smoke test workspaces inside container + run: | + docker run --rm -v "${{ github.workspace }}:/workspace" -w /workspace harpocrates-devcontainer:test bash -c ' + set -euo pipefail + + echo "=== Executing post-create setup ===" + bash .devcontainer/post-create.sh + + echo "=== Smoke test: Contracts workspace ===" + (cd contracts && cargo check) + + echo "=== Smoke test: Backend workspace ===" + backend/.venv/bin/python -m unittest discover -s backend -p "test_api_contract_conformance.py" -v + + echo "=== Smoke test: Frontend workspace ===" + (cd frontend && npm test -- src/stellar.test.ts) + + echo "=== Smoke test: CLI workspace ===" + (cd cli && npm test -- test/stellar-lookup.test.ts) + + echo "=== Smoke test: Noir ZK workspace ===" + (cd zk/noir/silent_witness && nargo check) + + echo "All workspace smoke tests passed inside the devcontainer!" + ' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 369778b7..bf5a88f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,17 @@ noirup ``` +### 1.1 Development Container (Recommended) + +For a fully configured environment with all toolchains (Rust, Node, Python, Stellar CLI, Nargo, and Barretenberg) preinstalled at pinned versions, open the repository in VS Code or GitHub Codespaces using the Dev Container: + +1. Install Docker and the VS Code [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers). +2. Open the repository root in VS Code. +3. Press `F1` and select **Dev Containers: Reopen in Container**. +4. The post-create script automatically installs workspace dependencies (`npm ci` for `frontend/` and `cli/`), sets up the Python backend virtual environment, and verifies dependency pins. + +--- + ## 2. Workspace Setup, Build, and Test Commands ### 2.1 Workspace Installation