Compare commits

..

4 Commits

537 changed files with 171809 additions and 56837 deletions

View File

@ -1,20 +1,21 @@
name: build-apps
name: build-publish-apps
on:
pull_request:
push:
branches:
- main
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
release:
types: [published]
schedule:
- cron: '0 4 * * *'
# Daily at 04:00 AM UTC
# Will checkout the last commit from the default branch (main as of 2023-10-04)
env:
IS_RELEASE: ${{ github.ref_type == 'tag' }}
IS_NIGHTLY: ${{ github.event_name == 'schedule' }}
CUT_RELEASE_PR: ${{ github.event_name == 'pull_request' && (contains(github.event.pull_request.title, 'Cut release v')) }}
BUILD_RELEASE: ${{ github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'pull_request' && (contains(github.event.pull_request.title, 'Cut release v')) }}
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Non-release build, commit {0}', github.sha) }}
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
@ -25,7 +26,6 @@ jobs:
runs-on: ubuntu-22.04 # seperate job on Ubuntu for easy string manipulations (compared to Windows)
outputs:
version: ${{ steps.export_version.outputs.version }}
notes: ${{ steps.export_notes.outputs.notes }}
steps:
- uses: actions/checkout@v4
@ -47,40 +47,48 @@ jobs:
- name: Run build:wasm
run: "yarn build:wasm"
- name: Set nightly version, product name, release notes, and icons
if: ${{ env.IS_NIGHTLY == 'true' }}
run: yarn files:flip-to-nightly
- name: Set release version
if: ${{ env.IS_RELEASE == 'true' }}
- name: Set nightly version
if: github.event_name == 'schedule'
run: |
export VERSION=${GITHUB_REF_NAME#v}
yarn files:set-version
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
- uses: actions/upload-artifact@v4
# TODO: see if we need to inject updater nightly URL here https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json
- name: Generate release notes
run: |
echo "$NOTES" > release-notes.md
cat release-notes.md
- uses: actions/upload-artifact@v3
with:
name: prepared-files
path: |
package.json
electron-builder.yml
src/wasm-lib/pkg/wasm_lib*
release-notes.md
assets/icon.ico
assets/icon.png
- id: export_version
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
- id: export_notes
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
- name: Prepare electron-builder.yml file for nightly
if: ${{ github.event_name == 'schedule' }}
run: |
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/nightly"' electron-builder.yml
- uses: actions/upload-artifact@v3
if: ${{ github.event_name == 'schedule' }}
with:
name: prepared-files-nightly
path: |
electron-builder.yml
- name: Prepare electron-builder.yml file for updater test
if: ${{ env.IS_RELEASE == 'true' }}
if: ${{ env.CUT_RELEASE_PR == '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' }}
- uses: actions/upload-artifact@v3
if: ${{ env.CUT_RELEASE_PR == 'true' }}
with:
name: prepared-files-updater-test
path: |
@ -101,24 +109,32 @@ jobs:
platform: linux
runs-on: ${{ matrix.os }}
env:
VERSION: ${{ github.event_name == 'schedule' && needs.prepare-files.outputs.version || format('v{0}', needs.prepare-files.outputs.version) }}
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
name: prepared-files
- name: Copy prepared files
run: |
ls -R prepared-files
cp prepared-files/package.json package.json
cp prepared-files/electron-builder.yml electron-builder.yml
cp prepared-files/src/wasm-lib/pkg/wasm_lib_bg.wasm public
mkdir src/wasm-lib/pkg
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
cp prepared-files/release-notes.md release-notes.md
cp prepared-files/assets/icon.ico assets/icon.ico
cp prepared-files/assets/icon.png assets/icon.png
- uses: actions/download-artifact@v3
if: ${{ github.event_name == 'schedule' }}
name: prepared-files-nightly
- name: Copy updated electron-builder.yml file for nightly build
if: ${{ github.event_name == 'schedule' }}
run: |
ls -R prepared-files-nightly
cp prepared-files-nightly/electron-builder.yml electron-builder.yml
- name: Sync node version and setup cache
uses: actions/setup-node@v4
@ -131,7 +147,7 @@ jobs:
- run: yarn tronb:vite
- name: Prepare certificate and variables (Windows only)
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'windows-2022' }}
run: |
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
cat /d/Certificate_pkcs12.p12
@ -146,7 +162,7 @@ jobs:
shell: bash
- name: Setup certicate with SSM KSP (Windows only)
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'windows-2022' }}
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
msiexec /i smtools-windows-x64.msi /quiet /qn
@ -157,13 +173,13 @@ jobs:
shell: cmd
- name: Build the app (debug)
if: ${{ env.IS_RELEASE == 'false' && env.IS_NIGHTLY == 'false' }}
if: ${{ env.BUILD_RELEASE == 'false' }}
# electron-builder doesn't have a concept of release vs debug,
# this is just not doing any codesign or release yml generation
run: yarn electron-builder --config
- name: Build the app (release)
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
if: ${{ env.BUILD_RELEASE == 'true' }}
env:
PUBLISH_FOR_PULL_REQUEST: true
APPLE_ID: ${{ secrets.APPLE_ID }}
@ -180,7 +196,7 @@ jobs:
- name: List artifacts in out/
run: ls -R out
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: out-arm64-${{ matrix.platform }}
# first two will pick both Zoo Modeling App-$VERSION-arm64-win.exe and Zoo Modeling App-$VERSION-win.exe
@ -190,7 +206,7 @@ jobs:
out/*-arm64-mac.*
out/*-arm64-linux.*
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: out-x64-${{ matrix.platform }}
path: |
@ -198,29 +214,27 @@ jobs:
out/*-x64-mac.*
out/*-x86_64-linux.*
- uses: actions/upload-artifact@v4
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
- uses: actions/upload-artifact@v3
if: ${{ env.BUILD_RELEASE == 'true' }}
with:
name: out-yml-${{ matrix.platform }}
name: out-yml
path: |
out/latest*.yml
# 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' }}
- uses: actions/download-artifact@v3
if: ${{ env.CUT_RELEASE_PR == 'true' }}
name: prepared-files-updater-test
- name: Copy updated electron-builder.yml file for updater test
if: ${{ env.IS_RELEASE == 'true' }}
if: ${{ env.CUT_RELEASE_PR == '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' }}
if: ${{ env.CUT_RELEASE_PR == 'true' }}
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
@ -233,8 +247,8 @@ jobs:
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
run: yarn electron-builder --config --publish always
- uses: actions/upload-artifact@v4
if: ${{ env.IS_RELEASE == 'true' }}
- uses: actions/upload-artifact@v3
if: ${{ env.CUT_RELEASE_PR == 'true' }}
with:
name: updater-test-arm64-${{ matrix.platform }}
path: |
@ -242,8 +256,8 @@ jobs:
out/*-arm64-mac.dmg
out/*-arm64-linux.AppImage
- uses: actions/upload-artifact@v4
if: ${{ env.IS_RELEASE == 'true' }}
- uses: actions/upload-artifact@v3
if: ${{ env.CUT_RELEASE_PR == 'true' }}
with:
name: updater-test-x64-${{ matrix.platform }}
path: |
@ -252,69 +266,58 @@ jobs:
out/*-x86_64-linux.AppImage
upload-apps-release:
publish-apps-release:
runs-on: ubuntu-22.04
permissions:
contents: write
if: ${{ github.ref_type == 'tag' || github.event_name == 'schedule' }}
if: ${{ github.event_name == 'release' || github.event_name == 'schedule' }}
needs: [prepare-files, build-apps]
env:
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
VERSION: ${{ format('v{0}', needs.prepare-files.outputs.version) }}
needs: [prepare-files, build-apps]
VERSION: ${{ github.event_name == 'schedule' && needs.prepare-files.outputs.version || format('v{0}', needs.prepare-files.outputs.version) }}
PUB_DATE: ${{ github.event_name == 'release' && github.event.release.created_at || github.event.repository.updated_at }}
BUCKET_DIR: ${{ github.event_name == 'schedule' && 'dl.kittycad.io/releases/modeling-app/nightly' || 'dl.kittycad.io/releases/modeling-app' }}
WEBSITE_DIR: ${{ github.event_name == 'schedule' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: out-arm64-win
path: out
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: out-x64-win
path: out
- uses: actions/download-artifact@v4
with:
name: out-yml-win
path: out
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: out-arm64-mac
path: out
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: out-x64-mac
path: out
- uses: actions/download-artifact@v4
with:
name: out-yml-mac
path: out
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: out-arm64-linux
path: out
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: out-x64-linux
path: out
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: out-yml-linux
name: out-yml
path: out
- name: Generate the download static endpoint
env:
NOTES: ${{ needs.prepare-files.outputs.notes }}
PUB_DATE: ${{ github.event.repository.updated_at }}
WEBSITE_DIR: ${{ github.event_name == 'schedule' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
run: |
RELEASE_DIR=https://${WEBSITE_DIR}
jq --null-input \
@ -351,44 +354,78 @@ jobs:
"url": $linux_x64_url
}
}
}' > out/last_download.json
cat out/last_download.json
- uses: actions/upload-artifact@v4
with:
name: out-download-json
path: out/last_download.json
}' > last_download.json
cat last_download.json
- name: List artifacts
run: "ls -R out"
- name: Authenticate to Google Cloud
if: ${{ env.IS_NIGHTLY == 'true' }}
uses: 'google-github-actions/auth@v2.1.7'
with:
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
- name: Set up Google Cloud SDK
if: ${{ env.IS_NIGHTLY == 'true' }}
uses: google-github-actions/setup-gcloud@v2.1.2
with:
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
- name: Upload nightly files to public bucket
if: ${{ env.IS_NIGHTLY == 'true' }}
- name: Upload release files to public bucket
uses: google-github-actions/upload-cloud-storage@v2.2.1
with:
path: out
glob: '*'
glob: 'Zoo*'
parent: false
destination: 'dl.kittycad.io/releases/modeling-app/nightly'
destination: ${{ env.BUCKET_DIR }}
- name: Create draft release
uses: softprops/action-gh-release@v2
if: ${{ env.IS_RELEASE == 'true' }}
- name: Upload update endpoint to public bucket
uses: google-github-actions/upload-cloud-storage@v2.2.1
with:
path: out
glob: 'latest*'
parent: false
destination: ${{ env.BUCKET_DIR }}
- name: Upload download endpoint to public bucket
uses: google-github-actions/upload-cloud-storage@v2.2.1
with:
path: last_download.json
destination: ${{ env.BUCKET_DIR }}
- name: Upload release files to Github
if: ${{ github.event_name == 'release' }}
uses: softprops/action-gh-release@v2
with:
name: ${{ env.VERSION }}
tag_name: ${{ env.VERSION }}
draft: true
generate_release_notes: true
files: 'out/Zoo*'
- name: Invalidate bucket cache on latest*.yml and last_download.json files
run: |
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/last_download.json" --async
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-linux-arm64.yml" --async
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-mac.yml" --async
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest.yml" --async
announce_release:
needs: [publish-apps-release]
runs-on: ubuntu-22.04
if: github.event_name == 'release'
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: Announce Release
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
RELEASE_VERSION: ${{ github.event.release.tag_name }}
RELEASE_BODY: ${{ github.event.release.body}}
run: python public/announce_release.py

37
.github/workflows/create-release.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: Create Release
on:
push:
branches:
- main
jobs:
create-release:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read
if: contains(github.event.head_commit.message, 'Cut release v')
steps:
- uses: actions/github-script@v7
name: Read Cut release PR info and create release
with:
script: |
const { owner, repo } = context.repo
const pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner,
repo,
commit_sha: context.sha,
})
const { title, body } = pulls.data[0]
const version = title.split('Cut release ')[1]
const result = await github.rest.repos.createRelease({
owner,
repo,
body,
tag_name: version,
name: version,
draft: true,
})
console.log(result)

View File

@ -1,158 +0,0 @@
name: publish-apps-release
on:
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
publish-apps-release:
runs-on: ubuntu-22.04
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Find tag workflow id
id: tag_workflow_id
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
id=$(gh run ls --repo kittycad/modeling-app -w build-apps.yml --branch ${{ github.event.release.tag_name }} --json databaseId | jq '.[0].databaseId')
echo "id=$id" >> "$GITHUB_OUTPUT"
- uses: actions/download-artifact@v4
with:
name: out-arm64-win
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-x64-win
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-yml-win
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-arm64-mac
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-x64-mac
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-yml-mac
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-arm64-linux
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-x64-linux
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-yml-linux
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: out-download-json
path: out
run-id: ${{ steps.tag_workflow_id.outputs.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: List artifacts
run: ls -R out
- name: Override release notes
env:
NOTES: ${{ github.event.release.body }}
run: yarn files:set-notes
- name: Authenticate to Google Cloud
uses: 'google-github-actions/auth@v2.1.7'
with:
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
- name: Set up Google Cloud SDK
uses: google-github-actions/setup-gcloud@v2.1.2
with:
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
- name: Upload release files to public bucket
uses: google-github-actions/upload-cloud-storage@v2.2.1
with:
path: out
glob: '*'
parent: false
destination: 'dl.kittycad.io/releases/modeling-app'
- name: Invalidate bucket cache on latest*.yml and last_download.json files
run: |
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/last_download.json" --async
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-linux-arm64.yml" --async
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-mac.yml" --async
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest.yml" --async
announce_release:
needs: [publish-apps-release]
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: Announce Release
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
RELEASE_VERSION: ${{ github.event.release.tag_name }}
RELEASE_BODY: ${{ github.event.release.body }}
run: python public/announce_release.py

View File

@ -128,39 +128,45 @@ Before you submit a contribution PR to this repo, please ensure that:
## Release a new version
#### 1. Create a 'Cut release $VERSION' issue
#### 1. Bump the versions by running `./make-release.sh`
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 (eg. `v0.28.0` for `$VERSION`)
The `./make-release.sh` script has git commands to pull main but to be sure you can run the following git commands to have a fresh `main` locally.
```
VERSION=$(./scripts/semantic-release.sh)
git tag $VERSION
git push origin --tags
git branch -D main
git checkout main
git pull origin
./make-release.sh
# Copy within the back ticks and paste the stdout of the change log
git push --set-upstream origin <branch name created from ./make-release.sh>
```
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
That will create the branch with the updated json files for you:
- run `./make-release.sh` or `./make-release.sh patch` for a patch update;
- run `./make-release.sh minor` for minor; or
- run `./make-release.sh major` for major.
Once the workflow succeeds, a draft release will be created at https://github.com/KittyCAD/modeling-app/releases.
After it runs you should just need the push the branch and open a PR.
#### 2. Create a Cut Release PR
When you open the PR copy the change log from the output of the `./make-release.sh` script into the description of the PR.
**Important:** Pull request title needs to be prefixed with `Cut release v` to build in release mode and a few other things to test in the best context possible, the intent would be for instance to have `Cut release v1.2.3` for the `v1.2.3` release candidate.
The PR may then serve as a place to discuss the human-readable changelog and extra QA. The `make-release.sh` tool suggests a changelog for you too to be used as PR description, just make sure to delete lines that are not user facing.
#### 3. Manually test artifacts from the Cut Release PR
##### 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.).
The release builds can be found under the `out-{platform}` zip, at the very bottom of the `build-publish-apps` summary page for each commit on this branch.
Alternatively, the draft release will also include these builds.
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.
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the Cut Release PR.
##### 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 other `build-publish-apps` output in Cut Release PRs is `updater-test-{platform}`. As we don't have a way to test this fully automatically, we have 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.
@ -176,15 +182,18 @@ If the prompt doesn't show up, start the app in command line to grab the electro
./Zoo Modeling App-{version}-{arch}-linux.AppImage
```
#### 4. Publish the release
#### 4. Merge the Cut Release PR
Head over to https://github.com/KittyCAD/modeling-app/releases, paste in the changelog discussed in the issue, and publish the draft release created by the `build-apps` workflow from step 2.
This will kick the `create-release` action, that creates a _Draft_ release out of this Cut Release PR merge after less than a minute, with the new version as title and Cut Release PR as description.
A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions, which can be found under `release` event filter. On success, the files will be uploaded to the public bucket and the announcement on Discord will be sent.
#### 5. Close the issue
#### 5. Publish the release
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
Head over to https://github.com/KittyCAD/modeling-app/releases, the draft release corresponding to the merged Cut Release PR should show up at the top as _Draft_. Click on it, verify the content, and hit _Publish_.
#### 6. Profit
A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions, which can be found under `release` event filter.
## Fuzzing the parser

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

BIN
assets/icon.icns Normal file

Binary file not shown.

BIN
assets/icon@2x.icns Normal file

Binary file not shown.

View File

@ -36,9 +36,9 @@ myAngle = -120
sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([8, 0], %)
|> angledLine({ angle = abs(myAngle), length = 5 }, %)
|> angledLine({ angle: abs(myAngle), length: 5 }, %)
|> line([-5, 0], %)
|> angledLine({ angle = myAngle, length = 5 }, %)
|> angledLine({ angle: myAngle, length: 5 }, %)
|> close(%)
baseExtrusion = extrude(5, sketch001)

View File

@ -34,8 +34,8 @@ acos(num: number) -> number
sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLine({
angle = toDegrees(acos(0.5)),
length = 10
angle: toDegrees(acos(0.5)),
length: 10
}, %)
|> line([5, 0], %)
|> lineTo([12, 0], %)

View File

@ -33,8 +33,8 @@ sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([1, 2], %, $seg01)
|> angledLine({
angle = angleToMatchLengthY(seg01, 15, %),
length = 5
angle: angleToMatchLengthY(seg01, 15, %),
length: 5
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -32,7 +32,7 @@ angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> yLineTo(15, %)
|> angledLine({ angle = 30, length = 15 }, %)
|> angledLine({ angle: 30, length: 15 }, %)
|> line([8, -10], %)
|> yLineTo(0, %)
|> close(%)

View File

@ -31,8 +31,8 @@ angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
```js
sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLineOfXLength({ angle = 45, length = 10 }, %, $edge1)
|> angledLineOfXLength({ angle = -15, length = 20 }, %, $edge2)
|> angledLineOfXLength({ angle: 45, length: 10 }, %, $edge1)
|> angledLineOfXLength({ angle: -15, length: 20 }, %, $edge2)
|> line([0, -5], %)
|> close(%, $edge3)

View File

@ -32,9 +32,9 @@ angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([10, 0], %)
|> angledLineOfYLength({ angle = 45, length = 10 }, %)
|> angledLineOfYLength({ angle: 45, length: 10 }, %)
|> line([0, 10], %)
|> angledLineOfYLength({ angle = 135, length = 10 }, %)
|> angledLineOfYLength({ angle: 135, length: 10 }, %)
|> line([-10, 0], %)
|> line([0, -30], %)

View File

@ -35,9 +35,9 @@ exampleSketch = startSketchOn('XZ')
|> lineTo([-10, 10], %, $lineToIntersect)
|> lineTo([0, 20], %)
|> angledLineThatIntersects({
angle = 80,
intersectTag = lineToIntersect,
offset = 10
angle: 80,
intersectTag: lineToIntersect,
offset: 10
}, %)
|> close(%)

View File

@ -31,7 +31,7 @@ angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
```js
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLineToX({ angle = 30, to = 10 }, %)
|> angledLineToX({ angle: 30, to: 10 }, %)
|> line([0, 10], %)
|> line([-10, 0], %)
|> close(%)

View File

@ -31,9 +31,9 @@ angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
```js
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLineToY({ angle = 60, to = 20 }, %)
|> angledLineToY({ angle: 60, to: 20 }, %)
|> line([-20, 0], %)
|> angledLineToY({ angle = 70, to = 10 }, %)
|> angledLineToY({ angle: 70, to: 10 }, %)
|> close(%)
example = extrude(10, exampleSketch)

View File

@ -35,9 +35,9 @@ exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([10, 0], %)
|> arc({
angleStart = 0,
angleEnd = 280,
radius = 16
angleStart: 0,
angleEnd: 280,
radius: 16
}, %)
|> close(%)
example = extrude(10, exampleSketch)

View File

@ -31,7 +31,7 @@ arcTo(data: ArcToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
```js
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> arcTo({ end = [10, 0], interior = [5, 5] }, %)
|> arcTo({ end: [10, 0], interior: [5, 5] }, %)
|> close(%)
example = extrude(10, exampleSketch)
```

View File

@ -34,8 +34,8 @@ asin(num: number) -> number
sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLine({
angle = toDegrees(asin(0.5)),
length = 20
angle: toDegrees(asin(0.5)),
length: 20
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -34,8 +34,8 @@ atan(num: number) -> number
sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLine({
angle = toDegrees(atan(1.25)),
length = 20
angle: toDegrees(atan(1.25)),
length: 20
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -33,9 +33,9 @@ exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([0, 10], %)
|> bezierCurve({
to = [10, 10],
control1 = [5, 0],
control2 = [5, 10]
to: [10, 10],
control1: [5, 0],
control2: [5, 10]
}, %)
|> lineTo([10, 0], %)
|> close(%)

View File

@ -44,8 +44,8 @@ mountingPlateSketch = startSketchOn("XY")
mountingPlate = extrude(thickness, mountingPlateSketch)
|> chamfer({
length = chamferLength,
tags = [
length: chamferLength,
tags: [
getNextAdjacentEdge(edge1),
getNextAdjacentEdge(edge2),
getNextAdjacentEdge(edge3),
@ -72,8 +72,8 @@ part001 = cube([0, 0], 20)
|> close(%, $line1)
|> extrude(20, %)
|> chamfer({
length = 10,
tags = [getOppositeEdge(line1)]
length: 10,
tags: [getOppositeEdge(line1)]
}, %, $chamfer1) // We tag the chamfer to reference it later.
sketch001 = startSketchOn(part001, chamfer1)

View File

@ -30,7 +30,7 @@ circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagDecl
```js
exampleSketch = startSketchOn("-XZ")
|> circle({ center = [0, 0], radius = 10 }, %)
|> circle({ center: [0, 0], radius: 10 }, %)
example = extrude(5, exampleSketch)
```
@ -44,7 +44,7 @@ exampleSketch = startSketchOn("XZ")
|> line([0, 30], %)
|> line([-30, 0], %)
|> close(%)
|> hole(circle({ center = [0, 15], radius = 5 }, %), %)
|> hole(circle({ center: [0, 15], radius: 5 }, %), %)
example = extrude(5, exampleSketch)
```

View File

@ -34,8 +34,8 @@ cos(num: number) -> number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 30,
length = 3 / cos(toRadians(30))
angle: 30,
length: 3 / cos(toRadians(30))
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -28,7 +28,7 @@ e() -> number
```js
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 30, length = 2 * e() ^ 2 }, %)
|> angledLine({ angle: 30, length: 2 * e() ^ 2 }, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -32,16 +32,16 @@ example = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([10, 0], %)
|> arc({
angleStart = 120,
angleEnd = 0,
radius = 5
angleStart: 120,
angleEnd: 0,
radius: 5
}, %)
|> line([5, 0], %)
|> line([0, 10], %)
|> bezierCurve({
control1 = [-10, 0],
control2 = [2, 10],
to = [-5, 10]
control1: [-10, 0],
control2: [2, 10],
to: [-5, 10]
}, %)
|> line([-5, -2], %)
|> close(%)
@ -54,16 +54,16 @@ example = startSketchOn('XZ')
exampleSketch = startSketchOn('XZ')
|> startProfileAt([-10, 0], %)
|> arc({
angleStart = 120,
angleEnd = -60,
radius = 5
angleStart: 120,
angleEnd: -60,
radius: 5
}, %)
|> line([10, 0], %)
|> line([5, 0], %)
|> bezierCurve({
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
control1: [-3, 0],
control2: [2, 10],
to: [-5, 10]
}, %)
|> line([-4, 10], %)
|> line([-5, -2], %)

View File

@ -43,8 +43,8 @@ mountingPlateSketch = startSketchOn("XY")
mountingPlate = extrude(thickness, mountingPlateSketch)
|> fillet({
radius = filletRadius,
tags = [
radius: filletRadius,
tags: [
getNextAdjacentEdge(edge1),
getNextAdjacentEdge(edge2),
getNextAdjacentEdge(edge3),
@ -70,9 +70,9 @@ mountingPlateSketch = startSketchOn("XY")
mountingPlate = extrude(thickness, mountingPlateSketch)
|> fillet({
radius = filletRadius,
tolerance = 0.000001,
tags = [
radius: filletRadius,
tolerance: 0.000001,
tags: [
getNextAdjacentEdge(edge1),
getNextAdjacentEdge(edge2),
getNextAdjacentEdge(edge3),

View File

@ -30,16 +30,16 @@ getNextAdjacentEdge(tag: TagIdentifier) -> Uuid
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([10, 0], %)
|> angledLine({ angle = 60, length = 10 }, %)
|> angledLine({ angle = 120, length = 10 }, %)
|> angledLine({ angle: 60, length: 10 }, %)
|> angledLine({ angle: 120, length: 10 }, %)
|> line([-10, 0], %)
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|> close(%)
example = extrude(5, exampleSketch)
|> fillet({
radius = 3,
tags = [getNextAdjacentEdge(referenceEdge)]
radius: 3,
tags: [getNextAdjacentEdge(referenceEdge)]
}, %)
```

View File

@ -30,16 +30,16 @@ getOppositeEdge(tag: TagIdentifier) -> Uuid
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([10, 0], %)
|> angledLine({ angle = 60, length = 10 }, %)
|> angledLine({ angle = 120, length = 10 }, %)
|> angledLine({ angle: 60, length: 10 }, %)
|> angledLine({ angle: 120, length: 10 }, %)
|> line([-10, 0], %)
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|> close(%)
example = extrude(5, exampleSketch)
|> fillet({
radius = 3,
tags = [getOppositeEdge(referenceEdge)]
radius: 3,
tags: [getOppositeEdge(referenceEdge)]
}, %)
```

View File

@ -30,16 +30,16 @@ getPreviousAdjacentEdge(tag: TagIdentifier) -> Uuid
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line([10, 0], %)
|> angledLine({ angle = 60, length = 10 }, %)
|> angledLine({ angle = 120, length = 10 }, %)
|> angledLine({ angle: 60, length: 10 }, %)
|> angledLine({ angle: 120, length: 10 }, %)
|> line([-10, 0], %)
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|> close(%)
example = extrude(5, exampleSketch)
|> fillet({
radius = 3,
tags = [getPreviousAdjacentEdge(referenceEdge)]
radius: 3,
tags: [getPreviousAdjacentEdge(referenceEdge)]
}, %)
```

View File

@ -29,12 +29,12 @@ helix(data: HelixData, solid: Solid) -> Solid
```js
part001 = startSketchOn('XY')
|> circle({ center = [5, 5], radius = 10 }, %)
|> circle({ center: [5, 5], radius: 10 }, %)
|> extrude(10, %)
|> helix({
angleStart = 0,
ccw = true,
revolutions = 16
angleStart: 0,
ccw: true,
revolutions: 16
}, %)
```

View File

@ -34,8 +34,8 @@ exampleSketch = startSketchOn('XY')
|> line([5, 0], %)
|> line([0, -5], %)
|> close(%)
|> hole(circle({ center = [1, 1], radius = .25 }, %), %)
|> hole(circle({ center = [1, 4], radius = .25 }, %), %)
|> hole(circle({ center: [1, 1], radius: .25 }, %), %)
|> hole(circle({ center: [1, 4], radius: .25 }, %), %)
example = extrude(1, exampleSketch)
```
@ -54,7 +54,7 @@ fn squareHoleSketch = () => {
}
exampleSketch = startSketchOn('-XZ')
|> circle({ center = [0, 0], radius = 3 }, %)
|> circle({ center: [0, 0], radius: 3 }, %)
|> hole(squareHoleSketch(), %)
example = extrude(1, exampleSketch)
```

View File

@ -68,15 +68,15 @@ case = startSketchOn('-XZ')
thing1 = startSketchOn(case, 'end')
|> circle({
center = [-size / 2, -size / 2],
radius = 25
center: [-size / 2, -size / 2],
radius: 25
}, %)
|> extrude(50, %)
thing2 = startSketchOn(case, 'end')
|> circle({
center = [size / 2, -size / 2],
radius = 25
center: [size / 2, -size / 2],
radius: 25
}, %)
|> extrude(50, %)

File diff suppressed because one or more lines are too long

View File

@ -74,7 +74,6 @@ layout: manual
* [`patternLinear2d`](kcl/patternLinear2d)
* [`patternLinear3d`](kcl/patternLinear3d)
* [`patternTransform`](kcl/patternTransform)
* [`patternTransform2d`](kcl/patternTransform2d)
* [`pi`](kcl/pi)
* [`polar`](kcl/polar)
* [`polygon`](kcl/polygon)
@ -86,7 +85,6 @@ layout: manual
* [`reduce`](kcl/reduce)
* [`rem`](kcl/rem)
* [`revolve`](kcl/revolve)
* [`round`](kcl/round)
* [`segAng`](kcl/segAng)
* [`segEnd`](kcl/segEnd)
* [`segEndX`](kcl/segEndX)
@ -102,7 +100,6 @@ layout: manual
* [`startSketchAt`](kcl/startSketchAt)
* [`startSketchOn`](kcl/startSketchOn)
* [`tan`](kcl/tan)
* [`tangentToEnd`](kcl/tangentToEnd)
* [`tangentialArc`](kcl/tangentialArc)
* [`tangentialArcTo`](kcl/tangentialArcTo)
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)

File diff suppressed because one or more lines are too long

View File

@ -60,10 +60,10 @@ squareSketch = startSketchOn('XY')
|> close(%)
circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|> circle({ center = [0, 100], radius = 50 }, %)
|> circle({ center: [0, 100], radius: 50 }, %)
circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|> circle({ center = [0, 100], radius = 20 }, %)
|> circle({ center: [0, 100], radius: 20 }, %)
loft([
squareSketch,
@ -85,10 +85,10 @@ squareSketch = startSketchOn('XY')
|> close(%)
circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|> circle({ center = [0, 100], radius = 50 }, %)
|> circle({ center: [0, 100], radius: 50 }, %)
circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|> circle({ center = [0, 100], radius = 20 }, %)
|> circle({ center: [0, 100], radius: 20 }, %)
loft([
squareSketch,
@ -97,17 +97,17 @@ loft([
], {
// This can be set to override the automatically determined
// topological base curve, which is usually the first section encountered.
baseCurveIndex = 0,
baseCurveIndex: 0,
// Attempt to approximate rational curves (such as arcs) using a bezier.
// This will remove banding around interpolations between arcs and non-arcs.
// It may produce errors in other scenarios Over time, this field won't be necessary.
bezApproximateRational = false,
bezApproximateRational: false,
// Tolerance for the loft operation.
tolerance = 0.000001,
tolerance: 0.000001,
// Degree of the interpolation. Must be greater than zero.
// For example, use 2 for quadratic, or 3 for cubic interpolation in
// the V direction. This defaults to 2, if not specified.
vDegree = 2
vDegree: 2
})
```

View File

@ -31,7 +31,7 @@ map(array: [KclValue], map_fn: FunctionParam) -> [KclValue]
r = 10 // radius
fn drawCircle = (id) => {
return startSketchOn("XY")
|> circle({ center = [id * 2 * r, 0], radius = r }, %)
|> circle({ center: [id * 2 * r, 0], radius: r }, %)
}
// Call `drawCircle`, passing in each element of the array.
@ -47,7 +47,7 @@ r = 10 // radius
// Call `map`, using an anonymous function instead of a named one.
circles = map([1..3], (id) => {
return startSketchOn("XY")
|> circle({ center = [id * 2 * r, 0], radius = r }, %)
|> circle({ center: [id * 2 * r, 0], radius: r }, %)
})
```

View File

@ -34,8 +34,8 @@ max(args: [number]) -> number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 70,
length = max(15, 31, 4, 13, 22)
angle: 70,
length: max(15, 31, 4, 13, 22)
}, %)
|> line([20, 0], %)
|> close(%)

View File

@ -34,8 +34,8 @@ min(args: [number]) -> number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 70,
length = min(15, 31, 4, 13, 22)
angle: 70,
length: min(15, 31, 4, 13, 22)
}, %)
|> line([20, 0], %)
|> close(%)

View File

@ -41,7 +41,7 @@ sketch001 = startSketchOn('XZ')
|> line([-8, -3], %)
|> line([9, -1], %)
|> line([-19, -0], %)
|> mirror2d({ axis = 'Y' }, %)
|> mirror2d({ axis: 'Y' }, %)
example = extrude(10, sketch001)
```
@ -54,7 +54,7 @@ sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 8.5], %)
|> line([20, -8.5], %)
|> line([-20, -8.5], %)
|> mirror2d({ axis = 'Y' }, %)
|> mirror2d({ axis: 'Y' }, %)
example = extrude(10, sketch001)
```
@ -71,7 +71,7 @@ sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 8.5], %)
|> line([20, -8.5], %)
|> line([-20, -8.5], %)
|> mirror2d({ axis = edge001 }, %)
|> mirror2d({ axis: edge001 }, %)
example = extrude(10, sketch001)
```
@ -85,11 +85,8 @@ sketch001 = startSketchOn('XZ')
|> line([20, -8.5], %)
|> line([-20, -8.5], %)
|> mirror2d({
axis = {
custom = {
axis = [0.0, 1.0],
origin = [0.0, 0.0]
}
axis: {
custom: { axis: [0.0, 1.0], origin: [0.0, 0.0] }
}
}, %)

View File

@ -38,7 +38,7 @@ squareSketch = startSketchOn('XY')
|> close(%)
circleSketch = startSketchOn(offsetPlane('XY', 150))
|> circle({ center = [0, 100], radius = 50 }, %)
|> circle({ center: [0, 100], radius: 50 }, %)
loft([squareSketch, circleSketch])
```
@ -56,7 +56,7 @@ squareSketch = startSketchOn('XZ')
|> close(%)
circleSketch = startSketchOn(offsetPlane('XZ', 150))
|> circle({ center = [0, 100], radius = 50 }, %)
|> circle({ center: [0, 100], radius: 50 }, %)
loft([squareSketch, circleSketch])
```
@ -74,7 +74,7 @@ squareSketch = startSketchOn('YZ')
|> close(%)
circleSketch = startSketchOn(offsetPlane('YZ', 150))
|> circle({ center = [0, 100], radius = 50 }, %)
|> circle({ center: [0, 100], radius: 50 }, %)
loft([squareSketch, circleSketch])
```
@ -92,7 +92,7 @@ squareSketch = startSketchOn('-XZ')
|> close(%)
circleSketch = startSketchOn(offsetPlane('-XZ', -150))
|> circle({ center = [0, 100], radius = 50 }, %)
|> circle({ center: [0, 100], radius: 50 }, %)
loft([squareSketch, circleSketch])
```
@ -103,7 +103,7 @@ loft([squareSketch, circleSketch])
// A circle on the XY plane
startSketchOn("XY")
|> startProfileAt([0, 0], %)
|> circle({ radius = 10, center = [0, 0] }, %)
|> circle({ radius: 10, center: [0, 0] }, %)
// Triangle on the plane 4 units above
startSketchOn(offsetPlane("XY", 4))

View File

@ -35,10 +35,10 @@ exampleSketch = startSketchOn('XZ')
|> line([0, -5], %)
|> close(%)
|> patternCircular2d({
center = [0, 0],
instances = 13,
arcDegrees = 360,
rotateDuplicates = true
center: [0, 0],
instances: 13,
arcDegrees: 360,
rotateDuplicates: true
}, %)
example = extrude(1, exampleSketch)

View File

@ -29,15 +29,15 @@ patternCircular3d(data: CircularPattern3dData, solid_set: SolidSet) -> [Solid]
```js
exampleSketch = startSketchOn('XZ')
|> circle({ center = [0, 0], radius = 1 }, %)
|> circle({ center: [0, 0], radius: 1 }, %)
example = extrude(-5, exampleSketch)
|> patternCircular3d({
axis = [1, -1, 0],
center = [10, -20, 0],
instances = 11,
arcDegrees = 360,
rotateDuplicates = true
axis: [1, -1, 0],
center: [10, -20, 0],
instances: 11,
arcDegrees: 360,
rotateDuplicates: true
}, %)
```

View File

@ -29,11 +29,11 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet) -> [Sketch]
```js
exampleSketch = startSketchOn('XZ')
|> circle({ center = [0, 0], radius = 1 }, %)
|> circle({ center: [0, 0], radius: 1 }, %)
|> patternLinear2d({
axis = [1, 0],
instances = 7,
distance = 4
axis: [1, 0],
instances: 7,
distance: 4
}, %)
example = extrude(1, exampleSketch)

View File

@ -37,9 +37,9 @@ exampleSketch = startSketchOn('XZ')
example = extrude(1, exampleSketch)
|> patternLinear3d({
axis = [1, 0, 1],
instances = 7,
distance = 6
axis: [1, 0, 1],
instances: 7,
distance: 6
}, %)
```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -30,8 +30,8 @@ circumference = 70
exampleSketch = startSketchOn("XZ")
|> circle({
center = [0, 0],
radius = circumference / (2 * pi())
center: [0, 0],
radius: circumference / (2 * pi())
}, %)
example = extrude(5, exampleSketch)

View File

@ -29,7 +29,7 @@ polar(data: PolarCoordsData) -> [number]
```js
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(polar({ angle = 30, length = 5 }), %, $thing)
|> line(polar({ angle: 30, length: 5 }), %, $thing)
|> line([0, 5], %)
|> line([segEndX(thing), 0], %)
|> line([-20, 10], %)

View File

@ -32,10 +32,10 @@ polygon(data: PolygonData, sketch_surface_or_group: SketchOrSurface, tag?: TagDe
// Create a regular hexagon inscribed in a circle of radius 10
hex = startSketchOn('XY')
|> polygon({
radius = 10,
numSides = 6,
center = [0, 0],
inscribed = true
radius: 10,
numSides: 6,
center: [0, 0],
inscribed: true
}, %)
example = extrude(5, hex)
@ -47,10 +47,10 @@ example = extrude(5, hex)
// Create a square circumscribed around a circle of radius 5
square = startSketchOn('XY')
|> polygon({
radius = 5.0,
numSides = 4,
center = [10, 10],
inscribed = false
radius: 5.0,
numSides: 4,
center: [10, 10],
inscribed: false
}, %)
example = extrude(5, square)
```

View File

@ -34,7 +34,7 @@ pow(num: number, pow: number) -> number
```js
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = pow(5, 2) }, %)
|> angledLine({ angle: 50, length: pow(5, 2) }, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -29,10 +29,10 @@ profileStart(sketch: Sketch) -> [number]
```js
sketch001 = startSketchOn('XY')
|> startProfileAt([5, 2], %)
|> angledLine({ angle = 120, length = 50 }, %, $seg01)
|> angledLine({ angle: 120, length: 50 }, %, $seg01)
|> angledLine({
angle = segAng(seg01) + 120,
length = 50
angle: segAng(seg01) + 120,
length: 50
}, %)
|> lineTo(profileStart(%), %)
|> close(%)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -89,7 +89,7 @@ fn decagon = (radius) => {
x = cos(stepAngle * i) * radius
y = sin(stepAngle * i) * radius
return lineTo([x, y], partialDecagon)
})
})
return fullDecagon
}

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

@ -38,11 +38,8 @@ cube = startSketchAt([0, 0])
fn cylinder = (radius, tag) => {
return startSketchAt([0, 0])
|> circle({
radius = radius,
center = segEnd(tag)
}, %)
|> extrude(radius, %)
|> circle({ radius: radius, center: segEnd(tag) }, %)
|> extrude(radius, %)
}
cylinder(1, line1)

View File

@ -29,9 +29,9 @@ segLen(tag: TagIdentifier) -> number
```js
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 60, length = 10 }, %, $thing)
|> tangentialArc({ offset = -120, radius = 5 }, %)
|> angledLine({ angle = -60, length = segLen(thing) }, %)
|> angledLine({ angle: 60, length: 10 }, %, $thing)
|> tangentialArc({ offset: -120, radius: 5 }, %)
|> angledLine({ angle: -60, length: segLen(thing) }, %)
|> close(%)
example = extrude(5, exampleSketch)

View File

@ -38,11 +38,11 @@ cube = startSketchAt([0, 0])
fn cylinder = (radius, tag) => {
return startSketchAt([0, 0])
|> circle({
radius = radius,
center = segStart(tag)
}, %)
|> extrude(radius, %)
|> circle({
radius: radius,
center: segStart(tag)
}, %)
|> extrude(radius, %)
}
cylinder(1, line1)

File diff suppressed because one or more lines are too long

View File

@ -34,8 +34,8 @@ sin(num: number) -> number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,
length = 15 / sin(toDegrees(135))
angle: 50,
length: 15 / sin(toDegrees(135))
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -33,7 +33,7 @@ sqrt(num: number) -> number
```js
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = sqrt(2500) }, %)
|> angledLine({ angle: 50, length: sqrt(2500) }, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -101,7 +101,7 @@ exampleSketch = startSketchOn('XY')
|> line([-2, 0], %)
|> close(%)
example = revolve({ axis = 'y', angle = 180 }, exampleSketch)
example = revolve({ axis: 'y', angle: 180 }, exampleSketch)
exampleSketch002 = startSketchOn(example, 'end')
|> startProfileAt([4.5, -5], %)
@ -117,11 +117,11 @@ example002 = extrude(5, exampleSketch002)
```js
a1 = startSketchOn({
plane = {
origin = { x = 0, y = 0, z = 0 },
xAxis = { x = 1, y = 0, z = 0 },
yAxis = { x = 0, y = 1, z = 0 },
zAxis = { x = 0, y = 0, z = 1 }
plane: {
origin: { x: 0, y: 0, z: 0 },
xAxis: { x: 1, y: 0, z: 0 },
yAxis: { x: 0, y: 1, z: 0 },
zAxis: { x: 0, y: 0, z: 1 }
}
})
|> startProfileAt([0, 0], %)

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ tan(num: number) -> number
```js
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = 50 * tan(1 / 2) }, %)
|> angledLine({ angle: 50, length: 50 * tan(1 / 2) }, %)
|> yLineTo(0, %)
|> close(%)

File diff suppressed because one or more lines are too long

View File

@ -31,9 +31,9 @@ tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> S
```js
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 60, length = 10 }, %)
|> tangentialArc({ radius = 10, offset = -120 }, %)
|> angledLine({ angle = -60, length = 10 }, %)
|> angledLine({ angle: 60, length: 10 }, %)
|> tangentialArc({ radius: 10, offset: -120 }, %)
|> angledLine({ angle: -60, length: 10 }, %)
|> close(%)
example = extrude(10, exampleSketch)

View File

@ -31,7 +31,7 @@ tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
```js
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 60, length = 10 }, %)
|> angledLine({ angle: 60, length: 10 }, %)
|> tangentialArcTo([15, 15], %)
|> line([10, -15], %)
|> close(%)

View File

@ -31,7 +31,7 @@ tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) ->
```js
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 45, length = 10 }, %)
|> angledLine({ angle: 45, length: 10 }, %)
|> tangentialArcToRelative([0, -10], %)
|> line([-10, 0], %)
|> close(%)

View File

@ -28,7 +28,7 @@ tau() -> number
```js
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = 10 * tau() }, %)
|> angledLine({ angle: 50, length: 10 * tau() }, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -34,8 +34,8 @@ toDegrees(num: number) -> number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,
length = 70 * cos(toDegrees(pi() / 4))
angle: 50,
length: 70 * cos(toDegrees(pi() / 4))
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -34,8 +34,8 @@ toRadians(num: number) -> number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,
length = 70 * cos(toRadians(45))
angle: 50,
length: 70 * cos(toRadians(45))
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -16,7 +16,7 @@ Data for a circular pattern on a 2D sketch.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `center` |`[number, number]`| The center about which to make the pattern. This is a 2D vector. | No |
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |

View File

@ -16,7 +16,7 @@ Data for a circular pattern on a 3D model.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `axis` |`[number, number, number]`| The axis around which to make the pattern. This is a 3D vector. | No |
| `center` |`[number, number, number]`| The center about which to make the pattern. This is a 3D vector. | No |
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |

View File

@ -24,7 +24,7 @@ Autodesk Filmbox (FBX) format
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `format` |enum: `fbx`| | No |
| `type` |enum: `fbx`| | No |
----
@ -40,7 +40,7 @@ Binary glTF 2.0. We refer to this as glTF since that is how our customers refer
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `format` |enum: `gltf`| | No |
| `type` |enum: `gltf`| | No |
----
@ -56,7 +56,7 @@ Wavefront OBJ format.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `format` |enum: `obj`| | No |
| `type` |enum: `obj`| | No |
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
@ -74,7 +74,7 @@ The PLY Polygon File Format.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `format` |enum: `ply`| | No |
| `type` |enum: `ply`| | No |
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
@ -92,7 +92,7 @@ SolidWorks part (SLDPRT) format.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `format` |enum: `sldprt`| | No |
| `type` |enum: `sldprt`| | No |
----
@ -108,7 +108,7 @@ ISO 10303-21 (STEP) format.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `format` |enum: `step`| | No |
| `type` |enum: `step`| | No |
----
@ -124,7 +124,7 @@ ST**ereo**L**ithography format.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `format` |enum: `stl`| | No |
| `type` |enum: `stl`| | No |
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |

View File

@ -16,7 +16,7 @@ Data for a linear pattern on a 2D sketch.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
| `axis` |`[number, number]`| The axis of the pattern. This is a 2D vector. | No |

View File

@ -16,7 +16,7 @@ Data for a linear pattern on a 3D model.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
| `axis` |`[number, number, number]`| The axis of the pattern. | No |

View File

@ -11,6 +11,16 @@ layout: manual
**This schema accepts any of the following:**
**Type:** `integer` (`int64`)
----
**Type:** `number` (`double`)

View File

@ -11,6 +11,23 @@ layout: manual
**This schema accepts exactly one of the following:**
A shebang. This is a special type of comment that is at the top of the file. It looks like this: ```python,no_run #!/usr/bin/env python ```
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `shebang`| | No |
| `value` |`string`| | No |
----
An inline comment. Here are examples: `1 + 1 // This is an inline comment`. `1 + 1 /* Here's another */`.
**Type:** `object`

View File

@ -91,7 +91,7 @@ a complete arc
| `type` |enum: `Circle`| | No |
| `center` |`[number, number]`| the arc's center | No |
| `radius` |`number`| the arc's radius | No |
| `ccw` |`boolean`| arc's direction This is used to compute the tangential angle. | No |
| `ccw` |`boolean`| arc's direction | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
@ -177,7 +177,6 @@ A circular arc, not necessarily tangential to the current point.
| `type` |enum: `Arc`| | No |
| `center` |`[number, number]`| Center of the circle that this arc is drawn on. | No |
| `radius` |`number`| Radius of the circle that this arc is drawn on. | No |
| `ccw` |`boolean`| True if the arc is counterclockwise. | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |

View File

@ -18,7 +18,6 @@ A KCL program top level, or function body.
|----------|------|-------------|----------|
| `body` |`[` [`BodyItem`](/docs/kcl/types/BodyItem) `]`| | No |
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| A KCL program top level, or function body. | No |
| `shebang` |[`Shebang`](/docs/kcl/types/Shebang)| | No |
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
| `start` |`integer`| | No |
| `end` |`integer`| | No |

View File

@ -1,23 +0,0 @@
---
title: "Shebang"
excerpt: "A shebang. This is a special type of comment that is at the top of the file. It looks like this: ```python,no_run #!/usr/bin/env python ```"
layout: manual
---
A shebang. This is a special type of comment that is at the top of the file. It looks like this: ```python,no_run #!/usr/bin/env python ```
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `content` |`string`| | No |
| `start` |`integer`| | No |
| `end` |`integer`| | No |

