Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash
set -euo pipefail

CONFIG=".canpixel-ci.json"
RUN_TSC=true
RUN_LINT=true
RUN_PRETTIER=true

if [ -f "$CONFIG" ]; then
RUN_TSC=$(jq -r '.run_tsc // true' "$CONFIG")
RUN_LINT=$(jq -r '.run_lint // true' "$CONFIG")
RUN_PRETTIER=$(jq -r '.run_prettier // true' "$CONFIG")
fi

if [ -f bun.lockb ] || [ -f bun.lock ]; then PM="bun"
elif [ -f pnpm-lock.yaml ]; then PM="pnpm"
elif [ -f yarn.lock ]; then PM="yarn"
else PM="npm"; fi

FAILED=()

if [ "$RUN_TSC" = "true" ]; then
echo "→ tsc..." >&2
case "$PM" in
bun) bun run typecheck 2>&1 || FAILED+=("tsc") ;;
pnpm) pnpm run typecheck 2>&1 || FAILED+=("tsc") ;;
yarn) yarn typecheck 2>&1 || FAILED+=("tsc") ;;
npm) npm run typecheck 2>&1 || FAILED+=("tsc") ;;
esac
fi

if [ "$RUN_LINT" = "true" ]; then
echo "→ lint..." >&2
case "$PM" in
bun) bun run lint 2>&1 || FAILED+=("lint") ;;
pnpm) pnpm run lint 2>&1 || FAILED+=("lint") ;;
yarn) yarn lint 2>&1 || FAILED+=("lint") ;;
npm) npm run lint 2>&1 || FAILED+=("lint") ;;
esac
fi

if [ "$RUN_PRETTIER" = "true" ]; then
echo "→ prettier..." >&2
case "$PM" in
bun) bunx prettier --check . 2>&1 || FAILED+=("prettier") ;;
pnpm) pnpm exec prettier --check . 2>&1 || FAILED+=("prettier") ;;
yarn) yarn format:check 2>&1 || FAILED+=("prettier") ;;
npm) npx prettier --check . 2>&1 || FAILED+=("prettier") ;;
esac
fi

