diff --git a/.changes/mobile.md b/.changes/mobile.md
new file mode 100644
index 0000000..1c38ac3
--- /dev/null
+++ b/.changes/mobile.md
@@ -0,0 +1,5 @@
+---
+action: patch
+---
+
+Added initial Android & iOS support. This only includes building (=== running `tauri android|ios build`), installing dependencies and uploading to stores must be done manually.
diff --git a/.github/fixtures/example-with-tauri-v2/src-tauri/Cargo.toml b/.github/fixtures/example-with-tauri-v2/src-tauri/Cargo.toml
index e72e538..1e75a1f 100644
--- a/.github/fixtures/example-with-tauri-v2/src-tauri/Cargo.toml
+++ b/.github/fixtures/example-with-tauri-v2/src-tauri/Cargo.toml
@@ -7,14 +7,23 @@ license = ""
repository = ""
edition = "2021"
-[dependencies]
-serde_json = "1"
-serde = { version = "1", features = ["derive"] }
-tauri = { version = "2", features = [] }
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[lib]
+# The `_lib` suffix may seem redundant but it is necessary
+# to make the lib name unique and wouldn't conflict with the bin name.
+# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
+name = "test_app_lib"
+crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
+[dependencies]
+tauri = { version = "2", features = [] }
+serde = { version = "1", features = ["derive"] }
+serde_json = "1"
+
[profile.dev]
opt-level = 0
lto = false
diff --git a/.github/fixtures/example-with-tauri-v2/src-tauri/src/lib.rs b/.github/fixtures/example-with-tauri-v2/src-tauri/src/lib.rs
new file mode 100644
index 0000000..3b48e91
--- /dev/null
+++ b/.github/fixtures/example-with-tauri-v2/src-tauri/src/lib.rs
@@ -0,0 +1,6 @@
+#[cfg_attr(mobile, tauri::mobile_entry_point)]
+pub fn run() {
+ tauri::Builder::default()
+ .run(tauri::generate_context!())
+ .expect("error while running tauri application");
+}
diff --git a/.github/fixtures/example-with-tauri-v2/src-tauri/src/main.rs b/.github/fixtures/example-with-tauri-v2/src-tauri/src/main.rs
index d387909..fee34e1 100644
--- a/.github/fixtures/example-with-tauri-v2/src-tauri/src/main.rs
+++ b/.github/fixtures/example-with-tauri-v2/src-tauri/src/main.rs
@@ -1,7 +1,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
- tauri::Builder::default()
- .run(tauri::generate_context!())
- .expect("error while running tauri application");
+ test_app_lib::run()
}
diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml
index 96489ef..730acf6 100644
--- a/.github/workflows/test-action.yml
+++ b/.github/workflows/test-action.yml
@@ -27,6 +27,13 @@ jobs:
args: '--verbose --debug'
- platform: 'windows-11-arm'
args: '--verbose --debug'
+ - platform: 'ubuntu-latest'
+ args: '--verbose --debug'
+ mobile: 'android'
+ # can't test without an apple account
+ #- platform: 'macos-26'
+ # args: '--verbose --debug'
+ # mobile: 'ios'
runs-on: ${{ matrix.platform }}
steps:
@@ -46,16 +53,61 @@ jobs:
- name: install example dependencies
run: |
echo "skipped"
- # disabled to test cli fallback install
+ # disabled on desktop to test cli fallback install
#cd ./.github/fixtures/example-with-tauri-v2
# pnpm install
# rust
- - name: install Rust stable
+ - name: install Rust stable (desktop)
+ if: matrix.mobile == ''
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin,x86_64-apple-darwin
+ - name: install Rust stable (android)
+ if: matrix.mobile == 'android'
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android
+
+ - name: install Rust stable (ios)
+ if: matrix.mobile == 'ios'
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ targets: aarch64-apple-ios
+
+ - name: Set up JDK
+ if: matrix.mobile == 'android'
+ uses: actions/setup-java@v5
+ with:
+ java-version: '21' # Maybe 17
+ distribution: 'temurin'
+
+ - name: Setup Android SDK
+ if: matrix.mobile == 'android'
+ uses: android-actions/setup-android@v3
+
+ - name: Setup Android NDK
+ if: matrix.mobile == 'android'
+ uses: nttld/setup-ndk@v1
+ id: setup-ndk
+ with:
+ ndk-version: r29
+ link-to-sdk: true
+
+ - uses: maxim-lobanov/setup-xcode@v1
+ if: matrix.mobile == 'ios'
+ with:
+ xcode-version: 26.1
+
+ - name: setup Apple API key
+ if: matrix.mobile == 'ios'
+ run: |
+ APPLE_API_KEY_PATH="$RUNNER_TEMP/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8"
+ echo "${{ secrets.APPLE_API_KEY }}" > $APPLE_API_KEY_PATH
+ echo "APPLE_API_KEY_PATH=$APPLE_API_KEY_PATH" >> $GITHUB_ENV
+ echo "API_PRIVATE_KEYS_DIR=$RUNNER_TEMP" >> $GITHUB_ENV
+
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
@@ -69,12 +121,19 @@ jobs:
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev
+ - name: init mobile project
+ if: matrix.mobile != ''
+ run: |
+ cd ./.github/fixtures/example-with-tauri-v2
+ pnpm dlx @tauri-apps/cli ${{ matrix.mobile }} init
+
- name: Preconfigured Tauri Project
uses: ./
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Updater signature is exposed here to make sure it works in PR's
TAURI_SIGNING_PRIVATE_KEY: dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5YTBGV3JiTy9lRDZVd3NkL0RoQ1htZmExNDd3RmJaNmRMT1ZGVjczWTBKZ0FBQkFBQUFBQUFBQUFBQUlBQUFBQWdMekUzVkE4K0tWQ1hjeGt1Vkx2QnRUR3pzQjVuV0ZpM2czWXNkRm9hVUxrVnB6TUN3K1NheHJMREhQbUVWVFZRK3NIL1VsMDBHNW5ET1EzQno0UStSb21nRW4vZlpTaXIwZFh5ZmRlL1lSN0dKcHdyOUVPclVvdzFhVkxDVnZrbHM2T1o4Tk1NWEU9Cg==
+ NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
with:
projectPath: ./.github/fixtures/example-with-tauri-v2
tagName: ${{ !github.event.pull_request.head.repo.fork && 'example-with-tauri-v__VERSION__' || '' }}
@@ -86,5 +145,6 @@ jobs:
uploadPlainBinary: true
uploadWorkflowArtifacts: true
uploadUpdaterSignatures: false
+ mobile: ${{ matrix.mobile }}
# workflowArtifactNamePattern: '[name]_${{ github.sha }}_[platform]_[arch]_[bundle]'
# releaseAssetNamePattern: '[name]x[version]x[platform]x[arch]x[mode]x[setup]x[ext]'
diff --git a/README.md b/README.md
index b5f0d66..0985b1f 100644
--- a/README.md
+++ b/README.md
@@ -244,6 +244,24 @@ jobs:
#
# default: true
uploadUpdaterSignatures: true
+
+ # EXPERIMENTAL - Whether to build for mobile or desktop.
+ #
+ # Effectively changes the build command from `${tauriScript} build`
+ # to `${tauriScript} android build` / ` ${tauriScript}ios build`
+ #
+ # Note that you have to install system dependencies (Xcode, SDKs, etc) yourself.
+ # Furthermore, the action does not upload the app to the App Store or Play Store.
+ # The .apk and .ipa files can be uploaded to the release or as workflow artifcats, but
+ # plain .ipa files are generally useless so uploading them to a release is not recommended.
+ #
+ # - Can be set to "android" to build for Android. This works on all runners but other
+ # required actions typically only work on Ubuntu so we recommend Ubuntu as well.
+ # - Can be set to "ios` to build for iOS. This only works on macOS runners.
+ # - Any other value will be ignored.
+ #
+ # default: unset
+ mobile: ''
```
## Outputs
@@ -287,6 +305,8 @@ jobs:
- `[bundle]` is likely only useful for `workflowArtifactNamePattern` and _not_ for `releaseAssetNamePattern` because of its conflict with `[ext]`.
+- The action's iOS and Android support is considered experimental, please report any issues or feedback you may have in this repository.
+
## Partners
diff --git a/action.yml b/action.yml
index 681fc46..ef8a788 100644
--- a/action.yml
+++ b/action.yml
@@ -61,6 +61,8 @@ inputs:
generateReleaseNotes:
description: "Whether to use GitHub's Release Notes API to generate the release title and body. If `releaseName` is set, it will overwrite the generated title. If `releaseBody` is set, it will be pre-pended to the automatically generated notes. This action is not responsible for the generated content."
default: 'false'
+ mobile:
+ description: 'EXPERIMENTAL - Whether to build for mobile or desktop. Can be "android" or "ios" or unset for desktop builds.'
outputs:
releaseId:
description: 'The ID of the created release'
diff --git a/dist/index.js b/dist/index.js
index f8bfcec..5d9b97f 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -84695,7 +84695,6 @@ async function getRunner() {
async function buildProject() {
const runner = await getRunner();
- const debug = inputs/* parsedArgs */.HD['debug'];
const targetPath = inputs/* parsedArgs */.HD['target'];
const configArg = inputs/* parsedArgs */.HD['config'];
const profile = inputs/* parsedRunnerArgs */.Nl['profile'];
@@ -84713,13 +84712,24 @@ async function buildProject() {
wixLanguage: info.wixLanguage,
rpmRelease: info.rpmRelease,
};
- await runner.execTauriCommand(['build'], inputs/* rawArgs */.ay, inputs/* projectPath */.DZ, targetInfo.platform === 'macos'
+ let command = ['build'];
+ if (inputs/* isAndroid */.m0)
+ command = ['android', 'build'];
+ if (inputs/* isIOS */.un)
+ command = ['ios', 'build'];
+ await runner.execTauriCommand(command, inputs/* rawArgs */.ay, inputs/* projectPath */.DZ, targetInfo.platform === 'macos'
? {
TAURI_BUNDLER_DMG_IGNORE_CI: process.env.TAURI_BUNDLER_DMG_IGNORE_CI ?? 'true',
}
: undefined, inputs/* retryAttempts */.z);
const workspacePath = (0,utils/* getWorkspaceDir */.Lw)(app.tauriPath) ?? app.tauriPath;
- const artifactsPath = (0,external_node_path_.join)((0,utils/* getTargetDir */.d)(workspacePath, info.tauriPath, !!targetPath), targetPath ?? '', profile ? profile : debug ? 'debug' : 'release');
+ let artifactsPath = (0,external_node_path_.join)((0,utils/* getTargetDir */.d)(workspacePath, info.tauriPath, !!targetPath), targetPath ?? '', profile ? profile : inputs/* isDebug */._o ? 'debug' : 'release');
+ if (inputs/* isAndroid */.m0) {
+ artifactsPath = (0,external_node_path_.join)(info.tauriPath, 'gen/android/app/build/outputs/');
+ }
+ if (inputs/* isIOS */.un) {
+ artifactsPath = (0,external_node_path_.join)(info.tauriPath, 'gen/apple/build/');
+ }
let artifacts = [];
let arch = targetInfo.arch;
if (targetInfo.platform === 'macos') {
@@ -84733,7 +84743,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/dmg/${app.name}_${app.version}_${arch}.dmg`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'dmg', // could be 'dmg' or 'app' depending on the usecase
@@ -84742,7 +84751,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/macos/${app.name}.app`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'app',
@@ -84751,7 +84759,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/macos/${app.name}.app.tar.gz`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'app',
@@ -84760,7 +84767,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/macos/${app.name}.app.tar.gz.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'app',
@@ -84796,7 +84802,6 @@ async function buildProject() {
winArtifacts.push((0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -84804,7 +84809,6 @@ async function buildProject() {
}), (0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -84812,7 +84816,6 @@ async function buildProject() {
}), (0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi.zip`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -84820,7 +84823,6 @@ async function buildProject() {
}), (0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi.zip.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -84830,7 +84832,6 @@ async function buildProject() {
winArtifacts.push((0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/nsis/${app.name}_${app.version}_${arch}-setup.exe`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -84838,7 +84839,6 @@ async function buildProject() {
}), (0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/nsis/${app.name}_${app.version}_${arch}-setup.exe.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -84846,7 +84846,6 @@ async function buildProject() {
}), (0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/nsis/${app.name}_${app.version}_${arch}-setup.nsis.zip`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -84854,7 +84853,6 @@ async function buildProject() {
}), (0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/nsis/${app.name}_${app.version}_${arch}-setup.nsis.zip.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -84862,7 +84860,7 @@ async function buildProject() {
}));
artifacts = winArtifacts;
}
- else {
+ else if (targetInfo.platform === 'linux') {
const debianArch = arch === 'x64' || arch === 'x86_64'
? 'amd64'
: arch === 'x32' || arch === 'i686'
@@ -84894,7 +84892,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/deb/${app.name}_${app.version}_${debianArch}.deb`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: debianArch,
bundle: 'deb',
@@ -84903,7 +84900,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/deb/${app.name}_${app.version}_${debianArch}.deb.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: debianArch,
bundle: 'deb',
@@ -84912,7 +84908,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/rpm/${app.name}-${app.version}-${app.rpmRelease}.${rpmArch}.rpm`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: rpmArch,
bundle: 'rpm',
@@ -84921,7 +84916,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/rpm/${app.name}-${app.version}-${app.rpmRelease}.${rpmArch}.rpm.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: rpmArch,
bundle: 'rpm',
@@ -84930,7 +84924,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
@@ -84939,7 +84932,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
@@ -84948,7 +84940,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage.tar.gz`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
@@ -84957,7 +84948,6 @@ async function buildProject() {
(0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage.tar.gz.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
@@ -84965,13 +84955,165 @@ async function buildProject() {
}),
];
}
+ else if (targetInfo.platform === 'android') {
+ const debug = inputs/* isDebug */._o ? 'debug' : 'release';
+ // TODO: detect (un)signed beforehand
+ if (!inputs/* isDebug */._o) {
+ // unsigned release apks
+ artifacts.push((0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/universal/release/app-universal-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/arm64/release/app-arm64-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/arm/release/app-arm-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/x86_64/release/app-x86_64-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/x86/release/app-x86-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86',
+ bundle: 'apk',
+ version: app.version,
+ }));
+ }
+ artifacts.push(
+ // signed release apks and debug apks
+ (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/universal/${debug}/app-universal-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/arm64/${debug}/app-arm64-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/arm/${debug}/app-arm-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/x86_64/${debug}/app-x86_64-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm',
+ bundle: 'apk',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `apk/x86/${debug}/app-x86-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ //
+ // aabs
+ //
+ (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `/bundle/universal${debug}/app-universal-${debug}.aab`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'aab',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `/bundle/arm64${debug}/app-arm64-${debug}.aab`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'aab',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `/bundle/arm${debug}/app-arm-${debug}.aab`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm',
+ bundle: 'aab',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `/bundle/x86_64${debug}/app-x86_64-${debug}.aab`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86_64',
+ bundle: 'aab',
+ version: app.version,
+ }), (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `/bundle/x86${debug}/app-x86-${debug}.aab`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86',
+ bundle: 'aab',
+ version: app.version,
+ }));
+ }
+ else if (targetInfo.platform === 'ios') {
+ // TODO: Confirm that info.name is correct.
+ artifacts = [
+ (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `x86_64/${app.name}.ipa`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86_64',
+ bundle: 'ipa',
+ version: app.version,
+ }),
+ (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `arm64/${app.name}.ipa`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'ipa',
+ version: app.version,
+ }),
+ (0,utils/* createArtifact */.Dg)({
+ path: (0,external_node_path_.join)(artifactsPath, `arm64-sim/${app.name}.ipa`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64-sim',
+ bundle: 'ipa',
+ version: app.version,
+ }),
+ ];
+ }
+ else {
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ console.error(`Unhandled target platform: "${targetInfo.platform}"`);
+ }
if (inputs/* uploadPlainBinary */.pm) {
const ext = targetInfo.platform === 'windows' ? '.exe' : '';
artifacts.push((0,utils/* createArtifact */.Dg)({
path: (0,external_node_path_.join)(artifactsPath, `${app.mainBinaryName}${ext}`),
name: 'binary', // app.mainBinaryName,
bundle: 'bin',
- debug,
platform: targetInfo.platform,
arch,
version: app.version,
@@ -85129,6 +85271,9 @@ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __we
async function run() {
try {
+ if (_inputs__WEBPACK_IMPORTED_MODULE_5__/* .isIOS */ .un && process.platform !== 'darwin') {
+ throw new Error('Building for iOS is only supported on macOS runners.');
+ }
// inputs that won't be changed are in ./inputs
let tagName = _actions_core__WEBPACK_IMPORTED_MODULE_2__.getInput('tagName').replace('refs/tags/', '');
let releaseId = Number(_actions_core__WEBPACK_IMPORTED_MODULE_2__.getInput('releaseId'));
@@ -85242,7 +85387,10 @@ __nccwpck_require__.d(__webpack_exports__, {
yK: () => (/* binding */ generateReleaseNotes),
qu: () => (/* binding */ githubBaseUrl),
Sv: () => (/* binding */ includeUpdaterJson),
+ m0: () => (/* binding */ isAndroid),
+ _o: () => (/* binding */ isDebug),
Hd: () => (/* binding */ isGitea),
+ un: () => (/* binding */ isIOS),
eC: () => (/* binding */ owner),
HD: () => (/* binding */ parsedArgs),
Nl: () => (/* binding */ parsedRunnerArgs),
@@ -85357,6 +85505,9 @@ const shouldUploadWorkflowArtifacts = core.getBooleanInput('uploadWorkflowArtifa
const workflowArtifactNamePattern = core.getInput('workflowArtifactNamePattern') || '[platform]-[arch]-[bundle]';
const uploadUpdaterSignatures = core.getBooleanInput('uploadUpdaterSignatures');
const updaterJsonPreferNsis = core.getBooleanInput('updaterJsonPreferNsis');
+const isAndroid = core.getInput('mobile').toLowerCase() === 'android';
+const isIOS = core.getInput('mobile').toLowerCase() === 'ios';
+const isDebug = parsedArgs['debug'];
/***/ }),
@@ -85673,7 +85824,6 @@ async function uploadVersionJSON(version, notes, tagName, releaseId, artifacts,
const artifact = (0,_utils__WEBPACK_IMPORTED_MODULE_5__/* .createArtifact */ .Dg)({
path: versionFile,
name: versionFilename,
- debug: false,
platform: targetInfo.platform,
arch: '',
bundle: '',
@@ -96121,7 +96271,7 @@ function ghAssetName(artifact, releaseAssetNamePattern) {
.replace(/[^a-zA-Z0-9_-]/g, '.')
.replace(/\.\./g, '.');
}
-function createArtifact({ path, name, debug, platform, arch, bundle, version, }) {
+function createArtifact({ path, name, platform, arch, bundle, version, }) {
const baseName = (0,external_node_path_.basename)(path);
const exts = extensions.filter((s) => baseName.includes(s));
const ext = exts[0] || (0,external_node_path_.extname)(path);
@@ -96133,7 +96283,7 @@ function createArtifact({ path, name, debug, platform, arch, bundle, version, })
return {
path,
name,
- mode: debug ? 'debug' : 'release',
+ mode: inputs/* isDebug */._o ? 'debug' : 'release',
platform: platform === 'macos' ? 'darwin' : platform,
arch,
bundle,
@@ -96427,11 +96577,22 @@ function getInfo(targetInfo, configFlag) {
}
function getTargetInfo(targetPath) {
let arch = process.arch;
- let platform = process.platform === 'win32'
- ? 'windows'
- : process.platform === 'darwin'
- ? 'macos'
- : 'linux';
+ let platform;
+ if (inputs/* isAndroid */.m0) {
+ platform = 'android';
+ }
+ else if (inputs/* isIOS */.un) {
+ platform = 'ios';
+ }
+ else if (process.platform === 'win32') {
+ platform = 'windows';
+ }
+ else if (process.platform === 'darwin') {
+ platform = 'macos';
+ }
+ else {
+ platform = 'linux';
+ }
if (targetPath) {
if (targetPath.includes('windows')) {
platform = 'windows';
diff --git a/src/build.ts b/src/build.ts
index ecc40f5..41c35fb 100644
--- a/src/build.ts
+++ b/src/build.ts
@@ -3,6 +3,9 @@ import { join } from 'node:path';
import { getRunner } from './runner';
import {
+ isAndroid,
+ isDebug,
+ isIOS,
parsedArgs,
parsedRunnerArgs,
projectPath,
@@ -23,7 +26,6 @@ import type { Artifact } from './types';
export async function buildProject(): Promise {
const runner = await getRunner();
- const debug = parsedArgs['debug'] as boolean;
const targetPath = parsedArgs['target'] as string | undefined;
const configArg = parsedArgs['config'] as string | undefined;
const profile = parsedRunnerArgs['profile'] as string | undefined;
@@ -46,8 +48,12 @@ export async function buildProject(): Promise {
rpmRelease: info.rpmRelease,
};
+ let command = ['build'];
+ if (isAndroid) command = ['android', 'build'];
+ if (isIOS) command = ['ios', 'build'];
+
await runner.execTauriCommand(
- ['build'],
+ command,
rawArgs,
projectPath,
targetInfo.platform === 'macos'
@@ -61,11 +67,17 @@ export async function buildProject(): Promise {
const workspacePath = getWorkspaceDir(app.tauriPath) ?? app.tauriPath;
- const artifactsPath = join(
+ let artifactsPath = join(
getTargetDir(workspacePath, info.tauriPath, !!targetPath),
targetPath ?? '',
- profile ? profile : debug ? 'debug' : 'release',
+ profile ? profile : isDebug ? 'debug' : 'release',
);
+ if (isAndroid) {
+ artifactsPath = join(info.tauriPath, 'gen/android/app/build/outputs/');
+ }
+ if (isIOS) {
+ artifactsPath = join(info.tauriPath, 'gen/apple/build/');
+ }
let artifacts: Artifact[] = [];
@@ -85,7 +97,6 @@ export async function buildProject(): Promise {
`bundle/dmg/${app.name}_${app.version}_${arch}.dmg`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'dmg', // could be 'dmg' or 'app' depending on the usecase
@@ -94,7 +105,6 @@ export async function buildProject(): Promise {
createArtifact({
path: join(artifactsPath, `bundle/macos/${app.name}.app`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'app',
@@ -103,7 +113,6 @@ export async function buildProject(): Promise {
createArtifact({
path: join(artifactsPath, `bundle/macos/${app.name}.app.tar.gz`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'app',
@@ -112,7 +121,6 @@ export async function buildProject(): Promise {
createArtifact({
path: join(artifactsPath, `bundle/macos/${app.name}.app.tar.gz.sig`),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'app',
@@ -150,7 +158,6 @@ export async function buildProject(): Promise {
`bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -162,7 +169,6 @@ export async function buildProject(): Promise {
`bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -174,7 +180,6 @@ export async function buildProject(): Promise {
`bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi.zip`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -186,7 +191,6 @@ export async function buildProject(): Promise {
`bundle/msi/${app.name}_${app.version}_${arch}_${lang}.msi.zip.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'msi',
@@ -202,7 +206,6 @@ export async function buildProject(): Promise {
`bundle/nsis/${app.name}_${app.version}_${arch}-setup.exe`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -214,7 +217,6 @@ export async function buildProject(): Promise {
`bundle/nsis/${app.name}_${app.version}_${arch}-setup.exe.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -226,7 +228,6 @@ export async function buildProject(): Promise {
`bundle/nsis/${app.name}_${app.version}_${arch}-setup.nsis.zip`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -238,7 +239,6 @@ export async function buildProject(): Promise {
`bundle/nsis/${app.name}_${app.version}_${arch}-setup.nsis.zip.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch,
bundle: 'nsis',
@@ -247,7 +247,7 @@ export async function buildProject(): Promise {
);
artifacts = winArtifacts;
- } else {
+ } else if (targetInfo.platform === 'linux') {
const debianArch =
arch === 'x64' || arch === 'x86_64'
? 'amd64'
@@ -286,7 +286,6 @@ export async function buildProject(): Promise {
`bundle/deb/${app.name}_${app.version}_${debianArch}.deb`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: debianArch,
bundle: 'deb',
@@ -298,7 +297,6 @@ export async function buildProject(): Promise {
`bundle/deb/${app.name}_${app.version}_${debianArch}.deb.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: debianArch,
bundle: 'deb',
@@ -310,7 +308,6 @@ export async function buildProject(): Promise {
`bundle/rpm/${app.name}-${app.version}-${app.rpmRelease}.${rpmArch}.rpm`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: rpmArch,
bundle: 'rpm',
@@ -322,7 +319,6 @@ export async function buildProject(): Promise {
`bundle/rpm/${app.name}-${app.version}-${app.rpmRelease}.${rpmArch}.rpm.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: rpmArch,
bundle: 'rpm',
@@ -334,7 +330,6 @@ export async function buildProject(): Promise {
`bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
@@ -346,7 +341,6 @@ export async function buildProject(): Promise {
`bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
@@ -358,7 +352,6 @@ export async function buildProject(): Promise {
`bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage.tar.gz`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
@@ -370,13 +363,201 @@ export async function buildProject(): Promise {
`bundle/appimage/${app.name}_${app.version}_${appImageArch}.AppImage.tar.gz.sig`,
),
name: app.name,
- debug,
platform: targetInfo.platform,
arch: appImageArch,
bundle: 'appimage',
version: app.version,
}),
];
+ } else if (targetInfo.platform === 'android') {
+ const debug = isDebug ? 'debug' : 'release';
+
+ // TODO: detect (un)signed beforehand
+
+ if (!isDebug) {
+ // unsigned release apks
+ artifacts.push(
+ createArtifact({
+ path: join(
+ artifactsPath,
+ `apk/universal/release/app-universal-unsigend.apk`,
+ ),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `apk/arm64/release/app-arm64-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `apk/arm/release/app-arm-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(
+ artifactsPath,
+ `apk/x86_64/release/app-x86_64-unsigend.apk`,
+ ),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `apk/x86/release/app-x86-unsigend.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ );
+ }
+
+ artifacts.push(
+ // signed release apks and debug apks
+ createArtifact({
+ path: join(
+ artifactsPath,
+ `apk/universal/${debug}/app-universal-${debug}.apk`,
+ ),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `apk/arm64/${debug}/app-arm64-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `apk/arm/${debug}/app-arm-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(
+ artifactsPath,
+ `apk/x86_64/${debug}/app-x86_64-${debug}.apk`,
+ ),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `apk/x86/${debug}/app-x86-${debug}.apk`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86',
+ bundle: 'apk',
+ version: app.version,
+ }),
+ //
+ // aabs
+ //
+ createArtifact({
+ path: join(
+ artifactsPath,
+ `/bundle/universal${debug}/app-universal-${debug}.aab`,
+ ),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'universal',
+ bundle: 'aab',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(
+ artifactsPath,
+ `/bundle/arm64${debug}/app-arm64-${debug}.aab`,
+ ),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'aab',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `/bundle/arm${debug}/app-arm-${debug}.aab`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm',
+ bundle: 'aab',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(
+ artifactsPath,
+ `/bundle/x86_64${debug}/app-x86_64-${debug}.aab`,
+ ),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86_64',
+ bundle: 'aab',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `/bundle/x86${debug}/app-x86-${debug}.aab`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86',
+ bundle: 'aab',
+ version: app.version,
+ }),
+ );
+ } else if (targetInfo.platform === 'ios') {
+ // TODO: Confirm that info.name is correct.
+ artifacts = [
+ createArtifact({
+ path: join(artifactsPath, `x86_64/${app.name}.ipa`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'x86_64',
+ bundle: 'ipa',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `arm64/${app.name}.ipa`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64',
+ bundle: 'ipa',
+ version: app.version,
+ }),
+ createArtifact({
+ path: join(artifactsPath, `arm64-sim/${app.name}.ipa`),
+ name: app.name,
+ platform: targetInfo.platform,
+ arch: 'arm64-sim',
+ bundle: 'ipa',
+ version: app.version,
+ }),
+ ];
+ } else {
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ console.error(`Unhandled target platform: "${targetInfo.platform}"`);
}
if (uploadPlainBinary) {
@@ -386,7 +567,7 @@ export async function buildProject(): Promise {
path: join(artifactsPath, `${app.mainBinaryName}${ext}`),
name: 'binary', // app.mainBinaryName,
bundle: 'bin',
- debug,
+
platform: targetInfo.platform,
arch,
version: app.version,
diff --git a/src/index.ts b/src/index.ts
index 6833fc1..bb64b5f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -7,6 +7,7 @@ import { buildProject } from './build';
import { getOrCreateRelease } from './create-release';
import {
includeUpdaterJson,
+ isIOS,
parsedArgs,
retryAttempts,
shouldUploadWorkflowArtifacts,
@@ -20,6 +21,10 @@ import type { Artifact } from './types';
async function run(): Promise {
try {
+ if (isIOS && process.platform !== 'darwin') {
+ throw new Error('Building for iOS is only supported on macOS runners.');
+ }
+
// inputs that won't be changed are in ./inputs
let tagName = core.getInput('tagName').replace('refs/tags/', '');
let releaseId = Number(core.getInput('releaseId'));
diff --git a/src/inputs.ts b/src/inputs.ts
index 06e996a..7a06ddc 100644
--- a/src/inputs.ts
+++ b/src/inputs.ts
@@ -84,3 +84,7 @@ export const uploadUpdaterSignatures = core.getBooleanInput(
export const updaterJsonPreferNsis = core.getBooleanInput(
'updaterJsonPreferNsis',
);
+
+export const isAndroid = core.getInput('mobile').toLowerCase() === 'android';
+export const isIOS = core.getInput('mobile').toLowerCase() === 'ios';
+export const isDebug = parsedArgs['debug'] as boolean;
diff --git a/src/upload-version-json.ts b/src/upload-version-json.ts
index 384b2b8..c63420b 100644
--- a/src/upload-version-json.ts
+++ b/src/upload-version-json.ts
@@ -328,7 +328,6 @@ export async function uploadVersionJSON(
const artifact = createArtifact({
path: versionFile,
name: versionFilename,
- debug: false,
platform: targetInfo.platform,
arch: '',
bundle: '',
diff --git a/src/utils.ts b/src/utils.ts
index c815ba2..3a8a975 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -24,7 +24,7 @@ import type {
} from './types';
import { GitHub } from '@actions/github/lib/utils';
import { findUpSync } from 'find-up-simple';
-import { owner, projectPath, repo } from './inputs';
+import { isAndroid, isDebug, isIOS, owner, projectPath, repo } from './inputs';
/*** constants ***/
export const extensions = [
@@ -139,7 +139,6 @@ export function ghAssetName(
export function createArtifact({
path,
name,
- debug,
platform,
arch,
bundle,
@@ -147,7 +146,6 @@ export function createArtifact({
}: {
path: string;
name: string;
- debug: boolean;
platform: TargetPlatform;
arch: string;
bundle: string;
@@ -167,7 +165,7 @@ export function createArtifact({
return {
path,
name,
- mode: debug ? 'debug' : 'release',
+ mode: isDebug ? 'debug' : 'release',
platform: platform === 'macos' ? 'darwin' : platform,
arch,
bundle,
@@ -546,12 +544,18 @@ export function getInfo(targetInfo?: TargetInfo, configFlag?: string): Info {
export function getTargetInfo(targetPath?: string): TargetInfo {
let arch: string = process.arch;
- let platform: TargetPlatform =
- process.platform === 'win32'
- ? 'windows'
- : process.platform === 'darwin'
- ? 'macos'
- : 'linux';
+ let platform: TargetPlatform;
+ if (isAndroid) {
+ platform = 'android';
+ } else if (isIOS) {
+ platform = 'ios';
+ } else if (process.platform === 'win32') {
+ platform = 'windows';
+ } else if (process.platform === 'darwin') {
+ platform = 'macos';
+ } else {
+ platform = 'linux';
+ }
if (targetPath) {
if (targetPath.includes('windows')) {