View File

@ -32,10 +32,10 @@ xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> xLine(15, %)
|> angledLine({ angle = 80, length = 15 }, %)
|> angledLine({ angle: 80, length: 15 }, %)
|> line([8, -10], %)
|> xLine(10, %)
|> angledLine({ angle = 120, length = 30 }, %)
|> angledLine({ angle: 120, length: 30 }, %)
|> xLine(-15, %)
|> close(%)

View File

@ -32,10 +32,10 @@ xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> xLineTo(15, %)
|> angledLine({ angle = 80, length = 15 }, %)
|> angledLine({ angle: 80, length: 15 }, %)
|> line([8, -10], %)
|> xLineTo(40, %)
|> angledLine({ angle = 135, length = 30 }, %)
|> angledLine({ angle: 135, length: 30 }, %)
|> xLineTo(10, %)
|> close(%)

View File

@ -32,7 +32,7 @@ yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> yLine(15, %)
|> angledLine({ angle = 30, length = 15 }, %)
|> angledLine({ angle: 30, length: 15 }, %)
|> line([8, -10], %)
|> yLine(-5, %)
|> close(%)

View File

@ -31,7 +31,7 @@ yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
```js
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = 45 }, %)
|> angledLine({ angle: 50, length: 45 }, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -87,7 +87,7 @@ extrude001 = extrude(-10, sketch001)`
await page.keyboard.press('Enter') // submit
await page.waitForTimeout(100)
await expect(page.locator('.cm-activeLine')).toContainText(
`fillet({ radius = ${KCL_DEFAULT_LENGTH}, tags = [seg01] }, %)`
`fillet({ radius: ${KCL_DEFAULT_LENGTH}, tags: [seg01] }, %)`
)
})

