Skip to content
Merged
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
8 changes: 4 additions & 4 deletions .changes/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ refactor = "Refactors"
[packages."@dropout/ui"]
path = "packages/ui"
resolver = "nodejs"
version-mode = { pre-release.tag = "beta" }
version-mode = { pre-release.tag = "rc" }

[packages."@dropout/docs"]
path = "packages/docs"
resolver = "nodejs"
version-mode = { pre-release.tag = "beta" }
version-mode = { pre-release.tag = "rc" }

[packages.dropout]
path = "src-tauri"
resolver = "rust"
version-mode = { pre-release.tag = "beta" }
version-mode = { pre-release.tag = "rc" }
assets = ["artifacts/**/*"]

[packages.dropout-macros]
path = "crates/macros"
resolver = "rust"
version-mode = { pre-release.tag = "beta" }
version-mode = { pre-release.tag = "rc" }

[resolver.rust.pre-check]
url = "https://crates.io/api/v1/crates/{{ package.name }}/{{ package.version }}"
Expand Down
7 changes: 7 additions & 0 deletions .changes/rc1-parity-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"dropout": "patch:feat"
"@dropout/ui": "patch:feat"
"@dropout/docs": "patch:feat"
---

Add a machine-checked 42-row launcher parity audit, bilingual RC1 evidence guides, isolated installer smoke tests across every supported desktop target, and durable release-manifest synchronization.
3 changes: 3 additions & 0 deletions .github/workflows/prek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ jobs:
- name: Test release workflow contract
run: pnpm test:release

- name: Test RC1 parity evidence contract
run: pnpm test:parity

- name: Check for changes
id: check_changes
if: steps.prek.outcome == 'failure'
Expand Down
18 changes: 15 additions & 3 deletions .github/workflows/semifold-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
Acquire::https::Timeout "30";
EOF

packages="libwebkit2gtk-4.1-dev build-essential curl wget file libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libfuse2"
packages="libwebkit2gtk-4.1-dev build-essential curl wget file libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libfuse2 rpm2cpio cpio"
for attempt in 1 2 3; do
sudo apt-get update && sudo apt-get install -y $packages && break
if [ "$attempt" = "3" ]; then
Expand Down Expand Up @@ -154,6 +154,19 @@ jobs:
fi
working-directory: target/release

- name: Smoke isolated install (Linux)
if: runner.os == 'Linux'
run: scripts/smoke-install-linux.sh "${{ matrix.target }}"

- name: Smoke isolated install (macOS)
if: runner.os == 'macOS'
run: scripts/smoke-install-macos.sh "${{ matrix.target }}"

