diff --git a/.github/actions/check-version/action.yml b/.github/actions/check-version/action.yml new file mode 100644 index 0000000..fb58d63 --- /dev/null +++ b/.github/actions/check-version/action.yml @@ -0,0 +1,31 @@ +name: Check ECOS Studio Version Consistency +description: Verify release version fields across MODULE.bazel, ecos-server, and ecos-studio. Optionally verify an expected git tag. + +inputs: + expected_tag: + description: Expected tag (for example, v0.1.0-alpha.3). If set, also verify the tag matches the detected version. + required: false + default: "" + +outputs: + version: + description: The repository release version detected from MODULE.bazel. + value: ${{ steps.verify.outputs.version }} + tag: + description: The git tag corresponding to the detected version. + value: ${{ steps.verify.outputs.tag }} + +runs: + using: composite + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Verify version consistency + id: verify + shell: bash + run: python3 .github/scripts/check-version.py + env: + EXPECTED_TAG: ${{ inputs.expected_tag }} diff --git a/.github/actions/install-tauri-linux-deps/action.yml b/.github/actions/install-tauri-linux-deps/action.yml new file mode 100644 index 0000000..877e3bf --- /dev/null +++ b/.github/actions/install-tauri-linux-deps/action.yml @@ -0,0 +1,29 @@ +name: Install Tauri Linux Dependencies +description: Install Linux packages required by Tauri GUI checks and builds. + +inputs: + extra-packages: + description: Additional apt packages to install. + required: false + default: "" + +runs: + using: composite + steps: + - name: Install packages + shell: bash + run: | + packages=( + libwebkit2gtk-4.1-dev + libgtk-3-dev + libayatana-appindicator3-dev + librsvg2-dev + ) + + if [[ -n "${{ inputs.extra-packages }}" ]]; then + read -r -a extra_packages <<< "${{ inputs.extra-packages }}" + packages+=("${extra_packages[@]}") + fi + + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing "${packages[@]}" diff --git a/.github/actions/setup-node-pnpm/action.yml b/.github/actions/setup-node-pnpm/action.yml new file mode 100644 index 0000000..7ae3ea1 --- /dev/null +++ b/.github/actions/setup-node-pnpm/action.yml @@ -0,0 +1,25 @@ +name: Setup Node.js And pnpm +description: Setup the Node.js and pnpm versions used by the GUI. + +inputs: + node-version-file: + description: Path to the Node.js version file. + required: false + default: ecos/gui/.nvmrc + pnpm-version: + description: pnpm version to install. + required: false + default: latest + +runs: + using: composite + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ${{ inputs.node-version-file }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.pnpm-version }} diff --git a/.github/actions/setup-rust-cache/action.yml b/.github/actions/setup-rust-cache/action.yml new file mode 100644 index 0000000..35d0a34 --- /dev/null +++ b/.github/actions/setup-rust-cache/action.yml @@ -0,0 +1,24 @@ +name: Setup Rust Cache +description: Setup stable Rust and cache Cargo artifacts. + +inputs: + workspaces: + description: Rust workspace paths for Swatinem/rust-cache. + required: false + default: ecos/gui/src-tauri + cache-targets: + description: Whether to cache target directories. + required: false + default: "true" + +runs: + using: composite + steps: + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache Rust build artifacts + uses: Swatinem/rust-cache@v2 + with: + workspaces: ${{ inputs.workspaces }} + cache-targets: ${{ inputs.cache-targets }} diff --git a/.github/scripts/check-version.py b/.github/scripts/check-version.py new file mode 100644 index 0000000..00754ac --- /dev/null +++ b/.github/scripts/check-version.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +import json +import os +import re +import sys +import tomllib +from pathlib import Path + + +expected_tag = os.environ.get("EXPECTED_TAG", "").strip() + + +def normalize_version(v: str) -> str: + """Normalize semver prerelease tags (e.g. 0.1.0-alpha.3) to PEP 440 (e.g. 0.1.0a3) + so they can be compared with uv.lock / packaging canonical forms.""" + return re.sub(r"-(alpha|beta|rc)\.?(\d+)", lambda m: m.group(1)[0] + m.group(2), v) + + +def read(path: str) -> str: + return Path(path).read_text(encoding="utf-8") + + +def parse_regex( + path: str, + pattern: str, + *, + flags: int = 0, + label: str | None = None, +) -> str: + text = read(path) + match = re.search(pattern, text, flags) + if not match: + raise SystemExit(f"ERROR: failed to parse {label or path}") + return match.group(1) + + +versions: list[tuple[str, str]] = [] + +module_version = parse_regex( + "MODULE.bazel", + r'(?m)^\s*version\s*=\s*"([^"]+)"', + label="MODULE.bazel version", +) +versions.append(("MODULE.bazel", module_version)) + +server_pyproject = tomllib.loads(read("ecos/server/pyproject.toml"))["project"]["version"] +versions.append(("ecos/server/pyproject.toml", server_pyproject)) + +server_default_nix = parse_regex( + "ecos/server/default.nix", + r'(?m)^\s*version\s*=\s*"([^"]+)"\s*;', + label="ecos/server/default.nix version", +) +versions.append(("ecos/server/default.nix", server_default_nix)) + +server_main_fastapi = parse_regex( + "ecos/server/ecos_server/main.py", + r'FastAPI\(.*?version\s*=\s*"([^"]+)"', + flags=re.S, + label="ecos/server/ecos_server/main.py FastAPI version", +) +versions.append(("ecos/server/ecos_server/main.py (FastAPI)", server_main_fastapi)) + +server_main_root = parse_regex( + "ecos/server/ecos_server/main.py", + r'"version"\s*:\s*"([^"]+)"', + label="ecos/server/ecos_server/main.py root endpoint version", +) +versions.append(("ecos/server/ecos_server/main.py (root endpoint)", server_main_root)) + +server_uv_lock = parse_regex( + "ecos/server/uv.lock", + r'\[\[package\]\]\s+name\s*=\s*"ecos-server"\s+version\s*=\s*"([^"]+)"', + flags=re.S, + label="ecos/server/uv.lock root package version", +) +versions.append(("ecos/server/uv.lock", server_uv_lock)) + +gui_package = json.loads(read("ecos/gui/package.json"))["version"] +versions.append(("ecos/gui/package.json", gui_package)) + +gui_default_nix = parse_regex( + "ecos/gui/default.nix", + r'(?m)^\s*version\s*=\s*"([^"]+)"\s*;', + label="ecos/gui/default.nix version", +) +versions.append(("ecos/gui/default.nix", gui_default_nix)) + +gui_cargo_toml = tomllib.loads(read("ecos/gui/src-tauri/Cargo.toml"))["package"][ + "version" +] +versions.append(("ecos/gui/src-tauri/Cargo.toml", gui_cargo_toml)) + +gui_cargo_lock = parse_regex( + "ecos/gui/src-tauri/Cargo.lock", + r'\[\[package\]\]\s+name\s*=\s*"ecos-studio"\s+version\s*=\s*"([^"]+)"', + flags=re.S, + label="ecos/gui/src-tauri/Cargo.lock root package version", +) +versions.append(("ecos/gui/src-tauri/Cargo.lock", gui_cargo_lock)) + +gui_tauri_conf = json.loads(read("ecos/gui/src-tauri/tauri.conf.json"))["version"] +versions.append(("ecos/gui/src-tauri/tauri.conf.json", gui_tauri_conf)) + +print("Detected versions:") +for name, value in versions: + print(f" {name}: {value}") + +normalized_module = normalize_version(module_version) +mismatches = [ + (name, value) + for name, value in versions + if normalize_version(value) != normalized_module +] +if mismatches: + print("") + print( + "ERROR: version mismatch detected. " + f"Expected all files to match MODULE.bazel ({module_version}).", + file=sys.stderr, + ) + for name, value in mismatches: + print(f" {name}: {value}", file=sys.stderr) + sys.exit(1) + +tag = f"v{module_version}" +if expected_tag and expected_tag != tag: + print( + f"ERROR: tag mismatch. expected {tag} from version files, got {expected_tag}.", + file=sys.stderr, + ) + sys.exit(1) + +github_output = os.environ["GITHUB_OUTPUT"] +with open(github_output, "a", encoding="utf-8") as fh: + fh.write(f"version={module_version}\n") + fh.write(f"tag={tag}\n") + +print("") +print(f"Version check passed: {module_version}") diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml new file mode 100644 index 0000000..373f7b1 --- /dev/null +++ b/.github/workflows/auto-tag.yml @@ -0,0 +1,53 @@ +name: Auto Tag + +on: + push: + branches: [main] + paths: + - "MODULE.bazel" + - "ecos/server/pyproject.toml" + - "ecos/server/default.nix" + - "ecos/server/ecos_server/main.py" + - "ecos/server/uv.lock" + - "ecos/gui/default.nix" + - "ecos/gui/package.json" + - "ecos/gui/src-tauri/Cargo.toml" + - "ecos/gui/src-tauri/Cargo.lock" + - "ecos/gui/src-tauri/tauri.conf.json" + +permissions: + contents: write + +jobs: + auto-tag: + name: Create version tag + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check version consistency + id: version + uses: ./.github/actions/check-version + + - name: Check if tag exists + id: check + run: | + if git ls-remote --tags origin "refs/tags/${{ steps.version.outputs.tag }}" | grep -q .; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "Tag ${{ steps.version.outputs.tag }} already exists, skipping." + else + echo "exists=false" >> "$GITHUB_OUTPUT" + echo "Tag ${{ steps.version.outputs.tag }} does not exist, will create." + fi + + - name: Create and push tag + if: steps.check.outputs.exists == 'false' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag "${{ steps.version.outputs.tag }}" + git push origin "${{ steps.version.outputs.tag }}" + echo "Created and pushed tag: ${{ steps.version.outputs.tag }}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6b5587a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,188 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + check-version: + name: Check Version Consistency + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Check version + uses: ./.github/actions/check-version + + ruff: + name: Ruff + runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ecos/server + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup uv + uses: astral-sh/setup-uv@v5 + + - name: Check formatting + run: uvx ruff format --check + + - name: Lint Python + run: uvx ruff check + + clippy: + name: Clippy + runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ecos/gui/src-tauri + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install system dependencies + uses: ./.github/actions/install-tauri-linux-deps + + - name: Setup Rust + uses: ./.github/actions/setup-rust-cache + with: + cache-targets: "false" + + - name: Lint Rust + env: + TAURI_CONFIG: '{"build":{"frontendDist":null},"bundle":{"resources":null,"externalBin":null}}' + run: cargo clippy -- -D warnings + + vue-tsc: + name: Vue Typecheck + runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ecos/gui + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: ./.github/actions/setup-node-pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Typecheck Vue + run: pnpm exec vue-tsc --noEmit + + build-appimage: + name: Build AppImage + needs: [check-version, ruff, clippy, vue-tsc] + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Install system dependencies + uses: ./.github/actions/install-tauri-linux-deps + with: + extra-packages: >- + git curl ca-certificates build-essential pkg-config + python3 python3-venv python3-pip python3-dev + libgtk-3-bin libcairo2-dev libpango1.0-dev libgdk-pixbuf-2.0-dev + libglib2.0-dev libglib2.0-bin + cmake ninja-build tcl-dev + libgflags-dev libgoogle-glog-dev libboost-all-dev libgtest-dev + flex libeigen3-dev libunwind-dev libmetis-dev libgmp-dev bison + libhwloc-dev libcurl4-openssl-dev libtbb-dev + patchelf jq wget + + - name: Setup Node.js + uses: ./.github/actions/setup-node-pnpm + + - name: Setup Rust + uses: ./.github/actions/setup-rust-cache + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Setup uv + uses: astral-sh/setup-uv@v5 + with: + version: latest + enable-cache: true + + - name: Setup Bazel + run: | + mkdir -p "$HOME/.local/bin" + curl -fsSL https://github.com/bazelbuild/bazel/releases/download/8.5.0/bazel-8.5.0-linux-x86_64 \ + -o "$HOME/.local/bin/bazel" + chmod +x "$HOME/.local/bin/bazel" + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + + - name: Sync server environment + working-directory: ecos/server + run: uv sync --frozen --all-groups --all-extras --python 3.11 + + - name: Build release bundle + env: + ENABLE_OSS_CAD_SUITE: "true" + TAURI_BUNDLES: appimage + run: | + PATH="$PWD/ecos/server/.venv/bin:$PATH" bazel build //:ecos_studio_bundle + + - name: Verify AppImage artifact + run: | + BUNDLE_TAR="bazel-bin/ecos/ecos_studio_bundle/ecos_studio_bundle.tar" + rm -rf dist/ci-appimage + mkdir -p dist/ci-appimage + + tar -tf "$BUNDLE_TAR" | grep -E '(^|/)[^/]+\.AppImage$' > /tmp/ecos-appimage-files.txt || true + + if [ ! -s /tmp/ecos-appimage-files.txt ]; then + echo "ERROR: AppImage artifact not found in $BUNDLE_TAR" >&2 + echo "Bundle contents:" >&2 + tar -tf "$BUNDLE_TAR" | sed -n '1,200p' >&2 + exit 1 + fi + + echo "Found AppImage artifact:" + cat /tmp/ecos-appimage-files.txt + + tar -xf "$BUNDLE_TAR" -C dist/ci-appimage -T /tmp/ecos-appimage-files.txt + ( + cd dist/ci-appimage + find . -type f -name '*.AppImage' -print0 \ + | sort -z \ + | xargs -0 sha256sum > SHA256SUMS + ) + + echo "Prepared CI AppImage artifact:" + find dist/ci-appimage -type f \( -name '*.AppImage' -o -name 'SHA256SUMS' \) | sort + echo "" + cat dist/ci-appimage/SHA256SUMS + + - name: Upload CI AppImage artifact + uses: actions/upload-artifact@v4 + with: + name: ecos-studio-appimage-${{ github.run_number }} + if-no-files-found: error + retention-days: 14 + path: | + dist/ci-appimage/**/*.AppImage + dist/ci-appimage/SHA256SUMS diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 1340aad..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: lint - -on: - push: - branches: [main] - pull_request: - -jobs: - ruff: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ecos/server - steps: - - uses: actions/checkout@v4 - - uses: astral-sh/setup-uv@v5 - - run: uvx ruff format --check - - run: uvx ruff check - - clippy: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ecos/gui/src-tauri - steps: - - uses: actions/checkout@v4 - - run: sudo apt-get update && sudo apt-get install -y --fix-missing libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - workspaces: ecos/gui/src-tauri - # Stub artifacts absent in CI: - # - api-server: Bazel/PyInstaller sidecar, checked by tauri-build build.rs - # - oss-cad-suite: not committed to git, checked by tauri-build build.rs - # - ../dist: Vite output, checked by tauri::generate_context!() proc macro - - run: | - mkdir -p binaries - touch binaries/api-server-x86_64-unknown-linux-gnu - chmod +x binaries/api-server-x86_64-unknown-linux-gnu - mkdir -p resources/oss-cad-suite - touch resources/oss-cad-suite/README - mkdir -p ../dist - - run: cargo clippy -- -D warnings - - vue-tsc: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ecos/gui - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version-file: ecos/gui/.nvmrc - - uses: pnpm/action-setup@v4 - with: - version: latest - - run: pnpm install --frozen-lockfile - - run: pnpm exec vue-tsc --noEmit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..759ddd9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,208 @@ +name: Release + +on: + push: + tags: ["v*"] + workflow_dispatch: + inputs: + tag_name: + description: Tag to release (for example, v0.1.0-alpha.3) + required: true + +permissions: + contents: write + +jobs: + check-version: + name: Check Version Consistency + runs-on: ubuntu-22.04 + outputs: + version: ${{ steps.version.outputs.version }} + tag: ${{ steps.version.outputs.tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag_name || github.ref }} + fetch-depth: 0 + + - name: Check version + id: version + uses: ./.github/actions/check-version + with: + expected_tag: ${{ github.event.inputs.tag_name || github.ref_name }} + + build: + name: Build AppImage + needs: check-version + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag_name || github.ref }} + submodules: recursive + fetch-depth: 0 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing \ + git curl ca-certificates build-essential pkg-config \ + python3 python3-venv python3-pip python3-dev \ + libgtk-3-dev libgtk-3-bin libwebkit2gtk-4.1-dev \ + libayatana-appindicator3-dev \ + libcairo2-dev libpango1.0-dev libgdk-pixbuf-2.0-dev \ + libglib2.0-dev libglib2.0-bin librsvg2-dev \ + cmake ninja-build tcl-dev \ + libgflags-dev libgoogle-glog-dev libboost-all-dev libgtest-dev \ + flex libeigen3-dev libunwind-dev libmetis-dev libgmp-dev bison \ + libhwloc-dev libcurl4-openssl-dev libtbb-dev \ + patchelf jq wget + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ecos/gui/.nvmrc + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: latest + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache Rust build artifacts + uses: Swatinem/rust-cache@v2 + with: + workspaces: ecos/gui/src-tauri + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Setup uv + uses: astral-sh/setup-uv@v5 + with: + version: latest + enable-cache: true + + - name: Setup Bazel + run: | + mkdir -p "$HOME/.local/bin" + curl -fsSL https://github.com/bazelbuild/bazel/releases/download/8.5.0/bazel-8.5.0-linux-x86_64 \ + -o "$HOME/.local/bin/bazel" + chmod +x "$HOME/.local/bin/bazel" + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + + - name: Sync server environment + working-directory: ecos/server + run: uv sync --frozen --all-groups --all-extras --python 3.11 + + - name: Build release bundle + env: + ENABLE_OSS_CAD_SUITE: "true" + TAURI_BUNDLES: appimage + run: | + PATH="$PWD/ecos/server/.venv/bin:$PATH" bazel build //:ecos_studio_bundle + + - name: Extract AppImage + run: | + BUNDLE_TAR="bazel-bin/ecos/ecos_studio_bundle/ecos_studio_bundle.tar" + + rm -rf dist/release + mkdir -p dist/release + + tar -tf "$BUNDLE_TAR" | grep -E '(^|/)[^/]+\.AppImage$' > /tmp/ecos-release-files.txt || true + if [ ! -s /tmp/ecos-release-files.txt ]; then + echo "ERROR: AppImage artifact not found in $BUNDLE_TAR" >&2 + echo "Bundle contents:" >&2 + tar -tf "$BUNDLE_TAR" | sed -n '1,200p' >&2 + exit 1 + fi + + tar -xf "$BUNDLE_TAR" -C dist/release -T /tmp/ecos-release-files.txt + + ( + cd dist/release + find . -type f -name '*.AppImage' -print0 \ + | sort -z \ + | xargs -0 sha256sum > SHA256SUMS + ) + + echo "Built AppImage artifact:" + find dist/release -type f \( -name '*.AppImage' -o -name 'SHA256SUMS' \) | sort + echo "" + cat dist/release/SHA256SUMS + + - name: Upload AppImage artifact + uses: actions/upload-artifact@v4 + with: + name: ecos-studio-release + if-no-files-found: error + path: | + dist/release/**/*.AppImage + dist/release/SHA256SUMS + + release: + name: Create Release + needs: [check-version, build] + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag_name || github.ref }} + fetch-depth: 0 + + - name: Download release artifacts + uses: actions/download-artifact@v4 + with: + name: ecos-studio-release + path: dist/release + + - name: Determine tag version + id: version + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + FULL_TAG="${{ github.event.inputs.tag_name }}" + else + FULL_TAG="${GITHUB_REF_NAME}" + fi + TAG_VERSION="${FULL_TAG#v}" + echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT" + echo "full_tag=$FULL_TAG" >> "$GITHUB_OUTPUT" + + - name: Generate release notes + run: | + PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + { + echo "> [!WARNING]" + echo "> **ECOS Studio** is still under rapid development. You can download the latest version from the [release page](https://github.com/openecos-projects/ecos-studio/releases) to try it out (The current release builds are produced on **Ubuntu 22.04**, so using an older Linux system may lead to compatibility issues. Additionally, ECOS Studio currently only supports the **x86_64** Linux platform.)." + echo ">" + echo "" + if [[ -n "$PREV_TAG" ]]; then + echo "## Changes" + echo "" + git log --oneline --no-merges "${PREV_TAG}..HEAD" | sed 's/^/- /' + echo "" + fi + echo "## Checksums" + echo "" + echo '```' + cat dist/release/SHA256SUMS + echo '```' + } > release-notes.md + cat release-notes.md + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: | + mapfile -t ASSETS < <(find dist/release -type f \( -name '*.AppImage' -o -name 'SHA256SUMS' \) | sort) + gh release create "${{ steps.version.outputs.full_tag }}" \ + --title "ECOS Studio ${{ steps.version.outputs.full_tag }}" \ + --notes-file release-notes.md \ + "${ASSETS[@]}" diff --git a/MODULE.bazel b/MODULE.bazel index 40bded2..2502db5 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,6 +1,6 @@ module( name = "ecos_studio", - version = "0.1.0", + version = "0.1.0-alpha.3", ) bazel_dep(name = "rules_shell", version = "0.6.1") @@ -16,4 +16,4 @@ appimage_tool = use_extension("@ecos-bazel//rules:appimage-tool.bzl", "appimage_ use_repo(appimage_tool, "appimagetool_x86_64_linux") oss_cad_suite = use_extension("@ecos-bazel//rules:oss_cad_suite.bzl", "oss_cad_suite") -use_repo(oss_cad_suite, "oss_cad_suite", "oss_cad_suite_pruned") \ No newline at end of file +use_repo(oss_cad_suite, "oss_cad_suite", "oss_cad_suite_pruned") diff --git a/ecc b/ecc index ec4b4e3..183dc25 160000 --- a/ecc +++ b/ecc @@ -1 +1 @@ -Subproject commit ec4b4e3a1d83c4b00b7eb63a921c2fd3fcd60662 +Subproject commit 183dc252db9ba8280e827d570f0e4376bb427a76 diff --git a/ecos/gui/default.nix b/ecos/gui/default.nix index a27e9be..82b8540 100644 --- a/ecos/gui/default.nix +++ b/ecos/gui/default.nix @@ -18,7 +18,7 @@ rustPlatform.buildRustPackage (finalAttrs: { pname = "ecos-studio"; - version = "0.1.0-alpha"; + version = "0.1.0-alpha.3"; src = with lib.fileset; diff --git a/ecos/gui/package.json b/ecos/gui/package.json index bfb3731..0d55e53 100644 --- a/ecos/gui/package.json +++ b/ecos/gui/package.json @@ -1,6 +1,6 @@ { "name": "ecos-studio-gui", - "version": "0.1.0", + "version": "0.1.0-alpha.3", "private": true, "type": "module", "pnpm": { diff --git a/ecos/gui/src-tauri/Cargo.lock b/ecos/gui/src-tauri/Cargo.lock index 74df8fb..808ec5b 100644 --- a/ecos/gui/src-tauri/Cargo.lock +++ b/ecos/gui/src-tauri/Cargo.lock @@ -751,7 +751,7 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ecos-studio" -version = "0.1.0" +version = "0.1.0-alpha.3" dependencies = [ "chrono", "env_logger", diff --git a/ecos/gui/src-tauri/Cargo.toml b/ecos/gui/src-tauri/Cargo.toml index 1038546..48e29af 100644 --- a/ecos/gui/src-tauri/Cargo.toml +++ b/ecos/gui/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecos-studio" -version = "0.1.0" +version = "0.1.0-alpha.3" description = "ECOS-Studio" authors = ["Ekko"] license = "" @@ -50,4 +50,3 @@ overflow-checks = false opt-level = 3 [profile.release.package.wry] opt-level = 3 - diff --git a/ecos/gui/src-tauri/tauri.conf.json b/ecos/gui/src-tauri/tauri.conf.json index bfb57b7..e43c1d1 100644 --- a/ecos/gui/src-tauri/tauri.conf.json +++ b/ecos/gui/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "productName": "ECOS-Studio", - "version": "0.1.0", + "version": "0.1.0-alpha.3", "identifier": "com.ecos.studio", "build": { "beforeDevCommand": "pnpm run dev", diff --git a/ecos/server/default.nix b/ecos/server/default.nix index 9af6a0d..856ade9 100644 --- a/ecos/server/default.nix +++ b/ecos/server/default.nix @@ -6,7 +6,7 @@ python3Packages.buildPythonPackage { pname = "ecos-server"; - version = "0.1.0"; + version = "0.1.0-alpha.3"; pyproject = true; src = diff --git a/ecos/server/ecos_server/main.py b/ecos/server/ecos_server/main.py index 82f1676..14a9563 100644 --- a/ecos/server/ecos_server/main.py +++ b/ecos/server/ecos_server/main.py @@ -8,7 +8,9 @@ from .ecc import sse_router, workspace_router # Create FastAPI application -app = FastAPI(title="ECOS Studio API", description="Backend API for ECOS Studio", version="0.1.0") +app = FastAPI( + title="ECOS Studio API", description="Backend API for ECOS Studio", version="0.1.0-alpha.3" +) # Configure CORS for frontend access app.add_middleware( @@ -35,7 +37,12 @@ @app.get("/") async def root(): """Root endpoint""" - return {"name": "ECOS Studio API", "version": "0.1.0", "status": "running", "tools": ["ecc"]} + return { + "name": "ECOS Studio API", + "version": "0.1.0-alpha.3", + "status": "running", + "tools": ["ecc"], + } @app.get("/health") diff --git a/ecos/server/pyproject.toml b/ecos/server/pyproject.toml index 7c6ce74..ed9cc51 100644 --- a/ecos/server/pyproject.toml +++ b/ecos/server/pyproject.toml @@ -4,11 +4,11 @@ requires = ["hatchling"] [project] name = "ecos-server" -version = "0.1.0" +version = "0.1.0-alpha.3" requires-python = ">=3.11" dependencies = [ "ecc==0.1.0a1", - "ecc-dreamplace==0.1.0a1", + "ecc-dreamplace==0.1.0a2", "ecc-tools==0.1.0a1", "fastapi>=0.109", "torch>=1.6.0", @@ -41,10 +41,14 @@ explicit = true environments = [ "sys_platform == 'linux' and platform_machine == 'x86_64'", ] +override-dependencies = [ +# Remove this after ecc bump its ecc-dreamplace dependency to 0.1.0a2 or later, which is the version that this server depends on. + "ecc-dreamplace==0.1.0a2", +] [tool.uv.sources] ecc = { url = "https://github.com/openecos-projects/ecc/releases/download/v0.1.0-alpha.1/ecc-0.1.0a1-py3-none-any.whl" } -ecc-dreamplace = { url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.1/ecc_dreamplace-0.1.0a1-py3-none-manylinux_2_34_x86_64.whl" } +ecc-dreamplace = { url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.2/ecc_dreamplace-0.1.0a2-py3-none-manylinux_2_34_x86_64.whl" } ecc-tools = { url = "https://github.com/openecos-projects/ecc-tools/releases/download/v0.1.0-alpha.1/ecc_tools-0.1.0a1-py3-none-manylinux_2_34_x86_64.whl" } torch = { index = "pytorch-cpu" } diff --git a/ecos/server/uv.lock b/ecos/server/uv.lock index ac0c9f0..bd294f8 100644 --- a/ecos/server/uv.lock +++ b/ecos/server/uv.lock @@ -9,6 +9,9 @@ supported-markers = [ "platform_machine == 'x86_64' and sys_platform == 'linux'", ] +[manifest] +overrides = [{ name = "ecc-dreamplace", url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.2/ecc_dreamplace-0.1.0a2-py3-none-manylinux_2_34_x86_64.whl" }] + [[package]] name = "altgraph" version = "0.17.5" @@ -264,8 +267,8 @@ requires-dist = [ [[package]] name = "ecc-dreamplace" -version = "0.1.0a1" -source = { url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.1/ecc_dreamplace-0.1.0a1-py3-none-manylinux_2_34_x86_64.whl" } +version = "0.1.0a2" +source = { url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.2/ecc_dreamplace-0.1.0a2-py3-none-manylinux_2_34_x86_64.whl" } dependencies = [ { name = "cairocffi", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "configspace", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, @@ -286,7 +289,7 @@ dependencies = [ { name = "xgboost", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, ] wheels = [ - { url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.1/ecc_dreamplace-0.1.0a1-py3-none-manylinux_2_34_x86_64.whl", hash = "sha256:212139c43f825498968eda10309959b99cd93aec0744d182a17bb5d34b53145e" }, + { url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.2/ecc_dreamplace-0.1.0a2-py3-none-manylinux_2_34_x86_64.whl", hash = "sha256:fad0e489bfba62f79c193e2e0ec5051a492768e2a3d6099aa5e604c08abb191f" }, ] [package.metadata] @@ -320,7 +323,7 @@ wheels = [ [[package]] name = "ecos-server" -version = "0.1.0" +version = "0.1.0a3" source = { editable = "." } dependencies = [ { name = "ecc", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, @@ -348,7 +351,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "ecc", url = "https://github.com/openecos-projects/ecc/releases/download/v0.1.0-alpha.1/ecc-0.1.0a1-py3-none-any.whl" }, - { name = "ecc-dreamplace", url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.1/ecc_dreamplace-0.1.0a1-py3-none-manylinux_2_34_x86_64.whl" }, + { name = "ecc-dreamplace", url = "https://github.com/openecos-projects/ecc-dreamplace/releases/download/v0.1.0-alpha.2/ecc_dreamplace-0.1.0a2-py3-none-manylinux_2_34_x86_64.whl" }, { name = "ecc-tools", url = "https://github.com/openecos-projects/ecc-tools/releases/download/v0.1.0-alpha.1/ecc_tools-0.1.0a1-py3-none-manylinux_2_34_x86_64.whl" }, { name = "fastapi", specifier = ">=0.109" }, { name = "torch", specifier = ">=1.6.0", index = "https://download.pytorch.org/whl/cpu" },