diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27531f2..cd1d993 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,4 +84,9 @@ jobs: - name: Verify runner architecture run: test "$(uname -m)" = "${{ matrix.architecture }}" - name: Build release products - run: swift build --configuration release + env: + EXPECTED_ARCHITECTURE: ${{ matrix.architecture }} + run: | + swift build --configuration release + release_binary="$(swift build --configuration release --show-bin-path)/Gloss" + lipo "$release_binary" -verify_arch "$EXPECTED_ARCHITECTURE" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53e5e4b..9f49483 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,9 +7,14 @@ on: workflow_dispatch: inputs: release_tag: - description: Existing tag to package without publishing + description: Existing tag to package required: true type: string + publish_release: + description: Publish the existing tag and update the Homebrew tap + required: true + default: false + type: boolean permissions: contents: read @@ -33,10 +38,11 @@ jobs: env: DISTRIBUTION_TOKEN: ${{ secrets.GLOSS_DISTRIBUTION_TOKEN }} EXTENSION_SSH_KEY: ${{ secrets.GLOSS_EXTENSION_SSH_KEY }} + PUBLISH_RELEASE: ${{ github.event_name == 'push' || inputs.publish_release }} run: | missing=() [[ -n "$EXTENSION_SSH_KEY" ]] || missing+=("GLOSS_EXTENSION_SSH_KEY") - if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then + if [[ "$PUBLISH_RELEASE" == "true" ]]; then [[ -n "$DISTRIBUTION_TOKEN" ]] || missing+=("GLOSS_DISTRIBUTION_TOKEN") fi if [[ ${#missing[@]} -ne 0 ]]; then @@ -99,7 +105,7 @@ jobs: env: EXPECTED_ARCHITECTURE: ${{ matrix.architecture }} run: | - lipo -verify_arch "$EXPECTED_ARCHITECTURE" dist/Gloss.app/Contents/MacOS/Gloss + lipo dist/Gloss.app/Contents/MacOS/Gloss -verify_arch "$EXPECTED_ARCHITECTURE" codesign --verify --deep --strict --verbose=2 dist/Gloss.app codesign --display --verbose=4 dist/Gloss.app 2>&1 \ | grep -F "Signature=adhoc" @@ -161,7 +167,7 @@ jobs: gloss/dist/release/Casks/gloss.rb if-no-files-found: error - name: Publish GitHub release assets - if: github.event_name == 'push' + if: github.event_name == 'push' || inputs.publish_release working-directory: gloss env: GH_TOKEN: ${{ secrets.GLOSS_DISTRIBUTION_TOKEN }} @@ -207,7 +213,7 @@ jobs: --repo "$GLOSS_RELEASE_REPOSITORY" \ --draft=false - name: Start Homebrew cask update - if: github.event_name == 'push' + if: github.event_name == 'push' || inputs.publish_release env: GH_TOKEN: ${{ secrets.GLOSS_DISTRIBUTION_TOKEN }} run: | diff --git a/docs/runtime-distribution.md b/docs/runtime-distribution.md index c173bba..6c4eb71 100644 --- a/docs/runtime-distribution.md +++ b/docs/runtime-distribution.md @@ -106,10 +106,10 @@ active runtime。 | `GLOSS_EXTENSION_SSH_KEY` | 只读检出私有 `SunChJ/personal-immersive-translator` | | `GLOSS_DISTRIBUTION_TOKEN` | 向公开 binary repo 上传 Release,并 dispatch 公开 tap workflow | -workflow 的第一个 job 始终检查 `GLOSS_EXTENSION_SSH_KEY`;tag 事件还会检查 -`GLOSS_DISTRIBUTION_TOKEN`。缺失即 fail closed,不会开始正式构建。手工 -`workflow_dispatch` 不走 public publication 路径,因此不需要 distribution token,但仍需 -只读 extension deploy key 才能构建完整 App。 +workflow 的第一个 job 始终检查 `GLOSS_EXTENSION_SSH_KEY`;tag 事件以及显式开启 +`publish_release` 的手工恢复任务还会检查 `GLOSS_DISTRIBUTION_TOKEN`。缺失即 fail closed, +不会开始正式构建。手工 `workflow_dispatch` 默认不走 public publication 路径,因此不需要 +distribution token,但仍需只读 extension deploy key 才能构建完整 App。 ### 公开仓库与凭据初始化 @@ -212,6 +212,11 @@ brew upgrade --cask sunchj/tap/gloss `SunChJ/gloss-releases`。不要从私有 Gloss Release 或未经 `SHA256SUMS` 验证的临时 URL 生成公开 Cask。 +如果 tag 触发的工作流在公开 Release 创建前因工作流本身失败,先在 `main` 修复工作流,再从 +Gloss 的 Actions 页面手工运行 Release,输入原 `release_tag` 并显式开启 +`publish_release`。恢复任务仍检出原 tag、校验 tag 与 App 版本完全一致,并拒绝覆盖已经发布的 +不可变 Release;不要移动或重建失败的 tag。 + ### Ad-hoc 分发的安全取舍 这个渠道刻意不使用 Developer ID Application 证书、Apple notarization 或 stapled ticket: