|
7 | 7 |
|
8 | 8 | permissions: |
9 | 9 | contents: write |
| 10 | + pull-requests: write |
10 | 11 |
|
11 | 12 | jobs: |
12 | 13 | release: |
@@ -84,6 +85,136 @@ jobs: |
84 | 85 |
|
85 | 86 | (cd dist && sha256sum * > checksums.txt) |
86 | 87 |
|
| 88 | + - name: Update Homebrew formulas in tap |
| 89 | + if: ${{ !contains(github.ref_name, '-') }} |
| 90 | + env: |
| 91 | + VERSION: ${{ github.ref_name }} |
| 92 | + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} |
| 93 | + REPO: ${{ github.repository }} |
| 94 | + GH_TOKEN: ${{ github.token }} |
| 95 | + run: | |
| 96 | + set -euo pipefail |
| 97 | +
|
| 98 | + git fetch origin "$DEFAULT_BRANCH" |
| 99 | + git checkout "$DEFAULT_BRANCH" |
| 100 | + git pull --ff-only origin "$DEFAULT_BRANCH" |
| 101 | +
|
| 102 | + version_no_v="${VERSION#v}" |
| 103 | + major_minor="$(echo "$version_no_v" | awk -F. '{print $1 "." $2}')" |
| 104 | + formula_version_class="PrtAT$(echo "$major_minor" | tr -d '.')" |
| 105 | + tarball_url="https://github.com/${REPO}/archive/refs/tags/${VERSION}.tar.gz" |
| 106 | + sha256="$(curl -fsSL "$tarball_url" | sha256sum | awk '{print $1}')" |
| 107 | +
|
| 108 | + # Guard against rare class-name collisions (e.g. 1.10 vs 11.0). |
| 109 | + for existing in Formula/prt@*.rb; do |
| 110 | + [ -e "$existing" ] || continue |
| 111 | + if [ "$existing" = "Formula/prt@${major_minor}.rb" ]; then |
| 112 | + continue |
| 113 | + fi |
| 114 | + if grep -q "^class ${formula_version_class} < Formula$" "$existing"; then |
| 115 | + echo "Formula class collision detected for ${formula_version_class} in ${existing}" |
| 116 | + echo "Refusing to auto-generate Formula/prt@${major_minor}.rb" |
| 117 | + exit 1 |
| 118 | + fi |
| 119 | + done |
| 120 | +
|
| 121 | + cat > Formula/prt.rb <<EOF |
| 122 | + class Prt < Formula |
| 123 | + desc "Open GitHub pull requests in isolated git worktrees" |
| 124 | + homepage "https://github.com/BradyPlanden/prt" |
| 125 | + url "${tarball_url}" |
| 126 | + sha256 "${sha256}" |
| 127 | + license "MIT" |
| 128 | +
|
| 129 | + depends_on "go" => :build |
| 130 | +
|
| 131 | + def install |
| 132 | + ldflags = %W[ |
| 133 | + -s |
| 134 | + -w |
| 135 | + -X |
| 136 | + main.version=v#{version} |
| 137 | + ] |
| 138 | +
|
| 139 | + system "go", "build", *std_go_args(ldflags: ldflags), "./cmd/prt" |
| 140 | + end |
| 141 | +
|
| 142 | + test do |
| 143 | + assert_match "Open a GitHub PR", shell_output("#{bin}/prt --help") |
| 144 | + end |
| 145 | + end |
| 146 | + EOF |
| 147 | +
|
| 148 | + cat > "Formula/prt@${major_minor}.rb" <<EOF |
| 149 | + class ${formula_version_class} < Formula |
| 150 | + desc "Open GitHub pull requests in isolated git worktrees" |
| 151 | + homepage "https://github.com/BradyPlanden/prt" |
| 152 | + url "${tarball_url}" |
| 153 | + sha256 "${sha256}" |
| 154 | + license "MIT" |
| 155 | +
|
| 156 | + keg_only :versioned_formula |
| 157 | +
|
| 158 | + depends_on "go" => :build |
| 159 | +
|
| 160 | + def install |
| 161 | + ldflags = %W[ |
| 162 | + -s |
| 163 | + -w |
| 164 | + -X |
| 165 | + main.version=v#{version} |
| 166 | + ] |
| 167 | +
|
| 168 | + system "go", "build", *std_go_args(ldflags: ldflags), "./cmd/prt" |
| 169 | + end |
| 170 | +
|
| 171 | + test do |
| 172 | + assert_match "Open a GitHub PR", shell_output("#{bin}/prt --help") |
| 173 | + end |
| 174 | + end |
| 175 | + EOF |
| 176 | +
|
| 177 | + if git diff --quiet -- Formula/prt.rb "Formula/prt@${major_minor}.rb"; then |
| 178 | + echo "Homebrew formulas already up to date." |
| 179 | + exit 0 |
| 180 | + fi |
| 181 | + |
| 182 | + git config user.name "github-actions[bot]" |
| 183 | + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" |
| 184 | + git add Formula/prt.rb "Formula/prt@${major_minor}.rb" |
| 185 | + git commit -m "chore(brew): update formulas for ${VERSION}" |
| 186 | +
|
| 187 | + # Prefer direct updates so the tap is ready immediately. |
| 188 | + if git push origin "HEAD:${DEFAULT_BRANCH}"; then |
| 189 | + echo "Pushed formula updates directly to ${DEFAULT_BRANCH}." |
| 190 | + exit 0 |
| 191 | + fi |
| 192 | +
|
| 193 | + # Fallback for protected branches: push to a branch and open a PR. |
| 194 | + safe_version="${VERSION//[^A-Za-z0-9._-]/-}" |
| 195 | + fallback_branch="chore/brew-update-${safe_version}-${GITHUB_RUN_ID}" |
| 196 | + git push --force-with-lease origin "HEAD:${fallback_branch}" |
| 197 | +
|
| 198 | + existing_pr_number="$(gh pr list \ |
| 199 | + --repo "$REPO" \ |
| 200 | + --base "$DEFAULT_BRANCH" \ |
| 201 | + --head "$fallback_branch" \ |
| 202 | + --state open \ |
| 203 | + --json number \ |
| 204 | + --jq '.[0].number // empty')" |
| 205 | +
|
| 206 | + if [ -n "$existing_pr_number" ]; then |
| 207 | + echo "PR #${existing_pr_number} already open for Homebrew formula updates." |
| 208 | + exit 0 |
| 209 | + fi |
| 210 | +
|
| 211 | + gh pr create \ |
| 212 | + --repo "$REPO" \ |
| 213 | + --base "$DEFAULT_BRANCH" \ |
| 214 | + --head "$fallback_branch" \ |
| 215 | + --title "chore(brew): update formulas for ${VERSION}" \ |
| 216 | + --body "Automated Homebrew formula updates for \`${VERSION}\`." |
| 217 | +
|
87 | 218 | - name: Publish GitHub release |
88 | 219 | uses: softprops/action-gh-release@v2 |
89 | 220 | with: |
|
0 commit comments