Skip to content

Commit b70292f

Browse files
sbryngelsonclaude
andauthored
Fix Homebrew CI and add automated release workflow (MFlowCode#1120)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a6d3f37 commit b70292f

3 files changed

Lines changed: 212 additions & 19 deletions

File tree

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
name: Update Homebrew Formula on Release
2+
3+
# Triggers when a new version tag is pushed
4+
on:
5+
push:
6+
tags:
7+
- 'v*'
8+
pull_request:
9+
branches: [master]
10+
paths:
11+
- '.github/workflows/homebrew-release.yml'
12+
workflow_dispatch:
13+
inputs:
14+
version:
15+
description: 'Version to release (without v prefix, e.g., 5.2.0)'
16+
required: true
17+
type: string
18+
dry_run:
19+
description: 'Dry run (skip push to homebrew-mfc)'
20+
required: false
21+
type: boolean
22+
default: false
23+
24+
jobs:
25+
update-homebrew-tap:
26+
name: Update homebrew-mfc tap
27+
runs-on: ubuntu-latest
28+
29+
steps:
30+
- name: Determine version
31+
id: version
32+
run: |
33+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
34+
VERSION="${{ inputs.version }}"
35+
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
36+
# Use existing version for PR testing
37+
VERSION="5.2.0"
38+
echo "::notice::PR test mode - using version $VERSION"
39+
else
40+
# Extract version from tag (remove 'v' prefix)
41+
VERSION="${GITHUB_REF#refs/tags/v}"
42+
fi
43+
44+
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
45+
echo "::error::Invalid version format: $VERSION (expected X.Y.Z)"
46+
exit 1
47+
fi
48+
49+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
50+
echo "Version: $VERSION"
51+
52+
- name: Compute SHA256 of release tarball
53+
id: sha256
54+
run: |
55+
VERSION="${{ steps.version.outputs.version }}"
56+
URL="https://github.com/MFlowCode/MFC/archive/refs/tags/v${VERSION}.tar.gz"
57+
58+
echo "Downloading tarball from: $URL"
59+
60+
# Verify URL is reachable
61+
HTTP_CODE=$(curl -sI -w "%{http_code}" -o /dev/null "$URL")
62+
if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "302" ]]; then
63+
echo "::error::Release tarball not found at $URL (HTTP $HTTP_CODE)"
64+
echo "::error::Make sure the tag v${VERSION} exists and the release is published"
65+
exit 1
66+
fi
67+
68+
# Compute SHA256
69+
SHA256=$(curl -sL "$URL" | sha256sum | awk '{print $1}')
70+
71+
if [[ -z "$SHA256" || "$SHA256" == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ]]; then
72+
echo "::error::Failed to compute SHA256 (empty file or download failed)"
73+
exit 1
74+
fi
75+
76+
echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
77+
echo "SHA256: $SHA256"
78+
79+
- name: PR test summary
80+
if: ${{ github.event_name == 'pull_request' }}
81+
run: |
82+
echo "## PR Test Mode" >> $GITHUB_STEP_SUMMARY
83+
echo "" >> $GITHUB_STEP_SUMMARY
84+
echo "Validated:" >> $GITHUB_STEP_SUMMARY
85+
echo "- Version parsing: v${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
86+
echo "- SHA256 computation: \`${{ steps.sha256.outputs.sha256 }}\`" >> $GITHUB_STEP_SUMMARY
87+
echo "" >> $GITHUB_STEP_SUMMARY
88+
echo "Skipped (secrets not available for fork PRs):" >> $GITHUB_STEP_SUMMARY
89+
echo "- Checkout homebrew-mfc" >> $GITHUB_STEP_SUMMARY
90+
echo "- Update formula" >> $GITHUB_STEP_SUMMARY
91+
echo "- Push to tap" >> $GITHUB_STEP_SUMMARY
92+
echo "" >> $GITHUB_STEP_SUMMARY
93+
echo "The full workflow will run when a \`v*\` tag is pushed after merge." >> $GITHUB_STEP_SUMMARY
94+
95+
- name: Checkout homebrew-mfc tap
96+
if: ${{ github.event_name != 'pull_request' }}
97+
uses: actions/checkout@v4
98+
with:
99+
repository: MFlowCode/homebrew-mfc
100+
token: ${{ secrets.TAP_REPO_TOKEN }}
101+
path: homebrew-mfc
102+
103+
- name: Update formula
104+
if: ${{ github.event_name != 'pull_request' }}
105+
run: |
106+
VERSION="${{ steps.version.outputs.version }}"
107+
SHA256="${{ steps.sha256.outputs.sha256 }}"
108+
FORMULA="homebrew-mfc/Formula/mfc.rb"
109+
110+
echo "Updating formula to v${VERSION}..."
111+
112+
# Update URL
113+
sed -i "s|url \"https://github.com/MFlowCode/MFC/archive/refs/tags/v[^\"]*\.tar\.gz\"|url \"https://github.com/MFlowCode/MFC/archive/refs/tags/v${VERSION}.tar.gz\"|" "$FORMULA"
114+
115+
# Update SHA256 (the one right after url, not bottle SHAs)
116+
# This uses awk to only update the first sha256 after the url line
117+
awk -v newsha="$SHA256" '
118+
/^ url "https:\/\/github.com\/MFlowCode\/MFC/ { found_url=1 }
119+
found_url && /^ sha256 "/ && !updated {
120+
sub(/sha256 "[^"]*"/, "sha256 \"" newsha "\"")
121+
updated=1
122+
}
123+
{ print }
124+
' "$FORMULA" > "$FORMULA.tmp" && mv "$FORMULA.tmp" "$FORMULA"
125+
126+
# Remove existing bottle block (new bottles will be built by bottle.yml)
127+
# This removes everything between "bottle do" and the matching "end"
128+
awk '
129+
/^ bottle do/ { in_bottle=1; next }
130+
in_bottle && /^ end/ { in_bottle=0; next }
131+
!in_bottle { print }
132+
' "$FORMULA" > "$FORMULA.tmp" && mv "$FORMULA.tmp" "$FORMULA"
133+
134+
echo "Updated formula:"
135+
head -30 "$FORMULA"
136+
137+
- name: Validate updated formula
138+
if: ${{ github.event_name != 'pull_request' }}
139+
run: |
140+
cd homebrew-mfc
141+
echo "Checking Ruby syntax..."
142+
ruby -c Formula/mfc.rb
143+
144+
echo "Verifying URL and SHA256 were updated..."
145+
grep -q "v${{ steps.version.outputs.version }}.tar.gz" Formula/mfc.rb || (echo "::error::URL not updated"; exit 1)
146+
grep -q "${{ steps.sha256.outputs.sha256 }}" Formula/mfc.rb || (echo "::error::SHA256 not updated"; exit 1)
147+
148+
echo "Formula validation passed!"
149+
150+
- name: Commit and push to homebrew-mfc
151+
if: ${{ github.event_name != 'pull_request' && github.event.inputs.dry_run != 'true' }}
152+
run: |
153+
cd homebrew-mfc
154+
VERSION="${{ steps.version.outputs.version }}"
155+
156+
git config user.name "github-actions[bot]"
157+
git config user.email "github-actions[bot]@users.noreply.github.com"
158+
159+
git add Formula/mfc.rb
160+
git commit -m "Update MFC to v${VERSION}"
161+
162+
echo "Pushing to homebrew-mfc..."
163+
git push origin main
164+
165+
echo "Successfully pushed formula update!"
166+
echo "The bottle.yml workflow in homebrew-mfc will now build bottles automatically."
167+
168+
- name: Dry run summary
169+
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' }}
170+
run: |
171+
echo "::notice::DRY RUN - skipped push to homebrew-mfc"
172+
echo ""
173+
echo "Would have committed the following changes:"
174+
cd homebrew-mfc
175+
git diff Formula/mfc.rb
176+
177+
- name: Summary
178+
if: ${{ github.event_name != 'pull_request' }}
179+
run: |
180+
VERSION="${{ steps.version.outputs.version }}"
181+
echo "## Homebrew Formula Updated" >> $GITHUB_STEP_SUMMARY
182+
echo "" >> $GITHUB_STEP_SUMMARY
183+
echo "- **Version:** v${VERSION}" >> $GITHUB_STEP_SUMMARY
184+
echo "- **SHA256:** \`${{ steps.sha256.outputs.sha256 }}\`" >> $GITHUB_STEP_SUMMARY
185+
echo "- **Tap:** [MFlowCode/homebrew-mfc](https://github.com/MFlowCode/homebrew-mfc)" >> $GITHUB_STEP_SUMMARY
186+
echo "" >> $GITHUB_STEP_SUMMARY
187+
echo "The [bottle.yml](https://github.com/MFlowCode/homebrew-mfc/actions/workflows/bottle.yml) workflow will now build bottles for this release." >> $GITHUB_STEP_SUMMARY

