Compare commits

..

1 Commits

Author SHA1 Message Date
dac3c0c224 Delete test that is covering a basic assumption 2025-05-13 12:46:28 -04:00
1875 changed files with 12255777 additions and 12163776 deletions

3
.github/CODEOWNERS vendored
View File

@ -1,3 +0,0 @@
* @KittyCAD/frontend
/src/ @KittyCAD/frontend
/rust/ @KittyCAD/kcl

View File

@ -1,38 +0,0 @@
---
name: Release
about: Create a new release for the Zoo Design Studio
title: "Cut release v1.?.?"
labels: [release]
---
> Instructions: https://github.com/KittyCAD/modeling-app/blob/main/CONTRIBUTING.md#shipping-releases
---
# Manual Checklist
Release builds URL: ???
## Windows via ???
* [ ] Download the release build for this platform
* [ ] Confirm the application opens (dismiss the updater)
* [ ] Create a project with a basic Text-to-CAD prompt
* [ ] Confirm the result is viewable in an engine stream
* [ ] Open the application again and confirm the updater can downgrade
## macOS via ???
* [ ] Download the release build for this platform
* [ ] Confirm the application opens (dismiss the updater)
* [ ] Create a project with a basic Text-to-CAD prompt
* [ ] Confirm the result is viewable in an engine stream
* [ ] Open the application again and confirm the updater can downgrade
## Linux via ???
* [ ] Download the release build for this platform
* [ ] Confirm the application opens (dismiss the updater)
* [ ] Create a project with a basic Text-to-CAD prompt
* [ ] Confirm the result is viewable in an engine stream
* [ ] Open the application again and confirm the updater can downgrade

View File

@ -7,11 +7,11 @@ if [[ ! -f "test-results/.last-run.json" ]]; then
# If no last run artifact, than run Playwright normally # If no last run artifact, than run Playwright normally
echo "run playwright normally" echo "run playwright normally"
if [[ "$3" == *ubuntu* ]]; then if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:desktop -- --shard=$1/$2 || true xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron -- --shard=$1/$2 || true
elif [[ "$3" == *windows* ]]; then elif [[ "$3" == *windows* ]]; then
npm run test:e2e:desktop -- --grep=@windows --shard=$1/$2 || true npm run test:playwright:electron -- --grep=@windows --shard=$1/$2 || true
elif [[ "$3" == *macos* ]]; then elif [[ "$3" == *macos* ]]; then
npm run test:e2e:desktop -- --grep=@macos --shard=$1/$2 || true npm run test:playwright:electron -- --grep=@macos --shard=$1/$2 || true
else else
echo "Do not run Playwright. Unable to detect os runtime." echo "Do not run Playwright. Unable to detect os runtime."
exit 1 exit 1
@ -31,11 +31,11 @@ while [[ $retry -le $max_retries ]]; do
echo "retried=true" >>$GITHUB_OUTPUT echo "retried=true" >>$GITHUB_OUTPUT
echo "run playwright with last failed tests and retry $retry" echo "run playwright with last failed tests and retry $retry"
if [[ "$3" == *ubuntu* ]]; then if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:desktop -- --last-failed || true xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron -- --last-failed || true
elif [[ "$3" == *windows* ]]; then elif [[ "$3" == *windows* ]]; then
npm run test:e2e:desktop -- --grep=@windows --last-failed || true npm run test:playwright:electron -- --grep=@windows --last-failed || true
elif [[ "$3" == *macos* ]]; then elif [[ "$3" == *macos* ]]; then
npm run test:e2e:desktop -- --grep=@macos --last-failed || true npm run test:playwright:electron -- --grep=@macos --last-failed || true
else else
echo "Do not run playwright. Unable to detect os runtime." echo "Do not run playwright. Unable to detect os runtime."
exit 1 exit 1

View File

@ -6,7 +6,6 @@ if [ -z "${TAB_API_URL:-}" ] || [ -z "${TAB_API_KEY:-}" ]; then
fi fi
project="https://github.com/KittyCAD/modeling-app" project="https://github.com/KittyCAD/modeling-app"
suite="${CI_SUITE:-unit}"
branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}" branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}" commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
@ -14,7 +13,6 @@ echo "Uploading batch results"
curl --silent --request POST \ curl --silent --request POST \
--header "X-API-Key: ${TAB_API_KEY}" \ --header "X-API-Key: ${TAB_API_KEY}" \
--form "project=${project}" \ --form "project=${project}" \
--form "suite=${suite}" \
--form "branch=${branch}" \ --form "branch=${branch}" \
--form "commit=${commit}" \ --form "commit=${commit}" \
--form "tests=@test-results/junit.xml" \ --form "tests=@test-results/junit.xml" \

731
.github/dependabot.yml vendored

File diff suppressed because it is too large Load Diff

View File

@ -10,10 +10,10 @@ on:
env: env:
IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }} IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }}
IS_STAGING: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} IS_NIGHTLY: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
@ -91,14 +91,14 @@ jobs:
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }} if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
run: "npm run build:wasm" run: "npm run build:wasm"
- name: Set staging version, product name, release notes, and icons - name: Set nightly version, product name, release notes, and icons
if: ${{ env.IS_STAGING == 'true' }} if: ${{ env.IS_NIGHTLY == 'true' }}
run: | run: |
COMMIT=$(git rev-parse --short HEAD) COMMIT=$(git rev-parse --short HEAD)
DATE=$(date +'%-y.%-m.%-d') DATE=$(date +'%-y.%-m.%-d')
export VERSION=$DATE-main.$COMMIT export VERSION=$DATE-main.$COMMIT
npm run files:set-version npm run files:set-version
npm run files:flip-to-staging npm run files:flip-to-nightly
- name: Set release version - name: Set release version
if: ${{ env.IS_RELEASE == 'true' }} if: ${{ env.IS_RELEASE == 'true' }}
@ -123,6 +123,18 @@ jobs:
- id: export_notes - id: export_notes
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT" run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
- name: Prepare electron-builder.yml file for updater test
if: ${{ env.IS_RELEASE == 'true' }}
run: |
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
- uses: actions/upload-artifact@v4
if: ${{ env.IS_RELEASE == 'true' }}
with:
name: prepared-files-updater-test
path: |
electron-builder.yml
build-apps: build-apps:
needs: [prepare-files] needs: [prepare-files]
@ -130,14 +142,13 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- os: namespace-profile-macos-6-cores - os: macos-14
platform: macos platform: mac
- os: namespace-profile-windows-4-cores - os: windows-2022
platform: windows platform: win
- os: ubuntu-22.04 - os: ubuntu-22.04
platform: linux platform: linux
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
name: build-apps (${{ matrix.platform }})
env: env:
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }} VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
steps: steps:
@ -167,14 +178,14 @@ jobs:
- run: npm install - run: npm install
- name: Prepare certificate and variables (Windows only) - name: Prepare certificate and variables (Windows only)
if: ${{ (env.IS_RELEASE == 'true' || env.IS_STAGING == 'true') && matrix.platform == 'windows' }} if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
run: | run: |
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /c/Certificate_pkcs12.p12 echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
cat /c/Certificate_pkcs12.p12 cat /d/Certificate_pkcs12.p12
echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV" echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV" echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_FILE=C:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH
echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH
@ -182,7 +193,7 @@ jobs:
shell: bash shell: bash
- name: Setup certicate with SSM KSP (Windows only) - name: Setup certicate with SSM KSP (Windows only)
if: ${{ (env.IS_RELEASE == 'true' || env.IS_STAGING == 'true') && matrix.platform == 'windows' }} if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
run: | run: |
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
msiexec /i smtools-windows-x64.msi /quiet /qn msiexec /i smtools-windows-x64.msi /quiet /qn
@ -192,7 +203,7 @@ jobs:
smksp_cert_sync.exe smksp_cert_sync.exe
smctl windows certsync smctl windows certsync
# This last line `smctl windows certsync` was added after windows codesign failures started happening # This last line `smctl windows certsync` was added after windows codesign failures started happening
# with staging-v25.4.10. It looks like `smksp_cert_sync.exe` used to do the sync to the local cert store, # with nightly-v25.4.10. It looks like `smksp_cert_sync.exe` used to do the sync to the local cert store,
# but stopped doing it overnight. This extra call that I randomly got from this azure-related doc page # but stopped doing it overnight. This extra call that I randomly got from this azure-related doc page
# https://docs.digicert.com/en/digicert-keylocker/code-signing/sign-with-third-party-signing-tools/windows-applications/sign-azure-apps-with-signtool-using-ksp-library.html#sync-certificates--windows-only--618365 # https://docs.digicert.com/en/digicert-keylocker/code-signing/sign-with-third-party-signing-tools/windows-applications/sign-azure-apps-with-signtool-using-ksp-library.html#sync-certificates--windows-only--618365
# seems to be doing that extra sync that we need for scripts/sign-win.js to work. # seems to be doing that extra sync that we need for scripts/sign-win.js to work.
@ -200,13 +211,13 @@ jobs:
shell: cmd shell: cmd
- name: Build the app (debug) - name: Build the app (debug)
if: ${{ env.IS_RELEASE == 'false' && env.IS_STAGING == 'false' }} if: ${{ env.IS_RELEASE == 'false' && env.IS_NIGHTLY == 'false' }}
# electron-builder doesn't have a concept of release vs debug, # electron-builder doesn't have a concept of release vs debug,
# this is just not doing any codesign or release yml generation, and points to dev infra # this is just not doing any codesign or release yml generation, and points to dev infra
run: npm run tronb:package:dev run: npm run tronb:package:dev
- name: Build the app (release) - name: Build the app (release)
if: ${{ env.IS_RELEASE == 'true' || env.IS_STAGING == 'true' }} if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
env: env:
APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
@ -216,7 +227,7 @@ jobs:
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }} CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }} WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
run: npm run tronb:package:${{ env.IS_STAGING == 'true' && 'dev' || 'prod' }} run: npm run tronb:package:prod
- name: List artifacts in out/ - name: List artifacts in out/
run: ls -R out run: ls -R out
@ -240,20 +251,63 @@ jobs:
out/*-x86_64-linux.* out/*-x86_64-linux.*
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: ${{ env.IS_RELEASE == 'true' || env.IS_STAGING == 'true' }} if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
with: with:
name: out-yml-${{ matrix.platform }} name: out-yml-${{ matrix.platform }}
path: | path: |
out/latest*.yml out/latest*.yml
# TODO: add the 'Build for Mac TestFlight' stage back # TODO: add the 'Build for Mac TestFlight (nightly)' stage back
# The steps below are for updater-test builds, only on release
- uses: actions/download-artifact@v4
if: ${{ env.IS_RELEASE == 'true' }}
name: prepared-files-updater-test
- name: Copy updated electron-builder.yml file for updater test
if: ${{ env.IS_RELEASE == 'true' }}
run: |
ls -R prepared-files-updater-test
cp prepared-files-updater-test/electron-builder.yml electron-builder.yml
- name: Build the app (updater-test)
if: ${{ env.IS_RELEASE == 'true' }}
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
run: npm run tronb:package:prod
- uses: actions/upload-artifact@v4
if: ${{ env.IS_RELEASE == 'true' }}
with:
name: updater-test-arm64-${{ matrix.platform }}
path: |
out/*-arm64-win.exe
out/*-arm64-mac.dmg
out/*-arm64-linux.AppImage
- uses: actions/upload-artifact@v4
if: ${{ env.IS_RELEASE == 'true' }}
with:
name: updater-test-x64-${{ matrix.platform }}
path: |
out/*-x64-win.exe
out/*-x64-mac.dmg
out/*-x86_64-linux.AppImage
upload-apps-release: upload-apps-release:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: write contents: write
# Equivalent to IS_RELEASE || IS_STAGING (but we can't access those env vars here) # Equivalent to IS_RELEASE || IS_NIGHTLY (but we can't access those env vars here)
if: ${{ (github.ref_type == 'tag' && startsWith(github.ref_name, 'v')) || (github.event_name == 'push' && github.ref == 'refs/heads/main') }} if: ${{ (github.ref_type == 'tag' && startsWith(github.ref_name, 'v')) || (github.event_name == 'push' && github.ref == 'refs/heads/main') }}
env: env:
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }} VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
@ -264,32 +318,32 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-arm64-windows name: out-arm64-win
path: out path: out
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-x64-windows name: out-x64-win
path: out path: out
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-yml-windows name: out-yml-win
path: out path: out
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-arm64-macos name: out-arm64-mac
path: out path: out
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-x64-macos name: out-x64-mac
path: out path: out
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-yml-macos name: out-yml-mac
path: out path: out
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
@ -311,8 +365,8 @@ jobs:
env: env:
NOTES: ${{ needs.prepare-files.outputs.notes }} NOTES: ${{ needs.prepare-files.outputs.notes }}
PUB_DATE: ${{ github.event.repository.updated_at }} PUB_DATE: ${{ github.event.repository.updated_at }}
WEBSITE_DIR: ${{ env.IS_STAGING == 'true' && 'dl.zoo.dev/releases/modeling-app/staging' || 'dl.zoo.dev/releases/modeling-app' }} WEBSITE_DIR: ${{ env.IS_NIGHTLY == 'true' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
URL_CODED_NAME: ${{ env.IS_STAGING == 'true' && 'Zoo%20Design%20Studio%20%28Staging%29' || 'Zoo%20Design%20Studio' }} URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Design%20Studio%20%28Nightly%29' || 'Zoo%20Design%20Studio' }}
run: | run: |
RELEASE_DIR=https://${WEBSITE_DIR} RELEASE_DIR=https://${WEBSITE_DIR}
jq --null-input \ jq --null-input \
@ -361,26 +415,26 @@ jobs:
run: "ls -R out" run: "ls -R out"
- name: Authenticate to Google Cloud - name: Authenticate to Google Cloud
if: ${{ env.IS_STAGING == 'true' }} if: ${{ env.IS_NIGHTLY == 'true' }}
uses: 'google-github-actions/auth@v2.1.8' uses: 'google-github-actions/auth@v2.1.8'
with: with:
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}' credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
- name: Set up Google Cloud SDK - name: Set up Google Cloud SDK
if: ${{ env.IS_STAGING == 'true' }} if: ${{ env.IS_NIGHTLY == 'true' }}
uses: google-github-actions/setup-gcloud@v2.1.4 uses: google-github-actions/setup-gcloud@v2.1.4
with: with:
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }} project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
- name: Upload staging files to public bucket - name: Upload nightly files to public bucket
if: ${{ env.IS_STAGING == 'true' }} if: ${{ env.IS_NIGHTLY == 'true' }}
uses: google-github-actions/upload-cloud-storage@v2.2.2 uses: google-github-actions/upload-cloud-storage@v2.2.2
with: with:
path: out path: out
glob: '*' glob: '*'
parent: false parent: false
destination: 'dl.kittycad.io/releases/modeling-app/staging' destination: 'dl.kittycad.io/releases/modeling-app/nightly'
- name: Invalidate bucket cache on latest*.yml and last_download.json files - name: Invalidate bucket cache on latest*.yml and last_download.json files
if: ${{ env.IS_STAGING == 'true' }} if: ${{ env.IS_NIGHTLY == 'true' }}
run: npm run files:invalidate-bucket:staging run: npm run files:invalidate-bucket:nightly

View File

@ -1,56 +0,0 @@
name: Build WASM
on:
workflow_call:
permissions:
contents: read
jobs:
npm-build-wasm:
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # configured below
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
with:
tool: wasm-pack
- name: Use Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: './rust'
- name: Build Wasm
shell: bash
run: npm run build:wasm
- uses: actions/upload-artifact@v4
with:
name: prepared-wasm
path: |
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
- uses: actions/upload-artifact@v4
with:
name: prepared-ts-rs-bindings
path: |
rust/kcl-lib/bindings/*

View File

@ -31,15 +31,15 @@ jobs:
- name: Use correct Rust toolchain - name: Use correct Rust toolchain
shell: bash shell: bash
run: | run: |
cp .github/workflows/nightly-rust-toolchain.toml rust-toolchain.toml [ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust - name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1 uses: actions-rust-lang/setup-rust-toolchain@v1
with: with:
cache-workspaces: rust cache-workspaces: rust
components: rustfmt components: rustfmt
- name: Run nightly cargo fmt - name: Run cargo fmt
run: | run: |
cd rust cd rust
cargo +nightly fmt -- --check cargo fmt -- --check
shell: bash shell: bash

View File

@ -1,22 +1,16 @@
name: cargo test
on: on:
push: push:
branches: branches:
- main - main
pull_request: pull_request:
workflow_dispatch: workflow_dispatch:
schedule:
- cron: 0 * * * * # hourly
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true cancel-in-progress: true
name: cargo test
jobs: jobs:
build-test-artifacts: build-test-artifacts:
name: Build test artifacts name: Build test artifacts
@ -94,7 +88,6 @@ jobs:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}} KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
ZOO_HOST: https://api.dev.zoo.dev ZOO_HOST: https://api.dev.zoo.dev
RUST_BACKTRACE: full RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000
- name: Commit differences - name: Commit differences
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure' if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
shell: bash shell: bash
@ -126,7 +119,6 @@ jobs:
# Configure nextest when it's run by insta (via just). # Configure nextest when it's run by insta (via just).
NEXTEST_PROFILE: ci NEXTEST_PROFILE: ci
RUST_BACKTRACE: full RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000
- name: Build and archive tests - name: Build and archive tests
run: | run: |
cd rust cd rust
@ -163,7 +155,7 @@ jobs:
shell: bash shell: bash
run: | run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./ [ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install Rust - name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1 uses: actions-rust-lang/setup-rust-toolchain@v1
with: with:
cache: false # Configured below. cache: false # Configured below.
@ -190,7 +182,6 @@ jobs:
env: env:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}} KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
ZOO_HOST: https://api.dev.zoo.dev ZOO_HOST: https://api.dev.zoo.dev
RUST_MIN_STACK: 10485760000
- name: Upload results - name: Upload results
if: always() if: always()
run: .github/ci-cd-scripts/upload-results.sh run: .github/ci-cd-scripts/upload-results.sh
@ -199,56 +190,6 @@ jobs:
TAB_API_KEY: ${{ secrets.TAB_API_KEY }} TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }} CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }} CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: e2e:kcl
run-internal-kcl-samples:
name: cargo test (internal-kcl-samples)
runs-on:
- runs-on=${{ github.run_id }}
- runner=32cpu-linux-x64
- extras=s3-cache
steps:
- uses: runs-on/action@v1
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- name: Start Vector
run: .github/ci-cd-scripts/start-vector-ubuntu.sh
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- uses: taiki-e/install-action@nextest
- name: Download internal KCL samples
run: git clone --depth=1 https://x-access-token:${{ secrets.GH_PAT_KCL_SAMPLES_INTERNAL }}@github.com/KittyCAD/kcl-samples-internal public/kcl-samples/internal
- name: Run tests
shell: bash
run: |-
cd rust/kcl-lib
cargo nextest run \
--retries=10 --no-fail-fast --features artifact-graph --profile=ci \
internal \
2>&1 | tee /tmp/github-actions.log
env:
TWENTY_TWENTY: overwrite
INSTA_UPDATE: always
EXPECTORATE: overwrite
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
ZOO_HOST: https://api.dev.zoo.dev
MODELING_APP_INTERNAL_SAMPLES_SECRET: ${{secrets.MODELING_APP_INTERNAL_SAMPLES_SECRET}}
RUST_MIN_STACK: 10485760000
run-wasm-tests: run-wasm-tests:
name: Run wasm tests name: Run wasm tests
strategy: strategy:

View File

@ -1,5 +1,4 @@
name: E2E Tests name: E2E Tests
on: on:
push: push:
branches: branches:
@ -20,11 +19,9 @@ permissions:
jobs: jobs:
prepare-wasm: prepare-wasm:
# separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner # separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64 runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- id: filter - id: filter
@ -43,7 +40,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm install run: npm install
- name: Download Wasm cache - name: Download Wasm Cache
id: download-wasm id: download-wasm
if: ${{ github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }} if: ${{ github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
uses: dawidd6/action-download-artifact@v7 uses: dawidd6/action-download-artifact@v7
@ -55,7 +52,7 @@ jobs:
branch: main branch: main
path: rust/kcl-wasm-lib/pkg path: rust/kcl-wasm-lib/pkg
- name: Build Wasm condition - name: Build WASM condition
id: wasm id: wasm
run: | run: |
set -euox pipefail set -euox pipefail
@ -73,7 +70,7 @@ jobs:
run: | run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./ [ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install Rust - name: Install rust
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }} if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
uses: actions-rust-lang/setup-rust-toolchain@v1 uses: actions-rust-lang/setup-rust-toolchain@v1
with: with:
@ -84,7 +81,7 @@ jobs:
with: with:
tool: wasm-pack tool: wasm-pack
- name: Use Rust cache - name: Rust Cache
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }} if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
uses: Swatinem/rust-cache@v2 uses: Swatinem/rust-cache@v2
with: with:
@ -95,21 +92,17 @@ jobs:
shell: bash shell: bash
run: npm run build:wasm run: npm run build:wasm
- name: Upload compiled wasm artifacts - uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v4
with: with:
name: prepared-wasm name: prepared-wasm
path: | path: |
rust/kcl-wasm-lib/pkg/kcl_wasm_lib* rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
snapshots: snapshots:
needs: [prepare-wasm] name: playwright:snapshots:ubuntu
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64 runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
name: e2e:snapshots needs: [prepare-wasm]
steps: steps:
- uses: actions/create-github-app-token@v1 - uses: actions/create-github-app-token@v1
id: app-token id: app-token
with: with:
@ -124,7 +117,7 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
name: prepared-wasm name: prepared-wasm
- name: Copy prepared Wasm - name: Copy prepared wasm
run: | run: |
ls -R prepared-wasm ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public cp prepared-wasm/kcl_wasm_lib_bg.wasm public
@ -137,19 +130,23 @@ jobs:
cache: 'npm' cache: 'npm'
- name: Install dependencies - name: Install dependencies
id: deps-install
run: npm install run: npm install
- name: Download browser cache - name: Cache Playwright Browsers
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
~/.cache/ms-playwright/ ~/.cache/ms-playwright/
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }} key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
- name: Install browsers - name: Install Playwright Browsers
run: npm run playwright install --with-deps run: npm run playwright install --with-deps
- name: npm run test:snapshots - name: build web
run: npm run tronb:vite:dev
- name: Run ubuntu/chrome snapshots
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2
with: with:
shell: bash shell: bash
@ -162,44 +159,31 @@ jobs:
TAB_API_KEY: ${{ secrets.TAB_API_KEY }} TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }} CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }} CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: e2e:snapshots
TARGET: web TARGET: web
- name: Update snapshots - uses: actions/upload-artifact@v4
if: always() if: ${{ !cancelled() && (success() || failure()) }}
run: npm run test:snapshots -- --last-failed --update-snapshots
env:
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
TAB_API_URL: ${{ secrets.TAB_API_URL }}
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: e2e:snapshots
TARGET: web
- name: Upload playwright report
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with: with:
name: playwright-report-snapshot-${{ github.sha }} name: playwright-report-ubuntu-snapshot-${{ github.sha }}
path: playwright-report/ path: playwright-report/
include-hidden-files: true include-hidden-files: true
retention-days: 30 retention-days: 30
overwrite: true overwrite: true
- name: Check diff - name: Check for changes
if: ${{ always() && github.ref != 'refs/heads/main' }} if: ${{ github.ref != 'refs/heads/main' }}
shell: bash shell: bash
id: git-check id: git-check
run: | run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
if git status | grep --quiet "Changes to be committed" if git status | grep -q "Changes to be committed"
then echo "modified=true" >> $GITHUB_OUTPUT then echo "modified=true" >> $GITHUB_OUTPUT
else echo "modified=false" >> $GITHUB_OUTPUT else echo "modified=false" >> $GITHUB_OUTPUT
fi fi
- name: Commit changes - name: Commit changes, if any
if: ${{ always() && steps.git-check.outputs.modified == 'true' }} # TODO: find a more reliable way to detect visual changes
if: ${{ false && steps.git-check.outputs.modified == 'true' }}
shell: bash shell: bash
run: | run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
@ -209,105 +193,20 @@ jobs:
git fetch origin git fetch origin
echo ${{ github.head_ref }} echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }} git checkout ${{ github.head_ref }}
git commit --message "Update snapshots" || true git commit -m "A snapshot a day keeps the bugs away! 📷🐛" || true
git push git push
git push origin ${{ github.head_ref }} git push origin ${{ github.head_ref }}
web: electron:
needs: [prepare-wasm] needs: [prepare-wasm]
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- os: namespace-profile-macos-8-cores
- os: namespace-profile-windows-8-cores
runs-on: ${{ matrix.os }}
name: e2e:web (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }})
env: env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} (shard ${{ matrix.shardIndex }})
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- uses: actions/download-artifact@v4
name: prepared-wasm
- name: Copy prepared Wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Download browser cache
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright/
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
- name: Install browsers
run: npm run playwright install --with-deps
- name: Start Vector
if: ${{ !contains(matrix.os, 'windows') }}
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- name: npm run test:e2e:web
uses: nick-fields/retry@v3.0.2
with:
shell: bash
command: npm run test:e2e:web
timeout_minutes: 5
max_attempts: 5
env:
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
TAB_API_URL: ${{ secrets.TAB_API_URL }}
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: e2e:web
TARGET: web
- name: Upload playwright report
uses: actions/upload-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
with:
name: playwright-report-web-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/
include-hidden-files: true
retention-days: 30
overwrite: true
desktop:
needs: [prepare-wasm]
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
# TODO: enable namespace-profile-windows-latest once available
include: include:
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64" - os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 1 shardIndex: 1
@ -335,28 +234,18 @@ jobs:
shardTotal: 8 shardTotal: 8
- os: namespace-profile-macos-8-cores - os: namespace-profile-macos-8-cores
shardIndex: 1 shardIndex: 1
shardTotal: 2 shardTotal: 1
- os: namespace-profile-macos-8-cores - os: windows-latest-8-cores
shardIndex: 2
shardTotal: 2
- os: namespace-profile-windows-8-cores
shardIndex: 1 shardIndex: 1
shardTotal: 2 shardTotal: 1
- os: namespace-profile-windows-8-cores
shardIndex: 2
shardTotal: 2
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
name: e2e:desktop (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}, shard ${{ matrix.shardIndex }})
env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
name: prepared-wasm name: prepared-wasm
- name: Copy prepared Wasm - name: Copy prepared wasm
run: | run: |
ls -R prepared-wasm ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public cp prepared-wasm/kcl_wasm_lib_bg.wasm public
@ -372,16 +261,19 @@ jobs:
id: deps-install id: deps-install
run: npm install run: npm install
- name: Download browser cache - name: Cache Playwright Browsers
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
~/.cache/ms-playwright/ ~/.cache/ms-playwright/
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }} key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
- name: Install browsers - name: Install Playwright Browsers
run: npm run playwright install --with-deps run: npm run playwright install --with-deps
- name: Build web
run: npm run tronb:vite:dev
- name: Start Vector - name: Start Vector
if: ${{ !contains(matrix.os, 'windows') }} if: ${{ !contains(matrix.os, 'windows') }}
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
@ -389,9 +281,6 @@ jobs:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }} GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }} OS_NAME: ${{ env.OS_NAME }}
- name: Build app
run: npm run tronb:vite:dev
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }} if: ${{ !cancelled() && (success() || failure()) }}
continue-on-error: true continue-on-error: true
@ -399,7 +288,7 @@ jobs:
name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }} name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
- name: npm run test:e2e:desktop - name: Run playwright/electron flow (with retries)
id: retry id: retry
if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }} if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }}
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2
@ -415,24 +304,21 @@ jobs:
TAB_API_KEY: ${{ secrets.TAB_API_KEY }} TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }} CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }} CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: e2e:desktop
TARGET: desktop TARGET: desktop
- name: Upload test report - uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: test-results-desktop-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }} name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
include-hidden-files: true include-hidden-files: true
retention-days: 30 retention-days: 30
overwrite: true overwrite: true
- name: Upload playwright report - uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: playwright-report-desktop-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }} name: playwright-report-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/ path: playwright-report/
include-hidden-files: true include-hidden-files: true
retention-days: 30 retention-days: 30

View File

@ -21,11 +21,14 @@ on:
- '**.rs' - '**.rs'
- .github/workflows/kcl-language-server.yml - .github/workflows/kcl-language-server.yml
workflow_dispatch: workflow_dispatch:
permissions: permissions:
contents: read contents: read
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true cancel-in-progress: true
env: env:
CARGO_INCREMENTAL: 0 CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10 CARGO_NET_RETRY: 10
@ -35,9 +38,10 @@ env:
MACOSX_DEPLOYMENT_TARGET: 10.15 MACOSX_DEPLOYMENT_TARGET: 10.15
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
jobs: jobs:
test: test:
name: kcl-language-server (vscode tests) name: vscode tests
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -73,20 +77,22 @@ jobs:
include: include:
- os: windows-latest - os: windows-latest
target: x86_64-pc-windows-msvc target: x86_64-pc-windows-msvc
code-target: win32-x64 code-target:
#- os: windows-latest win32-x64
#target: i686-pc-windows-msvc #- os: windows-latest
#code-target: #target: i686-pc-windows-msvc
#win32-ia32 #code-target:
#- os: windows-latest #win32-ia32
#target: aarch64-pc-windows-msvc #- os: windows-latest
#code-target: win32-arm64 #target: aarch64-pc-windows-msvc
#code-target: win32-arm64
- os: ubuntu-latest - os: ubuntu-latest
target: x86_64-unknown-linux-gnu target: x86_64-unknown-linux-gnu
code-target: linux-x64 code-target:
#- os: ubuntu-latest linux-x64
#target: aarch64-unknown-linux-musl #- os: ubuntu-latest
#code-target: linux-arm64 #target: aarch64-unknown-linux-musl
#code-target: linux-arm64
- os: ubuntu-latest - os: ubuntu-latest
target: aarch64-unknown-linux-gnu target: aarch64-unknown-linux-gnu
code-target: linux-arm64 code-target: linux-arm64
@ -99,33 +105,41 @@ jobs:
- os: macos-latest - os: macos-latest
target: aarch64-apple-darwin target: aarch64-apple-darwin
code-target: darwin-arm64 code-target: darwin-arm64
name: kcl-language-server build-release (${{ matrix.target }})
name: build-release (${{ matrix.target }})
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
container: ${{ matrix.container }} container: ${{ matrix.container }}
env: env:
RA_TARGET: ${{ matrix.target }} RA_TARGET: ${{ matrix.target }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: ${{ env.FETCH_DEPTH }} fetch-depth: ${{ env.FETCH_DEPTH }}
- name: Use correct Rust toolchain - name: Use correct Rust toolchain
shell: bash shell: bash
run: | run: |
rm rust/rust-toolchain.toml rm rust/rust-toolchain.toml
- name: Install rust - name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1 uses: actions-rust-lang/setup-rust-toolchain@v1
with: with:
cache: rust cache: rust
components: rust-src components: rust-src
target: ${{ matrix.target }} target: ${{ matrix.target }}
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version-file: ".nvmrc" node-version-file: ".nvmrc"
- name: Update apt repositories - name: Update apt repositories
if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' || matrix.os == 'ubuntu-latest' if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' || matrix.os == 'ubuntu-latest'
run: sudo apt-get update run: sudo apt-get update
- if: ${{ matrix.os == 'ubuntu-latest' }} - if: ${{ matrix.os == 'ubuntu-latest' }}
name: Install deps name: Install deps
shell: bash shell: bash
@ -150,53 +164,64 @@ jobs:
zlib1g-dev zlib1g-dev
cargo install cross cargo install cross
- name: Install AArch64 target toolchain - name: Install AArch64 target toolchain
if: matrix.target == 'aarch64-unknown-linux-gnu' if: matrix.target == 'aarch64-unknown-linux-gnu'
run: sudo apt-get install gcc-aarch64-linux-gnu run: sudo apt-get install gcc-aarch64-linux-gnu
- name: Install ARM target toolchain - name: Install ARM target toolchain
if: matrix.target == 'arm-unknown-linux-gnueabihf' if: matrix.target == 'arm-unknown-linux-gnueabihf'
run: sudo apt-get install gcc-arm-linux-gnueabihf run: sudo apt-get install gcc-arm-linux-gnueabihf
- name: build - name: build
run: | run: |
cd rust cd rust
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }} cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
- name: Install dependencies - name: Install dependencies
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
# npm will symlink which will cause issues w tarballing later # npm will symlink which will cause issues w tarballing later
yarn install yarn install
- name: Package Extension (release) - name: Package Extension (release)
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
- name: Package Extension (nightly) - name: Package Extension (nightly)
if: startsWith(github.event.ref, 'refs/tags/') == false if: startsWith(github.event.ref, 'refs/tags/') == false
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release
- name: remove server - name: remove server
if: matrix.target == 'x86_64-unknown-linux-gnu' if: matrix.target == 'x86_64-unknown-linux-gnu'
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
rm -rf server rm -rf server
- name: Package Extension (no server, release) - name: Package Extension (no server, release)
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/') if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/')
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix
- name: Package Extension (no server, nightly) - name: Package Extension (no server, nightly)
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/') == false if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/') == false
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix --pre-release npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix --pre-release
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: release-${{ matrix.target }} name: release-${{ matrix.target }}
path: ./rust/build path: ./rust/build
build-release-x86_64-unknown-linux-musl: build-release-x86_64-unknown-linux-musl:
name: kcl-language-server build-release (x86_64-unknown-linux-musl) name: build-release (x86_64-unknown-linux-musl)
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
RA_TARGET: x86_64-unknown-linux-musl RA_TARGET: x86_64-unknown-linux-musl
@ -206,6 +231,7 @@ jobs:
image: alpine:latest image: alpine:latest
volumes: volumes:
- /usr/local/cargo/registry:/usr/local/cargo/registry - /usr/local/cargo/registry:/usr/local/cargo/registry
steps: steps:
- name: Install dependencies - name: Install dependencies
run: | run: |
@ -219,46 +245,55 @@ jobs:
nodejs \ nodejs \
npm \ npm \
yarn yarn
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: ${{ env.FETCH_DEPTH }} fetch-depth: ${{ env.FETCH_DEPTH }}
- name: Use correct Rust toolchain - name: Use correct Rust toolchain
shell: bash shell: bash
run: | run: |
rm rust/rust-toolchain.toml rm rust/rust-toolchain.toml
- name: Install rust - name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1 uses: actions-rust-lang/setup-rust-toolchain@v1
with: with:
cache: rust cache: rust
components: rust-src components: rust-src
target: ${{ matrix.target }} target: ${{ matrix.target }}
- name: build - name: build
run: | run: |
cd rust cd rust
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }} cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
- name: Install dependencies - name: Install dependencies
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
# npm will symlink which will cause issues w tarballing later # npm will symlink which will cause issues w tarballing later
yarn install yarn install
- name: Package Extension (release) - name: Package Extension (release)
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64
- name: Package Extension (release) - name: Package Extension (release)
if: startsWith(github.event.ref, 'refs/tags/') == false if: startsWith(github.event.ref, 'refs/tags/') == false
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 --pre-release npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 --pre-release
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: release-x86_64-unknown-linux-musl name: release-x86_64-unknown-linux-musl
path: ./rust/build path: ./rust/build
publish: publish:
name: kcl-language-server (publish) name: publish
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: ["build-release", "build-release-x86_64-unknown-linux-musl"] needs: ["build-release", "build-release-x86_64-unknown-linux-musl"]
if: startsWith(github.event.ref, 'refs/tags') if: startsWith(github.event.ref, 'refs/tags')
@ -266,17 +301,22 @@ jobs:
contents: write contents: write
steps: steps:
- run: echo "TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - run: echo "TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- run: 'echo "TAG: $TAG"' - run: 'echo "TAG: $TAG"'
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: ${{ env.FETCH_DEPTH }} fetch-depth: ${{ env.FETCH_DEPTH }}
- name: Install Nodejs - name: Install Nodejs
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version-file: ".nvmrc" node-version-file: ".nvmrc"
- run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV - run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
- run: 'echo "HEAD_SHA: $HEAD_SHA"' - run: 'echo "HEAD_SHA: $HEAD_SHA"'
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: release-aarch64-apple-darwin name: release-aarch64-apple-darwin
@ -304,29 +344,33 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: release-x86_64-pc-windows-msvc name: release-x86_64-pc-windows-msvc
path: rust/build path:
#- uses: actions/download-artifact@v4 rust/build
#with: #- uses: actions/download-artifact@v4
#name: release-i686-pc-windows-msvc #with:
#path: #name: release-i686-pc-windows-msvc
#build #path:
#- uses: actions/download-artifact@v4 #build
#with: #- uses: actions/download-artifact@v4
#name: release-aarch64-pc-windows-msvc #with:
#path: rust/build #name: release-aarch64-pc-windows-msvc
#path: rust/build
- run: ls -al ./rust/build - run: ls -al ./rust/build
- name: Publish Release - name: Publish Release
uses: ./.github/actions/github-release uses: ./.github/actions/github-release
with: with:
files: "rust/build/*" files: "rust/build/*"
name: ${{ env.TAG }} name: ${{ env.TAG }}
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
- name: move files to dir for upload - name: move files to dir for upload
shell: bash shell: bash
run: | run: |
cd rust cd rust
mkdir -p releases/language-server/${{ env.TAG }} mkdir -p releases/language-server/${{ env.TAG }}
cp -r build/* releases/language-server/${{ env.TAG }} cp -r build/* releases/language-server/${{ env.TAG }}
- name: "Authenticate to Google Cloud" - name: "Authenticate to Google Cloud"
uses: "google-github-actions/auth@v2.1.8" uses: "google-github-actions/auth@v2.1.8"
with: with:
@ -341,12 +385,15 @@ jobs:
with: with:
path: rust/releases path: rust/releases
destination: dl.kittycad.io destination: dl.kittycad.io
- run: rm rust/build/kcl-language-server-no-server.vsix - run: rm rust/build/kcl-language-server-no-server.vsix
- name: Publish Extension (Code Marketplace, release) - name: Publish Extension (Code Marketplace, release)
# token from https://dev.azure.com/kcl-language-server/ # token from https://dev.azure.com/kcl-language-server/
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server
npx vsce publish --pat ${{ secrets.VSCE_PAT }} --packagePath ../build/kcl-language-server-*.vsix npx vsce publish --pat ${{ secrets.VSCE_PAT }} --packagePath ../build/kcl-language-server-*.vsix
- name: Publish Extension (OpenVSX, release) - name: Publish Extension (OpenVSX, release)
run: | run: |
cd rust/kcl-language-server cd rust/kcl-language-server

View File

@ -4,6 +4,7 @@
# maturin generate-ci github # maturin generate-ci github
# #
name: kcl-python-bindings name: kcl-python-bindings
on: on:
push: push:
branches: branches:
@ -26,14 +27,16 @@ on:
- '**.rs' - '**.rs'
- .github/workflows/kcl-python-bindings.yml - .github/workflows/kcl-python-bindings.yml
workflow_dispatch: workflow_dispatch:
permissions: permissions:
contents: read contents: read
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
linux-x86_64: linux-x86_64:
name: kcl-python-bindings (linux-x86_64)
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -55,8 +58,8 @@ jobs:
with: with:
name: wheels-linux-x86_64 name: wheels-linux-x86_64
path: rust/kcl-python-bindings/dist path: rust/kcl-python-bindings/dist
windows: windows:
name: kcl-python-bindings (windows)
runs-on: windows-16-cores runs-on: windows-16-cores
strategy: strategy:
matrix: matrix:
@ -81,8 +84,8 @@ jobs:
with: with:
name: wheels-windows-${{ matrix.target }} name: wheels-windows-${{ matrix.target }}
path: rust/kcl-python-bindings/dist path: rust/kcl-python-bindings/dist
macos: macos:
name: kcl-python-bindings (macos)
runs-on: macos-latest runs-on: macos-latest
strategy: strategy:
matrix: matrix:
@ -107,8 +110,8 @@ jobs:
with: with:
name: wheels-macos-${{ matrix.target }} name: wheels-macos-${{ matrix.target }}
path: rust/kcl-python-bindings/dist path: rust/kcl-python-bindings/dist
test: test:
name: kcl-python-bindings (test)
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -124,8 +127,8 @@ jobs:
env: env:
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
ZOO_HOST: https://api.dev.zoo.dev ZOO_HOST: https://api.dev.zoo.dev
sdist: sdist:
name: kcl-python-bindings (sdist)
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -133,10 +136,10 @@ jobs:
uses: astral-sh/setup-uv@v5 uses: astral-sh/setup-uv@v5
- name: Install codespell - name: Install codespell
run: | run: |
uv venv .venv uv venv .venv
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
echo "$PWD/.venv/bin" >> $GITHUB_PATH echo "$PWD/.venv/bin" >> $GITHUB_PATH
uv pip install pip --upgrade uv pip install pip --upgrade
- name: Build sdist - name: Build sdist
uses: PyO3/maturin-action@v1 uses: PyO3/maturin-action@v1
with: with:
@ -148,6 +151,7 @@ jobs:
with: with:
name: wheels-sdist name: wheels-sdist
path: rust/kcl-python-bindings/dist path: rust/kcl-python-bindings/dist
release: release:
name: Release name: Release
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -164,11 +168,11 @@ jobs:
uses: astral-sh/setup-uv@v5 uses: astral-sh/setup-uv@v5
- name: do uv things - name: do uv things
run: | run: |
cd rust/kcl-python-bindings cd rust/kcl-python-bindings
uv venv .venv uv venv .venv
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
echo "$PWD/.venv/bin" >> $GITHUB_PATH echo "$PWD/.venv/bin" >> $GITHUB_PATH
uv pip install pip --upgrade uv pip install pip --upgrade
- name: Publish to PyPI - name: Publish to PyPI
uses: PyO3/maturin-action@v1 uses: PyO3/maturin-action@v1
env: env:

View File

@ -1,3 +0,0 @@
[toolchain]
channel = "nightly"
components = ["rustfmt"]

View File

@ -31,42 +31,42 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-arm64-windows name: out-arm64-win
path: out path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }} run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-x64-windows name: out-x64-win
path: out path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }} run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-yml-windows name: out-yml-win
path: out path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }} run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-arm64-macos name: out-arm64-mac
path: out path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }} run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-x64-macos name: out-x64-mac
path: out path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }} run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: out-yml-macos name: out-yml-mac
path: out path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }} run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -28,7 +28,53 @@ jobs:
- run: npm run fmt:check - run: npm run fmt:check
npm-build-wasm: npm-build-wasm:
uses: ./.github/workflows/build-wasm.yml # Build the wasm blob once on the fastest runner.
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
with:
tool: wasm-pack
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: './rust'
- name: Build Wasm
shell: bash
run: npm run build:wasm
- uses: actions/upload-artifact@v4
with:
name: prepared-wasm
path: |
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
- uses: actions/upload-artifact@v4
with:
name: prepared-ts-rs-bindings
path: |
rust/kcl-lib/bindings/*
npm-tsc: npm-tsc:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -127,3 +173,122 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Run codespell - name: Run codespell
uses: crate-ci/typos@v1.32.0 uses: crate-ci/typos@v1.32.0
npm-unit-test-kcl-samples:
runs-on: ubuntu-latest
needs: npm-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
with:
tool: wasm-pack
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: npm run simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
- name: Install Chromium Browser
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: npm run playwright install chromium --with-deps
- name: Download internal KCL samples
run: git clone --depth=1 https://x-access-token:${{ secrets.GH_PAT_KCL_SAMPLES_INTERNAL }}@github.com/KittyCAD/kcl-samples-internal public/kcl-samples/internal
- name: Regenerate KCL samples manifest
run: cd rust/kcl-lib && EXPECTORATE=overwrite cargo test generate_manifest
- name: Check public and internal KCL samples
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: npm run test:unit:kcl-samples
env:
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
npm-unit-test:
runs-on: ubuntu-latest
needs: npm-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
with:
tool: wasm-pack
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: npm run simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
- name: Install Chromium Browser
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: npm run playwright install chromium --with-deps
- name: Run unit tests
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: xvfb-run -a npm run test:unit
env:
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
- name: Check for changes
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
id: git-check
run: |
git add src/lang/std/artifactMapGraphs
if git status src/lang/std/artifactMapGraphs | grep -q "Changes to be committed"
then echo "modified=true" >> $GITHUB_OUTPUT
else echo "modified=false" >> $GITHUB_OUTPUT
fi
- name: Commit changes, if any
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' && steps.git-check.outputs.modified == 'true' }}
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
git fetch origin
echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }}
# TODO when webkit works on ubuntu remove the os part of the commit message
git commit -am "Look at this (photo)Graph *in the voice of Nickelback*" || true
git push
git push origin ${{ github.head_ref }}

View File

@ -1,124 +0,0 @@
name: Unit Tests
on:
pull_request:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: write
pull-requests: write
actions: read
jobs:
npm-build-wasm:
uses: ./.github/workflows/build-wasm.yml
npm-test-unit:
runs-on: ubuntu-latest
needs: npm-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
with:
tool: wasm-pack
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: npm run simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
- name: Install Chromium Browser
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: npm run playwright install chromium --with-deps
- name: Run unit tests
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: xvfb-run -a npm run test:unit
env:
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
- name: Check for changes
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
id: git-check
run: |
git add src/lang/std/artifactMapGraphs
if git status src/lang/std/artifactMapGraphs | grep -q "Changes to be committed"
then echo "modified=true" >> $GITHUB_OUTPUT
else echo "modified=false" >> $GITHUB_OUTPUT
fi
- name: Commit changes, if any
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' && steps.git-check.outputs.modified == 'true' }}
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
git fetch origin
echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }}
# TODO when webkit works on ubuntu remove the os part of the commit message
git commit -am "Look at this (photo)Graph *in the voice of Nickelback*" || true
git push
git push origin ${{ github.head_ref }}
npm-test-unit-components:
runs-on: ubuntu-latest
needs: npm-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
with:
tool: wasm-pack
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- name: Run component tests
run: npm run test:unit:components

2
.gitignore vendored
View File

@ -58,8 +58,6 @@ trace.zip
/public/kcl-samples/.github /public/kcl-samples/.github
/public/kcl-samples/screenshots/main.kcl /public/kcl-samples/screenshots/main.kcl
/public/kcl-samples/step/main.kcl /public/kcl-samples/step/main.kcl
/public/kcl-samples/internal
/rust/kcl-lib/tests/kcl_samples/internal
/test-results/ /test-results/
/playwright-report/ /playwright-report/
/blob-report/ /blob-report/

View File

@ -1,6 +1,6 @@
# Contributor Guide # Contributor Guide
## Installing dependencies ## Running a development build
Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation). Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation).
@ -31,9 +31,7 @@ npm run install:rust:windows
npm run install:wasm-pack:cargo npm run install:wasm-pack:cargo
``` ```
## Building the app Then to build the WASM layer, run:
To build the WASM layer, run:
``` ```
# macOS/Linux # macOS/Linux
@ -76,7 +74,7 @@ enable third-party cookies. You can enable third-party cookies by clicking on
the eye with a slash through it in the URL bar, and clicking on "Enable the eye with a slash through it in the URL bar, and clicking on "Enable
Third-Party Cookies". Third-Party Cookies".
### Developing with Electron ## Desktop
To spin up the desktop app, `npm install` and `npm run build:wasm` need to have been done before hand then: To spin up the desktop app, `npm install` and `npm run build:wasm` need to have been done before hand then:
@ -90,7 +88,113 @@ Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (
To package the app for your platform with electron-builder, run `npm run tronb:package:dev` (or `npm run tronb:package:prod` to point to the .env.production variables). To package the app for your platform with electron-builder, run `npm run tronb:package:dev` (or `npm run tronb:package:prod` to point to the .env.production variables).
## Running tests ## Checking out commits / Bisecting
Which commands from setup are one off vs. need to be run every time?
The following will need to be run when checking out a new commit and guarantees the build is not stale:
```bash
npm install
npm run build:wasm
npm start
```
## Before submitting a PR
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
- `npm run fmt`
- `npm run tsc`
- `npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Release a new version
#### 1. Create a 'Cut release $VERSION' issue
It will be used to document changelog discussions and release testing.
https://github.com/KittyCAD/modeling-app/issues/new
#### 2. Push a new tag
Create a new tag and push it to the repo. The `semantic-release.sh` script will automatically bump the minor part, which we use the most. For instance going from `v0.27.0` to `v0.28.0`.
```
VERSION=$(./scripts/semantic-release.sh)
git tag $VERSION
git push origin --tags
```
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
#### 3. Manually test artifacts
##### Release builds
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
##### Updater-test builds
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
```
# Windows (PowerShell)
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
# macOS
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
# Linux
./Zoo Design Studio-{version}-{arch}-linux.AppImage
```
#### 4. Publish the release
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 5. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
## Fuzzing the parser
Make sure you install cargo fuzz:
```bash
$ cargo install cargo-fuzz
```
```bash
$ cd rust/kcl-lib
# list the fuzz targets
$ cargo fuzz list
# run the parser fuzzer
$ cargo +nightly fuzz run parser
```
For more information on fuzzing you can check out
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
## Tests
### Playwright tests ### Playwright tests
@ -100,7 +204,7 @@ Prepare these system dependencies:
#### Snapshot tests (Google Chrome on Ubuntu only) #### Snapshot tests (Google Chrome on Ubuntu only)
Only Ubuntu and Google Chrome is supported for the set of tests evaluating screenshot snapshots. Only Ubunu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
If you don't run Ubuntu locally or in a VM, you may use a GitHub Codespace. If you don't run Ubuntu locally or in a VM, you may use a GitHub Codespace.
``` ```
npm run playwright -- install chrome npm run playwright -- install chrome
@ -108,21 +212,14 @@ npm run test:snapshots
``` ```
You may use `-- --update-snapshots` as needed. You may use `-- --update-snapshots` as needed.
#### Desktop tests (Electron on all platforms) #### Electron flow tests (Chromium on Ubuntu, macOS, Windows)
``` ```
npm run playwright -- install chromium npm run playwright -- install chromium
npm run test:e2e:desktop:local npm run test:playwright:electron:local
``` ```
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file. You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
#### Web tests (Google Chrome on all platforms)
```
npm run test:e2e:web
```
#### Debugger #### Debugger
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying. However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
@ -208,86 +305,8 @@ then run tests that target the KCL language:
npm run test:rust npm run test:rust
``` ```
### Fuzzing the parser
Make sure you install cargo fuzz:
```bash
$ cargo install cargo-fuzz
```
```bash
$ cd rust/kcl-lib
# list the fuzz targets
$ cargo fuzz list
# run the parser fuzzer
$ cargo +nightly fuzz run parser
```
For more information on fuzzing you can check out
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
### Logging ### Logging
To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`. To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`.
To enable memory metrics, build with `--features dhat-heap`. To enable memory metrics, build with `--features dhat-heap`.
## Proposing changes
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
- `npm run fmt`
- `npm run tsc`
- `npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Shipping releases
#### 1. Create a 'Cut release $VERSION' issue
Use the **Release** issue template.
This will be used to facilitate changelog discussions and release testing.
https://github.com/KittyCAD/modeling-app/issues/new
#### 2. Push a new tag
Decide on a `v`-prefixed semver `VERSION` (e.g. `v1.2.3`) with the team and tag the repo on the latest main:
```
git tag $VERSION --message=""
git push origin $VERSION
```
This will trigger the `build-apps` workflow to set the version, build & sign the apps, and generate release files.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush).
#### 3. Manually test artifacts
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in step 2).
Assign someone to each section of the manual checklist generated by the issue template.
#### 4. Bump the KCL version
Follow the instructions [here](./rust/README.md) to publish new crates.
This ensures that the KCL accepted by the app is also accepted by the CLI.
#### 5. Publish the release
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the **Release title** field as well.
Click **Generate release notes** as a starting point to discuss the changelog in the issue. Once done, make sure **Set as the latest release** is checked, and click **Publish release**.
A new `publish-apps-release` workflow will start and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 6. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.

View File

@ -4,7 +4,7 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
## Windows ## Windows
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for Windows and for your processor type. 1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Windows and for your processor type.
2. Once downloaded, run the installer `Zoo Design Studio-{version}-{arch}-win.exe` which should take a few seconds. 2. Once downloaded, run the installer `Zoo Design Studio-{version}-{arch}-win.exe` which should take a few seconds.
@ -12,16 +12,16 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
## macOS ## macOS
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for macOS and for your processor type. 1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for macOS and for your processor type.
2. Once downloaded, open the disk image `Zoo Design Studio-{version}-{arch}-mac.dmg` and drag the applications to your `Applications` directory. 2. Once downloaded, open the disk image `Zoo Design Studio-{version}-{arch}-mac.dmg` and drag the applications to your `Applications` directory.
3. You can then open your `Applications` directory and double-click on `Zoo Design Studio` to open. 3. You can then open your `Applications` directory and double-click on `Zoo Design Studio` to open.
## Linux ## Linux
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for Linux and for your processor type. 1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Linux and for your processor type.
2. Install the dependencies needed to run the [AppImage format](https://appimage.org/). 2. Install the dependencies needed to run the [AppImage format](https://appimage.org/).
- On Ubuntu, install the FUSE library with these commands in a terminal. - On Ubuntu, install the FUSE library with these commands in a terminal.
@ -29,7 +29,7 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
sudo apt update sudo apt update
sudo apt install libfuse2 sudo apt install libfuse2
``` ```
- Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless. - Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless.
- Once installed, copy the downloaded `Zoo Design Studio-{version}-{arch}-linux.AppImage` to the directory of your choice, for instance `~/Applications`. - Once installed, copy the downloaded `Zoo Design Studio-{version}-{arch}-linux.AppImage` to the directory of your choice, for instance `~/Applications`.
- `appimaged` should automatically find it and make it executable. If not, run: - `appimaged` should automatically find it and make it executable. If not, run:

View File

@ -114,24 +114,26 @@ test-unit: install ## Run the unit tests
npm run test:unit:components npm run test:unit:components
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 ) @ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
npm run test:unit npm run test:unit
npm run test:unit:kcl-samples
.PHONY: test-e2e .PHONY: test-e2e
test-e2e: test-e2e-$(TARGET) test-e2e: test-e2e-$(TARGET)
.PHONY: test-e2e-web .PHONY: test-e2e-web
test-e2e-web: install build ## Run the web e2e tests test-e2e-web: install build ## Run the web e2e tests
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
ifdef E2E_GREP ifdef E2E_GREP
npm run test:e2e:web -- --headed --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES) npm run chrome:test -- --headed --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else else
npm run test:e2e:web -- --headed --workers='100%' npm run chrome:test -- --headed --workers='100%'
endif endif
.PHONY: test-e2e-desktop .PHONY: test-e2e-desktop
test-e2e-desktop: install build ## Run the desktop e2e tests test-e2e-desktop: install build ## Run the desktop e2e tests
ifdef E2E_GREP ifdef E2E_GREP
npm run test:e2e:desktop -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES) npm run test:playwright:electron -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else else
npm run test:e2e:desktop -- --workers='100%' npm run test:playwright:electron -- --workers='100%'
endif endif
############################################################################### ###############################################################################

View File

@ -2,7 +2,7 @@
# Zoo Design Studio # Zoo Design Studio
[zoo.dev/design-studio](https://zoo.dev/design-studio) [zoo.dev/modeling-app](https://zoo.dev/modeling-app)
A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev). A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev).
@ -34,14 +34,20 @@ The 3D view in Design Studio is just a video stream from our hosted geometry eng
- WebSockets (via [KittyCAD TS client](https://github.com/KittyCAD/kittycad.ts)) - WebSockets (via [KittyCAD TS client](https://github.com/KittyCAD/kittycad.ts))
- Code Editor - Code Editor
- [CodeMirror](https://codemirror.net/) - [CodeMirror](https://codemirror.net/)
- [Custom WASM LSP Server](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib/src/lsp/kcl) - Custom WASM LSP Server
- Modeling - Modeling
- [KittyCAD TypeScript client](https://github.com/KittyCAD/kittycad.ts) - [KittyCAD TypeScript client](https://github.com/KittyCAD/kittycad.ts)
## Get Started ## Get Started
We recommend downloading the latest application binary from our [website](https://zoo.dev/design-studio/download). If you don't see your platform or architecture supported there, please file an issue. See the [installation guide](INSTALL.md) for additional instructions. We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
If you'd like to try out upcoming changes sooner, you can also download those from our [nightly releases](https://zoo.dev/modeling-app/download/nightly) page.
## Developing ## Developing
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started. To contribute to the KittyCAD Language, see the dedicated [readme](rust/kcl-lib/README.md) for KCL. Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
## KCL
To contribute to the KittyCAD Language, see the [README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib) for KCL.

View File

@ -21,7 +21,7 @@ extend-exclude = [
] ]
[default.extend-words] [default.extend-words]
metalness = "metalness" # appearance API metalness = "metalness" # appearance API
Hom = "Hom" # short for homogenous Hom = "Hom" # short for homogenous
typ = "typ" # used to declare a variable named 'type' which is a reserved keyword in Rust typ = "typ" # used to declare a variable named 'type' which is a reserved keyword in Rust
ue = "ue" # short for UnaryExpression ue = "ue" # short for UnaryExpression
@ -29,7 +29,6 @@ THRE = "THRE" # Weird bug that wrongly detects THREEjs as a typo
nwo = "nwo" # don't know what this is about tbh nwo = "nwo" # don't know what this is about tbh
"ot" = "ot" # some abbreviation, idk what "ot" = "ot" # some abbreviation, idk what
"oe" = "oe" # some abbreviation, idk what "oe" = "oe" # some abbreviation, idk what
"colinear" = "colinear" # some engine shit, kidding
[default] [default]
extend-ignore-identifiers-re = [ extend-ignore-identifiers-re = [

View File

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 119 KiB

View File

Before

Width:  |  Height:  |  Size: 259 KiB

After

Width:  |  Height:  |  Size: 259 KiB

View File

@ -16,16 +16,15 @@ There are some useful functions for working with arrays in the standard library,
Arrays have their own types: `[T]` where `T` is the type of the elements of the array, for example, `[string]` means an array of `string`s and `[any]` means an array of any values. Arrays have their own types: `[T]` where `T` is the type of the elements of the array, for example, `[string]` means an array of `string`s and `[any]` means an array of any values.
Array types can also include length information: `[T; n]` denotes an array of length `n` (where `n` is a number literal) and `[T; n+]` denotes an array whose length is at least `n`. The common case for that is `[T; 1+]`, i.e., a non-empty array. E.g., `[string; 1+]` and `[number(mm); 3]` are valid array types. Array types can also include length information: `[T; n]` denotes an array of length `n` (where `n` is a number literal) and `[T; 1+]` denotes an array whose length is at least one (i.e., a non-empty array). E.g., `[string; 1+]` and `[number(mm); 3]` are valid array types.
## Ranges ## Ranges
Ranges are a succinct way to create an array of sequential numbers. The syntax is `[start .. end]` where `start` and `end` evaluate to whole numbers (integers). Ranges are inclusive of the start and end. The end must be greater than the start. A range which is exclusive of its end is written with `<end`. Examples: Ranges are a succinct way to create an array of sequential numbers. The syntax is `[start .. end]` where `start` and `end` evaluate to whole numbers (integers). Ranges are inclusive of the start and end. The end must be greater than the start. Examples:
```kcl,norun ```kcl,norun
[0..3] // [0, 1, 2, 3] [0..3] // [0, 1, 2, 3]
[3..10] // [3, 4, 5, 6, 7, 8, 9, 10] [3..10] // [3, 4, 5, 6, 7, 8, 9, 10]
[3..<10] // [3, 4, 5, 6, 7, 8, 9]
x = 2 x = 2
[x..x+1] // [2, 3] [x..x+1] // [2, 3]
``` ```

View File

@ -4,7 +4,7 @@ excerpt: "Documentation of the KCL language for the Zoo Design Studio."
layout: manual layout: manual
--- ---
This is a reference for KCL. If you are learning KCL, you may prefer the [guide](https://zoo.dev/docs/kcl-book/intro.html) which explains This is a reference for KCL. If you are learning KCL, you may prefer the [guide]() which explains
things in a more tutorial fashion. See also our documentation of the [standard library](/docs/kcl-std). things in a more tutorial fashion. See also our documentation of the [standard library](/docs/kcl-std).
## Topics ## Topics

View File

@ -27,6 +27,9 @@ import increment from "util.kcl"
answer = increment(41) answer = increment(41)
``` ```
Imported files _must_ be in the same project so that units are uniform across
modules. This means that it must be in the same directory.
Import statements must be at the top-level of a file. It is not allowed to have Import statements must be at the top-level of a file. It is not allowed to have
an `import` statement inside a function or in the body of an ifelse. an `import` statement inside a function or in the body of an ifelse.
@ -55,9 +58,6 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
import increment as inc, decrement as dec from "util.kcl" import increment as inc, decrement as dec from "util.kcl"
``` ```
You can import files from the current directory or from subdirectories, but if importing from a
subdirectory you can only import `main.kcl`.
--- ---
## Functions vs `clone` ## Functions vs `clone`
@ -177,7 +177,7 @@ You can also import the whole module. This is useful if you want to use the
result of a module as a variable, like a part. result of a module as a variable, like a part.
```norun ```norun
import "cube.kcl" import "tests/inputs/cube.kcl" as cube
cube cube
|> translate(x=10) |> translate(x=10)
``` ```
@ -229,19 +229,6 @@ The final statement is what's important because it's the return value of the
entire module. The module is expected to return a single object that can be used entire module. The module is expected to return a single object that can be used
as a variable by the file that imports it. as a variable by the file that imports it.
The name of the file or subdirectory is used as the name of the variable within the importing program.
If you want to use a different name, you can do so by using the `as` keyword:
```kcl,norun
import "cube.kcl" // Introduces a new variable called `cube`.
import "cube.kcl" as block // Introduces a new variable called `block`.
import "cube/main.kcl" // Introduces a new variable called `cube`.
import "cube/main.kcl" as block // Introduces a new variable called `block`.
```
If the filename includes hyphens (`-`) or starts with an underscore (`_`), then you must specify a
variable name.
--- ---
## Multiple instances of the same import ## Multiple instances of the same import
@ -254,7 +241,7 @@ If you want to have multiple instances of the same object, you can use the
[`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory. [`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory.
```norun ```norun
import cube from "cube.kcl" import cube from "tests/inputs/cube.kcl"
cube cube
|> translate(x=10) |> translate(x=10)
@ -270,7 +257,7 @@ separate objects in memory, and can be manipulated independently.
Here is an example with a file from another CAD system: Here is an example with a file from another CAD system:
```kcl ```kcl
import "tests/inputs/cube.step" import "tests/inputs/cube.step" as cube
cube cube
|> translate(x=10) |> translate(x=10)

View File

@ -46,7 +46,3 @@ KCL has no support for area, volume, or other higher dimension units. When inter
## Explicit conversions ## Explicit conversions
You might sometimes need to convert from one unit to another for some calculation. You can do this implicitly when calling a function (see above), but if you can't or don't want to, then you can use the explicit conversion functions in the [`std::units`](/docs/kcl-std/modules/std-units) module. You might sometimes need to convert from one unit to another for some calculation. You can do this implicitly when calling a function (see above), but if you can't or don't want to, then you can use the explicit conversion functions in the [`std::units`](/docs/kcl-std/modules/std-units) module.
KCL cannot know about changes to units caused by arithmetic. For example, you may intend for `10in * 25.4` to be the value `254mm` (i.e., `10in` in mm), however, the result of that computation in KCL is `254in`. It is always better to rely on automatic conversion or to use the explicit conversion functions, where possible.
Converting between degrees and radians using π ([`PI`](/docs/kcl-std/consts/std-math-PI) in KCL) is especially prone to this error and so the `PI` constant always requires specifying units of any computation it is used with. E.g., `radius = (circumference / (2 * PI)): number(mm)`.

View File

@ -4,6 +4,8 @@ excerpt: "Project specific settings for the app. These live in `project.toml` in
layout: manual layout: manual
--- ---
# Project Settings
Project specific settings for the app. These live in `project.toml` in the base of the project directory. Updating the settings for the project in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file. Project specific settings for the app. These live in `project.toml` in the base of the project directory. Updating the settings for the project in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file.
## Project Configuration Structure ## Project Configuration Structure
@ -182,4 +184,4 @@ color = 240.0
# Use inches as the default measurement unit # Use inches as the default measurement unit
base_unit = "in" base_unit = "in"
``` ```

View File

@ -4,6 +4,8 @@ excerpt: "User specific settings for the app. These live in `user.toml` in the a
layout: manual layout: manual
--- ---
# User Settings
User specific settings for the app. These live in `user.toml` in the app's configuration directory. Updating the settings in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file. User specific settings for the app. These live in `user.toml` in the app's configuration directory. Updating the settings in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file.
## User Configuration Structure ## User Configuration Structure
@ -232,4 +234,4 @@ base_unit = "mm"
# Disable text wrapping in the editor # Disable text wrapping in the editor
text_wrapping = false text_wrapping = false
``` ```

View File

@ -44,7 +44,7 @@ detail on importing geometry.
Tags are used to give a name (tag) to a specific path. Tags are used to give a name (tag) to a specific path.
### Tag declarations - `TagDecl` ### `TagDeclarator`
The syntax for declaring a tag is `$myTag` you would use it in the following The syntax for declaring a tag is `$myTag` you would use it in the following
way: way:
@ -67,28 +67,24 @@ startSketchOn(XZ)
|> close() |> close()
``` ```
When a function requires declaring a new tag (using the `$` syntax), the argument has type [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl). ### `TagIdentifier`
### Tag identifiers As per the example above you can use the tag identifier to get a reference to the
tagged object. The syntax for this is `myTag`.
A tag created using a tag declarator can be used by writing its name without the `$`, e.g., `myTag`. In the example above we use the tag identifier to get the angle of the segment
Where necessary to disambiguate from tag declarations, we call these tag identifiers. `segAng(rectangleSegmentA001)`.
In the example above we use the tag identifier `rectangleSegmentA001` to get the angle of the segment ### `Start`
using `segAng(rectangleSegmentA001)`.
Tags can identify either an edge or face of a solid, or a line or other edge of a sketch. Functions There is a special tag, `START` (with type `Start`, although under the cover, it's a string)
which take a tag identifier as an argument will use either [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) (for the edge of a for identifying the face of a solid which was the start of an extrusion (i.e., the surface which
solid or sketch) or [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace). is extruded).
If a line in a sketch is tagged and then the sketch is extruded, the tag is a `TaggedEdge` before ### `End`
extrusion and a `TaggedFace` after extrusion.
#### `START` and `END`
[`START`](/docs/kcl-std/consts/std-START) and [`END`](/docs/kcl-std/consts/std-END) are special tags
for identifying the starting and ending faces of an extruded solid.
There is a special tag, `END` (with type `End`, although under the cover, it's a string)
for identifying the face of a solid which was finishes an extrusion.
### Tag Scope ### Tag Scope

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

64
docs/kcl-std/assert.md Normal file

File diff suppressed because one or more lines are too long

40
docs/kcl-std/assertIs.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

33
docs/kcl-std/consts.md Normal file
View File

@ -0,0 +1,33 @@
---
title: "KCL Constants"
excerpt: "Documentation for the KCL constants."
layout: manual
---
## Table of Contents
### `std`
- [`END`](/docs/kcl/consts/std-END)
- [`START`](/docs/kcl/consts/std-START)
- [`X`](/docs/kcl/consts/std-X)
- [`XY`](/docs/kcl/consts/std-XY)
- [`XZ`](/docs/kcl/consts/std-XZ)
- [`Y`](/docs/kcl/consts/std-Y)
- [`YZ`](/docs/kcl/consts/std-YZ)
- [`Z`](/docs/kcl/consts/std-Z)
### `std::math`
- [`E`](/docs/kcl/consts/std-math-E)
- [`PI`](/docs/kcl/consts/std-math-PI)
- [`TAU`](/docs/kcl/consts/std-math-TAU)
### `std::turns`
- [`HALF_TURN`](/docs/kcl/consts/std-turns-HALF_TURN)
- [`QUARTER_TURN`](/docs/kcl/consts/std-turns-QUARTER_TURN)
- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-turns-THREE_QUARTER_TURN)
- [`ZERO`](/docs/kcl/consts/std-turns-ZERO)

View File

@ -8,13 +8,9 @@ layout: manual
Identifies the ending face of an extrusion. I.e., the new face created by an extrusion. Identifies the ending face of an extrusion. I.e., the new face created by an extrusion.
```kcl ```kcl
END: TaggedFace END: string = 'end'
``` ```
### Type
[`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace) - A tag which references a face of a solid, including the distinguished tags `START` and `END`.

View File

@ -8,13 +8,9 @@ layout: manual
Identifies the starting face of an extrusion. I.e., the face which is extruded. Identifies the starting face of an extrusion. I.e., the face which is extruded.
```kcl ```kcl
START: TaggedFace START: string = 'start'
``` ```
### Type
[`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace) - A tag which references a face of a solid, including the distinguished tags `START` and `END`.

View File

@ -8,13 +8,9 @@ layout: manual
The X-axis (can be used in both 2d and 3d contexts). The X-axis (can be used in both 2d and 3d contexts).
```kcl ```kcl
X: Axis3d X
``` ```
### Type
[`Axis3d`](/docs/kcl-std/types/std-types-Axis3d) - An abstract and infinite line in 3d space.

View File

@ -8,13 +8,9 @@ layout: manual
An abstract 3d plane aligned with the X and Y axes. Its normal is the positive Z axis. An abstract 3d plane aligned with the X and Y axes. Its normal is the positive Z axis.
```kcl ```kcl
XY: Plane XY
``` ```
### Type
[`Plane`](/docs/kcl-std/types/std-types-Plane) - An abstract plane.

View File

@ -8,13 +8,9 @@ layout: manual
An abstract 3d plane aligned with the X and Z axes. Its normal is the negative Y axis. An abstract 3d plane aligned with the X and Z axes. Its normal is the negative Y axis.
```kcl ```kcl
XZ: Plane XZ
``` ```
### Type
[`Plane`](/docs/kcl-std/types/std-types-Plane) - An abstract plane.

View File

@ -8,13 +8,9 @@ layout: manual
The Y-axis (can be used in both 2d and 3d contexts). The Y-axis (can be used in both 2d and 3d contexts).
```kcl ```kcl
Y: Axis3d Y
``` ```
### Type
[`Axis3d`](/docs/kcl-std/types/std-types-Axis3d) - An abstract and infinite line in 3d space.

View File

@ -8,13 +8,9 @@ layout: manual
An abstract 3d plane aligned with the Y and Z axes. Its normal is the positive X axis. An abstract 3d plane aligned with the Y and Z axes. Its normal is the positive X axis.
```kcl ```kcl
YZ: Plane YZ
``` ```
### Type
[`Plane`](/docs/kcl-std/types/std-types-Plane) - An abstract plane.

View File

@ -8,13 +8,9 @@ layout: manual
The 3D Z-axis. The 3D Z-axis.
```kcl ```kcl
Z: Axis3d Z
``` ```
### Type
[`Axis3d`](/docs/kcl-std/types/std-types-Axis3d) - An abstract and infinite line in 3d space.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,20 +0,0 @@
---
title: "sweep::SKETCH_PLANE"
subtitle: "Constant in std::sweep"
excerpt: "Local/relative to a position centered within the plane being sketched on"
layout: manual
---
Local/relative to a position centered within the plane being sketched on
```kcl
sweep::SKETCH_PLANE: string = 'sketchPlane'
```
### Type
[`string`](/docs/kcl-std/types/std-types-string) - A sequence of characters

View File

@ -1,20 +0,0 @@
---
title: "sweep::TRAJECTORY"
subtitle: "Constant in std::sweep"
excerpt: "Local/relative to the trajectory curve"
layout: manual
---
Local/relative to the trajectory curve
```kcl
sweep::TRAJECTORY: string = 'trajectoryCurve'
```
### Type
[`string`](/docs/kcl-std/types/std-types-string) - A sequence of characters

View File

@ -13,8 +13,4 @@ turns::HALF_TURN: number(deg) = 180deg
### Type
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.

View File

@ -13,8 +13,4 @@ turns::QUARTER_TURN: number(deg) = 90deg
### Type
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.

View File

@ -13,8 +13,4 @@ turns::THREE_QUARTER_TURN: number(deg) = 270deg
### Type
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.

View File

@ -8,13 +8,9 @@ layout: manual
No turn, zero degrees/radians. No turn, zero degrees/radians.
```kcl ```kcl
turns::ZERO: number(Angle) turns::ZERO: number = 0
``` ```
### Type
[`number(Angle)`](/docs/kcl-std/types/std-types-number) - A number.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,60 +0,0 @@
---
title: "assert"
subtitle: "Function in std"
excerpt: "Check a value meets some expected conditions at runtime. Program terminates with an error if conditions aren't met. If you provide multiple conditions, they will all be checked and all must be met."
layout: manual
---
Check a value meets some expected conditions at runtime. Program terminates with an error if conditions aren't met. If you provide multiple conditions, they will all be checked and all must be met.
```kcl
assert(
@actual: number,
isGreaterThan?: number,
isLessThan?: number,
isGreaterThanOrEqual?: number,
isLessThanOrEqual?: number,
isEqualTo?: number,
tolerance?: number,
error?: string,
)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `actual` | [`number`](/docs/kcl-std/types/std-types-number) | Value to check. If this is the boolean value true, assert passes. Otherwise it fails.. | Yes |
| `isGreaterThan` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is greater than this. | No |
| `isLessThan` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than this. | No |
| `isGreaterThanOrEqual` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is greater than or equal to this. | No |
| `isLessThanOrEqual` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than or equal to this. | No |
| `isEqualTo` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than or equal to this. | No |
| `tolerance` | [`number`](/docs/kcl-std/types/std-types-number) | If `isEqualTo` is used, this is the tolerance to allow for the comparison. This tolerance is used because KCL's number system has some floating-point imprecision when used with very large decimal places. | No |
| `error` | [`string`](/docs/kcl-std/types/std-types-string) | If the value was false, the program will terminate with this error message | No |
### Examples
```kcl
n = 10
assert(n, isEqualTo = 10)
assert(
n,
isGreaterThanOrEqual = 0,
isLessThan = 100,
error = "number should be between 0 and 100",
)
assert(
1.0000000000012,
isEqualTo = 1,
tolerance = 0.0001,
error = "number should be almost exactly 1",
)
```

View File

@ -1,36 +0,0 @@
---
title: "assertIs"
subtitle: "Function in std"
excerpt: "Asserts that a value is the boolean value true."
layout: manual
---
Asserts that a value is the boolean value true.
```kcl
assertIs(
@actual: bool,
error?: string,
)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `actual` | [`bool`](/docs/kcl-std/types/std-types-bool) | Value to check. If this is the boolean value true, assert passes. Otherwise it fails.. | Yes |
| `error` | [`string`](/docs/kcl-std/types/std-types-string) | If the value was false, the program will terminate with this error message | No |
### Examples
```kcl
kclIsFun = true
assertIs(kclIsFun)
```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,12 +29,14 @@ Consider using `atan2()` instead for the true inverse of tangent.
```kcl ```kcl
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0]) |> startProfile(at = [0, 0])
|> angledLine(angle = atan(1.25), length = 20) |> angledLine(
angle = atan(1.25),
length = 20,
)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()
extrude001 = extrude(sketch001, length = 5) extrude001 = extrude(sketch001, length = 5)
``` ```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,7 +32,6 @@ legAngX(
```kcl ```kcl
legAngX(hypotenuse = 5, leg = 3) legAngX(hypotenuse = 5, leg = 3)
``` ```

View File

@ -32,7 +32,6 @@ legAngY(
```kcl ```kcl
legAngY(hypotenuse = 5, leg = 3) legAngY(hypotenuse = 5, leg = 3)
``` ```

View File

@ -11,7 +11,7 @@ Compute the length of the given leg.
legLen( legLen(
hypotenuse: number(Length), hypotenuse: number(Length),
leg: number(Length), leg: number(Length),
): number(Length) ): number(deg)
``` ```
@ -25,14 +25,13 @@ legLen(
### Returns ### Returns
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number. [`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples ### Examples
```kcl ```kcl
legLen(hypotenuse = 5, leg = 3) legLen(hypotenuse = 5, leg = 3)
``` ```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More