mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-11 02:12:53 +00:00
perf: 优化客户端升级
This commit is contained in:
parent
da066e40ce
commit
21eab03684
63
.github/workflows/publish-android.yml
vendored
63
.github/workflows/publish-android.yml
vendored
@ -1,63 +0,0 @@
|
||||
name: Publish Android
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
name: Build Android
|
||||
runs-on: ubuntu-latest
|
||||
environment: build
|
||||
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Build Js
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 5
|
||||
command: |
|
||||
git submodule init
|
||||
git submodule update --remote "resources/mobile"
|
||||
./cmd appbuild publish
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: '11'
|
||||
|
||||
- name: Build Android
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
timeout_minutes: 60
|
||||
max_attempts: 10
|
||||
command: |
|
||||
cd resources/mobile/platforms/android/eeuiApp
|
||||
chmod +x ./gradlew
|
||||
./gradlew assembleRelease --quiet
|
||||
|
||||
- name: Upload File
|
||||
env:
|
||||
DP_KEY: ${{ secrets.DP_KEY }}
|
||||
run: |
|
||||
node ./electron/build.js android-upload
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
with:
|
||||
files: |
|
||||
resources/mobile/platforms/android/eeuiApp/app/build/outputs/apk/release/*.apk
|
||||
35
.github/workflows/publish-desktop-mac.yml
vendored
35
.github/workflows/publish-desktop-mac.yml
vendored
@ -1,35 +0,0 @@
|
||||
name: Publish Mac
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
name: Build Mac
|
||||
runs-on: macos-12
|
||||
environment: build
|
||||
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
APPLEID: ${{ secrets.APPLEID }}
|
||||
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
DP_KEY: ${{ secrets.DP_KEY }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
GH_REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
./cmd electron mac
|
||||
|
||||
31
.github/workflows/publish-desktop-win.yml
vendored
31
.github/workflows/publish-desktop-win.yml
vendored
@ -1,31 +0,0 @@
|
||||
name: Publish Win
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
name: Build Windows
|
||||
runs-on: windows-latest
|
||||
environment: build
|
||||
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
DP_KEY: ${{ secrets.DP_KEY }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
GH_REPOSITORY: ${{ github.repository }}
|
||||
shell: bash
|
||||
run: |
|
||||
./cmd electron win
|
||||
244
.github/workflows/publish.yml
vendored
Normal file
244
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,244 @@
|
||||
name: "Publish"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "pro"
|
||||
|
||||
jobs:
|
||||
check-version:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
should_release: ${{ steps.check-tag.outputs.should_release }}
|
||||
version: ${{ steps.get-version.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get version from package.json
|
||||
id: get-version
|
||||
run: |
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Check if tag exists
|
||||
id: check-tag
|
||||
run: |
|
||||
VERSION=${{ steps.get-version.outputs.version }}
|
||||
if git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; then
|
||||
echo "This version v${VERSION} has been released"
|
||||
echo "should_release=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Version v${VERSION} has not been released, continue building"
|
||||
echo "should_release=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
create-release:
|
||||
needs: check-version
|
||||
if: needs.check-version.outputs.should_release == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
release_id: ${{ steps.create-release.outputs.result }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: create release
|
||||
id: create-release
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
// 获取最新的 tag
|
||||
const { data: tags } = await github.rest.repos.listTags({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
per_page: 1
|
||||
});
|
||||
|
||||
// 获取提交日志
|
||||
let changelog = '';
|
||||
if (tags.length > 0) {
|
||||
const { data: commits } = await github.rest.repos.compareCommits({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
base: tags[0].name,
|
||||
head: 'HEAD'
|
||||
});
|
||||
|
||||
// 按类型分组提交
|
||||
const groups = {
|
||||
'feat:': { title: '## Features', commits: [] },
|
||||
'fix:': { title: '## Bug Fixes', commits: [] },
|
||||
'perf:': { title: '## Performance Improvements', commits: [] }
|
||||
};
|
||||
|
||||
// 分类收集提交
|
||||
commits.commits.forEach(commit => {
|
||||
const message = commit.commit.message.split('\n')[0].trim();
|
||||
for (const [prefix, group] of Object.entries(groups)) {
|
||||
if (message.startsWith(prefix)) {
|
||||
// 移除前缀后添加到对应分组
|
||||
const cleanMessage = message.slice(prefix.length).trim();
|
||||
group.commits.push(`- ${cleanMessage}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 生成更新日志
|
||||
const sections = [];
|
||||
for (const group of Object.values(groups)) {
|
||||
if (group.commits.length > 0) {
|
||||
sections.push(`${group.title}\n\n${group.commits.join('\n')}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (sections.length > 0) {
|
||||
changelog = '# Changelog\n\n' + sections.join('\n\n');
|
||||
}
|
||||
}
|
||||
|
||||
// 创建 release
|
||||
const { data } = await github.rest.repos.createRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
tag_name: `v${{ needs.check-version.outputs.version }}`,
|
||||
name: `${{ needs.check-version.outputs.version }}`,
|
||||
body: changelog || 'No significant changes in this release.',
|
||||
draft: true,
|
||||
prerelease: false
|
||||
})
|
||||
return data.id
|
||||
|
||||
build-client:
|
||||
needs: [ check-version, create-release ]
|
||||
if: needs.check-version.outputs.should_release == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: "macos-latest"
|
||||
build_type: "mac"
|
||||
args: "--target aarch64-apple-darwin"
|
||||
- platform: "macos-latest"
|
||||
build_type: "mac"
|
||||
args: "--target x86_64-apple-darwin"
|
||||
- platform: "ubuntu-latest"
|
||||
build_type: "android"
|
||||
args: ""
|
||||
- platform: "windows-latest"
|
||||
build_type: "windows"
|
||||
args: ""
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
environment: build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
# Android 构建步骤
|
||||
- name: Build Js for Android
|
||||
if: matrix.build_type == 'android'
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 5
|
||||
command: |
|
||||
git submodule init
|
||||
git submodule update --remote "resources/mobile"
|
||||
./cmd appbuild publish
|
||||
|
||||
- name: Setup JDK 11 for Android
|
||||
if: matrix.build_type == 'android'
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: "zulu"
|
||||
java-version: "11"
|
||||
|
||||
- name: Build Android App
|
||||
if: matrix.build_type == 'android'
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
timeout_minutes: 60
|
||||
max_attempts: 10
|
||||
command: |
|
||||
cd resources/mobile/platforms/android/eeuiApp
|
||||
chmod +x ./gradlew
|
||||
./gradlew assembleRelease --quiet
|
||||
|
||||
- name: Upload Android File
|
||||
if: matrix.build_type == 'android'
|
||||
env:
|
||||
DP_KEY: ${{ secrets.DP_KEY }}
|
||||
run: |
|
||||
node ./electron/build.js android-upload
|
||||
|
||||
# Mac 构建步骤
|
||||
- name: Build Mac App
|
||||
if: matrix.build_type == 'mac'
|
||||
env:
|
||||
APPLEID: ${{ secrets.APPLEID }}
|
||||
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
DP_KEY: ${{ secrets.DP_KEY }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
GH_REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
./cmd electron mac
|
||||
|
||||
# Windows 构建步骤
|
||||
- name: Build Windows App
|
||||
if: matrix.build_type == 'windows'
|
||||
env:
|
||||
DP_KEY: ${{ secrets.DP_KEY }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
GH_REPOSITORY: ${{ github.repository }}
|
||||
shell: bash
|
||||
run: |
|
||||
./cmd electron win
|
||||
|
||||
# 上传Android构建产物
|
||||
- name: Upload Android Release Assets
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
if: matrix.build_type == 'android'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: v${{ needs.check-version.outputs.version }}
|
||||
files: |
|
||||
resources/mobile/platforms/android/eeuiApp/app/build/outputs/apk/release/*.apk
|
||||
|
||||
# publish-release:
|
||||
# needs: [check-version, create-release, builds]
|
||||
# if: needs.check-version.outputs.should_release == 'true'
|
||||
# permissions:
|
||||
# contents: write
|
||||
# runs-on: ubuntu-latest
|
||||
|
||||
# steps:
|
||||
# - name: publish release
|
||||
# id: publish-release
|
||||
# uses: actions/github-script@v7
|
||||
# env:
|
||||
# release_id: ${{ needs.create-release.outputs.release_id }}
|
||||
# with:
|
||||
# script: |
|
||||
# github.rest.repos.updateRelease({
|
||||
# owner: context.repo.owner,
|
||||
# repo: context.repo.repo,
|
||||
# release_id: process.env.release_id,
|
||||
# draft: false,
|
||||
# prerelease: false
|
||||
# })
|
||||
@ -126,7 +126,7 @@ class IndexController extends InvokeController
|
||||
// 其他
|
||||
'bot', 'robot', 'auto', 'anonymous', 'guest', 'default', 'new', 'old'
|
||||
];
|
||||
$filterWords = array_map(function($word) {
|
||||
$filterWords = array_map(function ($word) {
|
||||
return preg_quote($word, '/');
|
||||
}, $filterWords);
|
||||
$name = preg_replace('/' . implode('|', $filterWords) . '/iu', '', $name) ?: $name;
|
||||
@ -157,7 +157,7 @@ class IndexController extends InvokeController
|
||||
'\x{1F900}-\x{1F9FF}',
|
||||
'\x{1F600}-\x{1F64F}'
|
||||
];
|
||||
$filterSymbols = array_map(function($symbol) {
|
||||
$filterSymbols = array_map(function ($symbol) {
|
||||
return preg_quote($symbol, '/');
|
||||
}, $filterSymbols);
|
||||
$name = preg_replace('/[' . implode('', $filterSymbols) . ']/u', '', $name) ?: $name;
|
||||
@ -171,7 +171,7 @@ class IndexController extends InvokeController
|
||||
if (empty($color)) {
|
||||
$color = '#ffffff';
|
||||
$cacheKey = "avatarBackgroundColor::" . md5($name);
|
||||
$background = Cache::rememberForever($cacheKey, function() {
|
||||
$background = Cache::rememberForever($cacheKey, function () {
|
||||
return RandomColor::one(['luminosity' => 'dark']);
|
||||
});
|
||||
}
|
||||
@ -192,7 +192,7 @@ class IndexController extends InvokeController
|
||||
'shape' => 'square',
|
||||
'width' => $size,
|
||||
'height' => $size,
|
||||
'chars' => 2,
|
||||
'chars' => 2,
|
||||
'fontSize' => $size / 2.9,
|
||||
'uppercase' => true,
|
||||
'fonts' => [resource_path('assets/statics/fonts/Source_Han_Sans_SC_Regular.otf')],
|
||||
@ -264,7 +264,6 @@ class IndexController extends InvokeController
|
||||
public function desktop__publish($name = '')
|
||||
{
|
||||
$publishVersion = Request::header('publish-version');
|
||||
$fileNum = Request::get('file_num', 1);
|
||||
$latestFile = public_path("uploads/desktop/latest");
|
||||
$latestVersion = file_exists($latestFile) ? trim(file_get_contents($latestFile)) : "0.0.1";
|
||||
if (strtolower($name) === 'latest') {
|
||||
@ -272,27 +271,29 @@ class IndexController extends InvokeController
|
||||
}
|
||||
// 上传
|
||||
if (preg_match("/^\d+\.\d+\.\d+$/", $publishVersion)) {
|
||||
$uploadSuccessFileNum = (int)Cache::get($publishVersion, 0);
|
||||
// 判断密钥
|
||||
$publishKey = Request::header('publish-key');
|
||||
if ($publishKey !== env('APP_KEY')) {
|
||||
return Base::retError("key error");
|
||||
}
|
||||
// 判断版本
|
||||
if (version_compare($publishVersion, $latestVersion) > -1) { // 限制上传版本必须 ≥ 当前版本
|
||||
$publishPath = "uploads/desktop/{$publishVersion}/";
|
||||
$res = Base::upload([
|
||||
"file" => Request::file('file'),
|
||||
"type" => 'publish',
|
||||
"path" => $publishPath,
|
||||
"fileName" => true,
|
||||
"quality" => 100
|
||||
]);
|
||||
if (Base::isSuccess($res)) {
|
||||
$action = Request::get('action');
|
||||
$draftPath = "uploads/desktop-draft/{$publishVersion}/";
|
||||
if ($action === 'release') {
|
||||
// 将草稿版本发布为正式版本
|
||||
$draftPath = public_path($draftPath);
|
||||
$releasePath = public_path("uploads/desktop/{$publishVersion}/");
|
||||
if (!file_exists($draftPath)) {
|
||||
return Base::retError("draft version not exists");
|
||||
}
|
||||
if (file_exists($releasePath)) {
|
||||
Base::deleteDirAndFile($releasePath);
|
||||
}
|
||||
Base::copyDirectory($draftPath, $releasePath);
|
||||
file_put_contents($latestFile, $publishVersion);
|
||||
$uploadSuccessFileNum = $uploadSuccessFileNum + 1;
|
||||
Cache::set($publishVersion, $uploadSuccessFileNum, 7200);
|
||||
}
|
||||
if ($uploadSuccessFileNum >= $fileNum) {
|
||||
// 删除旧版本
|
||||
Base::deleteDirAndFile(public_path("uploads/desktop-draft"));
|
||||
$dirs = Base::recursiveDirs(public_path("uploads/desktop"), false);
|
||||
sort($dirs);
|
||||
$num = 0;
|
||||
@ -309,8 +310,16 @@ class IndexController extends InvokeController
|
||||
Base::deleteDirAndFile($dir);
|
||||
}
|
||||
}
|
||||
return Base::retSuccess('success');
|
||||
}
|
||||
return $res;
|
||||
// 上传草稿版本
|
||||
return Base::upload([
|
||||
"file" => Request::file('file'),
|
||||
"type" => 'publish',
|
||||
"path" => $draftPath,
|
||||
"fileName" => true,
|
||||
"quality" => 100
|
||||
]);
|
||||
}
|
||||
}
|
||||
// 列表
|
||||
|
||||
@ -13,7 +13,6 @@ use League\CommonMark\Exception\CommonMarkException;
|
||||
use Overtrue\Pinyin\Pinyin;
|
||||
use Redirect;
|
||||
use Request;
|
||||
use Response;
|
||||
use Storage;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
@ -372,6 +371,34 @@ class Base
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制文件夹
|
||||
* @param $source
|
||||
* @param $destination
|
||||
* @return bool
|
||||
*/
|
||||
public static function copyDirectory($source, $destination)
|
||||
{
|
||||
if (!is_dir($source)) {
|
||||
return false;
|
||||
}
|
||||
if (!is_dir($destination)) {
|
||||
Base::makeDir($destination);
|
||||
}
|
||||
$dir = opendir($source);
|
||||
while (false !== ($file = readdir($dir))) {
|
||||
if (($file != '.') && ($file != '..')) {
|
||||
if (is_dir($source . '/' . $file)) {
|
||||
self::copyDirectory($source . '/' . $file, $destination . '/' . $file);
|
||||
} else {
|
||||
copy($source . '/' . $file, $destination . '/' . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 截取字符串
|
||||
|
||||
1
cmd
1
cmd
@ -174,6 +174,7 @@ run_electron() {
|
||||
mkdir -p ./electron/public
|
||||
cp ./electron/index.html ./electron/public/index.html
|
||||
npx vite build -- fromcmd electronBuild
|
||||
echo ""
|
||||
fi
|
||||
node ./electron/build.js $argv
|
||||
}
|
||||
|
||||
14
electron/build.js
vendored
14
electron/build.js
vendored
@ -292,7 +292,7 @@ function androidUpload(url) {
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("file", fs.createReadStream(localFile));
|
||||
formData.append("file_num", 1);
|
||||
formData.append("action", "draft");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
@ -358,16 +358,6 @@ function genericPublish({url, key, version, output}) {
|
||||
if (err) {
|
||||
console.warn(err)
|
||||
} else {
|
||||
let uploadFileNum = 0;
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(filePath, filename)
|
||||
if (fs.existsSync(localFile)) {
|
||||
const fileStat = fs.statSync(localFile)
|
||||
if (fileStat.isFile()) {
|
||||
uploadFileNum += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
const uploadOras = {}
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(filePath, filename)
|
||||
@ -377,7 +367,7 @@ function genericPublish({url, key, version, output}) {
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("file", fs.createReadStream(localFile));
|
||||
formData.append("file_num", uploadFileNum);
|
||||
formData.append("action", "draft");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "0.39.97",
|
||||
"version": "0.39.98",
|
||||
"codeVerson": 154,
|
||||
"description": "DooTask is task management system.",
|
||||
"scripts": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user