Skip to content

Bump Homebrew Formula #5

Bump Homebrew Formula

Bump Homebrew Formula #5

Workflow file for this run

name: Bump Homebrew Formula
# 触发:作为 reusable workflow 被 release.yml 在发版(tag 推送)后链式调用(workflow_call)。
# —— 不靠 release:published 事件:由默认 GITHUB_TOKEN 创建的 Release 不会触发其它 workflow(GitHub 防递归),
# 同一 run 内链式调用可绕开该限制,且无需 PAT。
# 备份:手动触发,可显式指定版本号(用于补救 / dry-run)。
on:
workflow_call:
inputs:
version:
description: 'Version to bump (e.g. 1.6.278)'
required: true
type: string
# 最小权限:只显式接收跨仓写 tap 所需的 HOMEBREW_TAP_TOKEN,不用 secrets: inherit
# 把 caller 的全部 secrets(CSC_*/APPLE_* 等)都灌进来。GITHUB_TOKEN 由平台自动提供。
secrets:
HOMEBREW_TAP_TOKEN:
required: true
workflow_dispatch:
inputs:
version:
# required:true 让 UI 在派发前强制填写(本 workflow 无 latest-tag 回落,空值会直接报错)。
description: 'Version to bump (e.g., 1.6.225)'
required: true
type: string
permissions:
contents: read
jobs:
bump:
runs-on: ubuntu-latest
steps:
- name: Resolve version
id: ver
# SECURITY: ${{ inputs.version }} 必须经 env: 注入,不得直接拼进 run: 脚本——后者会让恶意输入
# (仅 collaborator 可触发,但仍是标准 antipattern)在 semver 校验前就被 shell 解释。
# 版本来源统一为 inputs.version(workflow_call 与 workflow_dispatch 共用 inputs 上下文)。
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if [[ -z "$INPUT_VERSION" ]]; then
echo "Cannot resolve version: inputs.version is empty" >&2
exit 1
fi
VER="${INPUT_VERSION#v}" # caller 传 github.ref_name=vX.Y.Z 时剥前导 v
# 校验版本号严格 semver patch 格式(再次防御:确保所有后续步骤拿到的 VER 是干净的)
if ! [[ "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Invalid version: $VER" >&2
exit 1
fi
echo "version=$VER" >> "$GITHUB_OUTPUT"
echo "Resolved version: $VER"
- name: Wait for npm registry to publish
env:
VER: ${{ steps.ver.outputs.version }}
run: |
set -euo pipefail
# CDN 传播最长 ~5min;每 30s 重试,共 10 次 = 5min
for i in $(seq 1 10); do
if curl -fsSL "https://registry.npmjs.org/cc-viewer/${VER}" >/dev/null 2>&1; then
echo "✓ npm has cc-viewer@${VER}"
exit 0
fi
echo "[$i/10] npm not yet showing cc-viewer@${VER}, sleeping 30s..."
sleep 30
done
echo "✗ Timed out waiting for npm to publish cc-viewer@${VER}" >&2
exit 1
- name: Compute tarball sha256
id: hash
env:
VER: ${{ steps.ver.outputs.version }}
run: |
set -euo pipefail
URL="https://registry.npmjs.org/cc-viewer/-/cc-viewer-${VER}.tgz"
curl -fsSL "$URL" -o /tmp/pkg.tgz
SHA=$(sha256sum /tmp/pkg.tgz | cut -d' ' -f1)
echo "sha256=$SHA" >> "$GITHUB_OUTPUT"
echo "url=$URL" >> "$GITHUB_OUTPUT"
echo "✓ sha256=$SHA"
- name: Checkout tap repo
uses: actions/checkout@v4
with:
repository: weiesky/homebrew-cc-viewer
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: tap
- name: Update formula
env:
URL: ${{ steps.hash.outputs.url }}
SHA: ${{ steps.hash.outputs.sha256 }}
run: |
set -euo pipefail
FORMULA=tap/Formula/cc-viewer.rb
if [[ ! -f "$FORMULA" ]]; then
echo "$FORMULA not found in tap repo" >&2
exit 1
fi
# 仅替换 url 与 sha256 行;其它内容(depends_on / install / test 块)由维护者管理。
# python 通过 sys.argv 拿 env 注入的 URL/SHA,不让 Action 表达式直接拼进 shell 行。
python3 - "$FORMULA" "$URL" "$SHA" <<'PY'
import re, sys
path, url, sha = sys.argv[1], sys.argv[2], sys.argv[3]
with open(path, 'r', encoding='utf-8') as f:
src = f.read()
src = re.sub(r'url\s+"[^"]+"', f'url "{url}"', src, count=1)
src = re.sub(r'sha256\s+"[^"]+"', f'sha256 "{sha}"', src, count=1)
with open(path, 'w', encoding='utf-8') as f:
f.write(src)
PY
echo "--- Updated formula ---"
grep -E '(url|sha256) ' "$FORMULA"
- name: Create PR
id: cpr
uses: peter-evans/create-pull-request@v6
with:
path: tap
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
commit-message: "cc-viewer ${{ steps.ver.outputs.version }}"
title: "cc-viewer ${{ steps.ver.outputs.version }}"
body: |
Automated bump from [cc-viewer release `v${{ steps.ver.outputs.version }}`](https://github.com/weiesky/cc-viewer/releases/tag/v${{ steps.ver.outputs.version }}).
- npm tarball: <${{ steps.hash.outputs.url }}>
- sha256: `${{ steps.hash.outputs.sha256 }}`
Generated by `.github/workflows/bump-homebrew.yml` in `weiesky/cc-viewer`.
branch: bump-${{ steps.ver.outputs.version }}
delete-branch: true
- name: Auto-merge PR
# 只在 created / updated 分支跑(none / closed 时跳过,避免对错误 PR 号操作)。
# 跨仓 token 用 HOMEBREW_TAP_TOKEN(与 Create PR 同源),需在 tap 仓 settings →
# general → Pull Requests 启用 Allow merge commits(已是默认)。
if: steps.cpr.outputs.pull-request-operation == 'created' || steps.cpr.outputs.pull-request-operation == 'updated'
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
PR_NUM: ${{ steps.cpr.outputs.pull-request-number }}
run: |
set -euo pipefail
# 数字校验防注入(peter-evans action 输出可信,但本仓 hardening 风格一致)
if ! [[ "$PR_NUM" =~ ^[0-9]+$ ]]; then
echo "Invalid PR number: $PR_NUM" >&2
exit 1
fi
gh pr merge "$PR_NUM" \
--repo weiesky/homebrew-cc-viewer \
--merge \
--delete-branch
echo "✓ Merged PR #$PR_NUM into tap main"