chore(release): 更新版本号到 1.1.7 #64
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| permissions: | |
| contents: write | |
| on: | |
| push: | |
| tags: | |
| - 'v*' # 推送形如 v1.0.1 的 tag 时触发 | |
| jobs: | |
| build-and-release: | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Setup PNPM | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 9 | |
| - name: Install deps | |
| run: pnpm install --frozen-lockfile | |
| - name: Preflight check for signing secrets | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ -z "${TAURI_SIGNING_PRIVATE_KEY:-}" ]]; then | |
| echo "::error::Missing TAURI_SIGNING_PRIVATE_KEY secret"; | |
| exit 1; | |
| fi | |
| if [[ -z "${TAURI_SIGNING_PRIVATE_KEY_PASSWORD:-}" ]]; then | |
| echo "::warning::TAURI_SIGNING_PRIVATE_KEY_PASSWORD is empty (that's OK if your key has no password)."; | |
| fi | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| - name: Prepare updater endpoints (merge env & GitHub) | |
| run: node scripts/prepare-updater-endpoints.cjs | |
| env: | |
| # 用户自定义的端点列表(可包含多个,用逗号分隔),来自仓库 Secrets | |
| UPDATER_ENDPOINTS: ${{ secrets.UPDATER_ENDPOINTS != '' && format('{0},{1}', secrets.UPDATER_ENDPOINTS, env.CHANNEL_UPDATER_ENDPOINT) || env.CHANNEL_UPDATER_ENDPOINT }} | |
| # 根据是否为预发布决定通道端点:pre 通道使用固定 tag `pre`,稳定通道使用 `latest` | |
| CHANNEL_UPDATER_ENDPOINT: ${{ contains(github.ref_name, '-') && format('https://github.com/{0}/releases/download/pre/latest.json', github.repository) || format('https://github.com/{0}/releases/latest/download/latest.json', github.repository) }} | |
| - name: Tauri Build & Release | |
| uses: tauri-apps/tauri-action@v0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| # 将端点注入到构建中(与上一步一致)。如果用户配置了 Secrets.UPDATER_ENDPOINTS,会与通道端点合并。 | |
| UPDATER_ENDPOINTS: ${{ secrets.UPDATER_ENDPOINTS != '' && format('{0},{1}', secrets.UPDATER_ENDPOINTS, env.CHANNEL_UPDATER_ENDPOINT) || env.CHANNEL_UPDATER_ENDPOINT }} | |
| CHANNEL_UPDATER_ENDPOINT: ${{ contains(github.ref_name, '-') && format('https://github.com/{0}/releases/download/pre/latest.json', github.repository) || format('https://github.com/{0}/releases/latest/download/latest.json', github.repository) }} | |
| # 注入前端通道变量:pre/stable | |
| VITE_RELEASE_CHANNEL: ${{ contains(github.ref_name, '-') && 'pre' || 'stable' }} | |
| with: | |
| # 使用触发的 tag,避免额外创建 v__VERSION__ 的 tag/release | |
| tagName: ${{ github.ref_name }} | |
| releaseName: 'BPM Sniffer ${{ github.ref_name }}' | |
| releaseDraft: false | |
| prerelease: ${{ contains(github.ref_name, '-') }} | |
| includeUpdaterJson: true | |
| distPath: src-tauri/dist | |
| args: --bundles nsis,updater | |
| # 该 Action 会在发布中附带 latest.json(v2 插件使用), | |
| # 如需显式开关,可按官方文档添加 includeUpdaterJson/updaterJson 选项。 | |
| # 预发布同步:按安装包进行自包含同步(而非 updater zip) | |
| - name: 等待 Release 资产刷新 | |
| if: contains(github.ref_name, '-') | |
| shell: bash | |
| run: | | |
| # GitHub Release 资产上传后存在短暂延迟,这里稍作等待避免下载步骤立即失败 | |
| sleep 20 | |
| - name: 检查资产是否已经可见 | |
| if: contains(github.ref_name, '-') | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| let tag = context.ref_name || ''; | |
| if ((!tag || !tag.length) && context.ref && context.ref.startsWith('refs/tags/')) { | |
| tag = context.ref.substring('refs/tags/'.length); | |
| } | |
| if (!tag || !tag.length) { | |
| core.setFailed('无法解析当前构建对应的 tag 名称。'); | |
| return; | |
| } | |
| core.info(`正在检查 tag ${tag} 的资产...`); | |
| const patterns = [ | |
| /latest\.json$/, | |
| /_x64-setup.*\.exe$/, | |
| /_x64-setup.*\.exe\.sig$/ | |
| ]; | |
| for (let attempt = 1; attempt <= 10; attempt++) { | |
| const { data: release } = await github.rest.repos.getReleaseByTag({ owner, repo, tag }); | |
| const assets = release.assets || []; | |
| core.info(`第 ${attempt} 次轮询,共 ${assets.length} 个资产:${assets.map(a => a.name).join(', ') || '(空)'}`); | |
| const allFound = patterns.every((pattern) => assets.some((asset) => pattern.test(asset.name))); | |
| if (allFound) { | |
| core.info(`Release assets ready on attempt ${attempt}`); | |
| return; | |
| } | |
| if (attempt === 10) { | |
| core.setFailed(`Assets not ready after ${attempt} attempts.`); | |
| return; | |
| } | |
| core.info(`Assets missing on attempt ${attempt}, waiting 10s...`); | |
| await new Promise((resolve) => setTimeout(resolve, 10000)); | |
| } | |
| # 预发布:从“本次 tag 的 Release”下载 latest.json 到工作区 | |
| - name: Download latest.json from current release | |
| if: contains(github.ref_name, '-') | |
| uses: robinraju/release-downloader@v1 | |
| with: | |
| repository: ${{ github.repository }} | |
| tag: ${{ github.ref_name }} | |
| fileName: latest.json | |
| out-file-path: . | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Download NSIS installer from current release | |
| if: contains(github.ref_name, '-') | |
| uses: robinraju/release-downloader@v1 | |
| with: | |
| repository: ${{ github.repository }} | |
| tag: ${{ github.ref_name }} | |
| fileName: "*_x64-setup*.exe*" | |
| out-file-path: pre-assets | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Download NSIS installer signature from current release | |
| if: contains(github.ref_name, '-') | |
| uses: robinraju/release-downloader@v1 | |
| with: | |
| repository: ${{ github.repository }} | |
| tag: ${{ github.ref_name }} | |
| fileName: "*_x64-setup*.exe.sig*" | |
| out-file-path: pre-assets | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Repoint latest.json URLs to `pre` | |
| if: contains(github.ref_name, '-') | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| sed -E -i 's#/releases/download/[^/]+/#/releases/download/pre/#g' latest.json | |
| - name: Cleanup assets on pre release | |
| if: contains(github.ref_name, '-') | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const tag = 'pre'; | |
| try { | |
| const { data: release } = await github.rest.repos.getReleaseByTag({ owner, repo, tag }); | |
| if (release.assets && release.assets.length) { | |
| for (const asset of release.assets) { | |
| try { | |
| await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id: asset.id }); | |
| } catch (e) { | |
| core.warning(`delete asset failed: ${asset.name} -> ${e.message}`); | |
| } | |
| } | |
| } | |
| } catch (e) { | |
| core.warning(`pre release not found or cannot be fetched: ${e.message}`); | |
| } | |
| - name: Sync pre-channel assets to tag `pre` | |
| if: contains(github.ref_name, '-') | |
| uses: softprops/action-gh-release@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: pre | |
| prerelease: true | |
| files: | | |
| latest.json | |
| pre-assets/*_x64-setup.exe | |
| pre-assets/*_x64-setup.exe.sig | |
| - name: 失败时回滚当前 tag Release | |
| if: failure() && contains(github.ref_name, '-') | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| let tag = context.ref_name || ''; | |
| if ((!tag || !tag.length) && context.ref && context.ref.startsWith('refs/tags/')) { | |
| tag = context.ref.substring('refs/tags/'.length); | |
| } | |
| if (!tag || !tag.length) { | |
| core.warning('未能解析 tag,跳过回滚'); | |
| return; | |
| } | |
| try { | |
| const { data: release } = await github.rest.repos.getReleaseByTag({ owner, repo, tag }); | |
| core.info(`删除失败构建产生的 Release: ${release.name || release.tag_name}`); | |
| await github.rest.repos.deleteRelease({ owner, repo, release_id: release.id }); | |
| } catch (err) { | |
| core.warning(`回滚 Release 失败:${err.message}`); | |
| } |