View File

@ -568,7 +568,7 @@ test.describe('Editor tests', () => {
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Enter')
await page.keyboard.type(`extrusion = startSketchOn('XY')
|> circle({ center = [0, 0], radius = dia/2 }, %)
|> circle({ center: [0, 0], radius: dia/2 }, %)
|> hole(squareHole(length, width, height), %)
|> extrude(height, %)`)
@ -604,8 +604,8 @@ test.describe('Editor tests', () => {
|> line([0, -10], %)
|> close(%)
|> revolve({
axis = revolveAxis,
angle = 90
axis: revolveAxis,
angle: 90
}, %)
`
)

View File

@ -35,7 +35,7 @@ export class CmdBarFixture {
}
private _serialiseCmdBar = async (): Promise<CmdBarSerialised> => {
const reviewForm = this.page.locator('#review-form')
const reviewForm = await this.page.locator('#review-form')
const getHeaderArgs = async () => {
const inputs = await this.page.getByTestId('cmd-bar-input-tab').all()
const entries = await Promise.all(

View File

@ -6,7 +6,6 @@ export class ToolbarFixture {
public page: Page
extrudeButton!: Locator
offsetPlaneButton!: Locator
startSketchBtn!: Locator
lineBtn!: Locator
rectangleBtn!: Locator
@ -26,7 +25,6 @@ export class ToolbarFixture {
reConstruct = (page: Page) => {
this.page = page
this.extrudeButton = page.getByTestId('extrude')
this.offsetPlaneButton = page.getByTestId('plane-offset')
this.startSketchBtn = page.getByTestId('sketch')
this.lineBtn = page.getByTestId('line')
this.rectangleBtn = page.getByTestId('corner-rectangle')

View File

@ -25,7 +25,7 @@ test(
await test.step('check code model connection works and that button is still enable once circle is selected ', async () => {
await moveToCircle()
const circleSnippet =
'circle({ center = [318.33, 168.1], radius = 182.8 }, %)'
'circle({ center: [318.33, 168.1], radius: 182.8 }, %)'
await editor.expectState({
activeLines: [],
highlightedCode: circleSnippet,
@ -168,7 +168,7 @@ test.describe('verify sketch on chamfer works', () => {
cameraPos: { x: 16020, y: -2000, z: 10500 },
cameraTarget: { x: -150, y: -4500, z: -80 },
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
chamfer({length = 30,tags = [
chamfer({length:30,tags:[
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02),
@ -199,8 +199,8 @@ test.describe('verify sketch on chamfer works', () => {
segAng(rectangleSegmentA001) - 90,
217.26
], %, $seg01)chamfer({
length = 30,
tags = [
length: 30,
tags: [
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02)
@ -227,8 +227,8 @@ test.describe('verify sketch on chamfer works', () => {
cameraPos: { x: -6200, y: 1500, z: 6200 },
cameraTarget: { x: 8300, y: 1100, z: 4800 },
beforeChamferSnippet: `angledLine([0, 268.43], %, $rectangleSegmentA001)chamfer({
length = 30,
tags = [
length: 30,
tags: [
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02)
]
@ -254,8 +254,8 @@ test.describe('verify sketch on chamfer works', () => {
cameraPos: { x: -1100, y: -7700, z: 1600 },
cameraTarget: { x: 1450, y: 670, z: 4000 },
beforeChamferSnippet: `chamfer({
length = 30,
tags = [getNextAdjacentEdge(yo)]
length: 30,
tags: [getNextAdjacentEdge(yo)]
}, %)`,
afterChamferSelectSnippet:
'sketch005 = startSketchOn(extrude001, seg06)',
@ -292,17 +292,17 @@ test.describe('verify sketch on chamfer works', () => {
|> close(%)
extrude001 = extrude(100, sketch001)
|> chamfer({
length = 30,
tags = [getOppositeEdge(seg01)]
length: 30,
tags: [getOppositeEdge(seg01)]
}, %, $seg03)
|> chamfer({ length = 30, tags = [seg01] }, %, $seg04)
|> chamfer({ length: 30, tags: [seg01] }, %, $seg04)
|> chamfer({
length = 30,
tags = [getNextAdjacentEdge(seg02)]
length: 30,
tags: [getNextAdjacentEdge(seg02)]
}, %, $seg05)
|> chamfer({
length = 30,
tags = [getNextAdjacentEdge(yo)]
length: 30,
tags: [getNextAdjacentEdge(yo)]
}, %, $seg06)
sketch005 = startSketchOn(extrude001, seg06)
|> startProfileAt([-23.43, 19.69], %)
@ -383,7 +383,7 @@ test.describe('verify sketch on chamfer works', () => {
cameraPos: { x: 16020, y: -2000, z: 10500 },
cameraTarget: { x: -150, y: -4500, z: -80 },
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
chamfer({length=30,tags=[
chamfer({length:30,tags:[
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02),
@ -421,12 +421,12 @@ test.describe('verify sketch on chamfer works', () => {
|> close(%)
extrude001 = extrude(100, sketch001)
chamf = chamfer({
length = 30,
tags = [getOppositeEdge(seg01)]
length: 30,
tags: [getOppositeEdge(seg01)]
}, extrude001, $seg03)
|> chamfer({
length = 30,
tags = [
length: 30,
tags: [
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02)
@ -551,53 +551,3 @@ test(`Verify axis, origin, and horizontal snapping`, async ({
)
})
})
test(`Offset plane point-and-click`, async ({
app,
scene,
editor,
toolbar,
cmdBar,
}) => {
await app.initialise()
// One dumb hardcoded screen pixel value
const testPoint = { x: 700, y: 150 }
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
const expectedOutput = `plane001 = offsetPlane('XZ', 5)`
await test.step(`Look for the blue of the XZ plane`, async () => {
await scene.expectPixelColor([50, 51, 96], testPoint, 15)
})
await test.step(`Go through the command bar flow`, async () => {
await toolbar.offsetPlaneButton.click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'plane',
currentArgValue: '',
headerArguments: { Plane: '', Distance: '' },
highlightedHeaderArg: 'plane',
commandName: 'Offset plane',
})
await clickOnXzPlane()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'distance',
currentArgValue: '5',
headerArguments: { Plane: '1 plane', Distance: '' },
highlightedHeaderArg: 'distance',
commandName: 'Offset plane',
})
await cmdBar.progressCmdBar()
})
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
await editor.expectEditor.toContain(expectedOutput)
await editor.expectState({
diagnostics: [],
activeLines: [expectedOutput],
highlightedCode: '',
})
await scene.expectPixelColor([74, 74, 74], testPoint, 15)
})
})

View File

@ -45,9 +45,9 @@ test.describe('Sketch tests', () => {
screwHole = startSketchOn('XY')
${startProfileAt1}
|> arc({
radius = screwRadius,
angle_start = 0,
angle_end = 360
radius: screwRadius,
angle_start: 0,
angle_end: 360
}, %)
part001 = startSketchOn('XY')
@ -66,9 +66,9 @@ test.describe('Sketch tests', () => {
|> xLine(-width / 4 + wireRadius, %)
|> yLine(wireOffset, %)
|> arc({
radius = wireRadius,
angle_start = 0,
angle_end = 180
radius: wireRadius,
angle_start: 0,
angle_end: 180
}, %)
|> yLine(-wireOffset, %)
|> xLine(-width / 4, %)
@ -354,7 +354,7 @@ test.describe('Sketch tests', () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XZ')
|> circle({ center = [4.61, -5.01], radius = 8 }, %)`
|> circle({ center: [4.61, -5.01], radius: 8 }, %)`
)
})
@ -392,7 +392,7 @@ test.describe('Sketch tests', () => {
const dragPX = 40
await page
.getByText('circle({ center = [4.61, -5.01], radius = 8 }, %)')
.getByText('circle({ center: [4.61, -5.01], radius: 8 }, %)')
.click()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
@ -429,7 +429,7 @@ test.describe('Sketch tests', () => {
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
|> circle({ center = [7.26, -2.37], radius = 11.44 }, %)
|> circle({ center: [7.26, -2.37], radius: 11.44 }, %)
`)
})
test('Can edit a sketch that has been extruded in the same pipe', async ({
@ -547,7 +547,7 @@ test.describe('Sketch tests', () => {
|> line([12.73, -0.09], %)
|> tangentialArcTo([24.95, -5.38], %)
|> close(%)
|> revolve({ axis = "X",}, %)`
|> revolve({ axis: "X",}, %)`
)
})
@ -634,7 +634,7 @@ test.describe('Sketch tests', () => {
|> tangentialArcTo([24.95, -5.38], %)
|> line([1.97, 2.06], %)
|> close(%)
|> revolve({ axis = "X" }, %)`)
|> revolve({ axis: "X" }, %)`)
})
test('Can add multiple sketches', async ({ page }) => {
const u = await getUtils(page)
@ -1074,11 +1074,11 @@ sketch002 = startSketchOn(extrude001, 'END')
fn lug = (origin, length, diameter, plane) => {
lugSketch = startSketchOn(plane)
|> startProfileAt([origin[0] + lugDiameter / 2, origin[1]], %)
|> angledLineOfYLength({ angle = 60, length = lugHeadLength }, %)
|> angledLineOfYLength({ angle: 60, length: lugHeadLength }, %)
|> xLineTo(0 + .001, %)
|> yLineTo(0, %)
|> close(%)
|> revolve({ axis = "Y" }, %)
|> revolve({ axis: "Y" }, %)
return lugSketch
}

View File

@ -77,27 +77,27 @@ part001 = startSketchOn('-XZ')
|> yLine(baseHeight, %)
|> xLine(baseLen, %)
|> angledLineToY({
angle = topAng,
to = totalHeightHalf,
angle: topAng,
to: totalHeightHalf,
}, %, $seg04)
|> xLineTo(totalLen, %, $seg03)
|> yLine(-armThick, %, $seg01)
|> angledLineThatIntersects({
angle = HALF_TURN,
offset = -armThick,
intersectTag = seg04
angle: HALF_TURN,
offset: -armThick,
intersectTag: seg04
}, %)
|> angledLineToY([segAng(seg04, %) + 180, ZERO], %)
|> angledLineToY({
angle = -bottomAng,
to = -totalHeightHalf - armThick,
angle: -bottomAng,
to: -totalHeightHalf - armThick,
}, %, $seg02)
|> xLineTo(segEndX(seg03, %) + 0, %)
|> yLine(-segLen(seg01, %), %)
|> angledLineThatIntersects({
angle = HALF_TURN,
offset = -armThick,
intersectTag = seg02
angle: HALF_TURN,
offset: -armThick,
intersectTag: seg02
}, %)
|> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|> xLineTo(ZERO, %)
@ -592,7 +592,7 @@ test(
})
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')
|> circle({ center = [14.44, -2.44], radius = 1 }, %)`
|> circle({ center: [14.44, -2.44], radius: 1 }, %)`
)
}
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

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