From 2c664ce0d09c60a13d695e76281c7a1ee4e08a5e Mon Sep 17 00:00:00 2001 From: jerboy Date: Wed, 5 Aug 2026 16:26:22 +0800 Subject: [PATCH] ci(publish): route production through Platform Signed-off-by: jerboy --- .../workflows/publish-cindy-plugins-global.yml | 7 ++++--- .github/workflows/publish-cindy-plugins.yml | 7 ++++--- .tests/publish-workflows.test.mjs | 17 +++++++++++++---- README.md | 9 ++++++--- README.zh-CN.md | 8 +++++--- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/.github/workflows/publish-cindy-plugins-global.yml b/.github/workflows/publish-cindy-plugins-global.yml index 3ad5172..b9173a3 100644 --- a/.github/workflows/publish-cindy-plugins-global.yml +++ b/.github/workflows/publish-cindy-plugins-global.yml @@ -146,6 +146,7 @@ jobs: id-token: write strategy: fail-fast: false + max-parallel: 2 matrix: plugin: ${{ fromJSON(needs.detect.outputs.plugins) }} steps: @@ -162,10 +163,10 @@ jobs: - name: Publish plugin env: - CINDY_PLUGIN_SERVER_URL_GLOBAL: ${{ secrets.CINDY_PLUGIN_SERVER_URL_GLOBAL }} + CINDY_PLUGIN_PLATFORM_URL_GLOBAL: ${{ secrets.CINDY_PLUGIN_PLATFORM_URL_GLOBAL }} run: | set -euo pipefail - : "${CINDY_PLUGIN_SERVER_URL_GLOBAL:?CINDY_PLUGIN_SERVER_URL_GLOBAL is not configured}" + : "${CINDY_PLUGIN_PLATFORM_URL_GLOBAL:?CINDY_PLUGIN_PLATFORM_URL_GLOBAL is not configured}" oidc_response="$(curl \ --fail-with-body \ @@ -188,5 +189,5 @@ jobs: --header "Authorization: Bearer ${oidc_token}" \ --header "Content-Type: application/octet-stream" \ --data-binary "@$RUNNER_TEMP/plugin.cindy" \ - "${CINDY_PLUGIN_SERVER_URL_GLOBAL%/}" + "${CINDY_PLUGIN_PLATFORM_URL_GLOBAL%/}" echo diff --git a/.github/workflows/publish-cindy-plugins.yml b/.github/workflows/publish-cindy-plugins.yml index 0506513..75c5699 100644 --- a/.github/workflows/publish-cindy-plugins.yml +++ b/.github/workflows/publish-cindy-plugins.yml @@ -146,6 +146,7 @@ jobs: id-token: write strategy: fail-fast: false + max-parallel: 2 matrix: plugin: ${{ fromJSON(needs.detect.outputs.plugins) }} steps: @@ -162,10 +163,10 @@ jobs: - name: Publish plugin env: - CINDY_PLUGIN_SERVER_URL_CN: ${{ secrets.CINDY_PLUGIN_SERVER_URL_CN }} + CINDY_PLUGIN_PLATFORM_URL_CN: ${{ secrets.CINDY_PLUGIN_PLATFORM_URL_CN }} run: | set -euo pipefail - : "${CINDY_PLUGIN_SERVER_URL_CN:?CINDY_PLUGIN_SERVER_URL_CN is not configured}" + : "${CINDY_PLUGIN_PLATFORM_URL_CN:?CINDY_PLUGIN_PLATFORM_URL_CN is not configured}" oidc_response="$(curl \ --fail-with-body \ @@ -188,5 +189,5 @@ jobs: --header "Authorization: Bearer ${oidc_token}" \ --header "Content-Type: application/octet-stream" \ --data-binary "@$RUNNER_TEMP/plugin.cindy" \ - "${CINDY_PLUGIN_SERVER_URL_CN%/}" + "${CINDY_PLUGIN_PLATFORM_URL_CN%/}" echo diff --git a/.tests/publish-workflows.test.mjs b/.tests/publish-workflows.test.mjs index 9e78ad3..61812a9 100644 --- a/.tests/publish-workflows.test.mjs +++ b/.tests/publish-workflows.test.mjs @@ -18,10 +18,18 @@ test('CN and Global plugin publishers are operationally independent', () => { assert.match(cnWorkflow, /group: cindy-plugin-publish-cn-prod-/); assert.match(globalWorkflow, /group: cindy-plugin-publish-global-prod-/); - assert.match(cnWorkflow, /CINDY_PLUGIN_SERVER_URL_CN/); - assert.doesNotMatch(cnWorkflow, /CINDY_PLUGIN_SERVER_URL_GLOBAL/); - assert.match(globalWorkflow, /CINDY_PLUGIN_SERVER_URL_GLOBAL/); - assert.doesNotMatch(globalWorkflow, /CINDY_PLUGIN_SERVER_URL_CN/); + assert.match(cnWorkflow, /secrets\.CINDY_PLUGIN_PLATFORM_URL_CN/); + assert.doesNotMatch(cnWorkflow, /CINDY_PLUGIN_PLATFORM_URL_GLOBAL/); + assert.match(globalWorkflow, /secrets\.CINDY_PLUGIN_PLATFORM_URL_GLOBAL/); + assert.doesNotMatch(globalWorkflow, /CINDY_PLUGIN_PLATFORM_URL_CN/); +}); + +test('both production publishers route through protected Platform endpoints', () => { + for (const workflow of [cnWorkflow, globalWorkflow]) { + assert.doesNotMatch(workflow, /CINDY_PLUGIN_SERVER_URL_/); + assert.doesNotMatch(workflow, /api\/publisher\/releases/); + assert.doesNotMatch(workflow, /https:\/\/(?:plugin|platform)\./); + } }); test('both regional publishers support main pushes and full manual republish', () => { @@ -33,6 +41,7 @@ test('both regional publishers support main pushes and full manual republish', ( assert.match(workflow, /Publishing all Cindy plugins:/); assert.match(workflow, /id-token: write/); assert.match(workflow, /audience=cindy-plugin/); + assert.match(workflow, /max-parallel: 2/); } }); diff --git a/README.md b/README.md index 45bca95..917adf9 100644 --- a/README.md +++ b/README.md @@ -194,9 +194,12 @@ Both are active and behave identically: plugins in full — for initial setup after a repository migration or an explicit re-release. - Each publishes via GitHub Actions OIDC (audience `cindy-plugin`) to its own - endpoint, supplied by a repository secret. The two runs package, execute, and - report independently; a failure on one side does not affect the other's - workflow status. There is no development publishing workflow. + production Cindy Platform endpoint, supplied by the repository secrets + `CINDY_PLUGIN_PLATFORM_URL_CN` and `CINDY_PLUGIN_PLATFORM_URL_GLOBAL`. + Platform orchestrates the release and forwards the OIDC token and package to + Plugin Server; the workflows never call Plugin Server directly. The two runs + package, execute, and report independently; a failure on one side does not + affect the other's workflow status. There is no development publishing workflow. Because both fire on the same push, one merge that changes a plugin produces two releases of it — one per region. diff --git a/README.zh-CN.md b/README.zh-CN.md index 8bb458f..c466816 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -161,9 +161,11 @@ cindy-art/ - `main` 的普通 push 只发布本次发生变化的插件目录;没有触及任何插件目录的 push 不会 发布任何东西。 - Actions 页面手动运行会全量发布当前全部插件,供仓库迁移后首次建档或显式重发使用。 -- 各自通过 GitHub Actions OIDC(audience `cindy-plugin`)发布到由仓库 Secret 提供的 - 端点。两次运行独立打包、独立执行、独立汇报,一边失败不影响另一边的 Workflow 状态。 - 仓库不提供 Dev 发布 Workflow。 +- 各自通过 GitHub Actions OIDC(audience `cindy-plugin`)发布到由仓库 Secret + `CINDY_PLUGIN_PLATFORM_URL_CN` 与 `CINDY_PLUGIN_PLATFORM_URL_GLOBAL` 提供的对应生产 + Cindy Platform 入口。Platform 负责发布编排并把 OIDC Token 与包体转发给 Plugin + Server,Workflow 不再直连 Plugin Server。两次运行独立打包、独立执行、独立汇报, + 一边失败不影响另一边的 Workflow 状态。仓库不提供 Dev 发布 Workflow。 由于两者由同一次 push 触发,一次改动插件的合并会产生两个 Release —— 每个区域一个。