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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ Then release with a single command:
make release VERSION=0.28.0
```

This will: bump the version, archive, export, notarize, staple, generate the appcast, create a branch/commit/tag, open a PR with auto-merge, and create a GitHub release with the zip attached.
This will: bump the version, archive, export, notarize, staple, generate the appcast, create a branch/commit/tag, open a PR with auto-merge, create a GitHub release with the zip attached, and update the Homebrew cask automatically.

If `GH_PAT` is available in the environment, the release script will use it to push the Homebrew tap update to `pablopunk/homebrew-brew`.

## Star History

Expand Down
31 changes: 31 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,38 @@ else
--generate-notes
fi

# --- 11. Update Homebrew cask ---
echo "🍺 Updating Homebrew cask..."
ZIP_SHA=$(shasum -a 256 "$ZIP_PATH" | awk '{print $1}')
TAP_REPO="pablopunk/homebrew-brew"
TAP_CLONE_DIR="$(mktemp -d /tmp/swiftshift-homebrew.XXXXXX)"
TAP_CASK_PATH="$TAP_CLONE_DIR/Casks/swift-shift.rb"
GIT_REMOTE="https://github.com/$TAP_REPO.git"

if [[ -n "${GH_PAT:-}" ]]; then
GIT_REMOTE="https://x-access-token:${GH_PAT}@github.com/$TAP_REPO.git"
fi
Comment on lines +125 to +131
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

Avoid credential-in-URL cloning and guarantee cleanup on failure.

At Line 130, GH_PAT is embedded in the remote URL. That token can end up in .git/config inside the temp clone, and because cleanup only happens at Line 149, any earlier failure can leave credentials on disk in /tmp.

Please switch to a non-URL credential flow and register cleanup with an EXIT handler that also preserves the existing cleanup behavior.

Also applies to: 149-149

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/release.sh` around lines 125 - 131, Do not embed GH_PAT in
GIT_REMOTE; instead perform clones with credentials supplied via a git
configuration extra header or credential helper (e.g. use git -c
http.extraHeader="Authorization: Bearer $GH_PAT" when invoking git) so the token
is not written into the repo config, and keep the unauthenticated GIT_REMOTE
value as the public HTTPS URL; also register your cleanup function to run on
script exit (trap 'cleanup' EXIT) so TAP_CLONE_DIR is removed on any failure,
preserving the existing cleanup logic in cleanup().


git clone "$GIT_REMOTE" "$TAP_CLONE_DIR"
sed -i '' "s/version \".*\"/version \"$VERSION\"/" "$TAP_CASK_PATH"
sed -i '' "s/sha256 \".*\"/sha256 \"$ZIP_SHA\"/" "$TAP_CASK_PATH"
ruby -c "$TAP_CASK_PATH"
Comment on lines +134 to +136
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

Fail fast when cask replacements don’t apply.

If either sed replacement misses (format drift in swift-shift.rb), Line 141 can incorrectly report “already up to date.” Add explicit post-edit assertions for version and sha256 values before diff/commit logic.

✅ Suggested hardening
 sed -i '' "s/version \".*\"/version \"$VERSION\"/" "$TAP_CASK_PATH"
 sed -i '' "s/sha256 \".*\"/sha256 \"$ZIP_SHA\"/" "$TAP_CASK_PATH"
 ruby -c "$TAP_CASK_PATH"
+
+if ! grep -q "version \"$VERSION\"" "$TAP_CASK_PATH"; then
+    echo "Failed to update cask version to $VERSION"
+    exit 1
+fi
+if ! grep -q "sha256 \"$ZIP_SHA\"" "$TAP_CASK_PATH"; then
+    echo "Failed to update cask sha256 to $ZIP_SHA"
+    exit 1
+fi

Also applies to: 141-147

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/release.sh` around lines 134 - 136, After running the two sed
replacements that target TAP_CASK_PATH, immediately verify the edits actually
applied by checking that the file contains version "$VERSION" and sha256
"$ZIP_SHA"; if either check fails, print a clear error mentioning which
replacement missed and exit non‑zero to fail fast (keep the subsequent ruby -c
validation). Use the existing variables TAP_CASK_PATH, VERSION and ZIP_SHA to
perform the checks so the script aborts before any diff/commit logic when format
drift prevents replacements from matching.


pushd "$TAP_CLONE_DIR" > /dev/null
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if ! git diff --quiet -- Casks/swift-shift.rb; then
git add Casks/swift-shift.rb
git commit -m "swift-shift: update to $VERSION"
git push
else
echo "Homebrew cask already up to date."
fi
popd > /dev/null
rm -rf "$TAP_CLONE_DIR"

echo ""
echo "✅ Release $VERSION complete!"
echo " PR: $PR_URL"
echo " Release: https://github.com/pablopunk/SwiftShift/releases/tag/$VERSION"
echo " Homebrew: https://github.com/$TAP_REPO/blob/main/Casks/swift-shift.rb"
Loading