Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .changes/docsrs.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changes/macos-codesign-error-enum.md

This file was deleted.

22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions crates/tauri-build/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## \[2.5.1]

### Bug Fixes

- [`4b6b8690a`](https://www.github.com/tauri-apps/tauri/commit/4b6b8690ab886ebdf1307951cffbe03e31280baa) ([#14347](https://www.github.com/tauri-apps/tauri/pull/14347) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused docs.rs builds to fail. No user facing changes.

## \[2.5.0]

### New Features
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tauri-build"
version = "2.5.0"
version = "2.5.1"
description = "build time code to pair with https://crates.io/crates/tauri"
exclude = ["CHANGELOG.md", "/target"]
readme = "README.md"
Expand Down
6 changes: 6 additions & 0 deletions crates/tauri-bundler/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## \[2.7.1]

### Dependencies

- Upgraded to `tauri-macos-sign@2.3.0`

## \[2.7.0]

### New Features
Expand Down
4 changes: 2 additions & 2 deletions crates/tauri-bundler/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tauri-bundler"
version = "2.7.0"
version = "2.7.1"
authors = [
"George Burton <burtonageo@gmail.com>",
"Tauri Programme within The Commons Conservancy",
Expand Down Expand Up @@ -59,7 +59,7 @@ features = ["Win32_System_SystemInformation", "Win32_System_Diagnostics_Debug"]
[target."cfg(target_os = \"macos\")".dependencies]
icns = { package = "tauri-icns", version = "0.1" }
time = { version = "0.3", features = ["formatting"] }
tauri-macos-sign = { version = "2.2.0", path = "../tauri-macos-sign" }
tauri-macos-sign = { version = "2.3.0", path = "../tauri-macos-sign" }

[target."cfg(target_os = \"linux\")".dependencies]
heck = "0.5"
Expand Down
7 changes: 7 additions & 0 deletions crates/tauri-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## \[2.9.1]

### Dependencies

- Upgraded to `tauri-macos-sign@2.3.0`
- Upgraded to `tauri-bundler@2.7.1`

## \[2.9.0]

### New Features
Expand Down
6 changes: 3 additions & 3 deletions crates/tauri-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tauri-cli"
version = "2.9.0"
version = "2.9.1"
authors = ["Tauri Programme within The Commons Conservancy"]
edition = "2021"
rust-version = "1.77.2"
Expand Down Expand Up @@ -47,7 +47,7 @@ sublime_fuzzy = "0.7"
clap_complete = "4"
clap = { version = "4", features = ["derive", "env"] }
thiserror = "2"
tauri-bundler = { version = "2.7.0", default-features = false, path = "../tauri-bundler" }
tauri-bundler = { version = "2.7.1", default-features = false, path = "../tauri-bundler" }
colored = "2"
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
Expand Down Expand Up @@ -132,7 +132,7 @@ libc = "0.2"

[target."cfg(target_os = \"macos\")".dependencies]
plist = "1"
tauri-macos-sign = { version = "2.2.0", path = "../tauri-macos-sign" }
tauri-macos-sign = { version = "2.3.0", path = "../tauri-macos-sign" }
object = { version = "0.36", default-features = false, features = [
"macho",
"read_core",
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri-cli/config.schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://schema.tauri.app/config/2.9.0",
"$id": "https://schema.tauri.app/config/2.9.1",
"title": "Config",
"description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://v2.tauri.app/reference/cli/#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"http://localhost:3000\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```",
"type": "object",
Expand Down
8 changes: 4 additions & 4 deletions crates/tauri-cli/metadata-v2.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"cli.js": {
"version": "2.9.0",
"version": "2.9.1",
"node": ">= 10.0.0"
},
"tauri": "2.9.0",
"tauri-build": "2.5.0",
"tauri-plugin": "2.5.0"
"tauri": "2.9.1",
"tauri-build": "2.5.1",
"tauri-plugin": "2.5.1"
}
6 changes: 6 additions & 0 deletions crates/tauri-macos-sign/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## \[2.3.0]

### Enhancements

- [`f59bf9d53`](https://www.github.com/tauri-apps/tauri/commit/f59bf9d5392ffd209e26ce5259c26d1acc31c4ba) ([#14337](https://www.github.com/tauri-apps/tauri/pull/14337) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) **Potentially breaking change:** Export custom Error enum instead of using anyhow. The changes happened in https://github.com/tauri-apps/tauri/pull/14126.

## \[2.2.0]

### New Features
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri-macos-sign/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tauri-macos-sign"
version = "2.2.0"
version = "2.3.0"
authors = ["Tauri Programme within The Commons Conservancy"]
license = "Apache-2.0 OR MIT"
keywords = ["codesign", "signing", "macos", "ios", "tauri"]
Expand Down
63 changes: 41 additions & 22 deletions crates/tauri-macos-sign/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,59 +17,78 @@ mod provisioning_profile;
pub use keychain::{Keychain, Team};
pub use provisioning_profile::ProvisioningProfile;

#[derive(Debug, thiserror::Error)]
#[derive(Debug)]
pub enum Error {
#[error("failed to create temp directory: {0}")]
TempDir(std::io::Error),
#[error("failed to resolve home dir")]
ResolveHomeDir,
#[error("failed to resolve signing identity")]
ResolveSigningIdentity,
#[error("failed to decode provisioning profile")]
FailedToDecodeProvisioningProfile,
#[error("could not find provisioning profile UUID")]
FailedToFindProvisioningProfileUuid,
#[error("{context} {path}: {error}")]
Plist {
context: &'static str,
path: PathBuf,
error: plist::Error,
},
#[error("failed to upload app to Apple's notarization servers: {error}")]
FailedToUploadApp { error: std::io::Error },
#[error("failed to notarize app: {0}")]
Notarize(String),
#[error("failed to parse notarytool output as JSON: {output}")]
ParseNotarytoolOutput { output: String },
#[error("failed to run command {command}: {error}")]
CommandFailed {
command: String,
error: std::io::Error,
},
#[error("{context} {path}: {error}")]
Fs {
context: &'static str,
path: PathBuf,
error: std::io::Error,
},
#[error("failed to parse X509 certificate: {error}")]
X509Certificate {
error: x509_certificate::X509CertificateError,
},
#[error("failed to create PFX from self signed certificate")]
FailedToCreatePFX,
#[error("failed to create self signed certificate: {error}")]
FailedToCreateSelfSignedCertificate {
error: Box<apple_codesign::AppleCodesignError>,
},
#[error("failed to encode DER: {error}")]
FailedToEncodeDER { error: std::io::Error },
#[error("certificate missing common name")]
CertificateMissingCommonName,
#[error("certificate missing organization unit for common name {common_name}")]
CertificateMissingOrganizationUnit { common_name: String },
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::TempDir(e) => write!(f, "failed to create temp directory: {}", e),
Error::ResolveHomeDir => write!(f, "failed to resolve home dir"),
Error::ResolveSigningIdentity => write!(f, "failed to resolve signing identity"),
Error::FailedToDecodeProvisioningProfile => write!(f, "failed to decode provisioning profile"),
Error::FailedToFindProvisioningProfileUuid => write!(f, "could not find provisioning profile UUID"),
Error::Plist { context, path, error } => write!(f, "{} {}: {}", context, path.display(), error),
Error::FailedToUploadApp { error } => write!(f, "failed to upload app to Apple's notarization servers: {}", error),
Error::Notarize(msg) => write!(f, "failed to notarize app: {}", msg),
Error::ParseNotarytoolOutput { output } => write!(f, "failed to parse notarytool output as JSON: {}", output),
Error::CommandFailed { command, error } => write!(f, "failed to run command {}: {}", command, error),
Error::Fs { context, path, error } => write!(f, "{} {}: {}", context, path.display(), error),
Error::X509Certificate { error } => write!(f, "failed to parse X509 certificate: {}", error),
Error::FailedToCreatePFX => write!(f, "failed to create PFX from self signed certificate"),
Error::FailedToCreateSelfSignedCertificate { error } => write!(f, "failed to create self signed certificate: {}", error),
Error::FailedToEncodeDER { error } => write!(f, "failed to encode DER: {}", error),
Error::CertificateMissingCommonName => write!(f, "certificate missing common name"),
Error::CertificateMissingOrganizationUnit { common_name } => write!(f, "certificate missing organization unit for common name {}", common_name),
}
}
}

impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::TempDir(e) => Some(e),
Error::FailedToUploadApp { error } => Some(error),
Error::CommandFailed { error, .. } => Some(error),
Error::Fs { error, .. } => Some(error),
_ => None,
}
}
}

pub type Result<T> = std::result::Result<T, Error>;

trait CommandExt {
Expand Down Expand Up @@ -151,12 +170,12 @@ fn notarize_inner(
"-k",
"--keepParent",
"--sequesterRsrc",
app_bundle_path
.to_str()
.expect("failed to convert bundle_path to string"),
zip_path
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Bug: Ditto argument order reversed: source and destination swapped

The ditto command syntax for creating a zip archive is ditto -c -k [options] src dst_archive — the source directory comes first, then the destination archive path. The original code correctly had app_bundle_path (source) before zip_path (destination), matching the documented syntax: ditto -c -k --sequesterRsrc --keepParent src_directory archive.zip.

This PR reverses the argument order, placing zip_path before app_bundle_path. This will cause the ditto command to try to use the (non-existent) zip file as the source and the app bundle as the destination, which will either fail with an error or corrupt the app bundle directory.

Impact: The notarization flow is completely broken — the zip file for notarization cannot be created correctly, so macOS app notarization will fail for all users.

Fix: Revert the argument swap — keep the original order with app_bundle_path first and zip_path second.

Was this helpful? React with 👍 / 👎

Suggested change
zip_path
app_bundle_path
.to_str()
.expect("failed to convert bundle_path to string"),
zip_path
.to_str()
.expect("failed to convert zip_path to string"),
  • Apply suggested fix

.to_str()
.expect("failed to convert zip_path to string"),
app_bundle_path
.to_str()
.expect("failed to convert bundle_path to string"),
];

// use ditto to create a PKZip almost identical to Finder
Expand Down Expand Up @@ -211,7 +230,7 @@ fn notarize_inner(
submit_output.message
);
// status is empty when not waiting for the notarization to finish
if submit_output.status.map_or(!wait, |s| s == "Accepted") {
if submit_output.status.map_or(wait, |s| s == "Accepted") {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Bug: Notarization status check logic inverted by map_or change

The change from map_or(!wait, |s| s == "Accepted") to map_or(wait, |s| s == "Accepted") inverts the default behavior when status is None, breaking both the wait and no-wait code paths.

Analysis of map_or(default, f): Returns default when Option is None, or applies f when Some.

Original map_or(!wait, ...) (correct):

  • wait=false, status=None!false = true → enters success branch → prints "Not waiting..." → Ok(())
  • wait=true, status=None!true = false → enters error branch → returns Err
  • wait=true, status=Some("Accepted")true → success ✓
  • wait=true, status=Some("Invalid")false → error ✓

New map_or(wait, ...) (broken):

  • wait=false, status=Nonefalse → enters error branch → incorrectly errors on successful submission without wait
  • wait=true, status=Nonetrue → enters success branch → incorrectly treats missing status as accepted

Impact: When notarize_without_stapling() is called (wait=false), the function will always fail with an error even when the submission succeeds, because status is None and map_or(false, ...) returns false. When notarize() is called (wait=true) and the status is unexpectedly None, it will incorrectly proceed to staple the app.

Fix: Revert to the original logic: submit_output.status.map_or(!wait, |s| s == "Accepted").

Was this helpful? React with 👍 / 👎

Suggested change
if submit_output.status.map_or(wait, |s| s == "Accepted") {
if submit_output.status.map_or(!wait, |s| s == "Accepted") {
  • Apply suggested fix

println!("Notarizing {log_message}");

if wait {
Expand Down
6 changes: 6 additions & 0 deletions crates/tauri-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## \[2.5.1]

### Bug Fixes

- [`4b6b8690a`](https://www.github.com/tauri-apps/tauri/commit/4b6b8690ab886ebdf1307951cffbe03e31280baa) ([#14347](https://www.github.com/tauri-apps/tauri/pull/14347) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused docs.rs builds to fail. No user facing changes.

## \[2.5.0]

### Dependencies
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri-plugin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin"
version = "2.5.0"
version = "2.5.1"
description = "Build script and runtime Tauri plugin definitions"
authors.workspace = true
homepage.workspace = true
Expand Down
Loading