chore(release): prepare 1.1.2 and guard release tags

This commit is contained in:
NimBold
2026-07-21 20:13:21 +03:30
parent 886388d5f2
commit 81381a5a93
11 changed files with 140 additions and 10 deletions
+2
View File
@@ -44,6 +44,8 @@ jobs:
with: with:
node-version: 22 node-version: 22
cache: npm cache: npm
- name: Verify release version
run: node scripts/verify-release-version.js
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
with: with:
targets: ${{ matrix.target }} targets: ${{ matrix.target }}
+5
View File
@@ -18,8 +18,13 @@ CROSS_PLATFORM_CHECKLIST.md
Cross-platform-checklist-gemini.MD Cross-platform-checklist-gemini.MD
YouTube_media_download_handoff.md YouTube_media_download_handoff.md
Release_checklist.md Release_checklist.md
Release Checklist/
RC Read-only/
RC Read_only/
# Frontend output and logs # Frontend output and logs
.agents/
release_notes.md
node_modules/ node_modules/
dist/ dist/
dist-ssr/ dist-ssr/
+17
View File
@@ -5,6 +5,23 @@ All notable changes to Firelink will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.1.2] - 2026-07-21
This patch release hardens download lifecycle handling, localization, and packaged release checks.
### New
- Add localized desktop UI coverage for Persian, Hebrew, Russian, Ukrainian, and Simplified Chinese.
- Add optional batch folders and safer reuse of unfinished downloads with matching filenames.
### Improved
- Make pause, resume, remove, redownload, queue, scheduler, and settings actions safer when operations overlap.
- Improve first-open navigation, RTL layout, browser-cookie recovery, and download metadata handling.
- Strengthen packaged engine, Windows portable, Linux package, and release-asset verification.
### Fixed
- Prevent stale or duplicate lifecycle work from deleting or resurrecting the wrong download.
- Keep missed completion events, localized state, and browser handoffs from leaving misleading UI state.
## [1.1.1] - 2026-07-17 ## [1.1.1] - 2026-07-17
This patch release focuses on transfer reliability, browser captures, and easier download control. This patch release focuses on transfer reliability, browser captures, and easier download control.
+4 -4
View File
@@ -5,7 +5,7 @@
**A fast, focused desktop download manager for macOS, Windows, and Linux.** **A fast, focused desktop download manager for macOS, Windows, and Linux.**
[![Version](https://img.shields.io/badge/version-1.1.1-6f42c1?style=flat-square)](https://github.com/nimbold/Firelink/releases) [![Version](https://img.shields.io/badge/version-1.1.2-6f42c1?style=flat-square)](https://github.com/nimbold/Firelink/releases)
[![macOS](https://img.shields.io/badge/macOS-111111?style=flat-square&logo=apple&logoColor=white)](#platforms) [![macOS](https://img.shields.io/badge/macOS-111111?style=flat-square&logo=apple&logoColor=white)](#platforms)
[![Windows](.github/badges/windows.svg)](#platforms) [![Windows](.github/badges/windows.svg)](#platforms)
[![Linux](https://img.shields.io/badge/Linux-FCC624?style=flat-square&logo=linux&logoColor=black)](#platforms) [![Linux](https://img.shields.io/badge/Linux-FCC624?style=flat-square&logo=linux&logoColor=black)](#platforms)
@@ -37,9 +37,9 @@ Firelink is a cross-platform desktop download manager for direct transfers, brow
It combines a Rust/Tauri backend with a React and TypeScript interface. Bundled aria2, yt-dlp, FFmpeg, Deno, and SQLite support the download and media workflows. It combines a Rust/Tauri backend with a React and TypeScript interface. Bundled aria2, yt-dlp, FFmpeg, Deno, and SQLite support the download and media workflows.
The current desktop release is **1.1.1**, paired with Firelink Companion **2.0.5**. The current desktop release is **1.1.2**, paired with Firelink Companion **2.0.5**.
This release adds YouTube playlist downloads, live connection controls, clipboard capture, and clearer byte-level progress. It also improves slow-transfer recovery, authenticated browser captures, and startup consent handling. This patch release hardens download lifecycle handling, localization, and packaged release checks.
## Features ## Features
@@ -107,7 +107,7 @@ What it adds:
Install the extension, open Firelink, then pair it from **Settings -> Integrations**. Firefox users can install it from Mozilla Add-ons. Chromium users can load `firelink-chromium.zip` from the [extension releases](https://github.com/nimbold/Firelink-Extension/releases) with the [manual Chromium instructions](https://github.com/nimbold/Firelink-Extension#manual-chromium-installation). Install the extension, open Firelink, then pair it from **Settings -> Integrations**. Firefox users can install it from Mozilla Add-ons. Chromium users can load `firelink-chromium.zip` from the [extension releases](https://github.com/nimbold/Firelink-Extension/releases) with the [manual Chromium instructions](https://github.com/nimbold/Firelink-Extension#manual-chromium-installation).
Use the latest [Firelink Companion release](https://github.com/nimbold/Firelink-Extension/releases) with Firelink 1.1.1. The source is in the [Firelink-Extension repository](https://github.com/nimbold/Firelink-Extension), which this repo vendors as the `Extensions/Browser` submodule. Use the latest [Firelink Companion release](https://github.com/nimbold/Firelink-Extension/releases) with Firelink 1.1.2. The source is in the [Firelink-Extension repository](https://github.com/nimbold/Firelink-Extension), which this repo vendors as the `Extensions/Browser` submodule.
## Platforms ## Platforms
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "firelink", "name": "firelink",
"version": "1.1.1", "version": "1.1.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "firelink", "name": "firelink",
"version": "1.1.1", "version": "1.1.2",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@formkit/auto-animate": "^0.10.0", "@formkit/auto-animate": "^0.10.0",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "firelink", "name": "firelink",
"private": true, "private": true,
"version": "1.1.1", "version": "1.1.2",
"description": "A fast cross-platform desktop download manager powered by Rust, Tauri, React, aria2, and yt-dlp.", "description": "A fast cross-platform desktop download manager powered by Rust, Tauri, React, aria2, and yt-dlp.",
"license": "MIT", "license": "MIT",
"homepage": "https://github.com/nimbold/Firelink", "homepage": "https://github.com/nimbold/Firelink",
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const scriptDirectory = path.dirname(fileURLToPath(import.meta.url));
const repositoryRoot = path.resolve(scriptDirectory, '..');
function argValue(name) {
const index = process.argv.indexOf(name);
return index >= 0 ? process.argv[index + 1] : undefined;
}
function readPackageVersion(root) {
return JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')).version;
}
function readTauriVersion(root) {
return JSON.parse(
fs.readFileSync(path.join(root, 'src-tauri', 'tauri.conf.json'), 'utf8')
).version;
}
function readCargoVersion(root) {
const cargo = fs.readFileSync(path.join(root, 'src-tauri', 'Cargo.toml'), 'utf8');
const packageSection = cargo.match(/^\[package\]\s*([\s\S]*?)(?=^\[)/m)?.[1];
const version = packageSection?.match(/^version\s*=\s*"([^"]+)"/m)?.[1];
if (!version) {
throw new Error('Could not read the [package] version from src-tauri/Cargo.toml.');
}
return version;
}
function versionFromRef(ref) {
if (!ref || !ref.startsWith('v')) {
throw new Error(`Expected a semantic version tag such as v1.2.3, received ${ref || 'nothing'}.`);
}
const version = ref.slice(1);
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(version)) {
throw new Error(`Release tag ${ref} does not contain a valid semantic version.`);
}
return version;
}
const tag = argValue('--tag') || process.env.GITHUB_REF_NAME;
const expected = versionFromRef(tag);
const versions = {
'package.json': readPackageVersion(repositoryRoot),
'src-tauri/Cargo.toml': readCargoVersion(repositoryRoot),
'src-tauri/tauri.conf.json': readTauriVersion(repositoryRoot),
};
const mismatches = Object.entries(versions)
.filter(([, version]) => version !== expected)
.map(([file, version]) => `${file}=${version}`);
if (mismatches.length > 0) {
console.error(`Release tag ${tag} does not match the application manifests (expected ${expected}).`);
for (const mismatch of mismatches) console.error(` ${mismatch}`);
process.exit(1);
}
const uniqueVersions = new Set(Object.values(versions));
if (uniqueVersions.size !== 1) {
console.error('Application version manifests do not agree:');
for (const [file, version] of Object.entries(versions)) console.error(` ${file}=${version}`);
process.exit(1);
}
console.log(`Release version ${expected} matches ${Object.keys(versions).length} manifests.`);
@@ -0,0 +1,37 @@
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { spawnSync } from 'node:child_process';
import test from 'node:test';
const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const verifier = path.join(repositoryRoot, 'scripts', 'verify-release-version.js');
const currentVersion = JSON.parse(
fs.readFileSync(path.join(repositoryRoot, 'package.json'), 'utf8')
).version;
function runVerifier(tag) {
return spawnSync(process.execPath, [verifier, '--tag', tag], {
cwd: repositoryRoot,
encoding: 'utf8',
});
}
test('release version verifier accepts the aligned current version', () => {
const result = runVerifier(`v${currentVersion}`);
assert.equal(result.status, 0, result.stderr);
assert.match(result.stdout, new RegExp(`Release version ${currentVersion} matches`));
});
test('release version verifier rejects the already-published prior tag', () => {
const result = runVerifier('v1.1.1');
assert.equal(result.status, 1);
assert.match(result.stderr, /does not match the application manifests/);
});
test('release version verifier rejects non-semver tag names', () => {
const result = runVerifier('release-candidate');
assert.equal(result.status, 1);
assert.match(result.stderr, /semantic version tag/);
});
+1 -1
View File
@@ -1365,7 +1365,7 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]] [[package]]
name = "firelink" name = "firelink"
version = "1.1.1" version = "1.1.2"
dependencies = [ dependencies = [
"apple-native-keyring-store", "apple-native-keyring-store",
"async-trait", "async-trait",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "firelink" name = "firelink"
version = "1.1.1" version = "1.1.2"
description = "A fast cross-platform desktop download manager powered by Rust and Tauri" description = "A fast cross-platform desktop download manager powered by Rust and Tauri"
authors = ["NimBold"] authors = ["NimBold"]
edition = "2021" edition = "2021"
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Firelink", "productName": "Firelink",
"version": "1.1.1", "version": "1.1.2",
"identifier": "com.nimbold.firelink", "identifier": "com.nimbold.firelink",
"build": { "build": {
"beforeDevCommand": "node scripts/stage-engines.js && npm run dev", "beforeDevCommand": "node scripts/stage-engines.js && npm run dev",