mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-27 19:17:13 +00:00
fix(release): harden cross-platform gates
This commit is contained in:
@@ -4,6 +4,15 @@ on:
|
|||||||
push:
|
push:
|
||||||
tags: ['v*']
|
tags: ['v*']
|
||||||
workflow_dispatch:
|
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:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -89,7 +98,11 @@ jobs:
|
|||||||
|
|
||||||
publish:
|
publish:
|
||||||
name: Publish GitHub release
|
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
|
needs: build
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
+11
-3
@@ -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"
|
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
|
```bash
|
||||||
git tag v<version>
|
git tag v<version>
|
||||||
git push origin 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.
|
No target may silently skip missing engines, failed extraction, checksum mismatch, or missing package output.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
|
std::fs::create_dir_all("engine-dist")
|
||||||
|
.expect("failed to create generated engine resource directory");
|
||||||
tauri_build::build()
|
tauri_build::build()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2997,7 +2997,7 @@ fn get_free_space(app_handle: tauri::AppHandle, path: String) -> Result<String,
|
|||||||
|
|
||||||
for disk in disks.list() {
|
for disk in disks.list() {
|
||||||
let mount_point = disk.mount_point();
|
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();
|
let match_len = mount_point.as_os_str().len();
|
||||||
if match_len > max_match_len {
|
if match_len > max_match_len {
|
||||||
max_match_len = match_len;
|
max_match_len = match_len;
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ import {
|
|||||||
} from './downloadLocations';
|
} from './downloadLocations';
|
||||||
|
|
||||||
describe('download locations', () => {
|
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('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);
|
expect(downloadLocationEquals('/home/Test', 'Movie.MP4', '/home/test', 'movie.mp4', 'linux')).toBe(false);
|
||||||
});
|
});
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ export const downloadLocationEquals = (
|
|||||||
): boolean => {
|
): boolean => {
|
||||||
const normalize = (value: string) => {
|
const normalize = (value: string) => {
|
||||||
const normalized = value.replace(/\\/g, '/').replace(/\/+$/, '');
|
const normalized = value.replace(/\\/g, '/').replace(/\/+$/, '');
|
||||||
return os === 'windows' || os === 'macos'
|
return os === 'windows'
|
||||||
? normalized.toLocaleLowerCase()
|
? normalized.toLocaleLowerCase()
|
||||||
: normalized;
|
: normalized;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user