mirror of
https://github.com/kuaifan/dootask.git
synced 2026-04-23 10:18:41 +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
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
// 获取最新的 tag
|
const fs = require('fs');
|
||||||
const { data: tags } = await github.rest.repos.listTags({
|
const version = '${{ needs.check-version.outputs.version }}';
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
per_page: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取提交日志
|
// 从 CHANGELOG.md 提取当前版本段落
|
||||||
let changelog = '';
|
let changelog = '';
|
||||||
if (tags.length > 0) {
|
const changelogPath = 'CHANGELOG.md';
|
||||||
const { data: commits } = await github.rest.repos.compareCommits({
|
if (fs.existsSync(changelogPath)) {
|
||||||
owner: context.repo.owner,
|
const content = fs.readFileSync(changelogPath, 'utf-8');
|
||||||
repo: context.repo.repo,
|
const regex = new RegExp(`## \\[${version.replace(/\./g, '\\.')}\\][\\s\\S]*?(?=\\n## \\[|$)`);
|
||||||
base: tags[0].name,
|
const match = content.match(regex);
|
||||||
head: 'HEAD'
|
if (match) {
|
||||||
});
|
changelog = match[0].trim();
|
||||||
|
|
||||||
// 按类型分组提交
|
|
||||||
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');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +71,8 @@ jobs:
|
|||||||
const { data } = await github.rest.repos.createRelease({
|
const { data } = await github.rest.repos.createRelease({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
tag_name: `v${{ needs.check-version.outputs.version }}`,
|
tag_name: `v${version}`,
|
||||||
name: `${{ needs.check-version.outputs.version }}`,
|
name: version,
|
||||||
body: changelog || 'No significant changes in this release.',
|
body: changelog || 'No significant changes in this release.',
|
||||||
draft: true,
|
draft: true,
|
||||||
prerelease: false
|
prerelease: false
|
||||||
@ -215,7 +180,8 @@ jobs:
|
|||||||
- name: (Android) Upload File
|
- name: (Android) Upload File
|
||||||
if: matrix.build_type == 'android'
|
if: matrix.build_type == 'android'
|
||||||
env:
|
env:
|
||||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||||
|
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||||
run: |
|
run: |
|
||||||
node ./electron/build.js android-upload
|
node ./electron/build.js android-upload
|
||||||
|
|
||||||
@ -253,7 +219,8 @@ jobs:
|
|||||||
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
|
APPLEIDPASS: ${{ secrets.APPLEIDPASS }}
|
||||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
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_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||||
run: |
|
run: |
|
||||||
@ -263,7 +230,8 @@ jobs:
|
|||||||
- name: (Windows) Build Client
|
- name: (Windows) Build Client
|
||||||
if: matrix.build_type == 'windows'
|
if: matrix.build_type == 'windows'
|
||||||
env:
|
env:
|
||||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||||
|
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -294,11 +262,13 @@ jobs:
|
|||||||
prerelease: false
|
prerelease: false
|
||||||
})
|
})
|
||||||
|
|
||||||
- name: Publish Official
|
- name: Upload Changelog & Publish to Website
|
||||||
env:
|
env:
|
||||||
PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
|
UPLOAD_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
|
||||||
|
UPLOAD_URL: ${{ secrets.UPLOAD_URL }}
|
||||||
run: |
|
run: |
|
||||||
pushd electron || exit
|
pushd electron || exit
|
||||||
npm install
|
npm install
|
||||||
popd || exit
|
popd || exit
|
||||||
node ./electron/build.js published
|
node ./electron/build.js upload-changelog
|
||||||
|
node ./electron/build.js release
|
||||||
|
|||||||
332
electron/build.js
vendored
332
electron/build.js
vendored
@ -12,7 +12,7 @@ const utils = require('./lib/utils');
|
|||||||
const config = require('../package.json')
|
const config = require('../package.json')
|
||||||
const env = require('dotenv').config({ path: './.env' })
|
const env = require('dotenv').config({ path: './.env' })
|
||||||
const argv = process.argv;
|
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 electronDir = path.resolve(__dirname, "public");
|
||||||
const nativeCachePath = path.resolve(__dirname, ".native");
|
const nativeCachePath = path.resolve(__dirname, ".native");
|
||||||
@ -350,192 +350,166 @@ function axiosAutoTry(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传app应用
|
* 官网发布器
|
||||||
* @param url
|
|
||||||
*/
|
*/
|
||||||
function androidUpload(url) {
|
class WebsitePublisher {
|
||||||
if (!PUBLISH_KEY) {
|
constructor({baseUrl, token, version}) {
|
||||||
console.error("缺少 PUBLISH_KEY 环境变量");
|
this.baseUrl = baseUrl
|
||||||
process.exit()
|
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()
|
* @param localFile 本地文件路径
|
||||||
}
|
* @param options { platform, arch } 可选,有则为安装包
|
||||||
fs.readdir(releaseDir, async (err, files) => {
|
*/
|
||||||
if (err) {
|
async uploadPackage(localFile, options = {}) {
|
||||||
console.warn(err)
|
const filename = path.basename(localFile)
|
||||||
} else {
|
let spinner = ora(`Upload [0%] ${filename}`).start()
|
||||||
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()
|
const formData = new FormData()
|
||||||
formData.append("file", fs.createReadStream(localFile));
|
formData.append("file", fs.createReadStream(localFile))
|
||||||
formData.append("action", "draft");
|
formData.append("version", this.version)
|
||||||
|
if (options.platform) {
|
||||||
|
formData.append("platform", options.platform)
|
||||||
|
if (options.arch) {
|
||||||
|
formData.append("arch", options.arch)
|
||||||
|
}
|
||||||
|
}
|
||||||
await axiosAutoTry({
|
await axiosAutoTry({
|
||||||
axios: {
|
axios: {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: url,
|
url: `${this.baseUrl}/api/upload/package`,
|
||||||
data: formData,
|
data: formData,
|
||||||
headers: {
|
headers: {
|
||||||
'Publish-Version': config.version,
|
'Authorization': `Bearer ${this.token}`,
|
||||||
'Publish-Key': PUBLISH_KEY,
|
|
||||||
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
'Content-Type': 'multipart/form-data;boundary=' + formData.getBoundary(),
|
||||||
},
|
},
|
||||||
onUploadProgress: progress => {
|
onUploadProgress: progress => {
|
||||||
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
const complete = Math.min(99, Math.round(progress.loaded / progress.total * 100 | 0)) + '%'
|
||||||
uploadOras[filename].text = `Upload [${complete}] ${filename}`
|
spinner.text = `Upload [${complete}] ${filename}`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onRetry: _ => {
|
onRetry: _ => {
|
||||||
uploadOras[filename].warn(`Upload [retry] ${filename}`)
|
spinner.warn(`Upload [retry] ${filename}`)
|
||||||
uploadOras[filename] = ora(`Upload [0%] ${filename}`).start()
|
spinner = ora(`Upload [0%] ${filename}`).start()
|
||||||
},
|
},
|
||||||
retryNumber: 3
|
retryNumber: 3
|
||||||
}).then(({status, data}) => {
|
}).then(({status, data}) => {
|
||||||
if (status !== 200) {
|
if (status !== 200) {
|
||||||
uploadOras[filename].fail(`Upload [fail:${status}] ${filename}`)
|
spinner.fail(`Upload [fail:${status}] ${filename}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!utils.isJson(data)) {
|
if (!utils.isJson(data)) {
|
||||||
uploadOras[filename].fail(`Upload [fail:not json] ${filename}`)
|
spinner.fail(`Upload [fail:not json] ${filename}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (data.ret !== 1) {
|
if (!data.success) {
|
||||||
uploadOras[filename].fail(`Upload [fail:ret ${data.ret}] ${filename}`)
|
spinner.fail(`Upload [fail] ${filename}: ${data.message || JSON.stringify(data)}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uploadOras[filename].succeed(`Upload [100%] ${filename}`)
|
spinner.succeed(`Upload [100%] ${filename}`)
|
||||||
}).catch(_ => {
|
}).catch(_ => {
|
||||||
uploadOras[filename].fail(`Upload [fail] ${filename}`)
|
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')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知发布完成
|
* 通知发布完成
|
||||||
* @param url
|
|
||||||
*/
|
*/
|
||||||
async function published(url) {
|
async release() {
|
||||||
if (!PUBLISH_KEY) {
|
const spinner = ora('Publishing release...').start()
|
||||||
console.error("缺少 PUBLISH_KEY 环境变量");
|
|
||||||
process.exit()
|
|
||||||
}
|
|
||||||
const spinner = ora('完成发布...').start();
|
|
||||||
const formData = new FormData()
|
|
||||||
formData.append("action", "release");
|
|
||||||
await axiosAutoTry({
|
await axiosAutoTry({
|
||||||
axios: {
|
axios: {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: url,
|
url: `${this.baseUrl}/api/upload/release`,
|
||||||
data: formData,
|
data: { version: this.version },
|
||||||
headers: {
|
headers: {
|
||||||
'Publish-Version': config.version,
|
'Authorization': `Bearer ${this.token}`,
|
||||||
'Publish-Key': PUBLISH_KEY,
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
retryNumber: 3
|
retryNumber: 3
|
||||||
}).then(({status, data}) => {
|
}).then(({status, data}) => {
|
||||||
if (status !== 200) {
|
if (status !== 200 || !data.success) {
|
||||||
spinner.fail('发布失败, status: ' + status)
|
spinner.fail(`Release failed: ${data?.message || status}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!utils.isJson(data)) {
|
spinner.succeed('Release published')
|
||||||
spinner.fail('发布失败, not json')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (data.ret !== 1) {
|
|
||||||
spinner.fail(`发布失败, ${JSON.stringify(data)}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
spinner.succeed('发布完成')
|
|
||||||
}).catch(_ => {
|
}).catch(_ => {
|
||||||
spinner.fail('发布失败')
|
spinner.fail('Release failed')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安装包扩展名
|
||||||
|
const INSTALLER_EXTS = ['.dmg', '.exe', '.msi', '.appimage', '.deb', '.rpm', '.apk']
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 WebsitePublisher 实例(如果环境变量齐全)
|
||||||
|
*/
|
||||||
|
function createPublisher() {
|
||||||
|
if (!UPLOAD_TOKEN || !UPLOAD_URL) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
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}) {
|
function isInstaller(filename) {
|
||||||
if (!/https?:\/\//i.test(url)) {
|
return INSTALLER_EXTS.some(ext => filename.toLowerCase().endsWith(ext))
|
||||||
console.warn("发布地址无效: " + url)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
const filePath = path.resolve(__dirname, output)
|
|
||||||
if (!fs.existsSync(filePath)) {
|
/**
|
||||||
console.warn("发布文件未找到: " + filePath)
|
* 从文件名提取 arch
|
||||||
return
|
*/
|
||||||
|
function parseArchFromFilename(filename) {
|
||||||
|
if (/-arm64[.-]/i.test(filename)) return 'arm64'
|
||||||
|
if (/-x64[.-]/i.test(filename)) return 'x64'
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
fs.readdir(filePath, async (err, files) => {
|
|
||||||
if (err) {
|
/**
|
||||||
console.warn(err)
|
* 将构建平台名映射为 API platform
|
||||||
} else {
|
*/
|
||||||
const uploadOras = {}
|
function mapPlatform(buildPlatform) {
|
||||||
for (const filename of files) {
|
if (buildPlatform.includes('mac')) return 'mac'
|
||||||
const localFile = path.join(filePath, filename)
|
if (buildPlatform.includes('win')) return 'win'
|
||||||
if (fs.existsSync(localFile)) {
|
if (buildPlatform.includes('linux')) return 'linux'
|
||||||
const fileStat = fs.statSync(localFile)
|
return null
|
||||||
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}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -703,13 +677,27 @@ async function startBuild(data) {
|
|||||||
appConfig.build.directories.output = `${output}-generic`;
|
appConfig.build.directories.output = `${output}-generic`;
|
||||||
fs.writeFileSync(packageFile, JSON.stringify(appConfig, null, 4), 'utf8');
|
fs.writeFileSync(packageFile, JSON.stringify(appConfig, null, 4), 'utf8');
|
||||||
child_process.execSync(`npm run ${platform}`, {stdio: "inherit", cwd: "electron"});
|
child_process.execSync(`npm run ${platform}`, {stdio: "inherit", cwd: "electron"});
|
||||||
if (publish === true && PUBLISH_KEY) {
|
if (publish === true) {
|
||||||
genericPublish({
|
const publisher = createPublisher()
|
||||||
url: appConfig.build.publish.url,
|
if (publisher) {
|
||||||
key: PUBLISH_KEY,
|
const outputDir = path.resolve(__dirname, appConfig.build.directories.output)
|
||||||
version: config.version,
|
if (fs.existsSync(outputDir)) {
|
||||||
output: appConfig.build.directories.output
|
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
|
// package.json Recovery
|
||||||
recoveryPackage(true)
|
recoveryPackage(true)
|
||||||
@ -746,18 +734,56 @@ if (["dev"].includes(argv[2])) {
|
|||||||
})
|
})
|
||||||
} else if (["android-upload"].includes(argv[2])) {
|
} else if (["android-upload"].includes(argv[2])) {
|
||||||
// 上传安卓文件(GitHub Actions)
|
// 上传安卓文件(GitHub Actions)
|
||||||
config.app.forEach(({publish}) => {
|
(async () => {
|
||||||
if (publish.provider === 'generic') {
|
const publisher = createPublisher()
|
||||||
androidUpload(publish.url)
|
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 if (["published"].includes(argv[2])) {
|
|
||||||
// 发布完成(GitHub Actions)
|
|
||||||
config.app.forEach(async ({publish}) => {
|
|
||||||
if (publish.provider === 'generic') {
|
|
||||||
await published(publish.url)
|
|
||||||
}
|
}
|
||||||
})
|
} else {
|
||||||
|
console.error("发布文件未找到")
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("缺少 UPLOAD_TOKEN 或 UPLOAD_URL 环境变量")
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
} 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])) {
|
} else if (["all", "win", "mac"].includes(argv[2])) {
|
||||||
// 自动编译(GitHub Actions)
|
// 自动编译(GitHub Actions)
|
||||||
platforms.filter(p => {
|
platforms.filter(p => {
|
||||||
@ -907,8 +933,8 @@ if (["dev"].includes(argv[2])) {
|
|||||||
|
|
||||||
// 发布判断环境变量
|
// 发布判断环境变量
|
||||||
if (answers.publish) {
|
if (answers.publish) {
|
||||||
if (!PUBLISH_KEY && (!GITHUB_TOKEN || !utils.strExists(GITHUB_REPOSITORY, "/"))) {
|
if (!(UPLOAD_TOKEN && UPLOAD_URL) && !(GITHUB_TOKEN && utils.strExists(GITHUB_REPOSITORY, "/"))) {
|
||||||
console.error("发布需要 PUBLISH_KEY 或 GitHub Token 和 Repository, 请检查环境变量!");
|
console.error("发布需要 UPLOAD_TOKEN + UPLOAD_URL 或 GITHUB_TOKEN + GITHUB_REPOSITORY, 请检查环境变量!");
|
||||||
process.exit()
|
process.exit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,7 @@
|
|||||||
],
|
],
|
||||||
"publish": {
|
"publish": {
|
||||||
"provider": "generic",
|
"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