mirror of
https://github.com/kuaifan/dootask.git
synced 2026-04-22 12:28:07 +00:00
feat: connect publish pipeline to dootask-website API
- Refactor build.js: replace androidUpload/genericPublish/published with unified WebsitePublisher class using Authorization Bearer auth - New CLI commands: upload-changelog, release - Update auto-update URL to /api/download/update (legacy compat on website) - publish.yml: use CHANGELOG.md for GitHub Release body, replace PUBLISH_KEY with UPLOAD_TOKEN + UPLOAD_URL
This commit is contained in:
parent
d17f404853
commit
a67fcd6f02
76
.github/workflows/publish.yml
vendored
76
.github/workflows/publish.yml
vendored
@ -52,53 +52,18 @@ jobs:
|
||||
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
|
||||
});
|
||||
const fs = require('fs');
|
||||
const version = '${{ needs.check-version.outputs.version }}';
|
||||
|
||||
// 获取提交日志
|
||||
// 从 CHANGELOG.md 提取当前版本段落
|
||||
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: new Set() },
|
||||
'fix:': { title: '## Bug Fixes', commits: new Set() },
|
||||
'perf:': { title: '## Performance Improvements', commits: new Set() }
|
||||
};
|
||||
|
||||
// 分类收集提交,使用 Set 去重
|
||||
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.add(cleanMessage); // 使用 Set.add 自动去重
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 生成更新日志
|
||||
const sections = [];
|
||||
for (const group of Object.values(groups)) {
|
||||
if (group.commits.size > 0) {
|
||||
sections.push(`${group.title}\n\n${Array.from(group.commits).map(msg => `- ${msg}`).join('\n')}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (sections.length > 0) {
|
||||
changelog = '# Changelog\n\n' + sections.join('\n\n');
|
||||
const changelogPath = 'CHANGELOG.md';
|
||||
if (fs.existsSync(changelogPath)) {
|
||||
const content = fs.readFileSync(changelogPath, 'utf-8');
|
||||
const regex = new RegExp(`## \\[${version.replace(/\./g, '\\.')}\\][\\s\\S]*?(?=\\n## \\[|$)`);
|
||||
const match = content.match(regex);
|
||||
if (match) {
|
||||
changelog = match[0].trim();
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,8 +71,8 @@ jobs:
|
||||
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 }}`,
|
||||
tag_name: `v${version}`,
|
||||
name: version,
|
||||
body: changelog || 'No significant changes in this release.',
|
||||
draft: true,
|
||||
prerelease: false
|
||||
@ -215,7 +180,8 @@ jobs:
|
||||
- name: (Android) Upload File
|
||||
if: matrix.build_type == 'android'
|
||||
env:
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
run: |
|
||||
node ./electron/build.js android-upload
|
||||
|
||||
@ -253,7 +219,8 @@ jobs:
|
||||
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
@ -263,7 +230,8 @@ jobs:
|
||||
- name: (Windows) Build Client
|
||||
if: matrix.build_type == 'windows'
|
||||
env:
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
shell: bash
|
||||
@ -294,11 +262,13 @@ jobs:
|
||||
prerelease: false
|
||||
})
|
||||
|
||||
- name: Publish Official
|
||||
- name: Upload Changelog & Publish to Website
|
||||
env:
|
||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
||||
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||
run: |
|
||||
pushd electron || exit
|
||||
npm install
|
||||
popd || exit
|
||||
node ./electron/build.js published
|
||||
node ./electron/build.js upload-changelog
|
||||
node ./electron/build.js release
|
||||
|
||||
410
electron/build.js
vendored
410
electron/build.js
vendored
@ -12,7 +12,7 @@ const utils = require('./lib/utils');
|
||||
const config = require('../package.json')
|
||||
const env = require('dotenv').config({ path: './.env' })
|
||||
const argv = process.argv;
|
||||
const {BUILD_FRONTEND, APPLEID, APPLEIDPASS, GITHUB_TOKEN, GITHUB_REPOSITORY, PUBLISH_KEY} = process.env;
|
||||
const {BUILD_FRONTEND, APPLEID, APPLEIDPASS, GITHUB_TOKEN, GITHUB_REPOSITORY, UPLOAD_TOKEN, UPLOAD_URL} = process.env;
|
||||
|
||||
const electronDir = path.resolve(__dirname, "public");
|
||||
const nativeCachePath = path.resolve(__dirname, ".native");
|
||||
@ -350,192 +350,166 @@ function axiosAutoTry(data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传app应用
|
||||
* @param url
|
||||
* 官网发布器
|
||||
*/
|
||||
function androidUpload(url) {
|
||||
if (!PUBLISH_KEY) {
|
||||
console.error("缺少 PUBLISH_KEY 环境变量");
|
||||
process.exit()
|
||||
class WebsitePublisher {
|
||||
constructor({baseUrl, token, version}) {
|
||||
this.baseUrl = baseUrl
|
||||
this.token = token
|
||||
this.version = version
|
||||
}
|
||||
const releaseDir = path.resolve(__dirname, "../resources/mobile/platforms/android/eeuiApp/app/build/outputs/apk/release");
|
||||
if (!fs.existsSync(releaseDir)) {
|
||||
console.error("发布文件未找到");
|
||||
process.exit()
|
||||
}
|
||||
fs.readdir(releaseDir, async (err, files) => {
|
||||
if (err) {
|
||||
console.warn(err)
|
||||
} else {
|
||||
const uploadOras = {}
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(releaseDir, filename)
|
||||
if (/\.apk$/.test(filename) && fs.existsSync(localFile)) {
|
||||
const fileStat = fs.statSync(localFile)
|
||||
if (fileStat.isFile()) {
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("file", fs.createReadStream(localFile));
|
||||
formData.append("action", "draft");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Publish-Version': config.version,
|
||||
'Publish-Key': PUBLISH_KEY,
|
||||
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
||||
},
|
||||
onUploadProgress: progress => {
|
||||
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
||||
uploadOras[filename].text = `Upload [${complete}] ${filename}`
|
||||
},
|
||||
},
|
||||
onRetry: _ => {
|
||||
uploadOras[filename].warn(`Upload [retry] ${filename}`)
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200) {
|
||||
uploadOras[filename].fail(`Upload [fail:${status}] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (!utils.isJson(data)) {
|
||||
uploadOras[filename].fail(`Upload [fail:not json] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (data.ret !== 1) {
|
||||
uploadOras[filename].fail(`Upload [fail:ret ${data.ret}] ${filename}`)
|
||||
return
|
||||
}
|
||||
uploadOras[filename].succeed(`Upload [100%] ${filename}`)
|
||||
}).catch(_ => {
|
||||
uploadOras[filename].fail(`Upload [fail] ${filename}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传单个文件
|
||||
* @param localFile 本地文件路径
|
||||
* @param options { platform, arch } 可选,有则为安装包
|
||||
*/
|
||||
async uploadPackage(localFile, options = {}) {
|
||||
const filename = path.basename(localFile)
|
||||
let spinner = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("file", fs.createReadStream(localFile))
|
||||
formData.append("version", this.version)
|
||||
if (options.platform) {
|
||||
formData.append("platform", options.platform)
|
||||
if (options.arch) {
|
||||
formData.append("arch", options.arch)
|
||||
}
|
||||
}
|
||||
});
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: `${this.baseUrl}/api/upload/package`,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
||||
},
|
||||
onUploadProgress: progress => {
|
||||
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
||||
spinner.text = `Upload [${complete}] ${filename}`
|
||||
},
|
||||
},
|
||||
onRetry: _ => {
|
||||
spinner.warn(`Upload [retry] ${filename}`)
|
||||
spinner = ora(`Upload [0%] ${filename}`).start()
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200) {
|
||||
spinner.fail(`Upload [fail:${status}] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (!utils.isJson(data)) {
|
||||
spinner.fail(`Upload [fail:not json] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (!data.success) {
|
||||
spinner.fail(`Upload [fail] ${filename}: ${data.message || JSON.stringify(data)}`)
|
||||
return
|
||||
}
|
||||
spinner.succeed(`Upload [100%] ${filename}`)
|
||||
}).catch(_ => {
|
||||
spinner.fail(`Upload [fail] ${filename}`)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传 changelog
|
||||
*/
|
||||
async uploadChangelog(content) {
|
||||
const spinner = ora('Uploading changelog...').start()
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: `${this.baseUrl}/api/upload/changelog`,
|
||||
data: { content },
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200 || !data.success) {
|
||||
spinner.fail('Changelog upload failed')
|
||||
return
|
||||
}
|
||||
spinner.succeed('Changelog uploaded')
|
||||
}).catch(_ => {
|
||||
spinner.fail('Changelog upload failed')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知发布完成
|
||||
*/
|
||||
async release() {
|
||||
const spinner = ora('Publishing release...').start()
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: `${this.baseUrl}/api/upload/release`,
|
||||
data: { version: this.version },
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200 || !data.success) {
|
||||
spinner.fail(`Release failed: ${data?.message || status}`)
|
||||
return
|
||||
}
|
||||
spinner.succeed('Release published')
|
||||
}).catch(_ => {
|
||||
spinner.fail('Release failed')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 安装包扩展名
|
||||
const INSTALLER_EXTS = ['.dmg', '.exe', '.msi', '.appimage', '.deb', '.rpm', '.apk']
|
||||
|
||||
/**
|
||||
* 通知发布完成
|
||||
* @param url
|
||||
* 创建 WebsitePublisher 实例(如果环境变量齐全)
|
||||
*/
|
||||
async function published(url) {
|
||||
if (!PUBLISH_KEY) {
|
||||
console.error("缺少 PUBLISH_KEY 环境变量");
|
||||
process.exit()
|
||||
function createPublisher() {
|
||||
if (!UPLOAD_TOKEN || !UPLOAD_URL) {
|
||||
return null
|
||||
}
|
||||
const spinner = ora('完成发布...').start();
|
||||
const formData = new FormData()
|
||||
formData.append("action", "release");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Publish-Version': config.version,
|
||||
'Publish-Key': PUBLISH_KEY,
|
||||
},
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200) {
|
||||
spinner.fail('发布失败, status: ' + status)
|
||||
return
|
||||
}
|
||||
if (!utils.isJson(data)) {
|
||||
spinner.fail('发布失败, not json')
|
||||
return
|
||||
}
|
||||
if (data.ret !== 1) {
|
||||
spinner.fail(`发布失败, ${JSON.stringify(data)}`)
|
||||
return
|
||||
}
|
||||
spinner.succeed('发布完成')
|
||||
}).catch(_ => {
|
||||
spinner.fail('发布失败')
|
||||
return new WebsitePublisher({
|
||||
baseUrl: UPLOAD_URL.replace(/\/+$/, ''),
|
||||
token: UPLOAD_TOKEN,
|
||||
version: config.version
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用发布
|
||||
* @param url
|
||||
* @param key
|
||||
* @param version
|
||||
* @param output
|
||||
* 从文件名判断是否为安装包
|
||||
*/
|
||||
function genericPublish({url, key, version, output}) {
|
||||
if (!/https?:\/\//i.test(url)) {
|
||||
console.warn("发布地址无效: " + url)
|
||||
return
|
||||
}
|
||||
const filePath = path.resolve(__dirname, output)
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.warn("发布文件未找到: " + filePath)
|
||||
return
|
||||
}
|
||||
fs.readdir(filePath, async (err, files) => {
|
||||
if (err) {
|
||||
console.warn(err)
|
||||
} else {
|
||||
const uploadOras = {}
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(filePath, filename)
|
||||
if (fs.existsSync(localFile)) {
|
||||
const fileStat = fs.statSync(localFile)
|
||||
if (fileStat.isFile()) {
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
const formData = new FormData()
|
||||
formData.append("file", fs.createReadStream(localFile));
|
||||
formData.append("action", "draft");
|
||||
await axiosAutoTry({
|
||||
axios: {
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Publish-Version': version,
|
||||
'Publish-Key': key,
|
||||
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
||||
},
|
||||
onUploadProgress: progress => {
|
||||
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
||||
uploadOras[filename].text = `Upload [${complete}] ${filename}`
|
||||
},
|
||||
},
|
||||
onRetry: _ => {
|
||||
uploadOras[filename].warn(`Upload [retry] ${filename}`)
|
||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
||||
},
|
||||
retryNumber: 3
|
||||
}).then(({status, data}) => {
|
||||
if (status !== 200) {
|
||||
uploadOras[filename].fail(`Upload [fail:${status}] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (!utils.isJson(data)) {
|
||||
uploadOras[filename].fail(`Upload [fail:not json] ${filename}`)
|
||||
return
|
||||
}
|
||||
if (data.ret !== 1) {
|
||||
uploadOras[filename].fail(`Upload [fail:ret ${data.ret}] ${filename}`)
|
||||
return
|
||||
}
|
||||
uploadOras[filename].succeed(`Upload [100%] ${filename}`)
|
||||
}).catch(_ => {
|
||||
uploadOras[filename].fail(`Upload [fail] ${filename}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
function isInstaller(filename) {
|
||||
return INSTALLER_EXTS.some(ext => filename.toLowerCase().endsWith(ext))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件名提取 arch
|
||||
*/
|
||||
function parseArchFromFilename(filename) {
|
||||
if (/-arm64[.-]/i.test(filename)) return 'arm64'
|
||||
if (/-x64[.-]/i.test(filename)) return 'x64'
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 将构建平台名映射为 API platform
|
||||
*/
|
||||
function mapPlatform(buildPlatform) {
|
||||
if (buildPlatform.includes('mac')) return 'mac'
|
||||
if (buildPlatform.includes('win')) return 'win'
|
||||
if (buildPlatform.includes('linux')) return 'linux'
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
@ -703,13 +677,27 @@ async function startBuild(data) {
|
||||
appConfig.build.directories.output = `${output}-generic`;
|
||||
fs.writeFileSync(packageFile, JSON.stringify(appConfig, null, 4), 'utf8');
|
||||
child_process.execSync(`npm run ${platform}`, {stdio: "inherit", cwd: "electron"});
|
||||
if (publish === true && PUBLISH_KEY) {
|
||||
genericPublish({
|
||||
url: appConfig.build.publish.url,
|
||||
key: PUBLISH_KEY,
|
||||
version: config.version,
|
||||
output: appConfig.build.directories.output
|
||||
})
|
||||
if (publish === true) {
|
||||
const publisher = createPublisher()
|
||||
if (publisher) {
|
||||
const outputDir = path.resolve(__dirname, appConfig.build.directories.output)
|
||||
if (fs.existsSync(outputDir)) {
|
||||
const apiPlatform = mapPlatform(platform)
|
||||
const files = fs.readdirSync(outputDir)
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(outputDir, filename)
|
||||
const fileStat = fs.statSync(localFile)
|
||||
if (!fileStat.isFile()) continue
|
||||
|
||||
if (isInstaller(filename) && apiPlatform) {
|
||||
const arch = parseArchFromFilename(filename)
|
||||
await publisher.uploadPackage(localFile, { platform: apiPlatform, arch })
|
||||
} else {
|
||||
await publisher.uploadPackage(localFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// package.json Recovery
|
||||
recoveryPackage(true)
|
||||
@ -746,18 +734,56 @@ if (["dev"].includes(argv[2])) {
|
||||
})
|
||||
} else if (["android-upload"].includes(argv[2])) {
|
||||
// 上传安卓文件(GitHub Actions)
|
||||
config.app.forEach(({publish}) => {
|
||||
if (publish.provider === 'generic') {
|
||||
androidUpload(publish.url)
|
||||
(async () => {
|
||||
const publisher = createPublisher()
|
||||
if (publisher) {
|
||||
const releaseDir = path.resolve(__dirname, "../resources/mobile/platforms/android/eeuiApp/app/build/outputs/apk/release");
|
||||
if (fs.existsSync(releaseDir)) {
|
||||
const files = fs.readdirSync(releaseDir)
|
||||
for (const filename of files) {
|
||||
const localFile = path.join(releaseDir, filename)
|
||||
if (/\.apk$/.test(filename) && fs.existsSync(localFile) && fs.statSync(localFile).isFile()) {
|
||||
await publisher.uploadPackage(localFile, { platform: 'android' })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error("发布文件未找到")
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
console.error("缺少 UPLOAD_TOKEN 或 UPLOAD_URL 环境变量")
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
} else if (["published"].includes(argv[2])) {
|
||||
// 发布完成(GitHub Actions)
|
||||
config.app.forEach(async ({publish}) => {
|
||||
if (publish.provider === 'generic') {
|
||||
await published(publish.url)
|
||||
})()
|
||||
} else if (["release"].includes(argv[2])) {
|
||||
// 通知官网发布完成(GitHub Actions)
|
||||
(async () => {
|
||||
const publisher = createPublisher()
|
||||
if (publisher) {
|
||||
await publisher.release()
|
||||
} else {
|
||||
console.error("缺少 UPLOAD_TOKEN 或 UPLOAD_URL 环境变量")
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
})()
|
||||
} else if (["upload-changelog"].includes(argv[2])) {
|
||||
// 上传 changelog(GitHub Actions)
|
||||
(async () => {
|
||||
const publisher = createPublisher()
|
||||
if (publisher) {
|
||||
const changelogPath = path.resolve(__dirname, "../CHANGELOG.md")
|
||||
if (fs.existsSync(changelogPath)) {
|
||||
const content = fs.readFileSync(changelogPath, 'utf8')
|
||||
await publisher.uploadChangelog(content)
|
||||
} else {
|
||||
console.error("CHANGELOG.md 未找到")
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
console.error("缺少 UPLOAD_TOKEN 或 UPLOAD_URL 环境变量")
|
||||
process.exit(1)
|
||||
}
|
||||
})()
|
||||
} else if (["all", "win", "mac"].includes(argv[2])) {
|
||||
// 自动编译(GitHub Actions)
|
||||
platforms.filter(p => {
|
||||
@ -907,8 +933,8 @@ if (["dev"].includes(argv[2])) {
|
||||
|
||||
// 发布判断环境变量
|
||||
if (answers.publish) {
|
||||
if (!PUBLISH_KEY && (!GITHUB_TOKEN || !utils.strExists(GITHUB_REPOSITORY, "/"))) {
|
||||
console.error("发布需要 PUBLISH_KEY 或 GitHub Token 和 Repository, 请检查环境变量!");
|
||||
if (!(UPLOAD_TOKEN && UPLOAD_URL) && !(GITHUB_TOKEN && utils.strExists(GITHUB_REPOSITORY, "/"))) {
|
||||
console.error("发布需要 UPLOAD_TOKEN + UPLOAD_URL 或 GITHUB_TOKEN + GITHUB_REPOSITORY, 请检查环境变量!");
|
||||
process.exit()
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
],
|
||||
"publish": {
|
||||
"provider": "generic",
|
||||
"url": "https://www.dootask.com/desktop/publish"
|
||||
"url": "https://www.dootask.com/api/download/update"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user