fix(release): harden cross-platform gates

This commit is contained in:
NimBold
2026-06-23 21:43:11 +03:30
parent f603b74a99
commit 82ed38d55a
6 changed files with 31 additions and 8 deletions
+14 -1
View File
@@ -4,6 +4,15 @@ on:
push:
tags: ['v*']
workflow_dispatch:
inputs:
publish_release:
description: 'Publish the GitHub release after all platform QA is certified'
type: boolean
default: false
certified_cross_platform:
description: 'Confirm Windows, Linux, and macOS clean-machine QA passed'
type: boolean
default: false
permissions:
contents: write
@@ -89,7 +98,11 @@ jobs:
publish:
name: Publish GitHub release
if: github.ref_type == 'tag'
if: >-
github.event_name == 'workflow_dispatch' &&
startsWith(github.ref, 'refs/tags/v') &&
inputs.publish_release &&
inputs.certified_cross_platform
needs: build
runs-on: ubuntu-22.04
steps:
+11 -3
View File
@@ -53,15 +53,23 @@ node scripts/verify-binaries.js --search-root "$APP" --target aarch64-apple-darw
node scripts/smoke-packaged-app.js --executable "$APP/Contents/MacOS/firelink"
```
## Automated release
GitHub release publication is intentionally manual. Tag pushes build and upload
artifacts, but the `publish` job only runs from a `workflow_dispatch` on a `v*`
tag when both release-certification inputs are checked after Windows, Linux,
and macOS clean-machine QA.
Push a version tag:
## Automated release builds
Push a version tag to build and verify native artifacts:
```bash
git tag v<version>
git push origin v<version>
```
GitHub Actions builds all targets on native runners, verifies engines inside final package contents, performs packaged launch smoke where supported, creates SHA-256 sums, then publishes one GitHub Release.
GitHub Actions builds all targets on native runners, verifies engines inside
final package contents, performs packaged launch smoke where supported, and
uploads artifacts. Publish the GitHub Release with a manual `workflow_dispatch`
run on the same tag after clean-machine QA is complete.
No target may silently skip missing engines, failed extraction, checksum mismatch, or missing package output.
+2
View File
@@ -1,3 +1,5 @@
fn main() {
std::fs::create_dir_all("engine-dist")
.expect("failed to create generated engine resource directory");
tauri_build::build()
}
+1 -1
View File
@@ -2997,7 +2997,7 @@ fn get_free_space(app_handle: tauri::AppHandle, path: String) -> Result<String,
for disk in disks.list() {
let mount_point = disk.mount_point();
if resolved_dest.starts_with(mount_point) {
if crate::platform::path_is_within(&resolved_dest, mount_point) {
let match_len = mount_point.as_os_str().len();
if match_len > max_match_len {
max_match_len = match_len;
+2 -2
View File
@@ -17,9 +17,9 @@ import {
} from './downloadLocations';
describe('download locations', () => {
it('compares Windows and macOS locations case-insensitively', () => {
it('matches backend platform path case semantics', () => {
expect(downloadLocationEquals('D:\\Downloads', 'Movie.MP4', 'd:/downloads', 'movie.mp4', 'windows')).toBe(true);
expect(downloadLocationEquals('/Users/Test', 'Movie.MP4', '/users/test', 'movie.mp4', 'macos')).toBe(true);
expect(downloadLocationEquals('/Users/Test', 'Movie.MP4', '/users/test', 'movie.mp4', 'macos')).toBe(false);
expect(downloadLocationEquals('/home/Test', 'Movie.MP4', '/home/test', 'movie.mp4', 'linux')).toBe(false);
});
beforeEach(() => {
+1 -1
View File
@@ -153,7 +153,7 @@ export const downloadLocationEquals = (
): boolean => {
const normalize = (value: string) => {
const normalized = value.replace(/\\/g, '/').replace(/\/+$/, '');
return os === 'windows' || os === 'macos'
return os === 'windows'
? normalized.toLocaleLowerCase()
: normalized;
};