- name: Smoke isolated install (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: scripts/smoke-install-windows.ps1 -Target "${{ matrix.target }}"

- name: Upload Artifact (Linux)
if: runner.os == 'Linux'
uses: actions/upload-artifact@v6
Expand All @@ -162,7 +175,7 @@ jobs:
path: |
target/${{ matrix.target }}/release/bundle/appimage/*.AppImage
target/${{ matrix.target }}/release/bundle/deb/*.deb
target/${{ matrix.target }}/release/bundle/appimage/*.rpm
target/${{ matrix.target }}/release/bundle/rpm/*.rpm
retention-days: 7

- name: Upload Artifact (Windows)
Expand All @@ -171,7 +184,6 @@ jobs:
with:
name: windows-${{ matrix.target }}-artifacts
path: |
target/${{ matrix.target }}/release/bundle/msi/*.msi
target/${{ matrix.target }}/release/bundle/nsis/*.exe
retention-days: 1

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ artifacts/

# AUR Release
release/
!docs/release/
!docs/release/rc1-parity.json

# claude code
.claude/
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

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

430 changes: 430 additions & 0 deletions docs/release/rc1-parity.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"deploy:docs": "wrangler deploy",
"generate": "cargo test export_bindings && biome check packages/ui/src/types packages/ui/src/client.ts --fix",
"bump-tauri": "tsx scripts/bump-tauri.ts",
"test:parity": "node --test scripts/parity-audit.test.mjs",
"test:release": "node --test scripts/release-workflow.test.mjs",
"prepare": "node scripts/install-prek-hooks.mjs"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/content/en/manual/releases/meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"title": "Release Notes",
"pages": ["alpha-7"]
"pages": ["rc-1", "alpha-7"]
}
56 changes: 56 additions & 0 deletions packages/docs/content/en/manual/releases/rc-1.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: 0.2.0-rc.1 — Parity Evidence
description: A requirement-by-requirement PCL, HMCL, and PrismLauncher parity audit with reproducible release checks.
---

# 0.2.0-rc.1 — Release candidate 1

RC1 turns DropOut's PCL, HMCL, and PrismLauncher parity claim into a checked release contract. The repository audit covers 42 UI/UX, launcher-function, migration, distribution, and documentation requirements. Every row names current code plus a regression test, workflow, fixture, or published guide; missing files and stale evidence markers fail CI.

This is still a prerelease. Export irreplaceable instances before upgrading and report regressions on [GitHub Issues](https://github.com/HydroRoll-Team/DropOut/issues).

## What is included

- A state-aware Home workflow, scalable instance library, staged instance creation, content browsing, accounts, runtime management, downloads, errors, updates, accessibility, and bounded visual effects.
- Microsoft and offline authentication, managed Java, vanilla/Fabric/Forge installation, mods and packs, repair/export flows, system-tray lifecycle, the consent-gated assistant, and protected content conversion.
- Reviewed, copy-only Prism/MultiMC and PCL/HMCL migration with archive support, conflict previews, cancellation, operation-scoped rollback, and byte-for-byte source preservation fixtures.
- Linux x86_64/ARM64, macOS x86_64/ARM64, Windows x86_64/ARM64, and Alpine musl artifacts with release provenance.

## Reproduce the evidence gate

From a clean checkout with Node.js 22, pnpm 10, and stable Rust:

```bash
pnpm install --frozen-lockfile
pnpm test:parity
pnpm test:release
pnpm -C packages/ui test:unit
pnpm -C packages/ui test:ui
cargo test --manifest-path src-tauri/Cargo.toml --verbose
```

The machine-checked matrix lives at [`docs/release/rc1-parity.json`](https://github.com/HydroRoll-Team/DropOut/blob/main/docs/release/rc1-parity.json). Pull-request CI repeats Rust tests on Ubuntu, Arch Linux/Wayland, macOS, and Windows. Release CI builds every supported target and verifies each desktop installer in an isolated directory before upload; the musl archive executes in a clean Alpine runtime.

## Install and verify

Download the asset for your platform from [GitHub Releases](https://github.com/HydroRoll-Team/DropOut/releases). Verify its repository-bound provenance before opening it:

```bash
gh attestation verify <downloaded-file> -R HydroRoll-Team/DropOut
```

The [getting-started guide](/en/docs/manual/getting-started) covers platform assets and updater behavior. The [migration guide](/en/docs/manual/features/migration) explains source selection and rollback; [content conversion](/en/docs/manual/features/content-conversion) explains compatibility review and exclusions.

## Upgrade notes

- Existing DropOut configuration and instances remain in place.
- Migration and conversion create DropOut-managed copies. They do not convert a source launcher directory in place.
- Review unresolved content and explicit exclusions before applying a Minecraft or loader conversion.
- Keep the source launcher and important archives until the copied instance has launched successfully.

## Known limits

- RC1 is a release candidate, not the stable channel.
- Mod and pack compatibility depends on metadata exposed by the configured content provider; unresolved files require review or exclusion.
- Remote dependencies declared by launcher archives are reported for follow-up and are not silently treated as installed.
- GitHub build provenance is available for release assets. Operating-system code signing or notarization applies only where the release environment is configured for it.
2 changes: 1 addition & 1 deletion packages/docs/content/zh/manual/releases/meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"title": "发布说明",
"pages": ["alpha-7"]
"pages": ["rc-1", "alpha-7"]
}
56 changes: 56 additions & 0 deletions packages/docs/content/zh/manual/releases/rc-1.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: 0.2.0-rc.1 — 对标证据
description: 逐项核对 PCL、HMCL 与 PrismLauncher 对标要求,并提供可复现的发布检查。
---

# 0.2.0-rc.1 — 候选版本 1

RC1 将 DropOut 对 PCL、HMCL 与 PrismLauncher 的对标声明变成可检查的发布契约。仓库审计覆盖 42 项 UI/UX、启动器功能、迁移、分发与文档要求。每一项都绑定当前代码,以及回归测试、工作流、fixture 或已发布指南;文件缺失或证据标记过期都会让 CI 失败。

这仍是预发布版本。升级前请导出无法替代的重要实例,并在 [GitHub Issues](https://github.com/HydroRoll-Team/DropOut/issues) 报告回归问题。

## 包含内容

- 基于状态的主页流程、可扩展实例库、分步实例创建、内容浏览、账户、运行时管理、下载、错误、更新、无障碍与受控视觉效果。
- Microsoft/离线认证、托管 Java、原版/Fabric/Forge 安装、模组与资源包、修复/导出、系统托盘生命周期、需同意的诊断助手,以及受保护的内容转换。
- 经核对且只复制的 Prism/MultiMC、PCL/HMCL 迁移;支持归档包、冲突预览、取消、操作级回滚和来源逐字节不变 fixture。
- Linux x86_64/ARM64、macOS x86_64/ARM64、Windows x86_64/ARM64 与 Alpine musl 产物及发布来源证明。

## 复现证据门禁

在安装 Node.js 22、pnpm 10 和稳定版 Rust 的干净检出中运行:

```bash
pnpm install --frozen-lockfile
pnpm test:parity
pnpm test:release
pnpm -C packages/ui test:unit
pnpm -C packages/ui test:ui
cargo test --manifest-path src-tauri/Cargo.toml --verbose
```

机器检查矩阵位于 [`docs/release/rc1-parity.json`](https://github.com/HydroRoll-Team/DropOut/blob/main/docs/release/rc1-parity.json)。拉取请求 CI 会在 Ubuntu、Arch Linux/Wayland、macOS 和 Windows 重跑 Rust 测试;发布 CI 会构建所有受支持目标,在上传前把各桌面安装包放入隔离目录验证,并在干净 Alpine 运行时执行 musl 产物。

## 安装与验证

从 [GitHub Releases](https://github.com/HydroRoll-Team/DropOut/releases) 下载适合平台的产物。打开前验证与本仓库绑定的来源证明:

```bash
gh attestation verify <downloaded-file> -R HydroRoll-Team/DropOut
```

[入门指南](/docs/manual/getting-started)说明平台产物和更新器行为;[迁移指南](/docs/manual/features/migration)说明来源选择与回滚;[内容转换](/docs/manual/features/content-conversion)说明兼容性核对与排除项。

## 升级说明

- 现有 DropOut 配置和实例会继续保留。
- 迁移和转换会创建由 DropOut 管理的副本,不会原地修改来源启动器目录。
- 应用 Minecraft 或加载器转换前,必须核对未解决内容和明确排除项。
- 在复制后的实例成功启动前,请保留来源启动器和重要归档包。

## 已知限制

- RC1 是候选版本,不是稳定渠道。
- 模组和资源包兼容性取决于配置内容提供方公开的元数据;未解决文件必须人工核对或排除。
- 启动器归档包声明的远程依赖会作为后续任务报告,不会被静默视为已安装。
- 发布产物提供 GitHub 构建来源证明;操作系统代码签名或公证仅在发布环境已配置时适用。
2 changes: 1 addition & 1 deletion packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@dropout/docs",
"private": true,
"type": "module",
"version": "0.1.0-beta.2",
"version": "0.1.0-rc.0",
Comment thread
HsiangNianian marked this conversation as resolved.
"scripts": {
"build": "react-router build",
"dev": "react-router dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@dropout/ui",
"private": true,
"version": "0.1.0-beta.2",
"version": "0.1.0-rc.0",
Comment thread
HsiangNianian marked this conversation as resolved.
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
64 changes: 56 additions & 8 deletions scripts/bump-tauri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import path from "node:path";
import consola from "consola";
import toml from "toml";

const tauriJsonPath = path.join(
__dirname,
"..",
"src-tauri",
"tauri.conf.json",
);
const repoRoot = process.env.DROPOUT_REPO_ROOT ?? path.join(__dirname, "..");
const tauriJsonPath = path.join(repoRoot, "src-tauri", "tauri.conf.json");
consola.debug("tauriJsonPath:", tauriJsonPath);
const tauriTomlPath = path.join(__dirname, "..", "src-tauri", "Cargo.toml");
const tauriTomlPath = path.join(repoRoot, "src-tauri", "Cargo.toml");
consola.debug("tauriTomlPath:", tauriTomlPath);
const cargoLockPath = path.join(repoRoot, "Cargo.lock");
const packageJsonPaths = [
path.join(repoRoot, "packages", "ui", "package.json"),
path.join(repoRoot, "packages", "docs", "package.json"),
];

const getCurrentVersion = () => {
const tauriJsonData = fs.readFileSync(tauriJsonPath, "utf8");
Expand All @@ -37,6 +38,41 @@ const replaceVersion = (content: string, version: string) => {
return newJson;
};

const replaceLockedVersion = (content: string, version: string) => {
let matchedPackages = 0;
const sections = content.split(/(?=^\[\[package\]\]\s*(?:\r?\n|$))/m);

const synchronizedSections = sections.map((section) => {
if (!section.startsWith("[[package]]")) return section;

const parsed = toml.parse(section);
const lockedPackage = Array.isArray(parsed.package)
? parsed.package[0]
: undefined;
if (lockedPackage?.name !== "dropout") return section;

matchedPackages += 1;
const versionPattern = /^(\s*version\s*=\s*")[^"]+(".*)$/m;
if (!versionPattern.test(section)) {
throw new Error("DropOut package version not found in Cargo.lock");
}
return section.replace(versionPattern, `$1${version}$2`);
});

if (matchedPackages !== 1) {
throw new Error(
`Expected one DropOut package entry in Cargo.lock, found ${matchedPackages}`,
);
}
return synchronizedSections.join("");
};

const writeIfChanged = (filePath: string, previous: string, next: string) => {
if (previous !== next) {
fs.writeFileSync(filePath, next);
}
};

const tauriJsonData = fs.readFileSync(tauriJsonPath, "utf8");
const currentVersion = getCurrentVersion();
const bumpVersion = getBumpVersion();
Expand All @@ -46,7 +82,19 @@ consola.debug("bumpVersion:", bumpVersion);
if (currentVersion !== bumpVersion) {
const replacedData = replaceVersion(tauriJsonData, bumpVersion);
consola.info(`Bumped version from ${currentVersion} to ${bumpVersion}`);
fs.writeFileSync(tauriJsonPath, replacedData);
writeIfChanged(tauriJsonPath, tauriJsonData, replacedData);
} else {
consola.info(`Version ${currentVersion} is already up-to-date`);
}

const cargoLockData = fs.readFileSync(cargoLockPath, "utf8");
const synchronizedLock = replaceLockedVersion(cargoLockData, bumpVersion);
writeIfChanged(cargoLockPath, cargoLockData, synchronizedLock);

for (const packageJsonPath of packageJsonPaths) {
const packageJson = fs.readFileSync(packageJsonPath, "utf8");
const normalizedPackageJson = packageJson.endsWith("\n")
? packageJson
: `${packageJson}\n`;
writeIfChanged(packageJsonPath, packageJson, normalizedPackageJson);
}
Loading
Loading