Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/publish-dist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Publish Homebrew + Scoop (manual)

# Manually (re)publish the Homebrew formula + Scoop manifest for a version that
# is already on npm — without re-running the whole release (npm/docker). Use it
# to test the TAP_TOKEN wiring or to backfill a channel. Auto-publishing on
# release lives in the `dist` job of release.yml.
on:
workflow_dispatch:
inputs:
version:
description: Version to publish (blank = current package.json version)
required: false
default: ''

permissions:
contents: read

jobs:
dist:
name: Publish Homebrew + Scoop
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22

- name: Generate and push tap files
env:
TAP_TOKEN: ${{ secrets.TAP_TOKEN }}
INPUT_VERSION: ${{ inputs.version }}
run: |
V="${INPUT_VERSION:-$(node -p "require('./package.json').version")}"
echo "Publishing Homebrew + Scoop for $V"
node scripts/gen-dist.mjs "$V"
VERSION="$V" bash scripts/publish-tap.sh
28 changes: 4 additions & 24 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,30 +150,10 @@ jobs:
# Cross-repo push needs a PAT (the default GITHUB_TOKEN is scoped to this
# repo). Add a fine-grained TAP_TOKEN secret with contents:write on
# wavyx/homebrew-tap and wavyx/scoop-pdcli to enable auto-publish; without
# it this step no-ops so the release never fails on a missing secret.
# Prereleases are skipped (they must not move the stable formula/manifest).
# it publish-tap.sh no-ops so the release never fails. Prereleases skip.
# (Shared with the manual publish-dist workflow via scripts/publish-tap.sh.)
- name: Push to tap repos
env:
TAP_TOKEN: ${{ secrets.TAP_TOKEN }}
V: ${{ steps.gen.outputs.v }}
run: |
case "$V" in *-*) echo "prerelease $V — skipping tap publish"; exit 0 ;; esac
if [ -z "$TAP_TOKEN" ]; then
echo "No TAP_TOKEN secret — skipping Homebrew/Scoop publish."
echo "Run 'node scripts/gen-dist.mjs $V' and push manually, or add the PAT."
exit 0
fi
git config --global user.name "pdcli-release"
git config --global user.email "release@wavyx.dev"
push_file() {
repo="$1"; src="$2"; dest="$3"
tmp=$(mktemp -d)
git clone --depth 1 "https://x-access-token:${TAP_TOKEN}@github.com/${repo}.git" "$tmp"
mkdir -p "$(dirname "$tmp/$dest")"
cp "$src" "$tmp/$dest"
git -C "$tmp" add "$dest"
git -C "$tmp" commit -m "pdcli $V" || { echo "no change for $repo"; return 0; }
git -C "$tmp" push
}
push_file wavyx/homebrew-tap packaging/homebrew/pdcli.rb Formula/pdcli.rb
push_file wavyx/scoop-pdcli packaging/scoop/pdcli.json bucket/pdcli.json
VERSION: ${{ steps.gen.outputs.v }}
run: bash scripts/publish-tap.sh
47 changes: 47 additions & 0 deletions scripts/publish-tap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Push the generated Homebrew formula + Scoop manifest to the tap repos.
#
# Requires (env):
# VERSION the version being published (e.g. 0.22.0)
# TAP_TOKEN a fine-grained PAT with contents:write on wavyx/homebrew-tap and
# wavyx/scoop-pdcli. Absent -> this script no-ops (never fails).
# Requires (files): packaging/homebrew/pdcli.rb + packaging/scoop/pdcli.json,
# already generated by `node scripts/gen-dist.mjs "$VERSION"`.
#
# Shared by the release workflow (auto on tag) and the manual publish-dist
# workflow, so the two can never drift.
set -euo pipefail

: "${VERSION:?VERSION required}"

# A prerelease must never move the stable formula/manifest.
case "$VERSION" in
*-*) echo "prerelease $VERSION — skipping tap publish"; exit 0 ;;
esac

if [ -z "${TAP_TOKEN:-}" ]; then
echo "No TAP_TOKEN — skipping Homebrew/Scoop publish."
echo "Add the PAT secret, or run 'node scripts/gen-dist.mjs $VERSION' and push manually."
exit 0
fi

git config --global user.name "pdcli-release"
git config --global user.email "release@wavyx.dev"

push_file() {
repo="$1"; src="$2"; dest="$3"
tmp="$(mktemp -d)"
git clone --depth 1 "https://x-access-token:${TAP_TOKEN}@github.com/${repo}.git" "$tmp"
mkdir -p "$(dirname "$tmp/$dest")"
cp "$src" "$tmp/$dest"
git -C "$tmp" add "$dest"
if git -C "$tmp" commit -m "pdcli $VERSION"; then
git -C "$tmp" push
echo "pushed $repo/$dest"
else
echo "no change for $repo/$dest"
fi
}
Comment on lines +31 to +44

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 tmp is not declared with local, making it a global variable that is overwritten on each call to push_file. If set -e causes the script to exit mid-way (e.g., on a failed push), the temp directory from any prior call is never cleaned up. Declaring it local also makes the function self-contained and safe to call in any order.

Suggested change
push_file() {
repo="$1"; src="$2"; dest="$3"
tmp="$(mktemp -d)"
git clone --depth 1 "https://x-access-token:${TAP_TOKEN}@github.com/${repo}.git" "$tmp"
mkdir -p "$(dirname "$tmp/$dest")"
cp "$src" "$tmp/$dest"
git -C "$tmp" add "$dest"
if git -C "$tmp" commit -m "pdcli $VERSION"; then
git -C "$tmp" push
echo "pushed $repo/$dest"
else
echo "no change for $repo/$dest"
fi
}
push_file() {
local repo="$1" src="$2" dest="$3"
local tmp
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' RETURN
git clone --depth 1 "https://x-access-token:${TAP_TOKEN}@github.com/${repo}.git" "$tmp"
mkdir -p "$(dirname "$tmp/$dest")"
cp "$src" "$tmp/$dest"
git -C "$tmp" add "$dest"
if git -C "$tmp" commit -m "pdcli $VERSION"; then
git -C "$tmp" push
echo "pushed $repo/$dest"
else
echo "no change for $repo/$dest"
fi
}

Fix in Claude Code


push_file wavyx/homebrew-tap packaging/homebrew/pdcli.rb Formula/pdcli.rb
push_file wavyx/scoop-pdcli packaging/scoop/pdcli.json bucket/pdcli.json
Loading