Skip to content

Commit da82463

Browse files
authored
Merge branch 'master' into convergenceExample
2 parents f1c26f9 + a36a225 commit da82463

File tree

9 files changed

+759
-1
lines changed

9 files changed

+759
-1
lines changed

.github/workflows/deploy-tap.yml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
name: Deploy Homebrew Tap
2+
3+
on:
4+
push:
5+
branches: [ main, master, homebrew-formula ]
6+
paths:
7+
- 'packaging/homebrew/mfc.rb'
8+
- 'packaging/homebrew/README.md'
9+
tags:
10+
- 'v*.*.*'
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
16+
jobs:
17+
deploy-tap:
18+
name: Sync/bump formula in tap
19+
runs-on: macos-14
20+
permissions:
21+
contents: write
22+
pull-requests: write
23+
steps:
24+
- name: Checkout MFC repository
25+
uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Determine event metadata
30+
id: meta
31+
run: |
32+
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
33+
VERSION="${GITHUB_REF_NAME#v}"
34+
URL="https://github.com/${{ github.repository }}/archive/refs/tags/v${VERSION}.tar.gz"
35+
else
36+
# Extract URL from current formula to re-audit and sync
37+
URL="$(grep -Eo 'https://github.com/.*/archive/refs/tags/v[0-9]+\.[0-9]+\.[0-9]+\.tar\.gz' packaging/homebrew/mfc.rb | head -n1)"
38+
VERSION="$(echo "${URL}" | sed -E 's/.*v([0-9]+\.[0-9]+\.[0-9]+)\.tar\.gz/\1/')"
39+
fi
40+
SHASUM="$(curl -sL "${URL}" | shasum -a 256 | awk '{print $1}')"
41+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
42+
echo "url=${URL}" >> $GITHUB_OUTPUT
43+
echo "sha256=${SHASUM}" >> $GITHUB_OUTPUT
44+
45+
- name: Update formula (for tag events)
46+
if: github.ref_type == 'tag'
47+
run: |
48+
/usr/bin/sed -i '' "s@^ url \".*\"@ url \"${{ steps.meta.outputs.url }}\"@" packaging/homebrew/mfc.rb
49+
/usr/bin/sed -i '' "s@^ sha256 \".*\"@ sha256 \"${{ steps.meta.outputs.sha256 }}\"@" packaging/homebrew/mfc.rb
50+
51+
- name: Setup Homebrew
52+
uses: Homebrew/actions/setup-homebrew@master
53+
54+
- name: Audit/style formula before pushing
55+
run: |
56+
brew style packaging/homebrew/mfc.rb
57+
# Create temporary tap to audit the formula
58+
brew tap-new mfc/local
59+
cp packaging/homebrew/mfc.rb "$(brew --repository)/Library/Taps/mfc/homebrew-local/Formula/mfc.rb"
60+
brew audit --online --strict --new --except=homepage mfc/local/mfc || brew audit --online mfc/local/mfc
61+
brew untap mfc/local
62+
63+
- name: Clone or bootstrap tap repository
64+
env:
65+
TAP_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}
66+
run: |
67+
set -euo pipefail
68+
REPO="https://x-access-token:${TAP_TOKEN}@github.com/MFlowCode/homebrew-mfc.git"
69+
if git ls-remote "${REPO}" HEAD >/dev/null 2>&1; then
70+
git clone "${REPO}" tap-repo
71+
else
72+
# Repo exists but might be empty; fall back to bootstrap
73+
mkdir -p tap-repo
74+
cd tap-repo
75+
git init -b main
76+
git remote add origin "${REPO}"
77+
touch .keep
78+
git add .keep
79+
git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" commit -m "Initialize tap"
80+
git push -u origin main
81+
fi
82+
83+
- name: Copy formula and README into tap
84+
run: |
85+
mkdir -p tap-repo/Formula
86+
cp packaging/homebrew/mfc.rb tap-repo/Formula/mfc.rb
87+
cp packaging/homebrew/README.md tap-repo/README.md
88+
89+
- name: Commit & push if changed
90+
env:
91+
TAP_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}
92+
run: |
93+
cd tap-repo
94+
git add Formula/mfc.rb README.md
95+
if git diff --cached --quiet; then
96+
echo "No changes in Formula/mfc.rb or README.md; skipping push."
97+
exit 0
98+
fi
99+
git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" \
100+
commit -m "mfc: v${{ steps.meta.outputs.version }}"
101+
git push origin HEAD:main
102+