if [ ${#FAILED[@]} -gt 0 ]; then
echo "" >&2
echo "╔══════════════════════════════════════╗" >&2
echo "║ ✗ Commit blocked by CanPixel CI ║" >&2
echo "╠══════════════════════════════════════╣" >&2
for check in "${FAILED[@]}"; do
printf "║ • %-34s║\n" "$check failed" >&2
done
echo "╚══════════════════════════════════════╝" >&2
exit 1
fi

echo "✓ all checks passed" >&2
70 changes: 49 additions & 21 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,32 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: oven-sh/setup-bun@v2
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin,x86_64-apple-darwin
- uses: swatinem/rust-cache@v2
with:
workspaces: src-tauri

- run: bun install --frozen-lockfile
- run: pnpm install --frozen-lockfile

- id: updater
uses: ./.github/actions/updater-flags

# Keep this in step with `build:macos-universal`. The updater config must be
# inserted into the Tauri invocation, so CI spells the command out here.
- run: bun run typecheck
- run: bun run tauri build --bundles app --target universal-apple-darwin ${{ steps.updater.outputs.config }}
- run: pnpm run typecheck
- run: pnpm run tauri build --bundles app --target universal-apple-darwin ${{ steps.updater.outputs.config }}
- name: Verify universal app binary
run: |
lipo "src-tauri/target/universal-apple-darwin/release/bundle/macos/ÆTHER.app/Contents/MacOS/aether" \
-verify_arch arm64 x86_64
- run: AETHER_TAURI_TARGET=universal-apple-darwin bun run dmg
- run: AETHER_TAURI_TARGET=universal-apple-darwin pnpm run dmg

- uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -94,21 +98,27 @@ jobs:
libssl-dev libgtk-3-dev libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev librsvg2-dev

- uses: oven-sh/setup-bun@v2
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
with:
workspaces: src-tauri

- run: bun install --frozen-lockfile
- run: bun run typecheck:web
# appdmg is macOS-only, but pnpm still sees its native helper in the
# locked dependency graph. Do not run dependency build scripts here.
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm run typecheck:web
# Unit tests are platform-independent, so one runner is enough.
- run: bun run test
- run: pnpm run test

- id: updater
uses: ./.github/actions/updater-flags

- run: bun run tauri build --bundles deb,appimage ${{ steps.updater.outputs.config }}
- run: pnpm run tauri build --bundles deb,appimage ${{ steps.updater.outputs.config }}
- run: scripts/normalize-deb-package.sh src-tauri/target/release/bundle/deb/*.deb

- uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -145,15 +155,21 @@ jobs:
libssl-dev libgtk-3-dev libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev librsvg2-dev

- uses: oven-sh/setup-bun@v2
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
with:
workspaces: src-tauri

- run: bun install --frozen-lockfile
- run: bun run typecheck:web
- run: bun run tauri build --bundles deb
# appdmg is macOS-only, but pnpm still sees its native helper in the
# locked dependency graph. Do not run dependency build scripts here.
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm run typecheck:web
- run: pnpm run tauri build --bundles deb
- run: scripts/normalize-deb-package.sh src-tauri/target/release/bundle/deb/*.deb

- uses: actions/upload-artifact@v4
Expand All @@ -172,19 +188,25 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: oven-sh/setup-bun@v2
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
with:
workspaces: src-tauri

- run: bun install --frozen-lockfile
- run: bun run typecheck:web
# appdmg is macOS-only, but pnpm still sees its native helper in the
# locked dependency graph. Do not run dependency build scripts here.
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm run typecheck:web

- id: updater
uses: ./.github/actions/updater-flags

- run: bun run tauri build --bundles nsis ${{ steps.updater.outputs.config }}
- run: pnpm run tauri build --bundles nsis ${{ steps.updater.outputs.config }}

- uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -215,7 +237,11 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: oven-sh/setup-bun@v2
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- uses: actions/setup-java@v4
with:
distribution: temurin
Expand All @@ -237,8 +263,10 @@ jobs:
echo "NDK_HOME=$ANDROID_SDK_ROOT/ndk/$NDK_VERSION" >> "$GITHUB_ENV"
echo "ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk/$NDK_VERSION" >> "$GITHUB_ENV"

- run: bun install --frozen-lockfile
- run: bun run tauri android build --apk --target aarch64
# appdmg is macOS-only, but pnpm still sees its native helper in the
# locked dependency graph. Do not run dependency build scripts here.
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm run tauri android build --apk --target aarch64

- uses: actions/upload-artifact@v4
with:
Expand Down
17 changes: 13 additions & 4 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run lint
- run: bun run typecheck:web
# action-setup must precede setup-node: the pnpm cache key setup-node
# computes needs the pnpm binary to already be on PATH. It reads the
# version from the "packageManager" field in package.json.
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
# appdmg is macOS-only, but pnpm still sees its native helper in the
# locked dependency graph. Do not run dependency build scripts here.
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm run lint
- run: pnpm run typecheck:web

rust:
name: ${{ matrix.name }}
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Quality

on:
pull_request:
paths-ignore:
- '**/*.md'
push:
branches:
- $default-branch
paths-ignore:
- '**/*.md'
workflow_dispatch:

permissions:
contents: write
pull-requests: read

jobs:
ts-checks:
uses: CanPixel/.github/.github/workflows/typescript-checks.yml@main
secrets: inherit
with:
package-manager: auto
node-version: '22'
run-lint: true
# The reusable workflow runs on bare Ubuntu and cannot install Tauri's
# GTK/WebKit system libraries. checks.yml typechecks the renderer and
# compiles Rust on all desktop platforms with the required native SDKs.
run-tsc: false
run-prettier: true
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"printWidth": 100,
"trailingComma": "all"
}
4 changes: 0 additions & 4 deletions .prettierrc.yaml

This file was deleted.

8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ Setup and prerequisites are in the [README](README.md#development-prerequisites)
Before opening a pull request:

```bash
bun run typecheck # tsc + cargo check
bun run lint # eslint
bun run test # cargo test --lib
bun run format # prettier
pnpm run typecheck # tsc + cargo check
pnpm run lint # eslint
pnpm run test # cargo test --lib
pnpm run format # prettier
```

Rust also needs to be clippy-clean:
Expand Down
Loading
Loading