name: Build & Release on: push: tags: - 'v*' workflow_dispatch: inputs: version: description: 'Version to build (e.g., v1.0.0)' required: false env: RUST_BACKTRACE: 1 CARGO_TERM_COLOR: always jobs: test: name: Run Tests runs-on: linux/amd64 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 - name: Setup Rust uses: actions-rs/toolchain@v1 with: toolchain: stable override: true - name: Cache Rust dependencies uses: actions/cache@v3 with: path: | ~/.cargo/bin/ ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: Install dependencies run: bun install - name: Run frontend tests run: bun run test --run continue-on-error: false - name: Run Rust tests run: bun run test:rust continue-on-error: false - name: Check TypeScript run: bun run check continue-on-error: false build-linux: name: Build Linux runs-on: linux/amd64 needs: test steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 - name: Setup Rust uses: actions-rs/toolchain@v1 with: toolchain: stable override: true - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libwebkit2gtk-4.1-dev \ build-essential \ curl \ wget \ file \ libssl-dev \ libgtk-3-dev \ libayatana-appindicator3-dev \ librsvg2-dev - name: Cache Rust dependencies uses: actions/cache@v3 with: path: | ~/.cargo/bin/ ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: Install dependencies run: bun install - name: Build for Linux run: bun run tauri build env: TAURI_SKIP_UPDATER: true - name: Prepare Linux artifacts run: | mkdir -p dist/linux # Copy AppImage if [ -f "src-tauri/target/release/bundle/appimage/jellytau_"*.AppImage ]; then cp src-tauri/target/release/bundle/appimage/jellytau_*.AppImage dist/linux/ fi # Copy .deb if built if [ -f "src-tauri/target/release/bundle/deb/jellytau_"*.deb ]; then cp src-tauri/target/release/bundle/deb/jellytau_*.deb dist/linux/ fi ls -lah dist/linux/ - name: Upload Linux build artifact uses: actions/upload-artifact@v3 with: name: jellytau-linux path: dist/linux/ retention-days: 30 build-android: name: Build Android runs-on: linux/amd64 needs: test steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 - name: Setup Java uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '17' - name: Setup Android SDK uses: android-actions/setup-android@v2 with: api-level: 33 - name: Setup Rust uses: actions-rs/toolchain@v1 with: toolchain: stable override: true - name: Add Android targets run: | rustup target add aarch64-linux-android rustup target add armv7-linux-androideabi rustup target add x86_64-linux-android - name: Install Android NDK run: | sdkmanager "ndk;25.1.8937393" - name: Cache Rust dependencies uses: actions/cache@v3 with: path: | ~/.cargo/bin/ ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ key: ${{ runner.os }}-cargo-android-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-android- - name: Install dependencies run: bun install - name: Resolve Android NDK path run: echo "ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk/25.1.8937393" >> "$GITHUB_ENV" - name: Set app version from tag run: | REF="${GITHUB_REF#refs/tags/v}" VERSION="${REF#refs/heads/}" # On non-tag runs keep whatever is in tauri.conf.json if echo "$GITHUB_REF" | grep -q '^refs/tags/v'; then echo "Setting version to $VERSION" sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$VERSION\"/" src-tauri/tauri.conf.json fi grep '"version"' src-tauri/tauri.conf.json - name: Initialize Android project run: bun run tauri android init env: ANDROID_NDK_HOME: ${{ env.ANDROID_NDK_HOME }} - name: Sync custom Android sources & gradle config run: ./scripts/sync-android-sources.sh - name: Write signing keystore run: | echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > "$RUNNER_TEMP/jellytau-release.jks" cat > src-tauri/gen/android/keystore.properties <> $GITHUB_OUTPUT echo "RELEASE_NAME=JellyTau ${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - name: Download Linux artifacts uses: actions/download-artifact@v3 with: name: jellytau-linux path: artifacts/linux/ - name: Download Android artifacts uses: actions/download-artifact@v3 with: name: jellytau-android path: artifacts/android/ - name: Prepare release notes id: release_notes run: | VERSION="${{ steps.tag_name.outputs.VERSION }}" echo "## 📱 JellyTau $VERSION Release" > release_notes.md echo "" >> release_notes.md echo "### 📦 Downloads" >> release_notes.md echo "" >> release_notes.md echo "#### Linux" >> release_notes.md echo "- **AppImage** - Run directly on most Linux distributions" >> release_notes.md echo "- **DEB** - Install via `sudo dpkg -i jellytau_*.deb` (Ubuntu/Debian)" >> release_notes.md echo "" >> release_notes.md echo "#### Android" >> release_notes.md echo "- **APK** - Install via `adb install jellytau-release.apk` or sideload via file manager" >> release_notes.md echo "- **AAB** - Upload to Google Play Console or testing platforms" >> release_notes.md echo "" >> release_notes.md echo "### ✨ What's New" >> release_notes.md echo "" >> release_notes.md echo "See [CHANGELOG.md](CHANGELOG.md) for detailed changes." >> release_notes.md echo "" >> release_notes.md echo "### 🔧 Installation" >> release_notes.md echo "" >> release_notes.md echo "#### Linux (AppImage)" >> release_notes.md echo "\`\`\`bash" >> release_notes.md echo "chmod +x jellytau_*.AppImage" >> release_notes.md echo "./jellytau_*.AppImage" >> release_notes.md echo "\`\`\`" >> release_notes.md echo "" >> release_notes.md echo "#### Linux (DEB)" >> release_notes.md echo "\`\`\`bash" >> release_notes.md echo "sudo dpkg -i jellytau_*.deb" >> release_notes.md echo "jellytau" >> release_notes.md echo "\`\`\`" >> release_notes.md echo "" >> release_notes.md echo "#### Android" >> release_notes.md echo "- Sideload: Download APK and install via file manager or ADB" >> release_notes.md echo "- Play Store: Coming soon" >> release_notes.md echo "" >> release_notes.md echo "### 🐛 Known Issues" >> release_notes.md echo "" >> release_notes.md echo "See [GitHub Issues](../../issues) for reported bugs." >> release_notes.md echo "" >> release_notes.md echo "### 📝 Requirements" >> release_notes.md echo "" >> release_notes.md echo "**Linux:**" >> release_notes.md echo "- 64-bit Linux system" >> release_notes.md echo "- GLIBC 2.29+" >> release_notes.md echo "" >> release_notes.md echo "**Android:**" >> release_notes.md echo "- Android 8.0 or higher" >> release_notes.md echo "- 50MB free storage" >> release_notes.md echo "" >> release_notes.md echo "---" >> release_notes.md echo "Built with Tauri, SvelteKit, and Rust 🦀" >> release_notes.md - name: Publish Gitea release & upload assets env: # GITEA_TOKEN (a PAT) is preferred; falls back to the auto-provided token. GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} AUTO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -e command -v jq >/dev/null || { echo "❌ jq is required on the runner"; exit 1; } VERSION="${{ steps.tag_name.outputs.VERSION }}" API="${GITHUB_SERVER_URL}/api/v1" REPO="${GITHUB_REPOSITORY}" TOKEN="${GITEA_TOKEN:-$AUTO_TOKEN}" case "$VERSION" in *rc*|*beta*|*alpha*) PRE=true;; *) PRE=false;; esac PAYLOAD=$(jq -n \ --arg tag "$VERSION" \ --arg name "JellyTau $VERSION" \ --rawfile body release_notes.md \ --argjson pre "$PRE" \ '{tag_name:$tag, name:$name, body:$body, draft:false, prerelease:$pre}') echo "📦 Creating release $VERSION on $REPO" RESP=$(curl -fsS -X POST "$API/repos/$REPO/releases" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/json" \ -d "$PAYLOAD") RELEASE_ID=$(echo "$RESP" | jq -r '.id') echo "Release id=$RELEASE_ID" for f in artifacts/android/* artifacts/linux/*; do [ -f "$f" ] || continue echo "⬆️ Uploading $(basename "$f")" curl -fsS -X POST \ "$API/repos/$REPO/releases/$RELEASE_ID/assets?name=$(basename "$f")" \ -H "Authorization: token $TOKEN" \ -F "attachment=@$f" >/dev/null done echo "✅ Release $VERSION published with assets"