ci: fix macOS release builds #10
Workflow file for this run
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: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*.*.*' | |
| workflow_dispatch: | |
| inputs: | |
| job: | |
| description: 'Which job to run' | |
| required: true | |
| default: 'all' | |
| type: choice | |
| options: | |
| - all | |
| - docker-only | |
| - binaries-only | |
| permissions: | |
| contents: write | |
| packages: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| create-release: | |
| name: Create Release | |
| runs-on: ubuntu-22.04 | |
| if: github.event_name == 'push' || inputs.job == 'all' || inputs.job == 'binaries-only' | |
| outputs: | |
| upload_url: ${{ steps.create_release.outputs.upload_url }} | |
| version: ${{ steps.get_version.outputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get version from tag | |
| id: get_version | |
| run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT | |
| - name: Check if release already exists | |
| id: check_release | |
| run: | | |
| if gh release view ${{ github.ref_name }} >/dev/null 2>&1; then | |
| echo "exists=true" >> $GITHUB_OUTPUT | |
| echo "Release ${{ github.ref_name }} already exists" | |
| else | |
| echo "exists=false" >> $GITHUB_OUTPUT | |
| echo "Release ${{ github.ref_name }} does not exist" | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate changelog | |
| if: steps.check_release.outputs.exists == 'false' | |
| id: changelog | |
| run: | | |
| if [ $(git tag --list | wc -l) -eq 1 ]; then | |
| # First release - include all commits | |
| cat << EOF > changelog.md | |
| ## Initial Release v${{ steps.get_version.outputs.version }} | |
| First release of KURPOD Server - a secure encrypted file storage solution! | |
| ### Features | |
| - ** Military-grade encryption** using XChaCha20-Poly1305 + Argon2id | |
| - ** Plausible deniability** with dual volume support (standard + hidden) | |
| - ** Web interface** for easy file management from any device | |
| - ** Single binary** - no complex installation required | |
| - ** Cross-platform** support (Linux, macOS, Windows) | |
| ### 📥 Download Instructions | |
| 1. Download the appropriate binary for your platform below | |
| 2. Extract the archive: \`tar -xzf kurpod-*.tar.gz\` (or unzip \`*.zip\` for Windows) | |
| 3. Run the server: \`./kurpod_server\` (or \`kurpod_server.exe\` on Windows) | |
| 4. Open your browser to \`http://localhost:3000\` | |
| ### 🔐 Security Features | |
| - **Zero-knowledge architecture** - server never sees unencrypted data | |
| - **Password-based encryption** with strong key derivation | |
| - **File integrity verification** with authenticated encryption | |
| - **Memory security** with automatic key cleanup | |
| ### 📚 Documentation | |
| - [User Manual](https://github.com/${{ github.repository }}/blob/main/docs/USER_MANUAL.md) | |
| - [Architecture Documentation](https://github.com/${{ github.repository }}/blob/main/docs/ARCHITECTURE.md) | |
| - [Contributing Guidelines](https://github.com/${{ github.repository }}/blob/main/docs/CONTRIBUTING.md) | |
| ### 📋 Platform Support | |
| - **Linux x86_64** (GNU and musl libc) | |
| - **Linux ARM64** (Raspberry Pi and ARM servers) | |
| - **macOS Intel** (x86_64) | |
| - **macOS Apple Silicon** (M1/M2/M3) | |
| - **Windows x86_64** and **Windows ARM64** | |
| - **Docker** (Multi-arch: linux/amd64, linux/arm64) | |
| ### 🐳 Docker Usage | |
| \`\`\`bash | |
| # Pull and run latest version | |
| docker run -p 3000:3000 ghcr.io/srv1n/kurpod-server:latest | |
| # Run with persistent storage | |
| docker run -p 3000:3000 -e BLOB_DIR=/data -v ./data:/data ghcr.io/srv1n/kurpod-server:latest | |
| # Run specific version | |
| docker run -p 3000:3000 ghcr.io/srv1n/kurpod:v${{ steps.get_version.outputs.version }} | |
| \`\`\` | |
| ⚠️ **License**: This software is licensed under AGPLv3. | |
| EOF | |
| else | |
| # Get previous tag | |
| PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1) | |
| cat << EOF > changelog.md | |
| ## What's Changed in v${{ steps.get_version.outputs.version }} | |
| ### Changes Since $PREV_TAG | |
| EOF | |
| git log --oneline --pretty=format:"- %s" $PREV_TAG..HEAD | head -20 >> changelog.md | |
| cat << EOF >> changelog.md | |
| ### Download Instructions | |
| 1. Download the appropriate binary for your platform below | |
| 2. Extract: \`tar -xzf kurpod-*.tar.gz\` (or unzip \`*.zip\` for Windows) | |
| 3. Run: \`./kurpod_server\` (or \`kurpod_server.exe\` on Windows) | |
| ### Docker | |
| \`\`\`bash | |
| docker run -p 3000:3000 ghcr.io/srv1n/kurpod:v${{ steps.get_version.outputs.version }} | |
| \`\`\` | |
| **Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...${{ github.ref_name }} | |
| EOF | |
| fi | |
| echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT | |
| cat changelog.md >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: Create Release | |
| if: steps.check_release.outputs.exists == 'false' | |
| id: create_release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| name: "KURPOD Server ${{ github.ref_name }}" | |
| body: ${{ steps.changelog.outputs.CHANGELOG }} | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: false | |
| build-and-upload: | |
| name: Build and Upload (${{ matrix.target }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: create-release | |
| if: github.event_name == 'push' || inputs.job == 'all' || inputs.job == 'binaries-only' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Linux builds | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-22.04 | |
| name: linux-x86_64 | |
| display_name: "Linux x86_64" | |
| cross: false | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-22.04 | |
| name: linux-x86_64-musl | |
| display_name: "Linux x86_64 (musl)" | |
| cross: false | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-22.04 | |
| name: linux-arm64 | |
| display_name: "Linux ARM64 (Raspberry Pi)" | |
| cross: true | |
| - target: aarch64-unknown-linux-musl | |
| os: ubuntu-22.04 | |
| name: linux-arm64-musl | |
| display_name: "Linux ARM64 (musl)" | |
| cross: true | |
| # macOS builds | |
| - target: x86_64-apple-darwin | |
| os: macos-15-intel | |
| name: darwin-intel | |
| display_name: "macOS Intel" | |
| cross: false | |
| - target: aarch64-apple-darwin | |
| os: macos-15 | |
| name: darwin-apple-silicon | |
| display_name: "macOS Apple Silicon" | |
| cross: false | |
| # Windows builds | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-2022 | |
| name: windows-x86_64 | |
| display_name: "Windows x86_64" | |
| cross: false | |
| - target: aarch64-pc-windows-msvc | |
| os: windows-2022 | |
| name: windows-arm64 | |
| display_name: "Windows ARM64" | |
| cross: false | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install cross-compilation tools | |
| if: matrix.cross | |
| run: cargo install cross --git https://github.com/cross-rs/cross | |
| - name: Cache dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: release-${{ matrix.target }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.2.15 | |
| - name: Build frontend | |
| run: | | |
| cd frontend | |
| bun install --frozen-lockfile | |
| bun run build | |
| - name: Install Linux dependencies | |
| if: runner.os == 'Linux' && !matrix.cross | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y pkg-config libssl-dev | |
| if [[ "${{ matrix.target }}" == *"musl"* ]]; then | |
| sudo apt-get install -y musl-tools | |
| fi | |
| - name: Build binary (native) | |
| if: '!matrix.cross' | |
| run: cargo build --release --target ${{ matrix.target }} -p kurpod_server | |
| env: | |
| CARGO_TARGET_DIR: target | |
| - name: Build binary (cross-compilation) | |
| if: matrix.cross | |
| run: cross build --release --target ${{ matrix.target }} -p kurpod_server | |
| env: | |
| CARGO_TARGET_DIR: target | |
| # macOS code signing and notarization | |
| - name: Import Code-Signing Certificates (macOS) | |
| if: runner.os == 'macOS' | |
| uses: Apple-Actions/import-codesign-certs@v3 | |
| with: | |
| p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} | |
| p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} | |
| - name: Sign macOS binary | |
| if: runner.os == 'macOS' | |
| run: | | |
| codesign --force --sign "${{ secrets.APPLE_DEVELOPER_CERTIFICATE_ID }}" \ | |
| --options runtime \ | |
| --entitlements .github/entitlements.plist \ | |
| target/${{ matrix.target }}/release/kurpod_server | |
| # Verify the signature | |
| codesign --verify --verbose target/${{ matrix.target }}/release/kurpod_server | |
| - name: Notarize macOS binary | |
| if: runner.os == 'macOS' | |
| run: | | |
| # Create a zip file for notarization | |
| cd target/${{ matrix.target }}/release | |
| zip kurpod_server.zip kurpod_server | |
| # Submit for notarization | |
| xcrun notarytool submit kurpod_server.zip \ | |
| --apple-id "${{ secrets.APPLE_ID }}" \ | |
| --password "${{ secrets.APPLE_APP_PASSWORD }}" \ | |
| --team-id "${{ secrets.APPLE_TEAM_ID }}" \ | |
| --wait | |
| # Extract the binary back | |
| unzip -o kurpod_server.zip | |
| rm kurpod_server.zip | |
| # Staple the notarization ticket (with retries) | |
| echo "Attempting to staple notarization ticket..." | |
| for i in {1..5}; do | |
| if xcrun stapler staple kurpod_server; then | |
| echo "Stapling successful on attempt $i" | |
| xcrun stapler validate kurpod_server | |
| break | |
| else | |
| echo "Stapling attempt $i failed, waiting 30 seconds..." | |
| if [ $i -eq 5 ]; then | |
| echo "Stapling failed after 5 attempts, but notarization was successful." | |
| echo "The binary is notarized and will work, just without offline verification." | |
| else | |
| sleep 30 | |
| fi | |
| fi | |
| done | |
| # Linux GPG signing | |
| - name: Sign Linux binary with GPG | |
| if: runner.os == 'Linux' | |
| run: | | |
| # Setup GPG environment for non-interactive signing | |
| mkdir -p ~/.gnupg | |
| chmod 700 ~/.gnupg | |
| # Import GPG key | |
| echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import | |
| # Configure GPG for loopback pinentry (non-interactive) | |
| echo 'pinentry-mode loopback' >> ~/.gnupg/gpg.conf | |
| echo 'allow-loopback-pinentry' >> ~/.gnupg/gpg-agent.conf | |
| # Kill any auto-started agent so it reloads the new config | |
| gpgconf --kill gpg-agent || true | |
| # Sign the binary (creates .sig file) | |
| gpg --batch --yes \ | |
| --pinentry-mode loopback \ | |
| --passphrase "${{ secrets.GPG_PASSPHRASE }}" \ | |
| --local-user "${{ secrets.GPG_KEY_ID }}" \ | |
| --armor --detach-sign \ | |
| "target/${{ matrix.target }}/release/kurpod_server" | |
| # Verify signature | |
| gpg --verify "target/${{ matrix.target }}/release/kurpod_server.asc" "target/${{ matrix.target }}/release/kurpod_server" | |
| - name: Prepare Windows release asset | |
| if: runner.os == 'Windows' | |
| run: | | |
| mkdir release-assets | |
| copy "target\${{ matrix.target }}\release\kurpod_server.exe" "release-assets\" | |
| cd release-assets | |
| # Create README for Windows | |
| echo "KURPOD Server v${{ needs.create-release.outputs.version }} - ${{ matrix.name }}" > README.txt | |
| echo "" >> README.txt | |
| echo "## Quick Start" >> README.txt | |
| echo "1. Extract this zip file" >> README.txt | |
| echo "2. Run: kurpod_server.exe" >> README.txt | |
| echo "3. Open browser: http://localhost:3000" >> README.txt | |
| echo "" >> README.txt | |
| echo "## Options" >> README.txt | |
| echo "kurpod_server.exe --help # Show all options" >> README.txt | |
| echo "kurpod_server.exe --port 8080 # Use custom port" >> README.txt | |
| echo "kurpod_server.exe --blob data.blob # Use custom storage file" >> README.txt | |
| echo "" >> README.txt | |
| echo "## Documentation" >> README.txt | |
| echo "https://github.com/${{ github.repository }}" >> README.txt | |
| echo "" >> README.txt | |
| echo "## License" >> README.txt | |
| echo "Licensed under AGPLv3" >> README.txt | |
| 7z a "kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.zip" kurpod_server.exe README.txt | |
| echo "ASSET_PATH=release-assets/kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.zip" >> $env:GITHUB_ENV | |
| echo "ASSET_NAME=kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.zip" >> $env:GITHUB_ENV | |
| echo "CONTENT_TYPE=application/zip" >> $env:GITHUB_ENV | |
| - name: Prepare Unix release asset | |
| if: runner.os != 'Windows' | |
| run: | | |
| mkdir -p release-assets | |
| cp target/${{ matrix.target }}/release/kurpod_server release-assets/ | |
| # Copy signature files for Linux | |
| if [ "${{ runner.os }}" = "Linux" ] && [ -f "target/${{ matrix.target }}/release/kurpod_server.asc" ]; then | |
| cp target/${{ matrix.target }}/release/kurpod_server.asc release-assets/ | |
| fi | |
| cd release-assets | |
| # Create README for the release | |
| cat << EOF > README.txt | |
| KURPOD Server v${{ needs.create-release.outputs.version }} - ${{ matrix.name }} | |
| ## Quick Start | |
| 1. Extract this archive | |
| 2. Run: ./kurpod_server | |
| 3. Open browser: http://localhost:3000 | |
| ## Options | |
| ./kurpod_server --help # Show all options | |
| ./kurpod_server --port 8080 # Use custom port | |
| ./kurpod_server --blob data.blob # Use custom storage file | |
| ## Documentation | |
| https://github.com/${{ github.repository }} | |
| ## Support | |
| - Report issues: https://github.com/${{ github.repository }}/issues | |
| - User manual: https://github.com/${{ github.repository }}/blob/main/docs/USER_MANUAL.md | |
| ## License | |
| Licensed under AGPLv3 | |
| EOF | |
| # Create the archive | |
| if [ "${{ runner.os }}" = "Linux" ] && [ -f "kurpod_server.asc" ]; then | |
| tar -czf kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz kurpod_server kurpod_server.asc README.txt | |
| else | |
| tar -czf kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz kurpod_server README.txt | |
| fi | |
| # Generate checksums | |
| if command -v sha256sum >/dev/null; then | |
| sha256sum kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz > kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz.sha256 | |
| elif command -v shasum >/dev/null; then | |
| shasum -a 256 kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz > kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz.sha256 | |
| fi | |
| echo "ASSET_PATH=release-assets/kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz" >> $GITHUB_ENV | |
| echo "CHECKSUM_PATH=release-assets/kurpod-v${{ needs.create-release.outputs.version }}-${{ matrix.name }}.tar.gz.sha256" >> $GITHUB_ENV | |
| - name: Upload release binary | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| files: ${{ env.ASSET_PATH }} | |
| - name: Upload checksum (Unix only) | |
| if: runner.os != 'Windows' | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| files: ${{ env.CHECKSUM_PATH }} | |
| create-checksums: | |
| name: Create Combined Checksums | |
| runs-on: ubuntu-22.04 | |
| needs: [create-release, build-and-upload] | |
| if: github.event_name == 'push' || inputs.job == 'all' || inputs.job == 'binaries-only' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Download all release assets | |
| uses: robinraju/release-downloader@v1.8 | |
| with: | |
| tag: ${{ github.ref_name }} | |
| fileName: "*" | |
| out-file-path: "downloads" | |
| - name: Generate combined checksums | |
| run: | | |
| cd downloads | |
| # Create combined SHA256 checksums file | |
| cat << EOF > SHA256SUMS | |
| # KURPOD Server v${{ needs.create-release.outputs.version }} - SHA256 Checksums | |
| # Verify with: sha256sum -c SHA256SUMS | |
| EOF | |
| # Add checksums for all binary archives | |
| for file in *.tar.gz *.zip; do | |
| if [ -f "$file" ]; then | |
| if command -v sha256sum >/dev/null; then | |
| sha256sum "$file" >> SHA256SUMS | |
| elif command -v shasum >/dev/null; then | |
| shasum -a 256 "$file" >> SHA256SUMS | |
| fi | |
| fi | |
| done | |
| # Create installation script | |
| cat << 'EOF' > install.sh | |
| #!/bin/bash | |
| set -e | |
| # KURPOD Server Installation Script | |
| VERSION="${{ needs.create-release.outputs.version }}" | |
| REPO="${{ github.repository }}" | |
| # Detect platform | |
| OS=$(uname -s | tr '[:upper:]' '[:lower:]') | |
| ARCH=$(uname -m) | |
| case $OS in | |
| linux) | |
| case $ARCH in | |
| x86_64) PLATFORM="linux-x86_64" ;; | |
| aarch64|arm64) PLATFORM="linux-arm64" ;; | |
| *) echo "Unsupported architecture: $ARCH"; exit 1 ;; | |
| esac | |
| ARCHIVE="kurpod-v${VERSION}-${PLATFORM}.tar.gz" | |
| ;; | |
| darwin) | |
| case $ARCH in | |
| x86_64) PLATFORM="darwin-intel" ;; | |
| arm64) PLATFORM="darwin-apple-silicon" ;; | |
| *) echo "Unsupported architecture: $ARCH"; exit 1 ;; | |
| esac | |
| ARCHIVE="kurpod-v${VERSION}-${PLATFORM}.tar.gz" | |
| ;; | |
| *) | |
| echo "Unsupported OS: $OS" | |
| echo "Please download manually from: https://github.com/${REPO}/releases/tag/v${VERSION}" | |
| exit 1 | |
| ;; | |
| esac | |
| echo "Installing KURPOD Server v${VERSION} for ${OS}-${ARCH}" | |
| echo "Downloading ${ARCHIVE}..." | |
| # Download and extract | |
| curl -sL "https://github.com/${REPO}/releases/download/v${VERSION}/${ARCHIVE}" | tar -xz | |
| # Make executable | |
| chmod +x kurpod_server | |
| # Determine install location (prefer user install) | |
| if [ -n "$HOME" ] && mkdir -p "$HOME/.local/bin" 2>/dev/null; then | |
| INSTALL_DIR="$HOME/.local/bin" | |
| mv kurpod_server "$INSTALL_DIR/" | |
| echo "✅ KURPOD Server installed to $INSTALL_DIR/kurpod_server" | |
| # Add to PATH if not already there | |
| if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then | |
| echo "" | |
| echo " Add to your shell profile to make 'kurpod_server' available globally:" | |
| echo " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.bashrc" | |
| echo " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.zshrc" | |
| echo "" | |
| echo " Or reload your shell: source ~/.bashrc (or ~/.zshrc)" | |
| fi | |
| elif [ -w "/usr/local/bin" ]; then | |
| mv kurpod_server /usr/local/bin/ | |
| echo "✅ KURPOD Server installed to /usr/local/bin/kurpod_server" | |
| else | |
| echo "ℹ KURPOD Server extracted to current directory" | |
| echo " Run with: ./kurpod_server" | |
| echo "" | |
| echo " To install system-wide:" | |
| echo " sudo mv kurpod_server /usr/local/bin/" | |
| echo "" | |
| echo "🏠 To install for current user:" | |
| echo " mkdir -p ~/.local/bin && mv kurpod_server ~/.local/bin/" | |
| echo " export PATH=\"\$HOME/.local/bin:\$PATH\"" | |
| fi | |
| echo "" | |
| echo "Installation complete!" | |
| echo "Usage: kurpod_server --help" | |
| echo "Start server: kurpod_server" | |
| echo "Open browser: http://localhost:3000" | |
| EOF | |
| chmod +x install.sh | |
| - name: Upload combined checksums | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| files: | | |
| downloads/SHA256SUMS | |
| downloads/install.sh | |
| docker-build: | |
| name: Build and Push Docker Images | |
| runs-on: ubuntu-22.04 | |
| needs: [create-release] | |
| if: always() && (github.event_name == 'push' || inputs.job == 'all' || inputs.job == 'docker-only') | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.2.15 | |
| - name: Build frontend | |
| run: | | |
| cd frontend | |
| bun install --frozen-lockfile | |
| bun run build | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ghcr.io/${{ github.repository }}-server | |
| tags: | | |
| type=ref,event=tag | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| provenance: false # skip SBOM generation for faster builds | |
| # Disable GitHub Actions cache to avoid timeout issues with long builds | |
| # cache-from: type=gha | |
| # cache-to: type=gha,mode=max | |
| build-args: | | |
| VERSION=${{ needs.create-release.outputs.version }} |