Update build.yml #64
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - "v*" | |
| paths: | |
| - "backend/**" | |
| - "frontend/**" | |
| - "src-tauri/**" | |
| - ".github/workflows/build.yml" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUSTC_WRAPPER: "sccache" | |
| jobs: | |
| # Build frontend once and cache it | |
| build-frontend: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| cache-hit: ${{ steps.cache-frontend.outputs.cache-hit }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| submodules: recursive | |
| - name: Generate Frontend Cache Key | |
| id: frontend-hash | |
| run: | | |
| HASH=$(find frontend/src frontend/static frontend/package.json frontend/bun.lock frontend/vite.config.ts frontend/svelte.config.js frontend/tailwind.config.js -type f | sort | xargs sha256sum | sha256sum | cut -d' ' -f1) | |
| echo "hash=$HASH" >> $GITHUB_OUTPUT | |
| - name: Cache Frontend Build | |
| id: cache-frontend | |
| uses: actions/cache@v4 | |
| with: | |
| path: frontend/build/ | |
| key: frontend-build-${{ steps.frontend-hash.outputs.hash }} | |
| restore-keys: | | |
| frontend-build- | |
| - uses: oven-sh/setup-bun@v2 | |
| if: steps.cache-frontend.outputs.cache-hit != 'true' | |
| with: | |
| bun-version: latest | |
| - name: Cache Bun Dependencies | |
| if: steps.cache-frontend.outputs.cache-hit != 'true' | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| frontend/node_modules | |
| ~/.bun/install/cache | |
| key: bun-${{ runner.os }}-${{ hashFiles('frontend/bun.lock') }} | |
| restore-keys: | | |
| bun-${{ runner.os }}- | |
| - name: Build Frontend | |
| if: steps.cache-frontend.outputs.cache-hit != 'true' | |
| run: make build-frontend | |
| - uses: actions/upload-artifact@v5 | |
| with: | |
| name: frontend-build | |
| path: frontend/build/ | |
| retention-days: 1 | |
| # Build backend and desktop in one job | |
| build: | |
| needs: build-frontend | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: ubuntu-22.04 | |
| target: x86_64-unknown-linux-gnu | |
| - platform: ubuntu-22.04 | |
| target: aarch64-unknown-linux-gnu | |
| - platform: macos-latest | |
| target: x86_64-apple-darwin | |
| - platform: macos-latest | |
| target: aarch64-apple-darwin | |
| - platform: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| - platform: windows-latest | |
| target: aarch64-pc-windows-msvc | |
| runs-on: ${{ matrix.platform }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| submodules: recursive | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - uses: swatinem/rust-cache@v2 | |
| with: | |
| workspaces: | | |
| './backend -> target' | |
| './src-tauri -> target' | |
| key: ${{ matrix.target }} | |
| cache-all-crates: true | |
| shared-key: "rust-build" | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| - name: Cache Tauri CLI | |
| id: cache-tauri-cli | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cargo/bin/cargo-tauri | |
| key: tauri-cli-2.0.0-${{ runner.os }} | |
| - name: Install Tauri CLI | |
| if: steps.cache-tauri-cli.outputs.cache-hit != 'true' | |
| env: | |
| RUSTC_WRAPPER: "" | |
| run: cargo install tauri-cli --version "^2.0.0" --locked --force | |
| - name: Download Frontend Build | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: frontend-build | |
| path: frontend/build/ | |
| - name: Install Linux Dependencies | |
| if: runner.os == 'Linux' | |
| run: | | |
| if [ "${{ matrix.target }}" = "aarch64-unknown-linux-gnu" ]; then | |
| # For ARM64 cross-compilation, configure multi-arch first | |
| sudo dpkg --add-architecture arm64 | |
| sudo sed -i 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list | |
| sudo sed -i 's/deb mirror/deb [arch=amd64] mirror/g' /etc/apt/sources.list | |
| echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted" | sudo tee -a /etc/apt/sources.list | |
| echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted" | sudo tee -a /etc/apt/sources.list | |
| echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy universe" | sudo tee -a /etc/apt/sources.list | |
| echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates universe" | sudo tee -a /etc/apt/sources.list | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu | |
| sudo apt-get install -y libssl-dev:arm64 libwebkit2gtk-4.1-dev:arm64 libappindicator3-dev:arm64 librsvg2-dev:arm64 patchelf | |
| else | |
| sudo apt-get update | |
| sudo apt-get install -y libssl-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf | |
| fi | |
| - name: Build Backend (Unix) | |
| if: runner.os != 'Windows' | |
| env: | |
| CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc | |
| OPENSSL_DIR: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '/usr/lib/aarch64-linux-gnu' || matrix.target == 'x86_64-unknown-linux-gnu' && '/usr/lib/x86_64-linux-gnu' || '' }} | |
| OPENSSL_INCLUDE_DIR: ${{ (matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'x86_64-unknown-linux-gnu') && '/usr/include' || '' }} | |
| OPENSSL_LIB_DIR: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '/usr/lib/aarch64-linux-gnu' || matrix.target == 'x86_64-unknown-linux-gnu' && '/usr/lib/x86_64-linux-gnu' || '' }} | |
| PKG_CONFIG_ALLOW_CROSS: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '1' || '' }} | |
| PKG_CONFIG_PATH: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '/usr/lib/aarch64-linux-gnu/pkgconfig' || '' }} | |
| CARGO_PROFILE_RELEASE_LTO: thin | |
| CARGO_INCREMENTAL: 1 | |
| run: | | |
| mkdir -p bin | |
| cd backend | |
| cargo fetch --target ${{ matrix.target }} | |
| cargo build --release --target ${{ matrix.target }} | |
| cp target/${{ matrix.target }}/release/open-webui-rust ../bin/open-coreui-${{ matrix.target }} | |
| - name: Build Backend (Windows) | |
| if: runner.os == 'Windows' | |
| env: | |
| CARGO_PROFILE_RELEASE_LTO: thin | |
| CARGO_INCREMENTAL: 1 | |
| run: | | |
| mkdir bin | |
| cd backend | |
| cargo build --release --target ${{ matrix.target }} | |
| copy target/${{ matrix.target }}/release/open-webui-rust.exe ..\bin\open-coreui-${{ matrix.target }}.exe | |
| - name: Build Desktop (Unix) | |
| if: runner.os != 'Windows' | |
| env: | |
| CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc | |
| PKG_CONFIG_SYSROOT_DIR: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '/usr/aarch64-linux-gnu' || '' }} | |
| OPENSSL_DIR: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '/usr/lib/aarch64-linux-gnu' || matrix.target == 'x86_64-unknown-linux-gnu' && '/usr/lib/x86_64-linux-gnu' || '' }} | |
| OPENSSL_INCLUDE_DIR: ${{ (matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'x86_64-unknown-linux-gnu') && '/usr/include' || '' }} | |
| OPENSSL_LIB_DIR: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '/usr/lib/aarch64-linux-gnu' || matrix.target == 'x86_64-unknown-linux-gnu' && '/usr/lib/x86_64-linux-gnu' || '' }} | |
| PKG_CONFIG_ALLOW_CROSS: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '1' || '' }} | |
| PKG_CONFIG_PATH: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '/usr/lib/aarch64-linux-gnu/pkgconfig' || '' }} | |
| CARGO_PROFILE_RELEASE_LTO: thin | |
| CARGO_INCREMENTAL: 1 | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| run: | | |
| cd src-tauri | |
| cargo fetch --target ${{ matrix.target }} | |
| cd .. | |
| cargo tauri build --target ${{ matrix.target }} | |
| - name: Build Desktop (Windows) | |
| if: runner.os == 'Windows' | |
| env: | |
| CARGO_PROFILE_RELEASE_LTO: thin | |
| CARGO_INCREMENTAL: 1 | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| run: | | |
| cd src-tauri | |
| cargo fetch --target ${{ matrix.target }} | |
| cd .. | |
| cargo tauri build --target ${{ matrix.target }} | |
| - name: Cache Docker Image | |
| if: runner.os == 'Linux' | |
| uses: actions/cache@v4 | |
| with: | |
| path: /tmp/archlinux-docker.tar | |
| key: archlinux-docker-${{ hashFiles('.github/workflows/build.yml') }} | |
| restore-keys: | | |
| archlinux-docker- | |
| - name: Load or Pull Docker Image | |
| if: runner.os == 'Linux' | |
| run: | | |
| if [ -f /tmp/archlinux-docker.tar ]; then | |
| docker load -i /tmp/archlinux-docker.tar | |
| else | |
| docker pull archlinux:latest | |
| docker save archlinux:latest -o /tmp/archlinux-docker.tar | |
| fi | |
| - name: Build Arch Linux Package | |
| if: runner.os == 'Linux' | |
| run: | | |
| ARCH="${{ matrix.target == 'aarch64-unknown-linux-gnu' && 'aarch64' || 'x86_64' }}" | |
| docker run --rm -v $PWD:/workspace -w /workspace archlinux:latest bash -c " | |
| pacman -Sy --noconfirm base-devel fakeroot cairo desktop-file-utils gdk-pixbuf2 glib2 gtk3 hicolor-icon-theme libsoup pango webkit2gtk-4.1 && | |
| useradd -m builder && | |
| chown -R builder:builder /workspace && | |
| su builder -c 'CARCH=${ARCH} makepkg -f' | |
| " | |
| mkdir -p arch-pkg | |
| mv *.pkg.tar.zst arch-pkg/ || true | |
| - name: Upload Artifacts | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: build-${{ matrix.target }} | |
| path: | | |
| src-tauri/target/${{ matrix.target }}/release/bundle/**/* | |
| bin/open-coreui-${{ matrix.target }}* | |
| arch-pkg/*.pkg.tar.zst | |
| if-no-files-found: error | |
| retention-days: ${{ startsWith(github.ref, 'refs/tags/v') && 90 || 30 }} | |
| release: | |
| needs: build | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Download Artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| path: artifacts | |
| pattern: build-* | |
| - name: Organize Release Assets | |
| run: | | |
| mkdir -p release-assets | |
| VERSION=$(cat src-tauri/tauri.conf.json | grep '"version"' | head -1 | sed 's/.*"version": "\(.*\)".*/\1/') | |
| # Copy desktop app packages (only the final installer packages) | |
| find artifacts -name "*.deb" -type f -exec cp {} release-assets/ \; | |
| find artifacts -name "*.rpm" -type f -exec cp {} release-assets/ \; | |
| find artifacts -name "*.dmg" -type f -exec cp {} release-assets/ \; | |
| find artifacts -name "*.msi" -type f -exec cp {} release-assets/ \; | |
| find artifacts -name "*-setup.exe" -type f -exec cp {} release-assets/ \; | |
| find artifacts -name "*.app.tar.gz" -type f -exec cp {} release-assets/ \; | |
| find artifacts -name "*.AppImage" -type f -exec cp {} release-assets/ \; | |
| find artifacts -name "*.pkg.tar.zst" -type f -exec cp {} release-assets/ \; | |
| # Copy and rename backend binaries with version | |
| find artifacts/build-x86_64-unknown-linux-gnu -name "open-coreui-x86_64-unknown-linux-gnu" -type f -exec cp {} release-assets/open-coreui-${VERSION}-x86_64-unknown-linux-gnu \; | |
| find artifacts/build-aarch64-unknown-linux-gnu -name "open-coreui-aarch64-unknown-linux-gnu" -type f -exec cp {} release-assets/open-coreui-${VERSION}-aarch64-unknown-linux-gnu \; | |
| find artifacts/build-x86_64-apple-darwin -name "open-coreui-x86_64-apple-darwin" -type f -exec cp {} release-assets/open-coreui-${VERSION}-x86_64-apple-darwin \; | |
| find artifacts/build-aarch64-apple-darwin -name "open-coreui-aarch64-apple-darwin" -type f -exec cp {} release-assets/open-coreui-${VERSION}-aarch64-apple-darwin \; | |
| find artifacts/build-x86_64-pc-windows-msvc -name "open-coreui-x86_64-pc-windows-msvc.exe" -type f -exec cp {} release-assets/open-coreui-${VERSION}-x86_64-pc-windows-msvc.exe \; | |
| find artifacts/build-aarch64-pc-windows-msvc -name "open-coreui-aarch64-pc-windows-msvc.exe" -type f -exec cp {} release-assets/open-coreui-${VERSION}-aarch64-pc-windows-msvc.exe \; | |
| ls -lh release-assets/ | |
| - name: Generate Checksums | |
| run: | | |
| cd release-assets | |
| sha256sum * > SHA256SUMS | |
| cat SHA256SUMS | |
| - name: Determine Release Type | |
| id: release_info | |
| run: | | |
| if [[ "${{ github.ref }}" == refs/tags/v* ]]; then | |
| echo "is_release=true" >> $GITHUB_OUTPUT | |
| echo "tag_name=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| echo "prerelease=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "is_release=false" >> $GITHUB_OUTPUT | |
| echo "tag_name=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | |
| echo "prerelease=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Generate Release Body | |
| id: generate_body | |
| run: | | |
| TAG="${{ steps.release_info.outputs.tag_name }}" | |
| REPO="${{ github.repository }}" | |
| IS_RELEASE="${{ steps.release_info.outputs.is_release }}" | |
| VERSION=$(cat src-tauri/tauri.conf.json | grep '"version"' | head -1 | sed 's/.*"version": "\(.*\)".*/\1/') | |
| if [ "$IS_RELEASE" == "true" ]; then | |
| WARNING="" | |
| else | |
| WARNING="**⚠️ Development build - may be unstable**"$'\n\n' | |
| fi | |
| cat > release_body.md << 'EOF' | |
| ${WARNING}## Desktop Application | |
| | Platform | Architecture | Download | | |
| |----------|-------------|----------| | |
| | Windows | x64 | [Open.CoreUI.Desktop_${VERSION}_x64-setup.exe](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_x64-setup.exe) / [.msi](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_x64_en-US.msi) | | |
| | Windows | ARM64 | [Open.CoreUI.Desktop_${VERSION}_arm64-setup.exe](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_arm64-setup.exe) / [.msi](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_arm64_en-US.msi) | | |
| | macOS | Intel | [Open.CoreUI.Desktop_${VERSION}_x64.dmg](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_x64.dmg) | | |
| | macOS | Apple Silicon | [Open.CoreUI.Desktop_${VERSION}_aarch64.dmg](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_aarch64.dmg) | | |
| | Linux | x64 | [Open.CoreUI.Desktop_${VERSION}_amd64.deb](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_amd64.deb) / [.rpm](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop-${VERSION}-1.x86_64.rpm) / [.pkg.tar.zst](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-desktop-${VERSION}-1-x86_64.pkg.tar.zst) | | |
| | Linux | ARM64 | [Open.CoreUI.Desktop_${VERSION}_arm64.deb](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop_${VERSION}_arm64.deb) / [.rpm](https://github.com/${REPO}/releases/download/${TAG}/Open.CoreUI.Desktop-${VERSION}-1.aarch64.rpm) / [.pkg.tar.zst](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-desktop-${VERSION}-1-aarch64.pkg.tar.zst) | | |
| > **macOS Users**: If you see "app is damaged" error, run this command in Terminal App: | |
| > | |
| > ```bash | |
| > sudo xattr -d com.apple.quarantine "/Applications/Open CoreUI Desktop.app" | |
| > ``` | |
| ## Backend Server (CLI) | |
| | Platform | Architecture | Binary | | |
| |----------|-------------|--------| | |
| | Linux | x64 | [open-coreui-${VERSION}-x86_64-unknown-linux-gnu](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-${VERSION}-x86_64-unknown-linux-gnu) | | |
| | Linux | ARM64 | [open-coreui-${VERSION}-aarch64-unknown-linux-gnu](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-${VERSION}-aarch64-unknown-linux-gnu) | | |
| | macOS | Intel | [open-coreui-${VERSION}-x86_64-apple-darwin](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-${VERSION}-x86_64-apple-darwin) | | |
| | macOS | Apple Silicon | [open-coreui-${VERSION}-aarch64-apple-darwin](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-${VERSION}-aarch64-apple-darwin) | | |
| | Windows | x64 | [open-coreui-${VERSION}-x86_64-pc-windows-msvc.exe](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-${VERSION}-x86_64-pc-windows-msvc.exe) | | |
| | Windows | ARM64 | [open-coreui-${VERSION}-aarch64-pc-windows-msvc.exe](https://github.com/${REPO}/releases/download/${TAG}/open-coreui-${VERSION}-aarch64-pc-windows-msvc.exe) | | |
| EOF | |
| # Replace variables | |
| sed -i "s|\${WARNING}|${WARNING}|g" release_body.md | |
| sed -i "s|\${REPO}|${REPO}|g" release_body.md | |
| sed -i "s|\${TAG}|${TAG}|g" release_body.md | |
| sed -i "s|\${VERSION}|${VERSION}|g" release_body.md | |
| { | |
| echo "body<<EOFMARKER" | |
| cat release_body.md | |
| echo "EOFMARKER" | |
| } >> $GITHUB_OUTPUT | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.release_info.outputs.tag_name }} | |
| name: ${{ steps.release_info.outputs.is_release == 'true' && format('Release {0}', steps.release_info.outputs.tag_name) || format('Development Build ({0})', steps.release_info.outputs.tag_name) }} | |
| body: ${{ steps.generate_body.outputs.body }} | |
| files: release-assets/* | |
| prerelease: ${{ steps.release_info.outputs.prerelease }} | |
| draft: false | |
| fail_on_unmatched_files: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |