feat: add GitHub Actions auto-release workflow
This commit is contained in:
parent
13f9e5b71c
commit
468e05f7cc
96
.github/workflows/release.yml
vendored
Normal file
96
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
name: Build and Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*' # 当推送 v 开头的标签时触发,如 v1.0.0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||||
|
include:
|
||||||
|
- os: windows-latest
|
||||||
|
artifact_name: EasyShell-Windows
|
||||||
|
build_cmd: npm run build && npx electron-builder --win
|
||||||
|
- os: macos-latest
|
||||||
|
artifact_name: EasyShell-Mac
|
||||||
|
build_cmd: npm run build && npx electron-builder --mac
|
||||||
|
- os: ubuntu-latest
|
||||||
|
artifact_name: EasyShell-Linux
|
||||||
|
build_cmd: npm run build && npx electron-builder --linux
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '18'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Generate icons
|
||||||
|
run: npm run icons
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Build application
|
||||||
|
run: ${{ matrix.build_cmd }}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.artifact_name }}
|
||||||
|
path: |
|
||||||
|
dist/*.exe
|
||||||
|
dist/*.dmg
|
||||||
|
dist/*.AppImage
|
||||||
|
dist/*.deb
|
||||||
|
if-no-files-found: ignore
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: Create Release
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Download all artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: artifacts
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -R artifacts
|
||||||
|
|
||||||
|
- name: Get version from tag
|
||||||
|
id: get_version
|
||||||
|
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
name: EasyShell ${{ steps.get_version.outputs.VERSION }}
|
||||||
|
tag_name: ${{ steps.get_version.outputs.VERSION }}
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
generate_release_notes: true
|
||||||
|
files: |
|
||||||
|
artifacts/**/*.exe
|
||||||
|
artifacts/**/*.dmg
|
||||||
|
artifacts/**/*.AppImage
|
||||||
|
artifacts/**/*.deb
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
43
README.md
43
README.md
@ -171,6 +171,49 @@ npm run dist
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🏷️ 版本发布
|
||||||
|
|
||||||
|
项目已配置 GitHub Actions 自动化发布流程。
|
||||||
|
|
||||||
|
### 一键发布
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 发布补丁版本 (1.0.0 -> 1.0.1)
|
||||||
|
npm run release
|
||||||
|
|
||||||
|
# 发布次要版本 (1.0.0 -> 1.1.0)
|
||||||
|
npm run release:minor
|
||||||
|
|
||||||
|
# 发布主要版本 (1.0.0 -> 2.0.0)
|
||||||
|
npm run release:major
|
||||||
|
```
|
||||||
|
|
||||||
|
发布脚本会自动:
|
||||||
|
1. ✅ 更新 `package.json` 版本号
|
||||||
|
2. ✅ 更新界面显示的版本号
|
||||||
|
3. ✅ 提交更改
|
||||||
|
4. ✅ 创建 Git 标签
|
||||||
|
5. ✅ 推送到 GitHub
|
||||||
|
6. ✅ 触发 GitHub Actions 自动构建
|
||||||
|
|
||||||
|
### 自动构建
|
||||||
|
|
||||||
|
当推送 `v*` 格式的标签时(如 `v1.0.0`),GitHub Actions 将自动:
|
||||||
|
|
||||||
|
| 平台 | 产物 |
|
||||||
|
|------|------|
|
||||||
|
| Windows | `EasyShell Setup x.x.x.exe` |
|
||||||
|
| macOS | `EasyShell-x.x.x.dmg` |
|
||||||
|
| Linux | `EasyShell-x.x.x.AppImage` |
|
||||||
|
|
||||||
|
构建完成后会自动创建 GitHub Release 并上传安装包。
|
||||||
|
|
||||||
|
### 查看构建状态
|
||||||
|
|
||||||
|
[](https://github.com/ethanfly/easyshell/actions)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 📱 移动端部署
|
## 📱 移动端部署
|
||||||
|
|
||||||
### 1. 启动后端服务器
|
### 1. 启动后端服务器
|
||||||
|
|||||||
@ -17,6 +17,9 @@
|
|||||||
"version:patch": "node scripts/bump-version.js patch",
|
"version:patch": "node scripts/bump-version.js patch",
|
||||||
"version:minor": "node scripts/bump-version.js minor",
|
"version:minor": "node scripts/bump-version.js minor",
|
||||||
"version:major": "node scripts/bump-version.js major",
|
"version:major": "node scripts/bump-version.js major",
|
||||||
|
"release": "node scripts/release.js patch",
|
||||||
|
"release:minor": "node scripts/release.js minor",
|
||||||
|
"release:major": "node scripts/release.js major",
|
||||||
"icons": "node scripts/generate-icons.js",
|
"icons": "node scripts/generate-icons.js",
|
||||||
"server": "cd server && npm start",
|
"server": "cd server && npm start",
|
||||||
"server:dev": "cd server && npm run dev",
|
"server:dev": "cd server && npm run dev",
|
||||||
|
|||||||
108
scripts/release.js
Normal file
108
scripts/release.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* 发布脚本
|
||||||
|
* 自动更新版本号、提交、打标签并推送到 GitHub
|
||||||
|
*
|
||||||
|
* 用法:
|
||||||
|
* npm run release # patch 版本 (1.0.0 -> 1.0.1)
|
||||||
|
* npm run release:minor # minor 版本 (1.0.0 -> 1.1.0)
|
||||||
|
* npm run release:major # major 版本 (1.0.0 -> 2.0.0)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { execSync } = require('child_process');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
||||||
|
const titleBarPath = path.resolve(__dirname, '../src/components/TitleBar.js');
|
||||||
|
|
||||||
|
function exec(cmd, options = {}) {
|
||||||
|
console.log(`\n🔧 执行: ${cmd}`);
|
||||||
|
try {
|
||||||
|
execSync(cmd, { stdio: 'inherit', ...options });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`❌ 命令执行失败: ${cmd}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bumpVersion(type = 'patch') {
|
||||||
|
// 读取 package.json
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||||
|
let [major, minor, patch] = packageJson.version.split('.').map(Number);
|
||||||
|
|
||||||
|
// 递增版本号
|
||||||
|
if (type === 'major') {
|
||||||
|
major++;
|
||||||
|
minor = 0;
|
||||||
|
patch = 0;
|
||||||
|
} else if (type === 'minor') {
|
||||||
|
minor++;
|
||||||
|
patch = 0;
|
||||||
|
} else {
|
||||||
|
patch++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newVersion = `${major}.${minor}.${patch}`;
|
||||||
|
packageJson.version = newVersion;
|
||||||
|
|
||||||
|
// 更新 package.json
|
||||||
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4) + '\n');
|
||||||
|
console.log(`📦 版本号已更新: ${newVersion}`);
|
||||||
|
|
||||||
|
// 更新 TitleBar.js
|
||||||
|
if (fs.existsSync(titleBarPath)) {
|
||||||
|
let titleBarContent = fs.readFileSync(titleBarPath, 'utf8');
|
||||||
|
const newTitleBarContent = titleBarContent.replace(
|
||||||
|
/v\d+\.\d+\.\d+/g,
|
||||||
|
`v${newVersion}`
|
||||||
|
);
|
||||||
|
fs.writeFileSync(titleBarPath, newTitleBarContent, 'utf8');
|
||||||
|
console.log('📝 TitleBar.js 版本号已更新');
|
||||||
|
}
|
||||||
|
|
||||||
|
return newVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
function release() {
|
||||||
|
const versionType = process.argv[2] || 'patch';
|
||||||
|
|
||||||
|
console.log('🚀 开始发布流程...\n');
|
||||||
|
console.log(`📋 版本类型: ${versionType}`);
|
||||||
|
|
||||||
|
// 1. 检查是否有未提交的更改
|
||||||
|
try {
|
||||||
|
const status = execSync('git status --porcelain', { encoding: 'utf8' });
|
||||||
|
if (status.trim()) {
|
||||||
|
console.log('\n⚠️ 检测到未提交的更改,将一起提交...');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('❌ Git 状态检查失败');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 更新版本号
|
||||||
|
const newVersion = bumpVersion(versionType);
|
||||||
|
const tagName = `v${newVersion}`;
|
||||||
|
|
||||||
|
// 3. 添加所有更改
|
||||||
|
exec('git add .');
|
||||||
|
|
||||||
|
// 4. 提交更改
|
||||||
|
exec(`git commit -m "chore: release ${tagName}"`);
|
||||||
|
|
||||||
|
// 5. 创建标签
|
||||||
|
exec(`git tag -a ${tagName} -m "Release ${tagName}"`);
|
||||||
|
console.log(`\n🏷️ 标签已创建: ${tagName}`);
|
||||||
|
|
||||||
|
// 6. 推送到远程
|
||||||
|
console.log('\n📤 推送到远程仓库...');
|
||||||
|
exec('git push origin main');
|
||||||
|
exec(`git push origin ${tagName}`);
|
||||||
|
|
||||||
|
console.log(`\n✅ 发布完成!`);
|
||||||
|
console.log(` 版本: ${tagName}`);
|
||||||
|
console.log(` GitHub Actions 将自动开始构建...`);
|
||||||
|
console.log(`\n🔗 查看构建进度: https://github.com/ethanfly/easyshell/actions`);
|
||||||
|
}
|
||||||
|
|
||||||
|
release();
|
||||||
Loading…
Reference in New Issue
Block a user