NapCatQQ source snapshot
This commit is contained in:
commit
f954252a34
1111 files changed
+139867
No files matched your search
@@ -0,0 +1,113 @@
|
||||
name: Build NapCat Artifacts
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
windows-loader-test:
|
||||
name: Windows Loader Test
|
||||
needs: build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: NapCat.Shell
|
||||
path: shell-dist
|
||||
- name: Verify Windows loader file queries
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake -S .github/tests/windows-loader -B "$env:RUNNER_TEMP/windows-loader-test" -A x64
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
cmake --build "$env:RUNNER_TEMP/windows-loader-test" --config Release
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
& "$env:RUNNER_TEMP/windows-loader-test/Release/windows-loader-test.exe" "$pwd/shell-dist/NapCatWinBootHook.dll" "$pwd/shell-dist/loadNapCat.js"
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
|
||||
typecheck-and-test:
|
||||
name: Type Check & Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
run_install: false
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
- name: Install Dependencies
|
||||
run: pnpm i
|
||||
- name: Type Check
|
||||
run: pnpm run typecheck
|
||||
- name: Run Tests
|
||||
run: pnpm test
|
||||
|
||||
build:
|
||||
name: Build NapCat.${{ matrix.target.name }}
|
||||
needs: typecheck-and-test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- name: Framework
|
||||
build_cmd: build:framework
|
||||
src_dir: packages/napcat-framework/dist
|
||||
dist_dir: framework-dist
|
||||
- name: Shell
|
||||
build_cmd: build:shell
|
||||
src_dir: packages/napcat-shell/dist
|
||||
dist_dir: shell-dist
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
run_install: false
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
- name: Generate Version
|
||||
run: |
|
||||
LATEST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*" 2>/dev/null || echo "v0.0.0")
|
||||
BASE_VERSION="${LATEST_TAG#v}"
|
||||
SHORT_SHA="${GITHUB_SHA::7}"
|
||||
VERSION="${BASE_VERSION}-main.${{ github.run_number }}+${SHORT_SHA}"
|
||||
echo "NAPCAT_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
echo "Latest tag: ${LATEST_TAG}"
|
||||
echo "Build version: ${VERSION}"
|
||||
- name: Build NapCat.${{ matrix.target.name }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NAPCAT_VERSION: ${{ env.NAPCAT_VERSION }}
|
||||
run: |
|
||||
pnpm i
|
||||
pnpm --filter napcat-webui-frontend run build || exit 1
|
||||
pnpm run ${{ matrix.target.build_cmd }}
|
||||
pnpm --filter napcat-plugin-builtin run build || exit 1
|
||||
mv ${{ matrix.target.src_dir }} ${{ matrix.target.dist_dir }}
|
||||
cd ${{ matrix.target.dist_dir }}
|
||||
# --omit=dev still resolves dev peer dependencies; remove build tooling first.
|
||||
npm pkg delete devDependencies
|
||||
npm install --omit=dev
|
||||
rm ./package-lock.json || exit 0
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: NapCat.${{ matrix.target.name }}
|
||||
path: ${{ matrix.target.dist_dir }}
|
||||
@@ -0,0 +1,424 @@
|
||||
# =============================================================================
|
||||
# PR 构建工作流
|
||||
# =============================================================================
|
||||
# 安全模型:
|
||||
# 1. pull_request_target / issue_comment 入口只读取元数据、检查权限、更新评论并触发构建。
|
||||
# 2. 真正执行 PR 代码的构建流程只在 workflow_dispatch 中运行。
|
||||
# 3. 构建流程不具备写仓库/写评论/读 secrets 权限,显式清空 GITHUB_TOKEN,不持久化 checkout 凭据。
|
||||
# 4. 版本号在 Action 中提前生成,通过 NAPCAT_VERSION 传给 Vite 插件,插件无需 GitHub token。
|
||||
# 5. 发布 Release、触发 Docker 等可信操作只消费构建 artifact,不执行 PR artifact 中的代码。
|
||||
# =============================================================================
|
||||
|
||||
name: Build PR
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
description: PR 编号
|
||||
required: true
|
||||
type: string
|
||||
pr_sha:
|
||||
description: PR HEAD SHA
|
||||
required: true
|
||||
type: string
|
||||
pr_head_repo:
|
||||
description: PR 源仓库
|
||||
required: true
|
||||
type: string
|
||||
pr_head_ref:
|
||||
description: PR 源分支
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: pr-build-${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || github.event_name == 'pull_request_target' && github.event.pull_request.number || github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/build') && github.event.issue.number || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# ---------------------------------------------------------------------------
|
||||
# 特权入口:只检查条件、写入“构建中”评论、触发无权限构建
|
||||
# ---------------------------------------------------------------------------
|
||||
check-build:
|
||||
if: github.event_name != 'workflow_dispatch'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
issues: write
|
||||
outputs:
|
||||
should_build: ${{ steps.check.outputs.should_build }}
|
||||
pr_number: ${{ steps.check.outputs.pr_number }}
|
||||
pr_sha: ${{ steps.check.outputs.pr_sha }}
|
||||
pr_head_repo: ${{ steps.check.outputs.pr_head_repo }}
|
||||
pr_head_ref: ${{ steps.check.outputs.pr_head_ref }}
|
||||
steps:
|
||||
- name: Checkout scripts
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Check trigger condition
|
||||
id: check
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: node --experimental-strip-types .github/scripts/pr-build-check.ts
|
||||
|
||||
update-comment-building:
|
||||
needs: check-build
|
||||
if: needs.check-build.outputs.should_build == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout scripts
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Update building comment
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ needs.check-build.outputs.pr_number }}
|
||||
PR_SHA: ${{ needs.check-build.outputs.pr_sha }}
|
||||
run: node --experimental-strip-types .github/scripts/pr-build-building.ts
|
||||
|
||||
dispatch-build:
|
||||
needs: [check-build, update-comment-building]
|
||||
if: needs.check-build.outputs.should_build == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
steps:
|
||||
- name: Checkout scripts
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Dispatch untrusted build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ needs.check-build.outputs.pr_number }}
|
||||
PR_SHA: ${{ needs.check-build.outputs.pr_sha }}
|
||||
PR_HEAD_REPO: ${{ needs.check-build.outputs.pr_head_repo }}
|
||||
PR_HEAD_REF: ${{ needs.check-build.outputs.pr_head_ref }}
|
||||
WORKFLOW_FILE: build-pr.yml
|
||||
DISPATCH_REF: ${{ github.event.repository.default_branch }}
|
||||
run: node --experimental-strip-types .github/scripts/pr-build-dispatch.ts
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 无权限构建:只由 workflow_dispatch 执行 PR 代码
|
||||
# ---------------------------------------------------------------------------
|
||||
build-framework:
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
status: ${{ steps.build.outcome }}
|
||||
error: ${{ steps.build.outputs.error }}
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout scripts from base
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
path: _scripts
|
||||
persist-credentials: false
|
||||
|
||||
- name: Checkout PR code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: ${{ inputs.pr_head_repo }}
|
||||
ref: ${{ inputs.pr_sha }}
|
||||
path: workspace
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
run_install: false
|
||||
|
||||
- name: Generate Version
|
||||
id: version
|
||||
working-directory: workspace
|
||||
run: |
|
||||
LATEST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*" 2>/dev/null || echo "v0.0.0")
|
||||
BASE_VERSION="${LATEST_TAG#v}"
|
||||
SHORT_SHA="${{ inputs.pr_sha }}"
|
||||
SHORT_SHA="${SHORT_SHA::7}"
|
||||
VERSION="${BASE_VERSION}-pr.${{ inputs.pr_number }}.${{ github.run_number }}+${SHORT_SHA}"
|
||||
echo "NAPCAT_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
echo "Latest tag: ${LATEST_TAG}"
|
||||
echo "Build version: ${VERSION}"
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
working-directory: workspace
|
||||
env:
|
||||
GITHUB_TOKEN: ''
|
||||
NAPCAT_VERSION: ${{ env.NAPCAT_VERSION }}
|
||||
run: node --experimental-strip-types ../_scripts/.github/scripts/pr-build-run.ts framework
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload Artifact
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: NapCat.Framework
|
||||
path: workspace/framework-dist
|
||||
retention-days: 5
|
||||
|
||||
build-shell:
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
status: ${{ steps.build.outcome }}
|
||||
error: ${{ steps.build.outputs.error }}
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout scripts from base
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
path: _scripts
|
||||
persist-credentials: false
|
||||
|
||||
- name: Checkout PR code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: ${{ inputs.pr_head_repo }}
|
||||
ref: ${{ inputs.pr_sha }}
|
||||
path: workspace
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
run_install: false
|
||||
|
||||
- name: Generate Version
|
||||
id: version
|
||||
working-directory: workspace
|
||||
run: |
|
||||
LATEST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*" 2>/dev/null || echo "v0.0.0")
|
||||
BASE_VERSION="${LATEST_TAG#v}"
|
||||
SHORT_SHA="${{ inputs.pr_sha }}"
|
||||
SHORT_SHA="${SHORT_SHA::7}"
|
||||
VERSION="${BASE_VERSION}-pr.${{ inputs.pr_number }}.${{ github.run_number }}+${SHORT_SHA}"
|
||||
echo "NAPCAT_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
echo "Latest tag: ${LATEST_TAG}"
|
||||
echo "Build version: ${VERSION}"
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
working-directory: workspace
|
||||
env:
|
||||
GITHUB_TOKEN: ''
|
||||
NAPCAT_VERSION: ${{ env.NAPCAT_VERSION }}
|
||||
run: node --experimental-strip-types ../_scripts/.github/scripts/pr-build-run.ts shell
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload Artifact
|
||||
if: steps.build.outcome == 'success'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: NapCat.Shell
|
||||
path: workspace/shell-dist
|
||||
retention-days: 5
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 可信后处理:只下载/打包/发布 artifact,不执行 artifact 中的代码
|
||||
# ---------------------------------------------------------------------------
|
||||
publish-pr-release:
|
||||
needs: [build-framework, build-shell]
|
||||
if: always() && github.event_name == 'workflow_dispatch' && (needs.build-framework.outputs.status == 'success' || needs.build-shell.outputs.status == 'success')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
outputs:
|
||||
release_url: ${{ steps.publish.outputs.release_url }}
|
||||
release_tag: ${{ steps.publish.outputs.release_tag }}
|
||||
install_url: ${{ steps.publish.outputs.install_url }}
|
||||
publish_status: ${{ steps.publish.outcome }}
|
||||
steps:
|
||||
- name: Checkout scripts
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Download Framework artifact
|
||||
if: needs.build-framework.outputs.status == 'success'
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: NapCat.Framework
|
||||
path: ./artifacts/NapCat.Framework
|
||||
|
||||
- name: Download Shell artifact
|
||||
if: needs.build-shell.outputs.status == 'success'
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: NapCat.Shell
|
||||
path: ./artifacts/NapCat.Shell
|
||||
|
||||
- name: Publish release
|
||||
id: publish
|
||||
continue-on-error: true
|
||||
env:
|
||||
RELEASE_PAT: ${{ secrets.PR_RELEASE_PAT }}
|
||||
PR_NUMBER: ${{ inputs.pr_number }}
|
||||
PR_SHA: ${{ inputs.pr_sha }}
|
||||
NAPCAT_VERSION: ${{ needs.build-framework.outputs.version || needs.build-shell.outputs.version || '' }}
|
||||
ARTIFACTS_DIR: ./artifacts
|
||||
run: |
|
||||
if [ -z "${RELEASE_PAT}" ]; then
|
||||
echo "::warning::PR_RELEASE_PAT secret 未配置,跳过 PR Release 发布"
|
||||
exit 0
|
||||
fi
|
||||
node --experimental-strip-types .github/scripts/pr-publish-release.ts
|
||||
|
||||
- name: Upload install script as artifact
|
||||
if: steps.publish.outcome == 'success'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: install-script
|
||||
path: ./release-assets/install.sh
|
||||
retention-days: 5
|
||||
if-no-files-found: ignore
|
||||
|
||||
update-comment-result:
|
||||
needs: [build-framework, build-shell, publish-pr-release]
|
||||
if: always() && github.event_name == 'workflow_dispatch'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout scripts
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Update result comment
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ inputs.pr_number }}
|
||||
PR_SHA: ${{ inputs.pr_sha }}
|
||||
RUN_ID: ${{ github.run_id }}
|
||||
NAPCAT_VERSION: ${{ needs.build-framework.outputs.version || needs.build-shell.outputs.version || '' }}
|
||||
FRAMEWORK_STATUS: ${{ needs.build-framework.outputs.status || 'cancelled' }}
|
||||
FRAMEWORK_ERROR: ${{ needs.build-framework.outputs.error }}
|
||||
SHELL_STATUS: ${{ needs.build-shell.outputs.status || 'cancelled' }}
|
||||
SHELL_ERROR: ${{ needs.build-shell.outputs.error }}
|
||||
INSTALL_URL: ${{ needs.publish-pr-release.outputs.install_url || '' }}
|
||||
RELEASE_URL: ${{ needs.publish-pr-release.outputs.release_url || '' }}
|
||||
PUBLISH_STATUS: ${{ needs.publish-pr-release.outputs.publish_status || '' }}
|
||||
run: node --experimental-strip-types .github/scripts/pr-build-result.ts
|
||||
|
||||
trigger-docker:
|
||||
needs: [build-shell, publish-pr-release]
|
||||
if: github.event_name == 'workflow_dispatch' && needs.build-shell.outputs.status == 'success' && needs.publish-pr-release.outputs.release_tag != ''
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout scripts
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js 24
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Dispatch docker build
|
||||
continue-on-error: true
|
||||
env:
|
||||
DISPATCH_PAT: ${{ secrets.PR_RELEASE_PAT }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ inputs.pr_number }}
|
||||
PR_SHA: ${{ inputs.pr_sha }}
|
||||
PR_HEAD_REPO: ${{ inputs.pr_head_repo }}
|
||||
SOURCE_REPO: ${{ github.repository }}
|
||||
RELEASE_REPO: NapNeko/napcat-pr-release
|
||||
run: |
|
||||
if [ -z "${DISPATCH_PAT}" ]; then
|
||||
echo "::warning::PR_RELEASE_PAT secret 未配置,跳过 Docker 测试镜像构建"
|
||||
exit 0
|
||||
fi
|
||||
node --experimental-strip-types .github/scripts/pr-docker-dispatch.ts
|
||||
@@ -0,0 +1,155 @@
|
||||
name: Release Downstream
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: 'Release tag name (e.g., v4.10.7)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
QQ_URL_X86_64: 'https://qqdl.gtimg.cn/qqfile/QQNT/9.9.36/beta/9ee04bef/linuxqq_3.2.34-53644_x86_64.AppImage'
|
||||
QQ_URL_ARM64: 'https://qqdl.gtimg.cn/qqfile/QQNT/9.9.36/beta/9ee04bef/linuxqq_3.2.34-53644_arm64.AppImage'
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
latest_tag: ${{ steps.get_version.outputs.latest_tag }}
|
||||
version: ${{ steps.get_version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Get Latest NapCat Version
|
||||
id: get_version
|
||||
run: |
|
||||
if [ -n "${{ inputs.tag_name }}" ]; then
|
||||
latest_tag="${{ inputs.tag_name }}"
|
||||
else
|
||||
latest_tag=$(git describe --tags $(git rev-list --tags --max-count=1))
|
||||
fi
|
||||
version=${latest_tag#v}
|
||||
echo "Debug: Latest NapCat Version is ${latest_tag}, version is ${version}"
|
||||
echo "latest_tag=${latest_tag}" >> $GITHUB_OUTPUT
|
||||
echo "version=${version}" >> $GITHUB_OUTPUT
|
||||
|
||||
publish-schema:
|
||||
needs: get-version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build napcat-schema
|
||||
run: |
|
||||
cd packages/napcat-schema
|
||||
pnpm run build:openapi
|
||||
|
||||
- name: Checkout NapCatDocs
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: NapNeko/NapCatDocs
|
||||
token: ${{ secrets.NAPCAT_BUILD }}
|
||||
path: napcat-docs
|
||||
|
||||
- name: Copy OpenAPI Schema
|
||||
run: |
|
||||
VERSION="${{ needs.get-version.outputs.version }}"
|
||||
mkdir -p napcat-docs/src/api/${VERSION}
|
||||
cp packages/napcat-schema/dist/openapi.json napcat-docs/src/api/${VERSION}/openapi.json
|
||||
echo "OpenAPI schema copied to napcat-docs/src/api/${VERSION}/openapi.json"
|
||||
|
||||
- name: Commit and Push
|
||||
run: |
|
||||
VERSION="${{ needs.get-version.outputs.version }}"
|
||||
cd napcat-docs
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add src/api/${VERSION}/openapi.json
|
||||
git commit -m "chore: update OpenAPI schema for version ${VERSION}" || echo "No changes to commit"
|
||||
git push
|
||||
|
||||
shell-docker:
|
||||
needs: get-version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger NapCat-Docker docker-publish workflow
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||
NAPCAT_VERSION: ${{ needs.get-version.outputs.latest_tag }}
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer $GH_TOKEN" \
|
||||
https://api.github.com/repos/NapNeko/NapCat-Docker/actions/workflows/docker-publish.yml/dispatches \
|
||||
-d "{\"ref\":\"main\",\"inputs\":{\"napcat_version\":\"${NAPCAT_VERSION}\"}}"
|
||||
|
||||
framework-docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger NapCat-Framework-Docker docker-publish workflow
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer $GH_TOKEN" \
|
||||
https://api.github.com/repos/NapNeko/NapCat.Docker.Framework/actions/workflows/docker-image.yml/dispatches \
|
||||
-d '{"ref":"main"}'
|
||||
|
||||
appimage:
|
||||
needs: get-version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger NapCat AppImage build workflow
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||
NAPCAT_VERSION: ${{ needs.get-version.outputs.latest_tag }}
|
||||
run: |
|
||||
echo "Debug: Triggering NapCat AppImage with napcat_version=${NAPCAT_VERSION}"
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer $GH_TOKEN" \
|
||||
https://api.github.com/repos/NapNeko/NapCatAppImageBuild/actions/workflows/release.yml/dispatches \
|
||||
-d "{\"ref\":\"main\",\"inputs\":{\"napcat_version\":\"${NAPCAT_VERSION}\",\"qq_version_x86_64\":\"${{ env.QQ_URL_X86_64 }}\",\"qq_version_arm64\":\"${{ env.QQ_URL_ARM64 }}\"}}"
|
||||
|
||||
node-shell:
|
||||
needs: get-version
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||
NAPCAT_VERSION: ${{ needs.get-version.outputs.latest_tag }}
|
||||
steps:
|
||||
- name: Trigger NapCat NodeLoader release workflow
|
||||
run: |
|
||||
echo "Debug: Triggering NapCat NodeLoader release with napcat_version=${NAPCAT_VERSION}"
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer $GH_TOKEN" \
|
||||
https://api.github.com/repos/NapNeko/NapCatLinuxNodeLoader/actions/workflows/release.yml/dispatches \
|
||||
-d "{\"ref\":\"main\",\"inputs\":{\"napcat_version\":\"${NAPCAT_VERSION}\",\"qq_url_amd64\":\"${{ env.QQ_URL_X86_64 }}\",\"qq_url_arm64\":\"${{ env.QQ_URL_ARM64 }}\"}}"
|
||||
|
||||
- name: Trigger NapCat NodeLoader docker workflow
|
||||
run: |
|
||||
echo "Debug: Triggering NapCat NodeLoader docker with napcat_version=${NAPCAT_VERSION}"
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer $GH_TOKEN" \
|
||||
https://api.github.com/repos/NapNeko/NapCatLinuxNodeLoader/actions/workflows/docker-publish.yml/dispatches \
|
||||
-d "{\"ref\":\"main\",\"inputs\":{\"napcat_version\":\"${NAPCAT_VERSION}\",\"qq_url_amd64\":\"${{ env.QQ_URL_X86_64 }}\",\"qq_url_arm64\":\"${{ env.QQ_URL_ARM64 }}\"}}"
|
||||
@@ -0,0 +1,341 @@
|
||||
name: Release Publish
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Release version tag (e.g., v4.10.7)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: write-all
|
||||
|
||||
env:
|
||||
RELEASE_NAME: "NapCat"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build NapCat.${{ matrix.target.name }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- name: Framework
|
||||
build_cmd: build:framework
|
||||
src_dir: packages/napcat-framework/dist
|
||||
dist_dir: framework-dist
|
||||
- name: Shell
|
||||
build_cmd: build:shell
|
||||
src_dir: packages/napcat-shell/dist
|
||||
dist_dir: shell-dist
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ inputs.version }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
run_install: false
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
- name: Build NapCat.${{ matrix.target.name }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NAPCAT_VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
pnpm i
|
||||
pnpm --filter napcat-webui-frontend run build || exit 1
|
||||
pnpm run ${{ matrix.target.build_cmd }}
|
||||
pnpm --filter napcat-plugin-builtin run build || exit 1
|
||||
mv ${{ matrix.target.src_dir }} ${{ matrix.target.dist_dir }}
|
||||
cd ${{ matrix.target.dist_dir }}
|
||||
# --omit=dev still resolves dev peer dependencies; remove build tooling first.
|
||||
npm pkg delete devDependencies
|
||||
npm install --omit=dev
|
||||
rm ./package-lock.json || exit 0
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: NapCat.${{ matrix.target.name }}
|
||||
path: ${{ matrix.target.dist_dir }}
|
||||
|
||||
assemble-windows-node:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# QQ 9.9.31.49738; SHA256 matches the microsoft/winget-pkgs installer manifest.
|
||||
QQ_URL: https://github.com/Rodert/qq-versions/releases/download/qq-packages-20260528-3e8913a2/QQ_9.9.31_260528_x64_01.exe
|
||||
QQ_SHA256: 0beb5cb4ff776cba822caa0abadbd53f5892f12628a86dabea1b372c82c086bc
|
||||
NODE_VERSION: '22.11.0'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ inputs.version }}
|
||||
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./artifacts
|
||||
|
||||
- name: Setup tools
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y aria2 unzip zip p7zip-full curl jq
|
||||
|
||||
- name: Generate download cache key
|
||||
id: download-cache-key
|
||||
run: |
|
||||
DOWNLOAD_HASH=$(printf '%s\n' "$QQ_URL" "$QQ_SHA256" "$NODE_VERSION" | sha256sum | cut -d ' ' -f 1)
|
||||
echo "key=napcat-downloads-v2-$DOWNLOAD_HASH" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache QQ and Node.js downloads
|
||||
id: cache-downloads
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/napcat-downloads
|
||||
key: ${{ steps.download-cache-key.outputs.key }}
|
||||
|
||||
- name: Download QQ and Node.js
|
||||
if: steps.cache-downloads.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p /tmp/napcat-downloads
|
||||
cd /tmp/napcat-downloads
|
||||
|
||||
echo "Downloading QQ installer..."
|
||||
# Retry download errors, including HTTP 404 responses.
|
||||
curl --fail --location --retry 5 --retry-all-errors --retry-delay 5 \
|
||||
--connect-timeout 30 --max-time 600 --user-agent "Mozilla/5.0" \
|
||||
--output "QQ_x64.exe" "$QQ_URL"
|
||||
|
||||
NODE_URL="https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-win-x64.zip"
|
||||
echo "Downloading Node.js $NODE_VERSION..."
|
||||
aria2c -x1 -s1 -k1M -o "node-win-x64.zip" "$NODE_URL"
|
||||
|
||||
- name: Verify QQ installer
|
||||
run: |
|
||||
echo "$QQ_SHA256 /tmp/napcat-downloads/QQ_x64.exe" | sha256sum --check --strict -
|
||||
|
||||
- name: Assemble NapCat.Shell.Windows.Node.zip
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TMPDIR=$(mktemp -d)
|
||||
CACHE_DIR="/tmp/napcat-downloads"
|
||||
|
||||
# -----------------------------
|
||||
# 1) 解压 QQ x64
|
||||
# -----------------------------
|
||||
QQ_EXTRACT="$TMPDIR/qq_extracted"
|
||||
mkdir -p "$QQ_EXTRACT"
|
||||
7z x -y -o"$QQ_EXTRACT" "$CACHE_DIR/QQ_x64.exe" >/dev/null
|
||||
|
||||
# -----------------------------
|
||||
# 2) 解压 Node.js Windows x64
|
||||
# -----------------------------
|
||||
NODE_EXTRACT="$TMPDIR/node_extracted"
|
||||
mkdir -p "$NODE_EXTRACT"
|
||||
unzip -q "$CACHE_DIR/node-win-x64.zip" -d "$NODE_EXTRACT"
|
||||
|
||||
# -----------------------------
|
||||
# 3) 创建输出目录
|
||||
# -----------------------------
|
||||
OUT_DIR="$GITHUB_WORKSPACE/NapCat.Shell.Windows.Node"
|
||||
mkdir -p "$OUT_DIR/NapCat.Shell.Windows.Node"
|
||||
|
||||
# -----------------------------
|
||||
# 4) 解压 NapCat.Shell.zip 到 napcat
|
||||
# -----------------------------
|
||||
cp -a "$GITHUB_WORKSPACE/artifacts/NapCat.Shell/." "$OUT_DIR/napcat/"
|
||||
|
||||
# -----------------------------
|
||||
# 5) 拷贝 QQ 文件到 NapCat.Shell.Windows.Node
|
||||
# -----------------------------
|
||||
QQ_TARGETS=("avif_convert.dll" "broadcast_ipc.dll" "config.json" "crypto.dll" "ssl.dll" "libglib-2.0-0.dll" "libgobject-2.0-0.dll" "libvips-42.dll" "ncnn.dll" "opencv.dll" "package.json" "QBar.dll" "wrapper.node" "LightQuic.dll")
|
||||
for name in "${QQ_TARGETS[@]}"; do
|
||||
source_file=$(find "$QQ_EXTRACT" -type f -iname "$name" -print -quit)
|
||||
if [ -z "$source_file" ]; then
|
||||
echo "Missing required QQ file: $name" >&2
|
||||
exit 1
|
||||
fi
|
||||
cp -a "$source_file" "$OUT_DIR/"
|
||||
done
|
||||
|
||||
# -----------------------------
|
||||
# 5.1) 拷贝 win64 目录下的文件
|
||||
# -----------------------------
|
||||
mkdir -p "$OUT_DIR/win64"
|
||||
find "$QQ_EXTRACT" -ipath "*/win64/SSOShareInfoHelper64.dll" -exec cp -a {} "$OUT_DIR/win64/" \; || true
|
||||
find "$QQ_EXTRACT" -ipath "*/win64/parent-ipc-core-x64.dll" -exec cp -a {} "$OUT_DIR/win64/" \; || true
|
||||
|
||||
# -----------------------------
|
||||
# 6) 拷贝仓库文件 napcat.bat 和 index.js
|
||||
# -----------------------------
|
||||
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/napcat.bat" "$OUT_DIR/" || true
|
||||
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/index.js" "$OUT_DIR/" || true
|
||||
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/QQNT.dll" "$OUT_DIR/" || true
|
||||
|
||||
# -----------------------------
|
||||
# 7) 拷贝 Node.exe 到 NapCat.Shell.Windows.Node
|
||||
# -----------------------------
|
||||
cp -a "$NODE_EXTRACT/node-v$NODE_VERSION-win-x64/node.exe" "$OUT_DIR/" || true
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: NapCat.Shell.Windows.Node
|
||||
path: NapCat.Shell.Windows.Node
|
||||
|
||||
validate-windows-node:
|
||||
needs: assemble-windows-node
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ inputs.version }}
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: NapCat.Shell.Windows.Node
|
||||
path: windows-node
|
||||
|
||||
- name: Verify bundled Node and QQ native dependencies
|
||||
shell: pwsh
|
||||
working-directory: windows-node
|
||||
run: |
|
||||
& .\node.exe --check .\index.js
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
& .\node.exe -e "const wrapper = require('./wrapper.node'); if (!wrapper.NodeQQNTWrapperUtil) throw new Error('Missing NodeQQNTWrapperUtil'); console.log('wrapper.node native-load PASS'); process.exit(0);"
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
|
||||
- name: Verify Windows loader file queries
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake -S .github/tests/windows-loader -B "$env:RUNNER_TEMP/windows-loader-test" -A x64
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
cmake --build "$env:RUNNER_TEMP/windows-loader-test" --config Release
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
& "$env:RUNNER_TEMP/windows-loader-test/Release/windows-loader-test.exe" "$pwd/windows-node/napcat/NapCatWinBootHook.dll" "$pwd/windows-node/napcat/loadNapCat.js"
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
|
||||
release-napcat:
|
||||
needs: [build, assemble-windows-node, validate-windows-node]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./artifacts
|
||||
|
||||
- name: Download NapCat.Shell.Windows.OneKey.zip
|
||||
run: |
|
||||
curl -L -o NapCat.Shell.Windows.OneKey.zip https://github.com/NapNeko/NapCatResource/raw/main/NapCat.Shell.Windows.OneKey.zip
|
||||
|
||||
- name: Zip Artifacts
|
||||
run: |
|
||||
cd artifacts
|
||||
[ -d NapCat.Framework ] && (cd NapCat.Framework && zip -qr ../../NapCat.Framework.zip .)
|
||||
[ -d NapCat.Shell ] && (cd NapCat.Shell && zip -qr ../../NapCat.Shell.zip .)
|
||||
[ -d NapCat.Shell.Windows.Node ] && (cd NapCat.Shell.Windows.Node && zip -qr ../../NapCat.Shell.Windows.Node.zip .)
|
||||
cd ..
|
||||
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Generate release note
|
||||
env:
|
||||
CURRENT_TAG: ${{ inputs.version }}
|
||||
run: node .github/scripts/generate-release-notes.mjs "$CURRENT_TAG" "$GITHUB_REPOSITORY" CHANGELOG.md
|
||||
|
||||
- name: Create Release and Upload Artifacts
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ inputs.version }}
|
||||
name: NapCat ${{ inputs.version }}
|
||||
body_path: CHANGELOG.md
|
||||
files: |
|
||||
NapCat.Shell.Windows.Node.zip
|
||||
NapCat.Framework.zip
|
||||
NapCat.Shell.zip
|
||||
NapCat.Shell.Windows.OneKey.zip
|
||||
draft: false
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
run_install: false
|
||||
|
||||
- name: Update apifox
|
||||
env:
|
||||
APIFOX_TOKEN: ${{ secrets.APIFOX_TOKEN }}
|
||||
run: |
|
||||
pnpm i --ignore-scripts
|
||||
pnpm run build:openapi
|
||||
|
||||
jq -n --rawfile input packages/napcat-schema/dist/openapi.json \
|
||||
'{
|
||||
input: $input,
|
||||
options: {
|
||||
"endpointOverwriteBehavior": "OVERWRITE_EXISTING",
|
||||
"schemaOverwriteBehavior": "OVERWRITE_EXISTING",
|
||||
"updateFolderOfChangedEndpoint": true,
|
||||
"moduleId": 1140714,
|
||||
"deleteUnmatchedResources": true
|
||||
}
|
||||
}' > apifox_payload.json
|
||||
|
||||
curl --location -g --request POST 'https://api.apifox.com/v1/projects/5348325/import-openapi?locale=zh-CN' \
|
||||
--header 'X-Apifox-Api-Version: 2024-03-28' \
|
||||
--header "Authorization: Bearer $APIFOX_TOKEN" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-binary @apifox_payload.json
|
||||
|
||||
- name: Publish release hash
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${{ inputs.version }}"
|
||||
HASH_REPO="NapNeko/napcat-release-hash"
|
||||
|
||||
gh auth setup-git
|
||||
gh repo clone "$HASH_REPO" hash-repo
|
||||
|
||||
node .github/scripts/publish-release-hash.mjs \
|
||||
--version "$VERSION" \
|
||||
--shell "./artifacts/NapCat.Shell/napcat.mjs" \
|
||||
--framework "./artifacts/NapCat.Framework/napcat.mjs" \
|
||||
--file "./hash-repo/release.json"
|
||||
|
||||
cd hash-repo
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add release.json
|
||||
if git diff --cached --quiet; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "chore: update release hash for ${VERSION}"
|
||||
git push origin HEAD:main || git push origin HEAD:master
|
||||
fi
|
||||
|
||||
- name: Trigger downstream release workflows
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
echo "Triggering release-downstream workflow with tag_name=${VERSION}"
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer $GH_TOKEN" \
|
||||
https://api.github.com/repos/${{ github.repository }}/actions/workflows/release-downstream.yml/dispatches \
|
||||
-d "{\"ref\":\"main\",\"inputs\":{\"tag_name\":\"${VERSION}\"}}"
|
||||
@@ -0,0 +1,53 @@
|
||||
name: Release Tag
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
validate-version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
valid: ${{ steps.check.outputs.valid }}
|
||||
version: ${{ steps.check.outputs.version }}
|
||||
steps:
|
||||
- name: Validate semantic version
|
||||
id: check
|
||||
run: |
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
echo "Checking tag: $TAG"
|
||||
|
||||
SEMVER_REGEX="^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?$"
|
||||
|
||||
if [[ "$TAG" =~ $SEMVER_REGEX ]]; then
|
||||
echo "Valid semantic version: $TAG"
|
||||
echo "valid=true" >> $GITHUB_OUTPUT
|
||||
echo "version=$TAG" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Invalid version format: $TAG"
|
||||
echo "Expected format: vX.Y.Z or vX.Y.Z-prerelease"
|
||||
echo "Examples: v1.0.0, v1.2.3-beta, v2.0.0-rc.1"
|
||||
echo "valid=false" >> $GITHUB_OUTPUT
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trigger-release:
|
||||
needs: [validate-version]
|
||||
if: needs.validate-version.outputs.valid == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger release-publish workflow
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||
VERSION: ${{ needs.validate-version.outputs.version }}
|
||||
run: |
|
||||
echo "Triggering release-publish workflow with version=${VERSION}"
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer $GH_TOKEN" \
|
||||
https://api.github.com/repos/${{ github.repository }}/actions/workflows/release-publish.yml/dispatches \
|
||||
-d "{\"ref\":\"main\",\"inputs\":{\"version\":\"${VERSION}\"}}"
|
||||
Reference in new issue
Block a user