Skip to content
Open
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
111 changes: 111 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,114 @@ jobs:
run: |
echo "Published: ${{ steps.changesets.outputs.published }}"
echo "Published packages: ${{ steps.changesets.outputs.publishedPackages }}"

outputs:
published: ${{ steps.changesets.outputs.published }}
publishedPackages: ${{ steps.changesets.outputs.publishedPackages }}

# Opens a PR against inthhq/homebrew-tap whenever a new readie version is
# published to npm. Requires repository secret TAP_GITHUB_TOKEN: a
# fine-grained personal access token scoped to inthhq/homebrew-tap with
# Contents: write and Pull requests: write.
bump-homebrew-tap:
name: Bump Homebrew tap
needs: release
if: |
needs.release.outputs.published == 'true' &&
github.repository == 'inthhq/readie'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Extract published readie version
id: version
env:
PUBLISHED: ${{ needs.release.outputs.publishedPackages }}
run: |
set -euo pipefail
VERSION="$(node -e '
const pkgs = JSON.parse(process.env.PUBLISHED || "[]");
const hit = pkgs.find(p => p.name === "readie");
if (!hit) { process.exit(0); }
process.stdout.write(hit.version);
')"
if [ -z "$VERSION" ]; then
echo "readie not in publishedPackages; nothing to bump."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Wait for npm tarball to be served and compute sha256
id: sha
if: steps.version.outputs.skip != 'true'
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
URL="https://registry.npmjs.org/readie/-/readie-${VERSION}.tgz"
for i in 1 2 3 4 5 6 7 8 9 10; do
if curl -fSL --connect-timeout 10 --max-time 60 "$URL" -o readie.tgz; then
break
fi
echo "Attempt $i: tarball not ready yet, sleeping..."
sleep $((i * 6))
done
test -s readie.tgz
SHA="$(shasum -a 256 readie.tgz | awk '{print $1}')"
echo "sha256=$SHA" >> "$GITHUB_OUTPUT"
echo "url=$URL" >> "$GITHUB_OUTPUT"

- name: Check out homebrew-tap
if: steps.version.outputs.skip != 'true'
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
repository: inthhq/homebrew-tap
token: ${{ secrets.TAP_GITHUB_TOKEN }}
path: homebrew-tap

- name: Update formula
if: steps.version.outputs.skip != 'true'
env:
VERSION: ${{ steps.version.outputs.version }}
URL: ${{ steps.sha.outputs.url }}
SHA: ${{ steps.sha.outputs.sha256 }}
run: |
set -euo pipefail
cd homebrew-tap
node -e '
const fs = require("node:fs");
const path = "Formula/readie.rb";
const src = fs.readFileSync(path, "utf8");
const next = src
.replace(/^(\s*url\s+).*$/m, `$1"${process.env.URL}"`)
.replace(/^(\s*sha256\s+).*$/m, `$1"${process.env.SHA}"`);
Comment on lines +140 to +141

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Scope the checksum replacement to the source stanza (not first sha256).

On Line 141, ^(\s*sha256\s+).*$/m mutates the first sha256 in the file. If the formula later includes bottle checksums earlier, this can update the wrong field and produce a broken bump PR.

Suggested fix
-            const next = src
-              .replace(/^(\s*url\s+).*$/m, `$1"${process.env.URL}"`)
-              .replace(/^(\s*sha256\s+).*$/m, `$1"${process.env.SHA}"`);
+            const next = src.replace(
+              /(^\s*url\s+)"[^"]+"(\n\s*sha256\s+)"[^"]+"/m,
+              `$1"${process.env.URL}"$2"${process.env.SHA}"`
+            );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 140 - 141, The current .replace
chain uses .replace(/^(\s*sha256\s+).*$/m, ...) which can modify the first
sha256 anywhere in the file; change the second replace so it only targets the
sha256 inside the formula's source stanza instead of the first sha256 in the
file. Concretely, modify the .replace call that currently matches
/^(\s*sha256\s+).*$/m (the second replace in the chain that follows
.replace(/^(\s*url\s+).*$/m,...)) to first locate the "source" block and then
replace the sha256 only within that block (e.g., match the source stanza and
replace the sha256 line inside it), ensuring bottle checksums earlier in the
file are not touched.

if (next === src) {
console.error("Formula did not change; refusing to commit.");
process.exit(1);
}
fs.writeFileSync(path, next);
'
git diff -- Formula/readie.rb

- name: Create pull request
if: steps.version.outputs.skip != 'true'
uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11
with:
path: homebrew-tap
token: ${{ secrets.TAP_GITHUB_TOKEN }}
branch: bump-readie-${{ steps.version.outputs.version }}
base: main
commit-message: "readie ${{ steps.version.outputs.version }}"
title: "readie ${{ steps.version.outputs.version }}"
body: |
Bump `readie` to `${{ steps.version.outputs.version }}`.

- tarball: ${{ steps.sha.outputs.url }}
- sha256: `${{ steps.sha.outputs.sha256 }}`

Auto-generated by [inthhq/readie](https://github.com/inthhq/readie) release pipeline. Tap CI will run `brew audit --strict --online` and `brew test readie` against this change before it can be merged.
delete-branch: true
labels: |
automated
release
Loading