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
203 changes: 203 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
name: Build & Release

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
platform:
description: '构建平台'
required: true
default: 'all'
type: choice
options:
- all
- windows
- macos
- linux

permissions:
contents: write

jobs:
build_windows:
runs-on: windows-latest
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'windows' || startsWith(github.ref, 'refs/tags/') }}

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-pc-windows-msvc

- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/
~/.cargo/git/
src-tauri/target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Install Windows WebView2
run: |
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -OutFile "$env:TEMP\MicrosoftEdgeWebview2Setup.exe"
Start-Process "$env:TEMP\MicrosoftEdgeWebview2Setup.exe" -ArgumentList "/silent /install" -Wait

- name: Install Node.js dependencies
run: npm ci

- name: Build Tauri app
run: npx tauri build

- name: Upload Windows artifacts
uses: actions/upload-artifact@v4
with:
name: windows-build
path: |
src-tauri/target/release/bundle/**/*.msi
src-tauri/target/release/bundle/**/*.exe
if-no-files-found: error

build_macos:
runs-on: macos-latest
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'macos' || startsWith(github.ref, 'refs/tags/') }}
strategy:
matrix:
target: [aarch64-apple-darwin, x86_64-apple-darwin]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/
~/.cargo/git/
src-tauri/target/
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.target }}-cargo-

- name: Install Node.js dependencies
run: npm ci

- name: Build Tauri app
run: npx tauri build --target ${{ matrix.target }}

- name: Upload macOS artifacts
uses: actions/upload-artifact@v4
with:
name: macos-${{ matrix.target }}-build
path: |
src-tauri/target/${{ matrix.target }}/release/bundle/**/*.dmg
src-tauri/target/${{ matrix.target }}/release/bundle/**/*.app
if-no-files-found: error

build_linux:
runs-on: ubuntu-22.04
if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'linux' || startsWith(github.ref, 'refs/tags/') }}

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/
~/.cargo/git/
src-tauri/target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
file \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
pkg-config

- name: Install Node.js dependencies
run: npm ci

- name: Build Tauri app
run: npx tauri build

- name: Upload Linux artifacts
uses: actions/upload-artifact@v4
with:
name: linux-build
path: |
src-tauri/target/release/bundle/**/*.deb
src-tauri/target/release/bundle/**/*.AppImage
src-tauri/target/release/bundle/**/*.rpm
if-no-files-found: error

release:
needs: [build_windows, build_macos, build_linux]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')

steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts

- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
artifacts/**/*.msi
artifacts/**/*.exe
artifacts/**/*.dmg
artifacts/**/*.deb
artifacts/**/*.AppImage
artifacts/**/*.rpm
draft: true
generate_release_notes: true
17 changes: 9 additions & 8 deletions src/components/common/HashFileModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useFileSystem } from '../../providers/FileSystemProvider';
import { showError, showSuccess } from '../../utils/NotificationSystem';
import Modal from '../common/Modal';
import Button from '../common/Button';
import zhCN from '../../locales/zh-CN.js';

/**
* Modal component for generating a hash file for a selected file or directory
Expand Down Expand Up @@ -63,11 +64,11 @@ const HashFileModal = ({ isOpen, onClose, item }) => {
});

await loadDirectory(currentPath);
showSuccess(`Hash generated and saved to ${fileName}: ${hash.substring(0, 16)}...`);
showSuccess(zhCN.hash.hashGenerated.replace('{file}', fileName).replace('{hash}', hash.substring(0, 16)));
onClose();
} catch (error) {
console.error('Hash generation to file failed:', error);
showError(`Failed to generate hash file: ${error.message || error}`);
showError(`${zhCN.hash.hashGenerateFailed}: ${error.message || error}`);
} finally {
setIsGenerating(false);
}
Expand Down Expand Up @@ -97,7 +98,7 @@ const HashFileModal = ({ isOpen, onClose, item }) => {
<Modal
isOpen={isOpen}
onClose={onClose}
title="Generate Hash to File"
title={zhCN.hash.generateHashToFile}
size="sm"
footer={
<>
Expand All @@ -106,23 +107,23 @@ const HashFileModal = ({ isOpen, onClose, item }) => {
onClick={onClose}
disabled={isGenerating}
>
Cancel
{zhCN.common.cancel}
</Button>
<Button
type="submit"
variant="primary"
disabled={!fileName.trim() || isGenerating}
onClick={handleSubmit}
>
{isGenerating ? 'Generating...' : 'Generate Hash'}
{isGenerating ? zhCN.hash.generating : zhCN.hash.generateHash}
</Button>
</>
}
>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="hash-filename">
Hash file name:
{zhCN.hash.hashFileName}
</label>
<input
ref={inputRef}
Expand All @@ -132,11 +133,11 @@ const HashFileModal = ({ isOpen, onClose, item }) => {
onChange={handleChange}
onKeyDown={handleKeyDown}
className="input"
placeholder="Enter hash file name"
placeholder={zhCN.hash.hashFileNamePlaceholder}
disabled={isGenerating}
/>
<div className="input-hint">
The hash will be generated for "{item.name}" and saved to this file.
{zhCN.hash.hashFileHint.replace('{name}', item.name)}
</div>
</div>
</form>
Expand Down
Loading