Skip to content

Merge pull request #28 from fancyboi999/codex/fix-language-enforcement #29

Merge pull request #28 from fancyboi999/codex/fix-language-enforcement

Merge pull request #28 from fancyboi999/codex/fix-language-enforcement #29

Workflow file for this run

name: Build and Release
on:
push:
branches:
- main
workflow_dispatch:
inputs:
platform:
description: "Platform to build"
required: true
default: "all"
type: choice
options:
- all
- linux
- windows
- macos-intel
- macos-arm64
release:
description: "Create a release after build"
required: false
default: false
type: boolean
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: short
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- platform: linux
os: ubuntu-22.04
rust_target: x86_64-unknown-linux-gnu
tauri_target: x86_64-unknown-linux-gnu
bun_target: bun-linux-x64
name: linux-x86_64
- platform: windows
os: windows-latest
rust_target: x86_64-pc-windows-msvc
tauri_target: x86_64-pc-windows-msvc
bun_target: bun-windows-x64
name: windows-x86_64
- platform: macos-intel
os: macos-latest
rust_target: x86_64-apple-darwin
tauri_target: x86_64-apple-darwin
bun_target: bun-darwin-x64
name: macos-intel
- platform: macos-arm64
os: macos-latest
rust_target: aarch64-apple-darwin
tauri_target: aarch64-apple-darwin
bun_target: bun-darwin-arm64
name: macos-arm64
runs-on: ${{ matrix.os }}
steps:
- name: Check platform filter
id: check
shell: bash
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.platform }}" != "all" && "${{ github.event.inputs.platform }}" != "${{ matrix.platform }}" ]]; then
echo "skip=true" >> $GITHUB_OUTPUT
echo "Skipping ${{ matrix.platform }} (selected: ${{ github.event.inputs.platform }})"
else
echo "skip=false" >> $GITHUB_OUTPUT
echo "Building ${{ matrix.platform }}"
fi
- name: Checkout repository
if: steps.check.outputs.skip != 'true'
uses: actions/checkout@v4
- name: Install dependencies (Linux)
if: steps.check.outputs.skip != 'true' && matrix.platform == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libfuse2 file
# Fix for linuxdeploy in GitHub Actions (FUSE not available)
echo "APPIMAGE_EXTRACT_AND_RUN=1" >> $GITHUB_ENV
- name: Setup Node.js
if: steps.check.outputs.skip != 'true'
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Setup pnpm
if: steps.check.outputs.skip != 'true'
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Bun
if: steps.check.outputs.skip != 'true'
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Get pnpm store directory
if: steps.check.outputs.skip != 'true'
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
if: steps.check.outputs.skip != 'true'
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Setup Rust
if: steps.check.outputs.skip != 'true'
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.rust_target }}
- name: Setup Rust cache
if: steps.check.outputs.skip != 'true'
uses: swatinem/rust-cache@v2
with:
workspaces: "./src-tauri -> target"
shared-key: ${{ matrix.name }}
- name: Install frontend dependencies
if: steps.check.outputs.skip != 'true'
run: pnpm install
- name: Build API sidecar (Unix)
if: steps.check.outputs.skip != 'true' && matrix.platform != 'windows'
shell: bash
run: |
cd src-api
mkdir -p dist
bun build src/index.ts --compile --target=${{ matrix.bun_target }} --outfile dist/workany-api-${{ matrix.rust_target }}
- name: Build API sidecar (Windows)
if: steps.check.outputs.skip != 'true' && matrix.platform == 'windows'
shell: bash
run: |
cd src-api
mkdir -p dist
bun build src/index.ts --compile --target=${{ matrix.bun_target }} --outfile dist/workany-api-${{ matrix.rust_target }}.exe
- name: Bundle CLI tools (Unix)
if: steps.check.outputs.skip != 'true' && matrix.platform != 'windows'
shell: bash
run: |
cd src-api/dist
mkdir -p cli-bundle
cd cli-bundle
# Download Node.js for target platform
NODE_VERSION="22.2.0"
case "${{ matrix.rust_target }}" in
x86_64-unknown-linux-gnu)
NODE_PLATFORM="linux"
NODE_ARCH="x64"
;;
x86_64-apple-darwin)
NODE_PLATFORM="darwin"
NODE_ARCH="x64"
;;
aarch64-apple-darwin)
NODE_PLATFORM="darwin"
NODE_ARCH="arm64"
;;
esac
NODE_FILENAME="node-v${NODE_VERSION}-${NODE_PLATFORM}-${NODE_ARCH}"
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/${NODE_FILENAME}.tar.gz" | tar xz
cp "${NODE_FILENAME}/bin/node" ./node
chmod +x ./node
rm -rf "${NODE_FILENAME}"
# Install CLI packages
echo '{"name":"cli-bundle","private":true,"type":"module"}' > package.json
npm install @anthropic-ai/claude-code @openai/codex --registry=https://registry.npmmirror.com
# Copy wasm files
cp node_modules/@anthropic-ai/claude-code/*.wasm . 2>/dev/null || true
# Clean up unused platform binaries
case "${{ matrix.rust_target }}" in
x86_64-unknown-linux-gnu)
CODEX_KEEP="x86_64-unknown-linux-musl"
CLAUDE_KEEP="x64-linux"
;;
x86_64-apple-darwin)
CODEX_KEEP="x86_64-apple-darwin"
CLAUDE_KEEP="x64-darwin"
;;
aarch64-apple-darwin)
CODEX_KEEP="aarch64-apple-darwin"
CLAUDE_KEEP="arm64-darwin"
;;
esac
# Clean @openai/codex vendor
if [ -d "node_modules/@openai/codex/vendor" ]; then
for dir in node_modules/@openai/codex/vendor/*; do
dirname=$(basename "$dir")
if [ "$dirname" != "$CODEX_KEEP" ] && [ -d "$dir" ]; then
rm -rf "$dir"
fi
done
fi
# Clean @anthropic-ai/claude-code vendor/ripgrep
if [ -d "node_modules/@anthropic-ai/claude-code/vendor/ripgrep" ]; then
for item in node_modules/@anthropic-ai/claude-code/vendor/ripgrep/*; do
itemname=$(basename "$item")
if [ -d "$item" ] && [ "$itemname" != "$CLAUDE_KEEP" ]; then
rm -rf "$item"
fi
done
fi
cd ..
# Create claude launcher script using base64 decode (avoids escape issues)
# Supports: macOS (Resources), Linux (/usr/lib/WorkAny/)
echo "IyEvYmluL2Jhc2gKU0NSSVBUX0RJUj0iJChjZCAiJChkaXJuYW1lICIkMCIpIiAmJiBwd2QpIgpmb3IgRElSIGluICIkU0NSSVBUX0RJUi9jbGktYnVuZGxlIiBcCiAgICAgICAgICAgIiRTQ1JJUFRfRElSL191cF8vc3JjLWFwaS9kaXN0L2NsaS1idW5kbGUiIFwKICAgICAgICAgICAiJFNDUklQVF9ESVIvLi4vUmVzb3VyY2VzL191cF8vc3JjLWFwaS9kaXN0L2NsaS1idW5kbGUiIFwKICAgICAgICAgICAiJFNDUklQVF9ESVIvLi4vUmVzb3VyY2VzL2NsaS1idW5kbGUiIFwKICAgICAgICAgICAiJFNDUklQVF9ESVIvLi4vbGliL1dvcmtBbnkvX3VwXy9zcmMtYXBpL2Rpc3QvY2xpLWJ1bmRsZSIgXAogICAgICAgICAgICIkU0NSSVBUX0RJUi8uLi9saWIvd29ya2FueS9fdXBfL3NyYy1hcGkvZGlzdC9jbGktYnVuZGxlIjsgZG8KICAgIGlmIFsgLWYgIiRESVIvbm9kZSIgXSAmJiBbIC1kICIkRElSL25vZGVfbW9kdWxlcyIgXTsgdGhlbgogICAgICAgIEJVTkRMRV9ESVI9IiRESVIiCiAgICAgICAgYnJlYWsKICAgIGZpCmRvbmUKaWYgWyAteiAiJEJVTkRMRV9ESVIiIF07IHRoZW4KICAgIGVjaG8gIkVycm9yOiBjbGktYnVuZGxlIG5vdCBmb3VuZC4gU2VhcmNoZWQgcGF0aHM6IiA+JjIKICAgIGVjaG8gIiAgLSAkU0NSSVBUX0RJUi9jbGktYnVuZGxlIiA+JjIKICAgIGVjaG8gIiAgLSAkU0NSSVBUX0RJUi9fdXBfL3NyYy1hcGkvZGlzdC9jbGktYnVuZGxlIiA+JjIKICAgIGVjaG8gIiAgLSAkU0NSSVBUX0RJUi8uLi9SZXNvdXJjZXMvX3VwXy9zcmMtYXBpL2Rpc3QvY2xpLWJ1bmRsZSIgPiYyCiAgICBlY2hvICIgIC0gJFNDUklQVF9ESVIvLi4vbGliL1dvcmtBbnkvX3VwXy9zcmMtYXBpL2Rpc3QvY2xpLWJ1bmRsZSIgPiYyCiAgICBleGl0IDEKZmkKZXhlYyAiJEJVTkRMRV9ESVIvbm9kZSIgIiRCVU5ETEVfRElSL25vZGVfbW9kdWxlcy9AYW50aHJvcGljLWFpL2NsYXVkZS1jb2RlL2NsaS5qcyIgIiRAIgo=" | base64 -d > claude
chmod +x claude
cp claude "claude-${{ matrix.rust_target }}"
# Create codex launcher script using base64 decode
# Supports: macOS (Resources), Linux (/usr/lib/WorkAny/)
echo "IyEvYmluL2Jhc2gKU0NSSVBUX0RJUj0iJChjZCAiJChkaXJuYW1lICIkMCIpIiAmJiBwd2QpIgpmb3IgRElSIGluICIkU0NSSVBUX0RJUi9jbGktYnVuZGxlIiBcCiAgICAgICAgICAgIiRTQ1JJUFRfRElSL191cF8vc3JjLWFwaS9kaXN0L2NsaS1idW5kbGUiIFwKICAgICAgICAgICAiJFNDUklQVF9ESVIvLi4vUmVzb3VyY2VzL191cF8vc3JjLWFwaS9kaXN0L2NsaS1idW5kbGUiIFwKICAgICAgICAgICAiJFNDUklQVF9ESVIvLi4vUmVzb3VyY2VzL2NsaS1idW5kbGUiIFwKICAgICAgICAgICAiJFNDUklQVF9ESVIvLi4vbGliL1dvcmtBbnkvX3VwXy9zcmMtYXBpL2Rpc3QvY2xpLWJ1bmRsZSIgXAogICAgICAgICAgICIkU0NSSVBUX0RJUi8uLi9saWIvd29ya2FueS9fdXBfL3NyYy1hcGkvZGlzdC9jbGktYnVuZGxlIjsgZG8KICAgIGlmIFsgLWYgIiRESVIvbm9kZSIgXSAmJiBbIC1kICIkRElSL25vZGVfbW9kdWxlcyIgXTsgdGhlbgogICAgICAgIEJVTkRMRV9ESVI9IiRESVIiCiAgICAgICAgYnJlYWsKICAgIGZpCmRvbmUKaWYgWyAteiAiJEJVTkRMRV9ESVIiIF07IHRoZW4KICAgIGVjaG8gIkVycm9yOiBjbGktYnVuZGxlIG5vdCBmb3VuZC4gU2VhcmNoZWQgcGF0aHM6IiA+JjIKICAgIGVjaG8gIiAgLSAkU0NSSVBUX0RJUi9jbGktYnVuZGxlIiA+JjIKICAgIGVjaG8gIiAgLSAkU0NSSVBUX0RJUi9fdXBfL3NyYy1hcGkvZGlzdC9jbGktYnVuZGxlIiA+JjIKICAgIGVjaG8gIiAgLSAkU0NSSVBUX0RJUi8uLi9SZXNvdXJjZXMvX3VwXy9zcmMtYXBpL2Rpc3QvY2xpLWJ1bmRsZSIgPiYyCiAgICBlY2hvICIgIC0gJFNDUklQVF9ESVIvLi4vbGliL1dvcmtBbnkvX3VwXy9zcmMtYXBpL2Rpc3QvY2xpLWJ1bmRsZSIgPiYyCiAgICBleGl0IDEKZmkKZXhlYyAiJEJVTkRMRV9ESVIvbm9kZSIgIiRCVU5ETEVfRElSL25vZGVfbW9kdWxlcy9Ab3BlbmFpL2NvZGV4L2Jpbi9jb2RleC5qcyIgIiRAIgo=" | base64 -d > codex
chmod +x codex
cp codex "codex-${{ matrix.rust_target }}"
echo "CLI bundle created successfully"
ls -la
ls -la cli-bundle/
du -sh cli-bundle/
- name: Bundle CLI tools (Windows)
if: steps.check.outputs.skip != 'true' && matrix.platform == 'windows'
shell: bash
run: |
cd src-api/dist
mkdir -p cli-bundle
cd cli-bundle
# Download Node.js for Windows
NODE_VERSION="22.2.0"
NODE_FILENAME="node-v${NODE_VERSION}-win-x64"
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/${NODE_FILENAME}.zip" -o node.zip
unzip -q node.zip
cp "${NODE_FILENAME}/node.exe" ./node.exe
rm -rf "${NODE_FILENAME}" node.zip
# Install CLI packages
echo '{"name":"cli-bundle","private":true,"type":"module"}' > package.json
npm install @anthropic-ai/claude-code @openai/codex --registry=https://registry.npmmirror.com
# Copy wasm files
cp node_modules/@anthropic-ai/claude-code/*.wasm . 2>/dev/null || true
# Clean up unused platform binaries (keep Windows only)
if [ -d "node_modules/@openai/codex/vendor" ]; then
for dir in node_modules/@openai/codex/vendor/*; do
dirname=$(basename "$dir")
if [ "$dirname" != "x86_64-pc-windows-msvc" ] && [ -d "$dir" ]; then
rm -rf "$dir"
fi
done
fi
if [ -d "node_modules/@anthropic-ai/claude-code/vendor/ripgrep" ]; then
for item in node_modules/@anthropic-ai/claude-code/vendor/ripgrep/*; do
itemname=$(basename "$item")
if [ -d "$item" ] && [ "$itemname" != "x64-win32" ]; then
rm -rf "$item"
fi
done
fi
cd ..
# Create Windows batch launchers using base64 decode (avoids escape issues)
echo "QGVjaG8gb2ZmDQpzZXRsb2NhbA0Kc2V0ICJTQ1JJUFRfRElSPSV+ZHAwIg0Kc2V0ICJCVU5ETEVfRElSPSVTQ1JJUFRfRElSJWNsaS1idW5kbGUiDQppZiBub3QgZXhpc3QgIiVCVU5ETEVfRElSJVxub2RlLmV4ZSIgc2V0ICJCVU5ETEVfRElSPSVTQ1JJUFRfRElSJS4uXFJlc291cmNlc1xjbGktYnVuZGxlIg0KIiVCVU5ETEVfRElSJVxub2RlLmV4ZSIgIiVCVU5ETEVfRElSJVxub2RlX21vZHVsZXNcQGFudGhyb3BpYy1haVxjbGF1ZGUtY29kZVxjbGkuanMiICUqDQo=" | base64 -d > claude.cmd
cp claude.cmd "claude-${{ matrix.rust_target }}.cmd"
echo "QGVjaG8gb2ZmDQpzZXRsb2NhbA0Kc2V0ICJTQ1JJUFRfRElSPSV+ZHAwIg0Kc2V0ICJCVU5ETEVfRElSPSVTQ1JJUFRfRElSJWNsaS1idW5kbGUiDQppZiBub3QgZXhpc3QgIiVCVU5ETEVfRElSJVxub2RlLmV4ZSIgc2V0ICJCVU5ETEVfRElSPSVTQ1JJUFRfRElSJS4uXFJlc291cmNlc1xjbGktYnVuZGxlIg0KIiVCVU5ETEVfRElSJVxub2RlLmV4ZSIgIiVCVU5ETEVfRElSJVxub2RlX21vZHVsZXNcQG9wZW5haVxjb2RleFxiaW5cY29kZXguanMiICUqDQo=" | base64 -d > codex.cmd
cp codex.cmd "codex-${{ matrix.rust_target }}.cmd"
echo "CLI bundle created successfully"
ls -la
ls -la cli-bundle/
du -sh cli-bundle/
- name: Sign CLI bundle binaries (macOS)
if: steps.check.outputs.skip != 'true' && startsWith(matrix.platform, 'macos')
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
shell: bash
run: |
# Import certificate
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
ENTITLEMENTS_FILE="${GITHUB_WORKSPACE}/src-tauri/entitlements.plist"
# Decode and save certificate
echo -n "$APPLE_CERTIFICATE" | base64 --decode -o $CERTIFICATE_PATH
# Create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Import certificate to keychain
security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# Sign all executable binaries in cli-bundle
echo "Signing binaries in cli-bundle..."
cd src-api/dist/cli-bundle
# Sign node binary first with entitlements (required for JIT/V8)
if [ -f "node" ]; then
echo "Signing node with entitlements..."
codesign --force --options runtime --entitlements "$ENTITLEMENTS_FILE" --sign "$APPLE_SIGNING_IDENTITY" --timestamp node
fi
# Sign ALL .dylib files (including @img/sharp-libvips-*)
echo "Signing all .dylib files..."
find . -name "*.dylib" -type f | while read -r file; do
echo "Signing $file..."
codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --timestamp "$file" || true
done
# Sign ALL .node files (including @img/sharp-*)
echo "Signing all .node files..."
find . -name "*.node" -type f | while read -r file; do
echo "Signing $file..."
codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --timestamp "$file" || true
done
# Sign ALL .so files
echo "Signing all .so files..."
find . -name "*.so" -type f | while read -r file; do
echo "Signing $file..."
codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --timestamp "$file" || true
done
# Sign ripgrep and other Mach-O executables
echo "Signing Mach-O executable binaries..."
find . -type f \( -name "rg" -o -perm -u+x \) 2>/dev/null | while read -r file; do
# Skip non-binary files
case "$file" in
*.js|*.json|*.md|*.txt|*.ts|*.mjs|*.cjs|*.map|*.yml|*.yaml) continue ;;
esac
# Skip node (already signed with entitlements above)
filename=$(basename "$file")
if [ "$filename" = "node" ]; then
continue
fi
# Check if it's a Mach-O binary
if file "$file" 2>/dev/null | grep -q "Mach-O"; then
echo "Signing Mach-O: $file..."
codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --timestamp "$file" || true
fi
done
cd ../../..
# Also sign the launcher scripts (they are executables)
echo "Signing launcher scripts..."
codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --timestamp src-api/dist/claude
codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --timestamp src-api/dist/codex
echo "All binaries signed successfully"
# Cleanup
security delete-keychain $KEYCHAIN_PATH
rm -f $CERTIFICATE_PATH
- name: Update tauri.conf.json for CLI bundle (Unix)
if: steps.check.outputs.skip != 'true' && matrix.platform != 'windows'
shell: bash
run: |
node -e "
const fs = require('fs');
const config = JSON.parse(fs.readFileSync('src-tauri/tauri.conf.json', 'utf8'));
if (!config.bundle.externalBin) config.bundle.externalBin = [];
if (!config.bundle.resources) config.bundle.resources = [];
// Add CLI launchers (Unix only - they are shell scripts)
if (!config.bundle.externalBin.includes('../src-api/dist/claude')) {
config.bundle.externalBin.unshift('../src-api/dist/claude');
}
if (!config.bundle.externalBin.includes('../src-api/dist/codex')) {
config.bundle.externalBin.unshift('../src-api/dist/codex');
}
// Add cli-bundle as resource
const cliResource = '../src-api/dist/cli-bundle/**/*';
if (!config.bundle.resources.includes(cliResource)) {
config.bundle.resources = config.bundle.resources.filter(r =>
!r.includes('claude-bundle') && !r.includes('codex-bundle') && !r.includes('cli-bundle')
);
config.bundle.resources.push(cliResource);
}
fs.writeFileSync('src-tauri/tauri.conf.json', JSON.stringify(config, null, 2));
console.log('Updated tauri.conf.json with CLI bundle config (Unix)');
"
- name: Update tauri.conf.json for CLI bundle (Windows)
if: steps.check.outputs.skip != 'true' && matrix.platform == 'windows'
shell: bash
run: |
node -e "
const fs = require('fs');
const config = JSON.parse(fs.readFileSync('src-tauri/tauri.conf.json', 'utf8'));
if (!config.bundle.resources) config.bundle.resources = [];
// Windows: Don't add to externalBin (Tauri expects .exe files)
// Remove any existing claude/codex from externalBin
if (config.bundle.externalBin) {
config.bundle.externalBin = config.bundle.externalBin.filter(bin =>
!bin.includes('claude') && !bin.includes('codex')
);
}
// Add cli-bundle as resource
const cliResource = '../src-api/dist/cli-bundle/**/*';
if (!config.bundle.resources.includes(cliResource)) {
config.bundle.resources = config.bundle.resources.filter(r =>
!r.includes('claude-bundle') && !r.includes('codex-bundle') && !r.includes('cli-bundle')
);
config.bundle.resources.push(cliResource);
}
// Also add .cmd launcher files as resources for Windows
config.bundle.resources.push('../src-api/dist/claude.cmd');
config.bundle.resources.push('../src-api/dist/codex.cmd');
fs.writeFileSync('src-tauri/tauri.conf.json', JSON.stringify(config, null, 2));
console.log('Updated tauri.conf.json with CLI bundle config (Windows - resources only)');
"
- name: Build frontend
if: steps.check.outputs.skip != 'true'
run: pnpm build
- name: Build Tauri app (Linux - skip AppImage)
if: steps.check.outputs.skip != 'true' && matrix.platform == 'linux'
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tauriScript: pnpm tauri
args: --target ${{ matrix.tauri_target }} --bundles deb,rpm
- name: Build Tauri app (Windows/macOS)
if: steps.check.outputs.skip != 'true' && matrix.platform != 'linux'
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# macOS signing and notarization
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
with:
tauriScript: pnpm tauri
args: --target ${{ matrix.tauri_target }}
- name: Upload artifacts (Linux)
if: steps.check.outputs.skip != 'true' && matrix.platform == 'linux'
uses: actions/upload-artifact@v4
with:
name: WorkAny-${{ matrix.name }}
path: |
src-tauri/target/${{ matrix.tauri_target }}/release/bundle/deb/*.deb
src-tauri/target/${{ matrix.tauri_target }}/release/bundle/rpm/*.rpm
if-no-files-found: ignore
- name: Upload artifacts (Windows)
if: steps.check.outputs.skip != 'true' && matrix.platform == 'windows'
uses: actions/upload-artifact@v4
with:
name: WorkAny-${{ matrix.name }}
path: |
src-tauri/target/${{ matrix.tauri_target }}/release/bundle/msi/*.msi
src-tauri/target/${{ matrix.tauri_target }}/release/bundle/nsis/*.exe
if-no-files-found: ignore
- name: Upload artifacts (macOS)
if: steps.check.outputs.skip != 'true' && startsWith(matrix.platform, 'macos')
uses: actions/upload-artifact@v4
with:
name: WorkAny-${{ matrix.name }}
path: |
src-tauri/target/${{ matrix.tauri_target }}/release/bundle/dmg/*.dmg
src-tauri/target/${{ matrix.tauri_target }}/release/bundle/macos/*.app
if-no-files-found: ignore
release:
needs: build
runs-on: ubuntu-latest
# Auto release on: push to main or manual trigger with release=true
if: github.ref == 'refs/heads/main' || github.event.inputs.release == 'true'
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Display structure of downloaded files
run: |
ls -R artifacts
echo "---"
find artifacts -type f -name "*.deb" -o -name "*.rpm" -o -name "*.msi" -o -name "*.exe" -o -name "*.dmg" | head -20
- name: Checkout for version
uses: actions/checkout@v4
with:
path: repo
- name: Get version from package.json
id: version
run: |
VERSION=$(node -p "require('./repo/package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Flatten artifacts for release
run: |
mkdir -p release-files
find artifacts -type f \( -name "*.deb" -o -name "*.rpm" -o -name "*.msi" -o -name "*.exe" -o -name "*.dmg" \) -exec cp {} release-files/ \;
ls -la release-files/
- name: Create Release
uses: softprops/action-gh-release@v2
with:
draft: true
generate_release_notes: true
tag_name: v${{ steps.version.outputs.version }}
name: WorkAny v${{ steps.version.outputs.version }}
files: release-files/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}