Release workflow: Linux tar.gz and AppImage, Windows zip, universal macOS app, web zip, SHA256SUMS
.github/workflows/release.yml builds on a pushed v* tag (or by hand) and attaches everything to a
GitHub release, a pre-release while the version is 0.x, with .github/release-notes.md. The
packaging lives in .github/release/package-{linux,macos}.sh so it can be run locally; the
AppImage icon is rendered by solvecraft-cli from the bracket example.
Fixes #32
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
1d11898a2c
commit
2279a8e255
4 files changed
+272
No files matched your search
@@ -0,0 +1,62 @@
|
|||||||
|
SolveCraft is an open-source parametric 3D CAD application in pure Rust: sketch on a plane,
|
||||||
|
constrain and dimension the sketch, turn profiles into solids on a feature timeline, and change a
|
||||||
|
parameter to watch the timeline rebuild. This is the first public build, a **pre-release**: it is
|
||||||
|
early, and we'd like your bug reports.
|
||||||
|
|
||||||
|
- **Documentation:** https://bherbruck.github.io/solvecraft/
|
||||||
|
- **Try it in the browser:** https://bherbruck.github.io/solvecraft/app/ (`?sample` opens a sample part)
|
||||||
|
- **Contributing:** [CONTRIBUTING.md](https://github.com/bherbruck/solvecraft/blob/main/CONTRIBUTING.md)
|
||||||
|
- **Bugs and ideas:** [issues](https://github.com/bherbruck/solvecraft/issues)
|
||||||
|
|
||||||
|
## What works
|
||||||
|
|
||||||
|
- Sketches with SolveCraft's own constraint solver: lines, rectangles, circles, arcs, polygons,
|
||||||
|
slots, splines, text; constraints and parameter-driven dimensions; automatic profiles.
|
||||||
|
- Solid features on a parametric timeline that rebuilds incrementally: extrude, revolve, sweep,
|
||||||
|
loft, fillet and chamfer, shell, draft, holes and threads, patterns, mirror, combine, split,
|
||||||
|
primitives. Faces and edges are referenced by persistent names, so upstream edits don't
|
||||||
|
scramble downstream features.
|
||||||
|
- Parameters with unit-aware expressions, and configurations.
|
||||||
|
- Components, joints, motion studies, sheet metal with flat patterns, and a plastic-enclosure
|
||||||
|
subset (bosses, lips, snap fits).
|
||||||
|
- Files: `.solvecraft` designs; STEP (AP203/214/242) and IGES import and export; 3MF, STL and OBJ;
|
||||||
|
DXF. Atomic saves, autosave and crash recovery.
|
||||||
|
- 76 of 76 reference parts built in Fusion rebuild in SolveCraft with the same volume, area and
|
||||||
|
topology.
|
||||||
|
|
||||||
|
## Built for AI agents
|
||||||
|
|
||||||
|
Everything the UI does is a command with JSON parameters, so an agent can do it too.
|
||||||
|
`solvecraft-cli mcp` is a Model Context Protocol server: headless, or bridged to the running app
|
||||||
|
(`solvecraft --control 7878`, then `solvecraft-cli mcp --connect 127.0.0.1:7878`) so you can
|
||||||
|
watch the agent model. In Claude Code: `claude mcp add solvecraft -- solvecraft-cli mcp`. The
|
||||||
|
attached video shows an agent building an enclosure through the UI and MCP.
|
||||||
|
|
||||||
|
## Downloads
|
||||||
|
|
||||||
|
| File | What |
|
||||||
|
|---|---|
|
||||||
|
| `solvecraft-v0.1.0-windows-x86_64.zip` | Windows 10/11: `solvecraft.exe` (the app) and `solvecraft-cli.exe` |
|
||||||
|
| `solvecraft-v0.1.0-linux-x86_64.tar.gz` | Linux x86_64 (glibc 2.35 or newer): `solvecraft` and `solvecraft-cli` |
|
||||||
|
| `SolveCraft-v0.1.0-x86_64.AppImage` | Linux, the app as one file: `chmod +x` and run it |
|
||||||
|
| `solvecraft-v0.1.0-macos-universal.zip` | macOS 11 or newer, Apple silicon and Intel: `SolveCraft.app` and `solvecraft-cli` |
|
||||||
|
| `solvecraft-v0.1.0-web.zip` | the web app, to host yourself (any static server; HTTPS or localhost for saving files) |
|
||||||
|
| `SHA256SUMS` | checksums: `sha256sum -c SHA256SUMS` |
|
||||||
|
|
||||||
|
### The binaries are not signed
|
||||||
|
|
||||||
|
- **macOS:** the first time, right-click (or Control-click) `SolveCraft.app` and choose **Open**,
|
||||||
|
then **Open** again in the dialog. If macOS says the app is damaged, run
|
||||||
|
`xattr -dr com.apple.quarantine SolveCraft.app`. Do the same for `solvecraft-cli`.
|
||||||
|
- **Windows:** SmartScreen may say "Windows protected your PC". Click **More info**, then
|
||||||
|
**Run anyway**.
|
||||||
|
|
||||||
|
## Known limitations
|
||||||
|
|
||||||
|
SolveCraft is early. Some fillet, chamfer and boolean configurations still fail (with an error,
|
||||||
|
never a crash); surfaces, drawings, CAM, mesh tools and simulation are out of scope for now; the
|
||||||
|
model is Z-up only, so STEP files from Y-up tools open lying on their backs. The full list is in
|
||||||
|
[ROADMAP.md](https://github.com/bherbruck/solvecraft/blob/main/ROADMAP.md#known-limitations).
|
||||||
|
|
||||||
|
SolveCraft is MIT OR Apache-2.0. It is a clean-room implementation and is not affiliated with
|
||||||
|
Autodesk; Fusion is a trademark of Autodesk, Inc.
|
||||||
Executable
+39
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Package the Linux release build: a tar.gz with both binaries, and an AppImage of the desktop app.
|
||||||
|
# Usage: .github/release/package-linux.sh <tag> (from the repository root, after
|
||||||
|
# `cargo build --release -p solvecraft -p solvecraft-cli`). Writes out/.
|
||||||
|
set -euo pipefail
|
||||||
|
tag=${1:?usage: package-linux.sh <tag>}
|
||||||
|
bin=${CARGO_TARGET_DIR:-target}/release
|
||||||
|
name="solvecraft-$tag-linux-x86_64"
|
||||||
|
rm -rf stage out && mkdir -p "stage/$name" out
|
||||||
|
cp "$bin/solvecraft" "$bin/solvecraft-cli" README.md LICENSE-MIT LICENSE-APACHE NOTICE ATTRIBUTION.md "stage/$name/"
|
||||||
|
tar -C stage -czf "out/$name.tar.gz" "$name"
|
||||||
|
|
||||||
|
# AppImage. The icon is rendered by SolveCraft itself from the bracket example, so no image file
|
||||||
|
# is committed.
|
||||||
|
app=stage/SolveCraft.AppDir
|
||||||
|
mkdir -p "$app/usr/bin"
|
||||||
|
cp "$bin/solvecraft" "$bin/solvecraft-cli" "$app/usr/bin/"
|
||||||
|
"$bin/solvecraft-cli" snapshot examples/bracket.json --out "$app/solvecraft.png" --width 256 --height 256 >/dev/null
|
||||||
|
cat > "$app/solvecraft.desktop" <<'DESKTOP'
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=SolveCraft
|
||||||
|
Comment=Parametric 3D CAD
|
||||||
|
Exec=solvecraft %f
|
||||||
|
Icon=solvecraft
|
||||||
|
Categories=Graphics;Engineering;
|
||||||
|
MimeType=model/step;
|
||||||
|
DESKTOP
|
||||||
|
cat > "$app/AppRun" <<'APPRUN'
|
||||||
|
#!/bin/sh
|
||||||
|
here="$(dirname "$(readlink -f "$0")")"
|
||||||
|
exec "$here/usr/bin/solvecraft" "$@"
|
||||||
|
APPRUN
|
||||||
|
chmod +x "$app/AppRun"
|
||||||
|
tool=stage/appimagetool
|
||||||
|
curl -sSfL -o "$tool" https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||||
|
chmod +x "$tool"
|
||||||
|
APPIMAGE_EXTRACT_AND_RUN=1 ARCH=x86_64 "$tool" --no-appstream "$app" "out/SolveCraft-$tag-x86_64.AppImage"
|
||||||
|
ls -l out
|
||||||
Executable
+35
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Package the macOS release build: a universal (arm64 + x86_64) SolveCraft.app and CLI in one zip.
|
||||||
|
# Usage: .github/release/package-macos.sh <tag> (from the repository root, after building both
|
||||||
|
# aarch64-apple-darwin and x86_64-apple-darwin). Writes out/. The app is not signed.
|
||||||
|
set -euo pipefail
|
||||||
|
tag=${1:?usage: package-macos.sh <tag>}
|
||||||
|
version=${tag#v}
|
||||||
|
t=${CARGO_TARGET_DIR:-target}
|
||||||
|
name="solvecraft-$tag-macos-universal"
|
||||||
|
rm -rf stage out && mkdir -p "stage/$name" out
|
||||||
|
app="stage/$name/SolveCraft.app"
|
||||||
|
mkdir -p "$app/Contents/MacOS"
|
||||||
|
lipo -create -output "$app/Contents/MacOS/solvecraft" "$t/aarch64-apple-darwin/release/solvecraft" "$t/x86_64-apple-darwin/release/solvecraft"
|
||||||
|
lipo -create -output "stage/$name/solvecraft-cli" "$t/aarch64-apple-darwin/release/solvecraft-cli" "$t/x86_64-apple-darwin/release/solvecraft-cli"
|
||||||
|
cat > "$app/Contents/Info.plist" <<PLIST
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleName</key><string>SolveCraft</string>
|
||||||
|
<key>CFBundleDisplayName</key><string>SolveCraft</string>
|
||||||
|
<key>CFBundleIdentifier</key><string>io.github.bherbruck.solvecraft</string>
|
||||||
|
<key>CFBundleExecutable</key><string>solvecraft</string>
|
||||||
|
<key>CFBundlePackageType</key><string>APPL</string>
|
||||||
|
<key>CFBundleVersion</key><string>$version</string>
|
||||||
|
<key>CFBundleShortVersionString</key><string>$version</string>
|
||||||
|
<key>LSMinimumSystemVersion</key><string>11.0</string>
|
||||||
|
<key>NSHighResolutionCapable</key><true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
PLIST
|
||||||
|
cp README.md LICENSE-MIT LICENSE-APACHE NOTICE ATTRIBUTION.md "stage/$name/"
|
||||||
|
lipo -info "$app/Contents/MacOS/solvecraft"
|
||||||
|
(cd stage && ditto -c -k --keepParent "$name" "../out/$name.zip")
|
||||||
|
ls -l out
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
# Release builds: push a tag `v*` (or run it by hand with a tag name) and this builds the desktop
|
||||||
|
# app and the CLI for Linux, Windows and macOS plus the web app, and attaches them to a GitHub
|
||||||
|
# release (a pre-release while the version is 0.x) with SHA256SUMS. Notes:
|
||||||
|
# .github/release-notes.md.
|
||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ["v*"]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: "Tag to release (must exist), e.g. v0.1.0"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
TAG: ${{ inputs.tag || github.ref_name }}
|
||||||
|
TRUNK_VERSION: v0.21.14
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
runs-on: ubuntu-22.04 # an older glibc, so the binaries run on older distributions
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ env.TAG }}
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
- run: cargo build --release --locked -p solvecraft -p solvecraft-cli
|
||||||
|
- name: Package
|
||||||
|
run: .github/release/package-linux.sh "$TAG"
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: linux
|
||||||
|
path: out/*
|
||||||
|
|
||||||
|
windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ env.TAG }}
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
- run: cargo build --release --locked -p solvecraft -p solvecraft-cli
|
||||||
|
- name: Package
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$name = "solvecraft-$env:TAG-windows-x86_64"
|
||||||
|
New-Item -ItemType Directory -Force -Path "stage/$name", out | Out-Null
|
||||||
|
Copy-Item target/release/solvecraft.exe, target/release/solvecraft-cli.exe, README.md, LICENSE-MIT, LICENSE-APACHE, NOTICE, ATTRIBUTION.md "stage/$name/"
|
||||||
|
Compress-Archive -Path "stage/$name" -DestinationPath "out/$name.zip"
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: windows
|
||||||
|
path: out/*
|
||||||
|
|
||||||
|
macos:
|
||||||
|
# One universal build: arm64 natively, x86_64 cross-compiled on the same runner, joined by lipo.
|
||||||
|
runs-on: macos-14
|
||||||
|
timeout-minutes: 90
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ env.TAG }}
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: aarch64-apple-darwin, x86_64-apple-darwin
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
- run: |
|
||||||
|
cargo build --release --locked -p solvecraft -p solvecraft-cli --target aarch64-apple-darwin
|
||||||
|
cargo build --release --locked -p solvecraft -p solvecraft-cli --target x86_64-apple-darwin
|
||||||
|
- name: Package
|
||||||
|
run: .github/release/package-macos.sh "$TAG"
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: macos
|
||||||
|
path: out/*
|
||||||
|
|
||||||
|
web:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ env.TAG }}
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: wasm32-unknown-unknown
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
- name: Install trunk
|
||||||
|
run: |
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
curl -sSfL "https://github.com/trunk-rs/trunk/releases/download/${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz" | tar -xz -C "$HOME/.local/bin"
|
||||||
|
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
||||||
|
- name: Build (relative public URL, so it can be served from any path)
|
||||||
|
working-directory: apps/solvecraft-web
|
||||||
|
run: trunk build --release
|
||||||
|
- name: Package
|
||||||
|
run: |
|
||||||
|
name="solvecraft-$TAG-web"
|
||||||
|
mkdir -p out && cp -r dist/web "$name"
|
||||||
|
cp LICENSE-MIT LICENSE-APACHE NOTICE "$name/"
|
||||||
|
zip -qr "out/$name.zip" "$name"
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: web
|
||||||
|
path: out/*
|
||||||
|
|
||||||
|
release:
|
||||||
|
needs: [linux, windows, macos, web]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ env.TAG }}
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: assets
|
||||||
|
merge-multiple: true
|
||||||
|
- name: Checksums
|
||||||
|
working-directory: assets
|
||||||
|
run: sha256sum * > SHA256SUMS && cat SHA256SUMS
|
||||||
|
- uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: ${{ env.TAG }}
|
||||||
|
name: SolveCraft ${{ env.TAG }}
|
||||||
|
body_path: .github/release-notes.md
|
||||||
|
prerelease: ${{ startsWith(env.TAG, 'v0.') }}
|
||||||
|
files: assets/*
|
||||||
Reference in new issue
Block a user