.github/workflows/homebrew.yml

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
name: Homebrew Formula Test
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- homebrew-formula
8+
paths:
9+
- 'packaging/homebrew/**'
10+
- '.github/workflows/homebrew.yml'
11+
pull_request:
12+
branches:
13+
- master
14+
paths:
15+
- 'packaging/homebrew/**'
16+
- '.github/workflows/homebrew.yml'
17+
workflow_dispatch:
18+
19+
jobs:
20+
# Fast smoke tests that run before expensive operations
21+
smoke-test:
22+
name: Quick Formula Validation
23+
runs-on: ubuntu-latest # Use Linux for speed (Homebrew works on Linux too)
24+
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
29+
- name: Set up Homebrew
30+
uses: Homebrew/actions/setup-homebrew@master
31+
32+
- name: Validate formula syntax with brew style
33+
run: |
34+
echo "Checking formula syntax..."
35+
brew style packaging/homebrew/mfc.rb
36+
37+
- name: Run brew audit (without installation)
38+
run: |
39+
echo "Configuring git for brew tap-new..."
40+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
41+
git config --global user.name "github-actions[bot]"
42+
43+
echo "Creating temporary local tap..."
44+
brew tap-new mflowcode/test
45+
cp packaging/homebrew/mfc.rb $(brew --repository)/Library/Taps/mflowcode/homebrew-test/Formula/mfc.rb
46+
47+
echo "Running brew audit (online checks)..."
48+
brew audit --online --skip-style mflowcode/test/mfc || true
49+
50+
echo "Cleaning up tap..."
51+
brew untap mflowcode/test
52+
53+
- name: Validate Ruby syntax
54+
run: |
55+
echo "Checking Ruby syntax..."
56+
ruby -c packaging/homebrew/mfc.rb
57+
58+
- name: Check for common formula issues
59+
run: |
60+
echo "Checking for common issues..."
61+
62+
# Check that required fields are present
63+
grep -q 'desc "' packaging/homebrew/mfc.rb || (echo "❌ Missing desc"; exit 1)
64+
grep -q 'homepage "' packaging/homebrew/mfc.rb || (echo "❌ Missing homepage"; exit 1)
65+
grep -q 'url "' packaging/homebrew/mfc.rb || (echo "❌ Missing url"; exit 1)
66+
grep -q 'sha256 "' packaging/homebrew/mfc.rb || (echo "❌ Missing sha256"; exit 1)
67+
grep -q 'license "' packaging/homebrew/mfc.rb || (echo "❌ Missing license"; exit 1)
68+
69+
# Check that install method exists
70+
grep -q 'def install' packaging/homebrew/mfc.rb || (echo "❌ Missing install method"; exit 1)
71+
72+
# Check that test block exists
73+
grep -q 'test do' packaging/homebrew/mfc.rb || (echo "❌ Missing test block"; exit 1)
74+
75+
echo "✅ All required formula components present"
76+
77+
- name: Verify URL is reachable
78+
run: |
79+
echo "Checking that source URL is reachable..."
80+
URL=$(grep -E 'url "https://[^"]+' packaging/homebrew/mfc.rb | head -1 | sed 's/.*url "\([^"]*\)".*/\1/')
81+
82+
if [ -z "$URL" ]; then
83+
echo "❌ Could not extract URL from formula"
84+
exit 1
85+
fi
86+
87+
echo "URL: $URL"
88+
HTTP_CODE=$(curl -sI -w "%{http_code}" -o /dev/null "$URL")
89+
90+
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ]; then
91+
echo "✅ URL is reachable (HTTP $HTTP_CODE)"
92+
else
93+
echo "⚠️ URL returned HTTP $HTTP_CODE (may indicate an issue)"
94+
# Don't fail here - could be a temporary issue
95+
fi
96+
97+
- name: Verify SHA256 checksum
98+
run: |
99+
echo "Verifying SHA256 checksum matches URL..."
100+
URL=$(grep -E 'url "https://[^"]+' packaging/homebrew/mfc.rb | head -1 | sed 's/.*url "\([^"]*\)".*/\1/')
101+
EXPECTED_SHA=$(grep 'sha256 "' packaging/homebrew/mfc.rb | head -1 | sed 's/.*sha256 "\([^"]*\)".*/\1/')
102+
103+
if [ -z "$URL" ] || [ -z "$EXPECTED_SHA" ]; then
104+
echo "❌ Could not extract URL or SHA256 from formula"
105+
exit 1
106+
fi
107+
108+
echo "Downloading tarball to compute checksum..."
109+
ACTUAL_SHA=$(curl -sL "$URL" | shasum -a 256 | awk '{print $1}')
110+
111+
echo "Expected SHA256: $EXPECTED_SHA"
112+
echo "Actual SHA256: $ACTUAL_SHA"
113+
114+
if [ "$EXPECTED_SHA" = "$ACTUAL_SHA" ]; then
115+
echo "✅ SHA256 checksum matches!"
116+
else
117+
echo "❌ SHA256 mismatch!"
118+
exit 1
119+
fi
120+
121+
# Full installation test (only runs if smoke tests pass)
122+
test-formula:
123+
name: Full Installation Test
124+
needs: smoke-test # Only run after smoke tests pass
125+
runs-on: macos-latest
126+
127+
steps:
128+
- name: Checkout repository
129+
uses: actions/checkout@v4
130+
131+
- name: Set up Homebrew
132+
run: |
133+
echo "Homebrew version:"
134+
brew --version
135+
echo "Updating Homebrew..."
136+
brew update
137+
138+
- name: Install formula dependencies
139+
run: |
140+
echo "Installing MFC dependencies..."
141+
brew install cmake gcc [email protected] boost fftw hdf5 open-mpi openblas
142+
143+
- name: Install MFC from formula
144+
run: |
145+
echo "Creating temporary local tap..."
146+
brew tap-new mflowcode/test
147+
148+
echo "Copying formula to tap..."
149+
cp packaging/homebrew/mfc.rb $(brew --repository)/Library/Taps/mflowcode/homebrew-test/Formula/mfc.rb
150+
151+
echo "Installing MFC from local tap..."
152+
# Note: brew may exit with code 1 due to dylib fixup warnings on some Python packages (non-fatal)
153+
# We verify installation using brew commands rather than parsing log output
154+
set +e # Don't fail immediately on error
155+
brew install --build-from-source --verbose mflowcode/test/mfc 2>&1 | tee /tmp/brew-install.log
156+
brew_exit_code=$?
157+
set -e
158+
159+
# Verify installation using brew list (more robust than log parsing)
160+
if brew list mflowcode/test/mfc &>/dev/null; then
161+
echo "✅ MFC installed successfully (ignoring dylib relocation warnings)"
162+
# Optionally verify with brew info
163+
brew info mflowcode/test/mfc
164+
exit 0
165+
else
166+
echo "❌ MFC installation failed"
167+
exit $brew_exit_code
168+
fi
169+
170+
- name: Display error logs on failure
171+
if: failure()
172+
run: |
173+
echo "=== Displaying last 200 lines of brew install log ==="
174+
if [ -f /tmp/brew-install.log ]; then
175+
tail -200 /tmp/brew-install.log
176+
fi
177+
178+
echo -e "\n=== Displaying Homebrew log files ==="
179+
if [ -d ~/Library/Logs/Homebrew/mfc/ ]; then
180+
for logfile in ~/Library/Logs/Homebrew/mfc/*; do
181+
if [ -f "$logfile" ]; then
182+
echo -e "\n\n====== $logfile ======"
183+
cat "$logfile"
184+
fi
185+
done
186+
fi
187+
188+
echo -e "\n=== Searching for Cantera config.log ==="
189+
cantera_config_log=$(find /private/tmp -name "config.log" -path "*/mfc--cantera*" 2>/dev/null | head -1)
190+
if [ -n "$cantera_config_log" ] && [ -f "$cantera_config_log" ]; then
191+
echo -e "\n\n====== Cantera config.log ======"
192+
echo "Found at: $cantera_config_log"
193+
cat "$cantera_config_log"
194+
# Copy to a known location for artifact upload
195+
mkdir -p /tmp/cantera-logs
196+
cp "$cantera_config_log" /tmp/cantera-logs/config.log
197+
else
198+
echo "Cantera config.log not found"
199+
echo "Searching in all /private/tmp directories:"
200+
find /private/tmp -name "config.log" 2>/dev/null || echo "No config.log files found"
201+
fi
202+
203+
- name: Upload Homebrew logs on failure
204+
if: failure()
205+
uses: actions/upload-artifact@v4
206+
with:
207+
name: homebrew-logs
208+
path: |
209+
/tmp/brew-install.log
210+
/tmp/cantera-logs/
211+
~/Library/Logs/Homebrew/mfc/
212+
if-no-files-found: ignore
213+
214+
- name: Test MFC installation
215+
run: |
216+
echo "=== Testing MFC Installation ==="
217+
218+
echo "1. Checking binaries exist and are executable..."
219+
test -f $(brew --prefix)/bin/mfc && test -x $(brew --prefix)/bin/mfc
220+
test -f $(brew --prefix)/bin/pre_process && test -x $(brew --prefix)/bin/pre_process
221+
test -f $(brew --prefix)/bin/simulation && test -x $(brew --prefix)/bin/simulation
222+
test -f $(brew --prefix)/bin/post_process && test -x $(brew --prefix)/bin/post_process
223+
echo " ✓ All binaries exist and are executable"
224+
225+
echo "2. Verifying installation structure..."
226+
test -f $(brew --prefix mfc)/libexec/mfc.sh
227+
test -d $(brew --prefix mfc)/toolchain
228+
echo " ✓ Installation structure verified"
229+
230+
echo "3. Checking Python venv..."
231+
test -d $(brew --prefix mfc)/libexec/venv
232+
test -f $(brew --prefix mfc)/libexec/venv/bin/python
233+
test -f $(brew --prefix mfc)/libexec/venv/bin/pip
234+
echo " ✓ Python venv exists"
235+
236+
echo "4. Checking examples..."
237+
test -d $(brew --prefix mfc)/examples
238+
test -f $(brew --prefix mfc)/examples/1D_sodshocktube/case.py
239+
echo " ✓ Examples installed"
240+
241+
echo "5. Testing mfc wrapper..."
242+
mfc --help
243+
echo " ✓ mfc --help succeeded"
244+
245+
echo "=== All tests passed! ==="
246+
247+
- name: Run MFC test case
248+
run: |
249+
echo "Running a simple test case (1D Sod shock tube)..."
250+
TESTDIR=$(mktemp -d)
251+
cp $(brew --prefix mfc)/examples/1D_sodshocktube/case.py "$TESTDIR/"
252+
253+
echo "Running with $(sysctl -n hw.ncpu) processors..."
254+
# Use absolute path since mfc wrapper creates its own tmpdir
255+
mfc run "$TESTDIR/case.py" -j $(sysctl -n hw.ncpu)
256+
257+
echo "Test case completed successfully!"
258+
259+
- name: Uninstall and cleanup
260+
if: always()
261+
run: |
262+
echo "Cleaning up..."
263+
brew uninstall mfc || true
264+
brew cleanup

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ benchmarks/*.png
8686
*.mov
8787
*.mkv
8888
*.avi
89+
90+
packaging/spack/spack-test
91+
.spack

.typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Strang = "Strang"
2020
TKE = "TKE"
2121
HSA = "HSA"
2222
infp = "infp"
23+
Sur = "Sur"
2324

2425
[files]
2526
extend-exclude = ["docs/documentation/references*", "tests/", "toolchain/cce_simulation_workgroup_256.sh"]

0 commit comments

Comments
 (0)