name: Build App on: push: branches: [main] paths: - "app/**" - ".gitea/workflows/build-app.yml" pull_request: branches: [main] paths: - "app/**" workflow_dispatch: env: GITEA_URL: ${{ gitea.server_url }} REPO: ${{ gitea.repository }} jobs: build-linux: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Compute version id: version run: | COMMIT_COUNT=$(git rev-list --count HEAD) VERSION="0.1.${COMMIT_COUNT}" echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT echo "Computed version: ${VERSION}" - name: Set app version run: | VERSION="${{ steps.version.outputs.VERSION }}" sed -i "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/src-tauri/tauri.conf.json sed -i "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/package.json sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" app/src-tauri/Cargo.toml echo "Patched version to ${VERSION}" - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libgtk-3-dev \ libwebkit2gtk-4.1-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ libsoup-3.0-dev \ libssl-dev \ libxdo-dev \ patchelf \ pkg-config \ build-essential \ curl \ wget \ file \ xdg-utils - name: Install Rust stable run: | if command -v rustup &>/dev/null; then echo "Rust already installed: $(rustc --version)" rustup update stable rustup default stable else curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable . "$HOME/.cargo/env" fi rustc --version cargo --version - name: Install Node.js run: | if command -v node &>/dev/null; then echo "Node.js already installed: $(node --version)" else echo "Installing Node.js 22..." curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt-get install -y nodejs fi node --version npm --version - name: Install frontend dependencies working-directory: ./app run: npm ci - name: Install Tauri CLI working-directory: ./app run: npx tauri --version || npm install @tauri-apps/cli - name: Build Tauri app working-directory: ./app run: npx tauri build - name: Collect artifacts run: | mkdir -p artifacts cp app/src-tauri/target/release/bundle/appimage/*.AppImage artifacts/ 2>/dev/null || true cp app/src-tauri/target/release/bundle/deb/*.deb artifacts/ 2>/dev/null || true cp app/src-tauri/target/release/bundle/rpm/*.rpm artifacts/ 2>/dev/null || true ls -la artifacts/ - name: Upload to Gitea release if: gitea.event_name == 'push' env: TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | TAG="v${{ steps.version.outputs.VERSION }}" # Create release curl -s -X POST \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"tag_name\": \"${TAG}\", \"name\": \"Triple-C ${TAG} (Linux)\", \"body\": \"Automated build from commit ${{ gitea.sha }}\"}" \ "${GITEA_URL}/api/v1/repos/${REPO}/releases" > release.json RELEASE_ID=$(cat release.json | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*') echo "Release ID: ${RELEASE_ID}" # Upload each artifact for file in artifacts/*; do [ -f "$file" ] || continue filename=$(basename "$file") echo "Uploading ${filename}..." curl -s -X POST \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/octet-stream" \ --data-binary "@${file}" \ "${GITEA_URL}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${filename}" done build-macos: runs-on: macos-latest steps: - name: Install Node.js run: | if command -v node &>/dev/null; then echo "Node.js already installed: $(node --version)" else echo "Installing Node.js 22 via Homebrew..." brew install node@22 brew link --overwrite node@22 fi node --version npm --version - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Compute version id: version run: | COMMIT_COUNT=$(git rev-list --count HEAD) VERSION="0.1.${COMMIT_COUNT}" echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT echo "Computed version: ${VERSION}" - name: Set app version run: | VERSION="${{ steps.version.outputs.VERSION }}" sed -i '' "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/src-tauri/tauri.conf.json sed -i '' "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/package.json sed -i '' "s/^version = \".*\"/version = \"${VERSION}\"/" app/src-tauri/Cargo.toml echo "Patched version to ${VERSION}" - name: Install Rust stable run: | if command -v rustup &>/dev/null; then rustup update stable rustup default stable else curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable . "$HOME/.cargo/env" fi rustup target add aarch64-apple-darwin x86_64-apple-darwin rustc --version cargo --version - name: Install frontend dependencies working-directory: ./app run: npm ci - name: Install Tauri CLI working-directory: ./app run: npx tauri --version || npm install @tauri-apps/cli - name: Build Tauri app (universal) working-directory: ./app env: PATH: ${{ format('{0}/.cargo/bin:{1}', env.HOME, env.PATH) }} run: npx tauri build --target universal-apple-darwin - name: Collect artifacts run: | mkdir -p artifacts cp app/src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg artifacts/ 2>/dev/null || true cp app/src-tauri/target/universal-apple-darwin/release/bundle/macos/*.app.tar.gz artifacts/ 2>/dev/null || true ls -la artifacts/ - name: Upload to Gitea release if: gitea.event_name == 'push' env: TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | TAG="v${{ steps.version.outputs.VERSION }}-mac" # Create release curl -s -X POST \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"tag_name\": \"${TAG}\", \"name\": \"Triple-C v${{ steps.version.outputs.VERSION }} (macOS)\", \"body\": \"Automated build from commit ${{ gitea.sha }}\"}" \ "${GITEA_URL}/api/v1/repos/${REPO}/releases" > release.json RELEASE_ID=$(cat release.json | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*') echo "Release ID: ${RELEASE_ID}" # Upload each artifact for file in artifacts/*; do [ -f "$file" ] || continue filename=$(basename "$file") echo "Uploading ${filename}..." curl -s -X POST \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/octet-stream" \ --data-binary "@${file}" \ "${GITEA_URL}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${filename}" done build-windows: runs-on: windows-latest defaults: run: shell: cmd steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Compute version id: version run: | for /f %%i in ('git rev-list --count HEAD') do set "COMMIT_COUNT=%%i" set "VERSION=0.1.%COMMIT_COUNT%" echo VERSION=%VERSION%>> %GITHUB_OUTPUT% echo Computed version: %VERSION% - name: Set app version shell: powershell run: | $version = "${{ steps.version.outputs.VERSION }}" (Get-Content app/src-tauri/tauri.conf.json) -replace '"version": ".*?"', "`"version`": `"$version`"" | Set-Content app/src-tauri/tauri.conf.json (Get-Content app/package.json) -replace '"version": ".*?"', "`"version`": `"$version`"" | Set-Content app/package.json (Get-Content app/src-tauri/Cargo.toml) -replace '^version = ".*?"', "version = `"$version`"" | Set-Content app/src-tauri/Cargo.toml Write-Host "Patched version to $version" - name: Install Rust stable run: | where rustup >nul 2>&1 && ( rustup update stable rustup default stable ) || ( curl -fSL -o rustup-init.exe https://win.rustup.rs/x86_64 rustup-init.exe -y --default-toolchain stable del rustup-init.exe ) - name: Install Node.js run: | where node >nul 2>&1 && ( node --version ) || ( curl -fSL -o node-install.msi "https://nodejs.org/dist/v22.14.0/node-v22.14.0-x64.msi" msiexec /i node-install.msi /quiet /norestart del node-install.msi ) - name: Verify tools run: | set "PATH=%USERPROFILE%\.cargo\bin;C:\Program Files\nodejs;%PATH%" rustc --version cargo --version node --version npm --version - name: Install Tauri CLI via cargo run: | set "PATH=%USERPROFILE%\.cargo\bin;C:\Program Files\nodejs;%PATH%" cargo install tauri-cli --version "^2" - name: Fix npm platform detection run: | set "PATH=%USERPROFILE%\.cargo\bin;C:\Program Files\nodejs;%PATH%" npm config set os win32 npm config list - name: Install frontend dependencies working-directory: ./app run: | set "PATH=%USERPROFILE%\.cargo\bin;C:\Program Files\nodejs;%PATH%" if exist node_modules rmdir /s /q node_modules npm ci - name: Build frontend working-directory: ./app run: | set "PATH=%USERPROFILE%\.cargo\bin;C:\Program Files\nodejs;%PATH%" npm run build - name: Build Tauri app working-directory: ./app env: TAURI_CONFIG: "{\"build\":{\"beforeBuildCommand\":\"\"}}" run: | set "PATH=%USERPROFILE%\.cargo\bin;C:\Program Files\nodejs;%PATH%" cargo tauri build - name: Collect artifacts run: | set "PATH=%USERPROFILE%\.cargo\bin;C:\Program Files\nodejs;%PATH%" mkdir artifacts copy app\src-tauri\target\release\bundle\msi\*.msi artifacts\ 2>nul copy app\src-tauri\target\release\bundle\nsis\*.exe artifacts\ 2>nul dir artifacts\ - name: Upload to Gitea release if: gitea.event_name == 'push' env: TOKEN: ${{ secrets.REGISTRY_TOKEN }} COMMIT_SHA: ${{ gitea.sha }} run: | set "TAG=v${{ steps.version.outputs.VERSION }}-win" echo Creating release %TAG%... curl -s -X POST -H "Authorization: token %TOKEN%" -H "Content-Type: application/json" -d "{\"tag_name\": \"%TAG%\", \"name\": \"Triple-C v${{ steps.version.outputs.VERSION }} (Windows)\", \"body\": \"Automated build from commit %COMMIT_SHA%\"}" "%GITEA_URL%/api/v1/repos/%REPO%/releases" > release.json for /f "tokens=2 delims=:," %%a in ('findstr /c:"\"id\"" release.json') do set "RELEASE_ID=%%a" & goto :found :found echo Release ID: %RELEASE_ID% for %%f in (artifacts\*) do ( echo Uploading %%~nxf... curl -s -X POST -H "Authorization: token %TOKEN%" -H "Content-Type: application/octet-stream" --data-binary "@%%f" "%GITEA_URL%/api/v1/repos/%REPO%/releases/%RELEASE_ID%/assets?name=%%~nxf" )