diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ff1b8f1b..eeb0dff2 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,4 +4,4 @@ "dockerfile": "Dockerfile" }, "postCreateCommand": "code --install-extension /tmp/compact.vsix && compact update 0.26.0" -} \ No newline at end of file +} diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index b13c757d..08af71c2 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -1,10 +1,30 @@ name: "Setup Environment" -description: "Sets up the environment with yarn, Node.js, and turbo" +description: "Sets up the environment with yarn, Node.js, turbo, and Compact compiler" + +inputs: + skip-compact: + description: "Skip Compact compiler installation" + required: false + default: "false" + +outputs: + compact-home: + description: "Path to Compact compiler installation" + value: ${{ steps.compact-outputs.outputs.compact-home }} + compact-version: + description: "Installed Compact compiler version" + value: ${{ steps.compact-outputs.outputs.version }} runs: using: "composite" steps: - - name: Enable Corepack + - name: Set shared environment variables + shell: bash + run: | + echo "COMPILER_VERSION=0.26.0" >> $GITHUB_ENV + echo "LANGUAGE_VERSION=0.18.0" >> $GITHUB_ENV + + - name: Get yarn cache directory path shell: bash run: corepack enable @@ -16,8 +36,17 @@ runs: restore-keys: | ${{ runner.os }}-turbo-${{ hashFiles('.turbo/*') }} + - name: Cache Compact compiler + if: inputs.skip-compact != 'true' + uses: actions/cache@v4 + id: compact-cache + with: + path: | + ~/.local/bin/compact + key: compact-compiler-${{ env.COMPILER_VERSION }}-${{ runner.os }} + - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version-file: ".nvmrc" cache: "yarn" @@ -31,5 +60,80 @@ runs: env: TURBO_MAJOR_VERSION: 2 TURBO_TELEMETRY_DISABLED: 1 + run: npm install turbo@${{ env.TURBO_MAJOR_VERSION }} -g + + - name: Install Compact compiler + if: inputs.skip-compact != 'true' && steps.compact-cache.outputs.cache-hit != 'true' + shell: bash run: | - npm install turbo@${{ env.TURBO_MAJOR_VERSION }} -g + set -euo pipefail + COMPACT_HOME="$HOME/.local/bin" + mkdir -p "$COMPACT_HOME" + + # Require COMPACT_INSTALLER_URL to be provided by the caller + if [ -z "${COMPACT_INSTALLER_URL:-}" ]; then + echo "::error::COMPACT_INSTALLER_URL is required but not set. Provide it via env or secrets." + exit 1 + fi + + echo "šŸ”§ Installing Compact compiler from $COMPACT_INSTALLER_URL ..." + curl --proto '=https' --tlsv1.2 -LsSf "$COMPACT_INSTALLER_URL" | sh + + echo "šŸ”§ Updating Compact compiler to $COMPILER_VERSION..." + "$COMPACT_HOME/compact" update "$COMPILER_VERSION" + + echo "āœ… Compact compiler installed" + + - name: Setup Compact environment + if: inputs.skip-compact != 'true' + shell: bash + run: | + COMPACT_HOME="$HOME/.local/bin" + echo "šŸ“ Setting Compact environment variables..." + echo "COMPACT_HOME=$COMPACT_HOME" >> "$GITHUB_ENV" + echo "$COMPACT_HOME" >> "$GITHUB_PATH" + + if [ -f "$COMPACT_HOME/compact" ]; then + echo "āœ… Compact compiler is installed at $COMPACT_HOME" + else + echo "::error::āŒ Compact compiler not found in $COMPACT_HOME" + exit 1 + fi + + - name: Set Compact outputs + if: inputs.skip-compact != 'true' + id: compact-outputs + shell: bash + run: | + echo "compact-home=$HOME/.local/bin" >> $GITHUB_OUTPUT + echo "version=$COMPILER_VERSION" >> $GITHUB_OUTPUT + + - name: Check compiler and language version + if: inputs.skip-compact != 'true' + shell: bash + run: | + set -euo pipefail + + echo "šŸ”§ Updating Compact compiler to $COMPILER_VERSION..." + "$COMPACT_HOME/compact" update "$COMPILER_VERSION" + + echo "šŸ” Checking Compact compiler version..." + COMPILER_OUTPUT=$("$COMPACT_HOME/compact" compile --version) + COMPUTED_COMPILER_VERSION=$(echo "$COMPILER_OUTPUT" | grep -oP '\b0\.[0-9]+\.[0-9]+\b' | head -n 1) + + if [ "$COMPUTED_COMPILER_VERSION" != "$COMPILER_VERSION" ]; then + echo "::error::āŒ Compiler version mismatch!%0AExpected: $COMPILER_VERSION%0AGot: $COMPUTED_COMPILER_VERSION" + exit 1 + fi + echo "āœ… Compiler version matches: $COMPUTED_COMPILER_VERSION" + + echo "šŸ” Checking Compact language version..." + LANGUAGE_OUTPUT=$("$COMPACT_HOME/compact" compile --language-version) + COMPUTED_LANGUAGE_VERSION=$(echo "$LANGUAGE_OUTPUT" | grep -oP '\b0\.[0-9]+\.[0-9]+\b' | tail -n 1) + + if [ "$COMPUTED_LANGUAGE_VERSION" != "$LANGUAGE_VERSION" ]; then + echo "::error::āŒ Language version mismatch!%0AExpected: $LANGUAGE_VERSION%0AGot: $COMPUTED_LANGUAGE_VERSION" + exit 1 + fi + echo "āœ… Language version matches: $COMPUTED_LANGUAGE_VERSION" + \ No newline at end of file diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 944d14a1..c42bc97c 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -14,6 +14,9 @@ jobs: name: Run Checks runs-on: ubuntu-24.04 + env: + COMPACT_INSTALLER_URL: ${{ vars.COMPACT_INSTALLER_URL }} + steps: - name: Check out code uses: actions/checkout@v5 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5f726e24..992ea100 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -22,6 +22,9 @@ jobs: matrix: language: ["javascript", "typescript"] + env: + COMPACT_INSTALLER_URL: ${{ vars.COMPACT_INSTALLER_URL }} + steps: - name: Check out code uses: actions/checkout@v5 diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 00000000..5d187507 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,83 @@ +name: Update version on new release branch + +on: + create: + +permissions: + contents: write + pull-requests: write + +jobs: + update_version: + if: github.ref_type == 'branch' && startsWith(github.ref, 'refs/heads/release-v') + runs-on: ubuntu-24.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version-file: ".nvmrc" + cache: "yarn" + + - name: Extract current version + run: | + CURRENT_VERSION=$(node -p "require('./contracts/package.json').version") + echo "CURRENT_VERSION=$CURRENT_VERSION" >> "$GITHUB_ENV" + + - name: Extract new version number + run: echo "NEW_VERSION=${GITHUB_REF#refs/heads/release-v}" >> "$GITHUB_ENV" + + - name: Validate new version + run: | + BRANCH="${GITHUB_REF#refs/heads/}" + echo "Branch: $BRANCH" + echo "Current version: $CURRENT_VERSION" + echo "New version: $NEW_VERSION" + + # 1) Branch must match release-v + if ! echo "$BRANCH" | grep -Eq '^release-v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$'; then + echo "Error: Branch '$BRANCH' must match 'release-v' (e.g., release-v1.2.3)." >&2 + exit 1 + fi + + # 2) NEW_VERSION must be valid semver + node -e "const v=process.env.NEW_VERSION; const semver=/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$/; if(!semver.test(v)){ console.error('Error: NEW_VERSION is not valid semver:', v); process.exit(1); }" + if [ $? -ne 0 ]; then + exit 1 + fi + + # 3) NEW_VERSION must differ from CURRENT_VERSION + if [ "$NEW_VERSION" = "$CURRENT_VERSION" ]; then + echo "Error: NEW_VERSION equals CURRENT_VERSION ($CURRENT_VERSION). Nothing to release." >&2 + exit 1 + fi + + - name: Replace version in files + env: + NEW_VERSION: ${{ env.NEW_VERSION }} + run: | + echo "Current version: $CURRENT_VERSION" + echo "New version: $NEW_VERSION" + + # Update package.json version field manually + yarn workspace @openzeppelin-compact/contracts version "$NEW_VERSION" + + # Escape special characters for sed + ESCAPED_CURRENT=$(printf '%s' "$CURRENT_VERSION" | sed -e 's/[\/&]/\\&/g') + ESCAPED_NEW=$(printf '%s' "$NEW_VERSION" | sed -e 's/[\/&]/\\&/g') + + # Replace version in contracts/src/ + find ./contracts/src/ -type d -name '.*' -prune -o \ + -type f -exec sed -i "s#$ESCAPED_CURRENT#$ESCAPED_NEW#g" {} + + + # Replace version in docs/, excluding package-lock.json + find ./docs/ -type d -name '.*' -prune -o \ + -type f ! -name 'package-lock.json' -exec sed -i "s#$ESCAPED_CURRENT#$ESCAPED_NEW#g" {} + + + - name: Auto-commit changes + uses: stefanzweifel/git-auto-commit-action@778341af668090896ca464160c2def5d1d1a3eb0 #v6.0.1 + with: + commit_message: Bump version to ${{ env.NEW_VERSION }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..4e1a335b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,93 @@ +name: Publish Package on Release + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write + + env: + COMPACT_INSTALLER_URL: ${{ vars.COMPACT_INSTALLER_URL }} + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Setup Environment + uses: ./.github/actions/setup + + - name: Build contracts + run: turbo build --filter=!'docs' + + - name: Validate version consistency + run: | + RELEASE_VERSION=${GITHUB_REF#refs/tags/v} + PACKAGE_VERSION=$(node -p "require('./contracts/package.json').version") + if [ "$RELEASE_VERSION" != "$PACKAGE_VERSION" ]; then + echo "āŒ Version mismatch: Release $RELEASE_VERSION vs Package $PACKAGE_VERSION" + exit 1 + fi + echo "āœ… Version consistency validated: $RELEASE_VERSION" + + - name: Setup npm registry + uses: actions/setup-node@v6 + with: + registry-url: "https://registry.npmjs.org" + + - name: Pack tarball + id: pack + run: | + cd contracts/dist + TARBALL=$(npm pack | tail -1) + echo "tarball_name=$TARBALL" >> $GITHUB_OUTPUT + echo "tarball=$(pwd)/$TARBALL" >> $GITHUB_OUTPUT + + # Determine dist-tag based on semver prerelease + PACKAGE_VERSION=$(node -p "require('./package.json').version") + if [[ "$PACKAGE_VERSION" =~ -.*$ ]]; then + # Has prerelease suffix (anything after -) + if [[ "$PACKAGE_VERSION" =~ -(alpha|beta|rc) ]]; then + echo "tag=beta" >> $GITHUB_OUTPUT + else + echo "tag=next" >> $GITHUB_OUTPUT + fi + else + # Stable release + echo "tag=latest" >> $GITHUB_OUTPUT + fi + + - name: Verify tarball integrity + run: | + echo "=== Verifying tarball contents ===" + PACKAGE_NAME=$(tar xfO "${{ steps.pack.outputs.tarball }}" package/package.json | jq -r .name) + PACKAGE_VERSION=$(tar xfO "${{ steps.pack.outputs.tarball }}" package/package.json | jq -r .version) + PRIVATE_FIELD=$(tar xfO "${{ steps.pack.outputs.tarball }}" package/package.json | jq -r '.private // "not found"') + + echo "šŸ“¦ Package: $PACKAGE_NAME@$PACKAGE_VERSION" + echo "šŸ·ļø Tag: ${{ steps.pack.outputs.tag }}" + echo "šŸ”’ Private field: $PRIVATE_FIELD" + + # Ensure no private field + if [ "$PRIVATE_FIELD" = "true" ]; then + echo "āŒ Tarball contains private: true - cannot publish" + exit 1 + fi + + - name: Publish to npm + run: | + # Publish the tarball with appropriate tag + npm publish "${{ steps.pack.outputs.tarball }}" --tag "${{ steps.pack.outputs.tag }}" --access public --provenance + env: + NPM_CONFIG_PROVENANCE: true + + - name: Log success + run: | + PACKAGE_NAME=$(tar xfO "${{ steps.pack.outputs.tarball }}" package/package.json | jq -r .name) + PACKAGE_VERSION=$(tar xfO "${{ steps.pack.outputs.tarball }}" package/package.json | jq -r .version) + echo "āœ… Successfully published $PACKAGE_NAME@$PACKAGE_VERSION to npm with tag ${{ steps.pack.outputs.tag }}" + echo "šŸ“¦ Install with: npm install $PACKAGE_NAME@${{ steps.pack.outputs.tag }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 264f8d03..8d02dc73 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,8 +16,9 @@ jobs: name: Run Test Suite runs-on: ubuntu-24.04 timeout-minutes: 15 + env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPACT_INSTALLER_URL: ${{ vars.COMPACT_INSTALLER_URL }} steps: - name: Check out code @@ -28,58 +29,8 @@ jobs: - name: Setup Environment uses: ./.github/actions/setup - - name: Install Compact developer tools - shell: bash - run: | - curl --proto '=https' --tlsv1.2 -LsSf https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh - echo "$HOME/.compact/bin" >> "$GITHUB_PATH" - - - name: Install and verify toolchain - run: | - compact update ${{ env.COMPILER_VERSION }} - echo "šŸ¤– Testing installation..." - compact compile --version - compact compile --language-version - - - name: Check compiler and language version - run: | - # Check toolchain version - COMPILER_OUTPUT=$(compact compile --version) - COMPUTED_COMPILER_VERSION=$(echo "$COMPILER_OUTPUT" | grep -oP '\b[0-9]+\.[0-9]+\.[0-9]+\b' | head -n 1) - if [ "$COMPUTED_COMPILER_VERSION" != "$COMPILER_VERSION" ]; then - errMsg="āŒ Compiler version mismatch!%0AExpected: $COMPILER_VERSION%0AGot: $COMPUTED_COMPILER_VERSION" - echo "::error::$errMsg" - exit 1 - fi - echo "āœ… Compiler version matches: $COMPUTED_COMPILER_VERSION" - - # Check language version using new command - LANGUAGE_OUTPUT=$(compact compile --language-version) - COMPUTED_LANGUAGE_VERSION=$(echo "$LANGUAGE_OUTPUT" | grep -oP '\b[0-9]+\.[0-9]+\.[0-9]+\b' | tail -n 1) - if [ "$COMPUTED_LANGUAGE_VERSION" != "$LANGUAGE_VERSION" ]; then - errMsg="āŒ Language version mismatch!%0AExpected: $LANGUAGE_VERSION%0AGot: $COMPUTED_LANGUAGE_VERSION" - echo "::error::$errMsg" - exit 1 - fi - echo "āœ… Language version matches: $COMPUTED_LANGUAGE_VERSION" - - - name: Compile contracts (with retry on hash mismatch) - shell: bash - run: | - compile() { - if ! output=$(turbo compact --concurrency=1 2>&1); then - if echo "$output" | grep -q "Hash mismatch" && [ -d "$HOME/.cache/midnight/zk-params" ]; then - echo "Hash mismatch detected. Clearing zk-params cache..." - rm -rf "$HOME/.cache/midnight/zk-params" - echo "Retrying compilation..." - turbo compact --concurrency=1 - else - echo "$output" - exit 1 - fi - fi - } - compile + - name: Compile contracts (with retry) + run: turbo compact --filter=@openzeppelin-compact/contracts --concurrency=1 - name: Run type checks run: turbo types diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..93a7b172 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,42 @@ +# Releasing + +(1) Checkout the branch to be released. +This will usually be `main` except in the event of a hotfix. +For hotfixes, checkout the release branch you want to fix. + +(2) Create a new release branch. + +```sh +git checkout -b release-v0.2.0 +``` + +(3) Push and open a PR targeting `main` to carefully review the release changes. +This will trigger a GitHub workflow that automatically bumps the version number throughout the project. + +```sh +git push origin release-v0.2.0 +``` + +(4) Once merged, pull the changes from the release branch. +Then, create a tag on the release branch and push it to the main repository. +Note that the version changes must be pulled *before* the tag is created; +otherwise, the version validation check will fail in the release workflow. + +```sh +git pull +git tag v0.2.0 +git push origin v0.2.0 +``` + +(5) After that, go to the repo's [releases page](https://github.com/OpenZeppelin/compact-contracts/releases/). +[Create a new release](https://github.com/OpenZeppelin/compact-contracts/releases/new) with the new tag and the base branch as target (`main` except in the event of a hotfix). +Make sure to write a detailed release description and a short changelog. +Once published, this will trigger a workflow to upload the release tarball to npm. + +(6) Finally, from the released tag, +create and push a doc branch to deploy the corresponding version to the doc-site. + +```sh +git checkout -b docs-v0.2.0 +git push origin docs-v0.2.0 +``` diff --git a/contracts/package.json b/contracts/package.json index e6fa4f9f..78e7a0fc 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,18 +1,25 @@ { "name": "@openzeppelin-compact/contracts", - "private": true, - "type": "module", - "main": "dist/index.js", - "module": "dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "require": "./dist/index.js", - "import": "./dist/index.js", - "default": "./dist/index.js" - } + "version": "0.0.1", + "description": "OpenZeppelin Compact contract library", + "keywords": [ + "openzeppelin", + "compact", + "midnight", + "contracts", + "security" + ], + "repository": { + "type": "git", + "url": "https://github.com/OpenZeppelin/compact-contracts.git" + }, + "license": "MIT", + "author": "OpenZeppelin Community ", + "bugs": { + "url": "https://github.com/OpenZeppelin/compact-contracts/issues" }, + "homepage": "https://docs.openzeppelin.com/contracts-compact/", + "type": "module", "scripts": { "compact": "compact-compiler", "compact:access": "compact-compiler --dir access", @@ -20,7 +27,7 @@ "compact:security": "compact-compiler --dir security", "compact:token": "compact-compiler --dir token", "compact:utils": "compact-compiler --dir utils", - "build": "compact-builder && tsc", + "build": "compact-builder", "test": "compact-compiler --skip-zk && vitest run", "types": "tsc -p tsconfig.json --noEmit", "clean": "git clean -fXd" diff --git a/contracts/src/utils/test/utils.test.ts b/contracts/src/utils/test/utils.test.ts index 1398d4d9..0d768441 100644 --- a/contracts/src/utils/test/utils.test.ts +++ b/contracts/src/utils/test/utils.test.ts @@ -19,15 +19,18 @@ describe('Utils', () => { describe('isKeyOrAddressZero', () => { it('should return zero for the zero address', () => { expect(contract.isKeyOrAddressZero(contractUtils.ZERO_KEY)).toBe(true); - expect(contract.isKeyOrAddressZero(contractUtils.ZERO_ADDRESS)).toBe( - true, - ); }); it('should not return zero for nonzero addresses', () => { expect(contract.isKeyOrAddressZero(Z_SOME_KEY)).toBe(false); expect(contract.isKeyOrAddressZero(SOME_CONTRACT)).toBe(false); }); + + it('should not return zero for a zero contract address', () => { + expect(contract.isKeyOrAddressZero(contractUtils.ZERO_ADDRESS)).toBe( + true, + ); + }); }); describe('isKeyOrAddressEqual', () => { diff --git a/contracts/tsconfig.json b/contracts/tsconfig.json index e6a0e5f7..56f85e46 100644 --- a/contracts/tsconfig.json +++ b/contracts/tsconfig.json @@ -1,8 +1,9 @@ { "extends": "@tsconfig/node24/tsconfig.json", "include": [ - "src/**/*.ts" + "src/**/witnesses/**/*.ts" ], + "exclude": ["src/archive/"], "compilerOptions": { "rootDir": "src", "outDir": "dist", @@ -11,7 +12,6 @@ "forceConsistentCasingInFileNames": true, "noImplicitAny": true, "isolatedModules": true, - "sourceMap": true, "resolveJsonModule": true, } } \ No newline at end of file diff --git a/packages/compact/src/Builder.ts b/packages/compact/src/Builder.ts index 43c2f40b..d6150a2c 100755 --- a/packages/compact/src/Builder.ts +++ b/packages/compact/src/Builder.ts @@ -13,8 +13,9 @@ const execAsync = promisify(exec); /** * A class to handle the build process for a project. * Runs CompactCompiler as a prerequisite, then executes build steps (TypeScript compilation, - * artifact copying, etc.) - * with progress feedback and colored output for success and error states. + * artifact copying, etc.) with progress feedback and colored output for success and error states. + * + * Creates a clean distribution structure without src/ paths for professional import experience. * * @notice `cmd` scripts discard `stderr` output and fail silently because this is * handled in `executeStep`. @@ -59,18 +60,43 @@ export class CompactBuilder { private readonly compilerFlags: string; private readonly steps: Array<{ cmd: string; msg: string; shell?: string }> = [ + // Step 1: Clean dist directory + { + cmd: 'rm -rf dist && mkdir -p dist', + msg: 'Cleaning dist directory', + shell: '/bin/bash', + }, + + // Step 2: TypeScript compilation (witnesses/ -> dist/witnesses/) { cmd: 'tsc --project tsconfig.build.json', msg: 'Compiling TypeScript', }, + + // Step 3: Copy .compact files preserving structure (excludes Mock* files and archive/) { - cmd: 'mkdir -p dist/artifacts && cp -Rf src/artifacts/* dist/artifacts/ 2>/dev/null || true', - msg: 'Copying artifacts', + // biome-ignore-start lint/suspicious/noUselessEscapeInString: Needed inside JS template literal + cmd: ` + find src -type f -name "*.compact" ! -name "Mock*" ! -path "*/archive/*" | while read file; do + # Remove src/ prefix from path + rel_path="\${file#src/}" + mkdir -p "dist/\$(dirname "\$rel_path")" + cp "\$file" "dist/\$rel_path" + done + `, + // biome-ignore-end lint/suspicious/noUselessEscapeInString: Needed inside JS template literal + msg: 'Copying .compact files (excluding mocks and archive)', shell: '/bin/bash', }, + + // Step 4: Copy essential files for distribution { - cmd: 'mkdir -p dist && find src -type f -name "*.compact" -exec cp {} dist/ \\; 2>/dev/null && rm dist/Mock*.compact 2>/dev/null || true', - msg: 'Copying and cleaning .compact files', + cmd: ` + # Copy package.json and README + cp package.json dist/ 2>/dev/null || true + cp ../README.md dist/ # Go up one level to monorepo root + `, + msg: 'Copying package metadata', shell: '/bin/bash', }, ]; @@ -99,6 +125,8 @@ export class CompactBuilder { for (const [index, step] of this.steps.entries()) { await this.executeStep(step, index, this.steps.length); } + + console.log(chalk.green('\nāœ… Build complete!')); } /** @@ -155,6 +183,8 @@ export class CompactBuilder { .split('\n') .filter((line: string): boolean => line.trim() !== '') .map((line: string): string => ` ${line}`); - console.log(colorFn(lines.join('\n'))); + if (lines.length > 0) { + console.log(colorFn(lines.join('\n'))); + } } } diff --git a/packages/compact/src/Compiler.ts b/packages/compact/src/Compiler.ts index de57236c..29b91528 100755 --- a/packages/compact/src/Compiler.ts +++ b/packages/compact/src/Compiler.ts @@ -13,6 +13,7 @@ import { DirectoryNotFoundError, isPromisifiedChildProcessError, } from './types/errors.ts'; +import { COMPACT_VERSION } from './versions.ts'; /** Source directory containing .compact files */ const SRC_DIR: string = 'src'; @@ -549,6 +550,11 @@ export class CompactCompiler { } } + // Apply default toolchain version if none provided; allow env to override + if (!version) { + version = env.COMPACT_TOOLCHAIN_VERSION ?? COMPACT_VERSION; + } + return new CompactCompiler(flags.join(' '), targetDir, version); } diff --git a/packages/compact/src/versions.ts b/packages/compact/src/versions.ts new file mode 100644 index 00000000..efb582eb --- /dev/null +++ b/packages/compact/src/versions.ts @@ -0,0 +1,2 @@ +export const COMPACT_VERSION = '0.26.0'; +export const LANGUAGE_VERSION = '0.18.0'; diff --git a/packages/compact/test/Compiler.test.ts b/packages/compact/test/Compiler.test.ts index e6377400..1a7cbdc0 100644 --- a/packages/compact/test/Compiler.test.ts +++ b/packages/compact/test/Compiler.test.ts @@ -21,6 +21,7 @@ import { CompilationError, DirectoryNotFoundError, } from '../src/types/errors.js'; +import { COMPACT_VERSION } from '../src/versions.js'; // Mock Node.js modules vi.mock('node:fs'); @@ -479,7 +480,7 @@ describe('CompactCompiler', () => { expect(compiler.testFlags).toBe(''); expect(compiler.testTargetDir).toBeUndefined(); - expect(compiler.testVersion).toBeUndefined(); + expect(compiler.testVersion).toBe(COMPACT_VERSION); }); it('should handle SKIP_ZK environment variable', () => {