Skip to content

refactor(resource): 统一资源管理、下载队列与多源回退 #1743

refactor(resource): 统一资源管理、下载队列与多源回退

refactor(resource): 统一资源管理、下载队列与多源回退 #1743

Workflow file for this run

name: Build and Release
on:
push:
tags:
- 'v*'
pull_request:
types: [opened, synchronize, reopened, labeled]
workflow_dispatch:
inputs:
create_release:
description: 'Create Release'
required: true
default: false
type: boolean
concurrency:
group: build-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CREATE_RELEASE: ${{ (github.event_name == 'workflow_dispatch' && inputs.create_release == true) || startsWith(github.ref, 'refs/tags/') }}
jobs:
version:
if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'build') }}
runs-on: windows-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Get version
id: get_version
shell: pwsh
run: python tools/ci/get_version.py
build:
if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'build') }}
runs-on: windows-latest
needs: version
outputs:
unsigned_artifact_id: ${{ steps.upload-unsigned-artifact.outputs.artifact-id }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install uv
shell: pwsh
run: |
Invoke-WebRequest -Uri https://astral.sh/uv/install.ps1 | Invoke-Expression
- name: Create and activate virtual environment
shell: pwsh
run: |
uv venv .venv --python=3.11.12
- name: Install dependencies
shell: pwsh
run: |
.\.venv\Scripts\Activate.ps1
uv sync --group dev
- name: Download and extract UPX into venv Scripts
shell: pwsh
run: |
$venvScripts = ".\.venv\Scripts"
$upxDir = Join-Path $venvScripts "upx"
$sourceUpxPath = Join-Path $upxDir "upx-4.2.3-win64" "upx.exe"
$destinationUpxPath = Join-Path $venvScripts "upx.exe"
$zipPath = "upx.zip"
Invoke-WebRequest -Uri "https://github.com/upx/upx/releases/download/v4.2.3/upx-4.2.3-win64.zip" -OutFile $zipPath
Expand-Archive -Path $zipPath -DestinationPath $upxDir -Force
Move-Item -Path $sourceUpxPath -Destination $destinationUpxPath -Force
Remove-Item -Path $upxDir -Recurse -Force
Remove-Item -Path $zipPath -Force
- name: Build executables
shell: pwsh
env:
RELEASE_VERSION: ${{ needs.version.outputs.version }}
run: |
echo "__version__ = '$env:RELEASE_VERSION'" | Out-File -FilePath src/one_dragon/version.py -Encoding utf8
.\.venv\Scripts\Activate.ps1
cd deploy
uv run pyinstaller --noconfirm --clean "OneDragon-Installer.spec"
uv run pyinstaller --noconfirm --clean "OneDragon-Launcher.spec"
uv run pyinstaller --noconfirm --clean "OneDragon-RuntimeLauncher.spec"
Copy-Item -Path "..\src" -Destination "dist\OneDragon-RuntimeLauncher\src" -Recurse -Force
- name: Bundle dependencies into wheels
shell: pwsh
run: |
# 激活虚拟环境
.\.venv\Scripts\Activate.ps1
# 创建目标目录并生成 wheel 包
New-Item -ItemType Directory -Path deploy/dist/wheels -Force
uv export --no-hashes --no-dev --format requirements-txt > deploy/dist/requirements.txt
pip wheel --wheel-dir=deploy/dist/wheels -r deploy/dist/requirements.txt
# 压缩生成的 wheels 目录
Compress-Archive -Path deploy/dist/wheels/* -DestinationPath deploy/dist/ZenlessZoneZero-OneDragon-Environment.zip
- name: Upload Installer
if: ${{ env.CREATE_RELEASE == 'false' }}
uses: actions/upload-artifact@v4
with:
name: Installer
path: deploy/dist/OneDragon-Installer.exe
- name: Upload Launcher
if: ${{ env.CREATE_RELEASE == 'false' }}
uses: actions/upload-artifact@v4
with:
name: Launcher
path: deploy/dist/OneDragon-Launcher.exe
- name: Upload RuntimeLauncher
if: ${{ env.CREATE_RELEASE == 'false' }}
uses: actions/upload-artifact@v4
with:
name: RuntimeLauncher
include-hidden-files: true
path: deploy/dist/OneDragon-RuntimeLauncher/
- name: Upload Wheels
if: ${{ env.CREATE_RELEASE == 'false' }}
uses: actions/upload-artifact@v4
with:
name: Wheels
path: deploy/dist/ZenlessZoneZero-OneDragon-Environment.zip
- name: Upload Dist
if: ${{ env.CREATE_RELEASE == 'true' }}
uses: actions/upload-artifact@v4
with:
name: dist
include-hidden-files: true
if-no-files-found: error
path: deploy/dist
- name: Upload Unsigned Artifact
if: ${{ env.CREATE_RELEASE == 'true' }}
id: upload-unsigned-artifact
uses: actions/upload-artifact@v4
with:
# 上传后是 unsigned.zip
name: unsigned
if-no-files-found: error
path: |
.\deploy\dist\OneDragon-Launcher.exe
.\deploy\dist\OneDragon-RuntimeLauncher\OneDragon-RuntimeLauncher.exe
.\deploy\dist\OneDragon-Installer.exe
sign:
runs-on: windows-latest
needs:
- version
- build
if: ${{ github.repository_owner == 'OneDragon-Anything' &&
((github.event_name == 'workflow_dispatch' && inputs.create_release == true) || startsWith(github.ref, 'refs/tags/'))
}}
env:
SIGNED_DIR: 'signed'
SIGNPATH_SIGNING_POLICY_SLUG: 'release-signing'
steps:
- name: Sign Artifact
if: ${{ needs.build.outputs.unsigned_artifact_id != '' }}
uses: signpath/github-action-submit-signing-request@v1.1
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '${{ vars.SIGNPATH_ORGANIZATION_ID }}'
project-slug: 'ZenlessZoneZero-OneDragon'
signing-policy-slug: '${{ env.SIGNPATH_SIGNING_POLICY_SLUG }}'
github-artifact-id: "${{ needs.build.outputs.unsigned_artifact_id }}"
wait-for-completion: true
# 签名后会自动下载到这个目录并解压 文件名和原来的一样
output-artifact-directory: '${{ env.SIGNED_DIR }}'
- name: Upload signed executables
uses: actions/upload-artifact@v4
with:
name: signed
if-no-files-found: error
path: ${{ env.SIGNED_DIR }}
release:
runs-on: windows-latest
needs:
- version
- build
- sign
if: ${{ always() &&
needs.build.result == 'success' &&
((github.event_name == 'workflow_dispatch' && inputs.create_release == true) || startsWith(github.ref, 'refs/tags/')) &&
(needs.sign.result == 'success')
}}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Download dist
uses: actions/download-artifact@v4
with:
name: dist
path: deploy/dist
- name: Download signed executables
if: ${{ needs.sign.result == 'success' }}
uses: actions/download-artifact@v4
with:
name: signed
path: deploy/dist/signed
- name: Prepare release directory and models
shell: pwsh
env:
RELEASE_VERSION: ${{ needs.version.outputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python tools/ci/prepare_release_assets.py --release-version "$env:RELEASE_VERSION"
- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.version.outputs.version }}
name: "Release ${{ needs.version.outputs.version }}"
body: |
## 安装方式
- `ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-Full-Environment.zip` 为带环境的完整包,不需要额外下载资源。
- `ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-Full.zip` 为完整包,解压后选择解压目录为安装目录,只需要下载环境依赖。
- `ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-Installer.exe` 为精简安装程序,运行后会自动下载所需的资源。
- `ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-WithRuntime-Full.zip` 为内嵌运行时 + 源码 + 模型的完整独立包(无需安装 Python,也无需额外下载模型),解压即用。
- `ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-WithRuntime.zip` 为内嵌运行时 + 源码的精简独立包(无需安装 Python,模型按需下载),解压即用。
- 如果你想更新启动器,前往主程序【设置】-【资源下载】页面更新,或者下载 `ZenlessZoneZero-OneDragon-Launcher.zip`,解压后替换。
- `ZenlessZoneZero-OneDragon-RuntimeLauncher.zip` 为集成启动器更新包(exe + .runtime),用于已有环境的就地升级。
- __不要下载Source Code__
安装前请查看 [安装指南](https://one-dragon.com/zzz/zh/quickstart.html)
若运行出错请查看 [自助排障指南](https://docs.qq.com/doc/p/7add96a4600d363b75d2df83bb2635a7c6a969b5)
已有 Mirror酱 CDK?前往 [Mirror酱](https://mirrorchyan.com/zh/projects?rid=ZZZ-OneDragon&source=zzzgh-release) 高速下载
## 签名策略 (Code Signing Policy)
免费代码签名由 [SignPath.io](https://signpath.io/) 提供,证书由 [SignPath Foundation](https://signpath.org/) 颁发
审批人:[DoctorReid](https://github.com/DoctorReid) [ShadowLemoon](https://github.com/ShadowLemoon)
Free code signing provided by [SignPath.io](https://signpath.io/), certificate by [SignPath Foundation](https://signpath.org/)
Approvers: [DoctorReid](https://github.com/DoctorReid) [ShadowLemoon](https://github.com/ShadowLemoon)
## 隐私政策 (Privacy Policy)
本程序的隐私政策详见:[隐私政策](.github/PRIVACY.md)。
See the [Privacy Policy](.github/PRIVACY.md).
files: |
ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-Full-Environment.zip
ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-Full.zip
ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-Installer.exe
ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-WithRuntime-Full.zip
ZenlessZoneZero-OneDragon-${{ needs.version.outputs.version }}-WithRuntime.zip
ZenlessZoneZero-OneDragon-Environment.zip
ZenlessZoneZero-OneDragon-Launcher.zip
ZenlessZoneZero-OneDragon-RuntimeLauncher.zip
generate_release_notes: false
prerelease: ${{ contains(needs.version.outputs.version, '-beta.') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Trigger CNB Release sync
if: ${{ github.repository == 'OneDragon-Anything/ZenlessZoneZero-OneDragon' }}
continue-on-error: true
shell: pwsh
env:
CNB_TOKEN: ${{ secrets.CNB_TOKEN }}
RELEASE_TAG: ${{ needs.version.outputs.version }}
run: |
if ([string]::IsNullOrWhiteSpace($env:CNB_TOKEN)) {
throw 'Missing GitHub Actions secret: CNB_TOKEN'
}
$headers = @{
Accept = 'application/vnd.cnb.api+json'
Authorization = "Bearer $env:CNB_TOKEN"
}
$body = @{
branch = 'main'
event = 'api_trigger_release'
title = "Sync GitHub Release $env:RELEASE_TAG"
env = @{
RELEASE_TAG = $env:RELEASE_TAG
}
} | ConvertTo-Json -Depth 3
$response = Invoke-RestMethod `
-Uri 'https://api.cnb.cool/OneDragon-Anything/ZenlessZoneZero-OneDragon/-/build/start' `
-Method Post `
-Headers $headers `
-ContentType 'application/json' `
-TimeoutSec 60 `
-Body $body
$response | ConvertTo-Json -Depth 5
if ($response.success -ne $true) {
throw "CNB build trigger failed: $($response.message)"
}