release-app #3
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 App | |
| on: | |
| push: | |
| tags: ['app-v*'] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| release-desktop: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: macos-latest | |
| args: '--target aarch64-apple-darwin' | |
| rust-target: aarch64-apple-darwin | |
| - platform: macos-latest | |
| args: '--target x86_64-apple-darwin' | |
| rust-target: x86_64-apple-darwin | |
| - platform: ubuntu-22.04 | |
| args: '' | |
| rust-target: '' | |
| - platform: windows-latest | |
| args: '' | |
| rust-target: '' | |
| runs-on: ${{ matrix.platform }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10.33.0 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.rust-target }} | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| packages/app/src-tauri/target | |
| key: ${{ matrix.platform }}-cargo-app-${{ hashFiles('packages/app/src-tauri/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ matrix.platform }}-cargo-app- | |
| - name: Install Linux deps | |
| if: matrix.platform == 'ubuntu-22.04' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf | |
| - run: pnpm install --frozen-lockfile | |
| - name: Extract release notes | |
| id: notes | |
| shell: bash | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#app-v}" | |
| BODY=$(awk -v v="$VERSION" ' | |
| $1 == "##" && $2 == v { capture=1; next } | |
| capture && $1 == "##" { exit } | |
| capture { print } | |
| ' packages/app/CHANGELOG.md) | |
| [ -z "$BODY" ] && BODY="Release $VERSION" | |
| { | |
| echo "body<<RELEASE_NOTES_EOF" | |
| echo "$BODY" | |
| echo "RELEASE_NOTES_EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - uses: tauri-apps/tauri-action@v0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| with: | |
| projectPath: packages/app | |
| tagName: app-v__VERSION__ | |
| releaseName: 'sbot v__VERSION__' | |
| releaseBody: ${{ steps.notes.outputs.body }} | |
| releaseDraft: true | |
| prerelease: false | |
| includeUpdaterJson: true | |
| updaterJsonPreferNsis: true | |
| args: ${{ matrix.args }} | |
| publish-manifest: | |
| needs: release-desktop | |
| if: ${{ !cancelled() }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Sync app manifest to updater channel | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REPO: ${{ github.repository }} | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| if ! gh release download "$TAG" -R "$REPO" -p "latest.json" -O latest-app.json; then | |
| echo "::error::latest.json not found on release $TAG — no platform produced an updater manifest" | |
| exit 1 | |
| fi | |
| gh release view updater -R "$REPO" >/dev/null 2>&1 || \ | |
| gh release create updater -R "$REPO" \ | |
| --title "Updater Manifests" \ | |
| --notes "Auto-maintained by CI. Hosts updater JSON for app and helper." \ | |
| --latest=false | |
| gh release upload updater latest-app.json -R "$REPO" --clobber | |
| gh release delete-asset "$TAG" latest.json -R "$REPO" --yes || true | |
| release-android: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10.33.0 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| - uses: android-actions/setup-android@v3 | |
| with: | |
| packages: 'platform-tools platforms;android-34 build-tools;34.0.0 ndk;27.0.12077973' | |
| - name: Install Rust with Android targets | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| packages/app/src-tauri/target | |
| key: android-cargo-app-${{ hashFiles('packages/app/src-tauri/Cargo.lock') }} | |
| restore-keys: | | |
| android-cargo-app- | |
| - run: pnpm install --frozen-lockfile | |
| - name: Decode Android keystore | |
| env: | |
| ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} | |
| run: | | |
| echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$RUNNER_TEMP/release.jks" | |
| echo "ANDROID_KEYSTORE_PATH=$RUNNER_TEMP/release.jks" >> "$GITHUB_ENV" | |
| - name: Build APK | |
| working-directory: packages/app | |
| env: | |
| NDK_HOME: ${{ env.ANDROID_NDK_ROOT }} | |
| ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | |
| ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | |
| ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} | |
| run: pnpm android:build --apk | |
| - name: Rename APK | |
| id: rename | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#app-v}" | |
| [ -z "$VERSION" ] && VERSION="dev" | |
| mkdir -p artifacts | |
| cp packages/app/src-tauri/gen/android/app/build/outputs/apk/universal/release/*.apk \ | |
| "artifacts/sbot_${VERSION}_universal.apk" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Upload APK to release | |
| if: startsWith(github.ref, 'refs/tags/app-v') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| name: 'sbot v${{ steps.rename.outputs.version }}' | |
| draft: true | |
| files: artifacts/*.apk | |
| - name: Upload APK as artifact | |
| if: github.event_name == 'workflow_dispatch' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbot-android-apk | |
| path: artifacts/*.apk | |
| publish-vscode: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10.33.0 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - name: Build extension | |
| run: pnpm run build:vscode | |
| - name: Resolve version | |
| id: version | |
| shell: bash | |
| run: | | |
| PKG_VERSION=$(node -p "require('./packages/vscode-extension/package.json').version") | |
| if [ "${{ github.event_name }}" = "push" ]; then | |
| TAG_VERSION="${GITHUB_REF_NAME#app-v}" | |
| if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then | |
| echo "::error::Tag version ($TAG_VERSION) does not match packages/vscode-extension/package.json version ($PKG_VERSION) — run pnpm run release:app to keep them in sync" | |
| exit 1 | |
| fi | |
| fi | |
| echo "version=$PKG_VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Package VSIX | |
| working-directory: packages/vscode-extension | |
| run: npx --yes @vscode/vsce package --no-dependencies --out "sbot-vscode-${{ steps.version.outputs.version }}.vsix" | |
| - name: Publish to VS Marketplace | |
| if: github.event_name == 'push' | |
| working-directory: packages/vscode-extension | |
| env: | |
| VSCE_PAT: ${{ secrets.VSCE_PAT }} | |
| shell: bash | |
| run: | | |
| VSIX="sbot-vscode-${{ steps.version.outputs.version }}.vsix" | |
| set +e | |
| OUT=$(npx --yes @vscode/vsce publish --no-dependencies --packagePath "$VSIX" 2>&1) | |
| CODE=$? | |
| set -e | |
| echo "$OUT" | |
| [ $CODE -eq 0 ] && exit 0 | |
| # Same version already on the Marketplace — skip without failing the workflow, | |
| # so the rest of the release pipeline (desktop/android) isn't blocked by a | |
| # re-run of the same tag. Bump the version to actually push an update. | |
| if echo "$OUT" | grep -qi "already exists"; then | |
| echo "::warning::v${{ steps.version.outputs.version }} already on Marketplace — skipped. Bump packages/vscode-extension/package.json to release a new version." | |
| exit 0 | |
| fi | |
| exit $CODE | |
| - name: Attach VSIX to release | |
| if: github.event_name == 'push' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| files: packages/vscode-extension/sbot-vscode-${{ steps.version.outputs.version }}.vsix | |
| draft: true | |
| - name: Upload VSIX as artifact | |
| if: github.event_name == 'workflow_dispatch' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbot-vscode-vsix | |
| path: packages/vscode-extension/sbot-vscode-${{ steps.version.outputs.version }}.vsix |