.github/workflows/homebrew.yml

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -209,51 +209,57 @@ jobs:
209209
- name: Test MFC installation
210210
run: |
211211
echo "=== Testing MFC Installation ==="
212-
212+
213+
# Use the full tap-qualified name since we installed from mflowcode/test
214+
MFC_PREFIX="$(brew --prefix mflowcode/test/mfc)"
215+
echo "MFC prefix: $MFC_PREFIX"
216+
213217
echo "1. Checking binaries exist and are executable..."
214218
test -f $(brew --prefix)/bin/mfc && test -x $(brew --prefix)/bin/mfc
215219
test -f $(brew --prefix)/bin/pre_process && test -x $(brew --prefix)/bin/pre_process
216220
test -f $(brew --prefix)/bin/simulation && test -x $(brew --prefix)/bin/simulation
217221
test -f $(brew --prefix)/bin/post_process && test -x $(brew --prefix)/bin/post_process
218222
echo " ✓ All binaries exist and are executable"
219-
223+
220224
echo "2. Verifying installation structure..."
221-
test -f $(brew --prefix mfc)/libexec/mfc.sh
222-
test -d $(brew --prefix mfc)/toolchain
225+
test -f "$MFC_PREFIX/libexec/mfc.sh"
226+
test -d "$MFC_PREFIX/toolchain"
223227
echo " ✓ Installation structure verified"
224-
228+
225229
echo "3. Checking Python venv..."
226-
test -d $(brew --prefix mfc)/libexec/venv
227-
test -f $(brew --prefix mfc)/libexec/venv/bin/python
228-
test -f $(brew --prefix mfc)/libexec/venv/bin/pip
230+
test -d "$MFC_PREFIX/libexec/venv"
231+
test -f "$MFC_PREFIX/libexec/venv/bin/python"
232+
test -f "$MFC_PREFIX/libexec/venv/bin/pip"
229233
echo " ✓ Python venv exists"
230-
234+
231235
echo "4. Checking examples..."
232-
test -d $(brew --prefix mfc)/examples
233-
test -f $(brew --prefix mfc)/examples/1D_sodshocktube/case.py
236+
test -d "$MFC_PREFIX/examples"
237+
test -f "$MFC_PREFIX/examples/1D_sodshocktube/case.py"
234238
echo " ✓ Examples installed"
235-
239+
236240
echo "5. Testing mfc wrapper..."
237241
mfc --help
238242
echo " ✓ mfc --help succeeded"
239-
243+
240244
echo "=== All tests passed! ==="
241245
242246
- name: Run MFC test case
243247
run: |
244248
echo "Running a simple test case (1D Sod shock tube)..."
249+
MFC_PREFIX="$(brew --prefix mflowcode/test/mfc)"
245250
TESTDIR=$(mktemp -d)
246-
cp $(brew --prefix mfc)/examples/1D_sodshocktube/case.py "$TESTDIR/"
247-
251+
cp "$MFC_PREFIX/examples/1D_sodshocktube/case.py" "$TESTDIR/"
252+
248253
echo "Running with $(sysctl -n hw.ncpu) processors..."
249254
# Use absolute path and shorthand syntax (mfc auto-detects and prepends 'run')
250255
mfc "$TESTDIR/case.py" -j $(sysctl -n hw.ncpu)
251-
256+
252257
echo "Test case completed successfully!"
253258
254259
- name: Uninstall and cleanup
255260
if: always()
256261
run: |
257262
echo "Cleaning up..."
258-
brew uninstall mfc || true
263+
brew uninstall mflowcode/test/mfc || true
264+
brew untap mflowcode/test || true
259265
brew cleanup

packaging/homebrew/mfc.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
class Mfc < Formula
77
desc "Exascale multiphase/multiphysics compressible flow solver"
88
homepage "https://mflowcode.github.io/"
9-
url "https://github.com/MFlowCode/MFC/archive/refs/tags/v5.1.5.tar.gz"
10-
sha256 "229ba4532d9b31e54e7db67cc6c6a4c069034bb143be7c57cba31c5a56fe6a0b"
9+
url "https://github.com/MFlowCode/MFC/archive/refs/tags/v5.2.0.tar.gz"
10+
sha256 "aaee855302950cb6bd8497170a6737214ed9a47ad3d109258f5b27ee2b78fe3d"
1111
license "MIT"
1212
head "https://github.com/MFlowCode/MFC.git", branch: "master"
1313

0 commit comments

Comments
 (0)