Skip to content

Commit 035af83

Browse files
authored
Update homebrew-update.yml
1 parent af0df79 commit 035af83

1 file changed

Lines changed: 203 additions & 30 deletions

File tree

.github/workflows/homebrew-update.yml

Lines changed: 203 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,83 @@ jobs:
2626
VERSION="${{ github.event.inputs.version }}"
2727
fi
2828
echo "VERSION=$VERSION" >> $GITHUB_ENV
29+
echo "Building Homebrew formula for version: $VERSION"
2930
30-
- name: Get PyPI package info and SHA256
31+
- name: Wait and get PyPI package info with retry
3132
run: |
32-
# Corrected URL to download the source package from PyPI
33-
wget "https://pypi.org/packages/source/o/omnipkg/omnipkg-${{ env.VERSION }}.tar.gz"
33+
# --- RESILIENT RETRY LOGIC FOR PYPI AVAILABILITY ---
34+
max_attempts=15
35+
attempt=1
36+
url="https://pypi.org/packages/source/o/omnipkg/omnipkg-${{ env.VERSION }}.tar.gz"
37+
38+
echo "🔍 Waiting for PyPI package to be available at: $url"
39+
echo "⏳ This may take a few minutes after release publication..."
40+
41+
# Initial wait before first attempt (PyPI needs time to process)
42+
echo "💤 Initial wait of 60 seconds for PyPI processing..."
43+
sleep 60
44+
45+
while [ $attempt -le $max_attempts ]; do
46+
echo "🚀 Attempt $attempt of $max_attempts..."
47+
48+
# Try to download with curl (more reliable than wget)
49+
if curl -L --fail --connect-timeout 30 --max-time 300 -o "omnipkg-${{ env.VERSION }}.tar.gz" "$url"; then
50+
echo "✅ Successfully downloaded package on attempt $attempt!"
51+
52+
# Verify the file is actually valid (not an error page)
53+
file_size=$(wc -c < "omnipkg-${{ env.VERSION }}.tar.gz")
54+
echo "📦 Downloaded file size: $file_size bytes"
55+
56+
if [ "$file_size" -gt 1000 ]; then
57+
echo "✅ File size looks good, proceeding..."
58+
break
59+
else
60+
echo "⚠️ File too small ($file_size bytes), might be error page. Retrying..."
61+
rm -f "omnipkg-${{ env.VERSION }}.tar.gz"
62+
fi
63+
else
64+
echo "❌ Download failed on attempt $attempt"
65+
fi
66+
67+
if [ $attempt -lt $max_attempts ]; then
68+
wait_time=$((30 + attempt * 10)) # Progressive backoff: 40s, 50s, 60s, etc.
69+
echo "⏰ Waiting $wait_time seconds before retry..."
70+
sleep $wait_time
71+
fi
72+
73+
attempt=$((attempt + 1))
74+
done
75+
76+
if [ $attempt -gt $max_attempts ]; then
77+
echo "💥 FAILED: Package not available on PyPI after $max_attempts attempts"
78+
echo "🤔 This might mean:"
79+
echo " - PyPI is still processing the release"
80+
echo " - The package failed to upload to PyPI"
81+
echo " - There's a network issue"
82+
echo ""
83+
echo "🔧 Try running this workflow manually in a few minutes with workflow_dispatch"
84+
exit 1
85+
fi
86+
87+
# Calculate SHA256 using a more reliable method
88+
echo "🔐 Calculating SHA256 hash..."
89+
if command -v sha256sum >/dev/null 2>&1; then
90+
SHA256=$(sha256sum "omnipkg-${{ env.VERSION }}.tar.gz" | cut -d' ' -f1)
91+
else
92+
# Fallback for systems without sha256sum
93+
SHA256=$(python3 -c "
94+
import hashlib
95+
with open('omnipkg-${{ env.VERSION }}.tar.gz', 'rb') as f:
96+
content = f.read()
97+
print(hashlib.sha256(content).hexdigest())
98+
")
99+
fi
34100
35-
SHA256=$(sha256sum "omnipkg-${{ env.VERSION }}.tar.gz" | cut -d' ' -f1)
36101
echo "SHA256=$SHA256" >> $GITHUB_ENV
37-
echo "Downloaded omnipkg-${{ env.VERSION }}.tar.gz with SHA256: $SHA256"
102+
echo "✅ Package SHA256: $SHA256"
103+
104+
# Clean up the downloaded file
105+
rm -f "omnipkg-${{ env.VERSION }}.tar.gz"
38106
39107
- name: Checkout Homebrew tap
40108
uses: actions/checkout@v4
@@ -43,36 +111,69 @@ jobs:
43111
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
44112
path: homebrew-tap
45113

46-
- name: Update formula
114+
- name: Update main formula
47115
run: |
48116
cd homebrew-tap
49117
50-
# Update the formula file
51-
sed -i 's|url "https://pypi.io/packages/source/o/omnipkg/omnipkg-.*\.tar\.gz"|url "https://pypi.org/packages/source/o/omnipkg/omnipkg-${{ env.VERSION }}.tar.gz"|' omnipkg.rb
118+
if [ ! -f "omnipkg.rb" ]; then
119+
echo "❌ Formula file omnipkg.rb not found!"
120+
exit 1
121+
fi
122+
123+
echo "🔧 Updating omnipkg formula..."
124+
125+
# Update the main package URL and SHA256
126+
# Handle both possible URL formats
127+
sed -i 's|url "https://pypi\.io/packages/source/o/omnipkg/omnipkg-.*\.tar\.gz"|url "https://pypi.org/packages/source/o/omnipkg/omnipkg-${{ env.VERSION }}.tar.gz"|' omnipkg.rb
128+
sed -i 's|url "https://pypi\.org/packages/source/o/omnipkg/omnipkg-.*\.tar\.gz"|url "https://pypi.org/packages/source/o/omnipkg/omnipkg-${{ env.VERSION }}.tar.gz"|' omnipkg.rb
52129
sed -i 's/sha256 ".*"/sha256 "${{ env.SHA256 }}"/' omnipkg.rb
53130
54-
echo "=== Updated formula ==="
55-
head -10 omnipkg.rb
131+
echo "=== Updated main formula section ==="
132+
head -15 omnipkg.rb
56133
57-
- name: Get latest dependency versions and hashes
134+
- name: Update dependency versions and hashes
58135
run: |
59136
cd homebrew-tap
137+
138+
echo "🔍 Updating dependency versions..."
139+
60140
python3 << 'EOF'
61141
import json
62142
import urllib.request
63143
import re
64-
# Dependencies to update (from your current formula)
144+
import time
145+
import sys
146+
from urllib.error import HTTPError, URLError
147+
148+
# Dependencies to update
65149
deps = [
66150
"aiohappyeyeballs", "aiohttp", "aiosignal", "attrs", "certifi",
67151
"charset-normalizer", "filelock", "frozenlist", "idna", "multidict",
68152
"packaging", "propcache", "python-magic", "redis", "requests",
69153
"tqdm", "typing-extensions", "urllib3", "yarl"
70154
]
71-
formula_content = open('omnipkg.rb', 'r').read()
72-
for dep in deps:
155+
156+
print(f"📋 Updating {len(deps)} dependencies...")
157+
158+
try:
159+
with open('omnipkg.rb', 'r') as f:
160+
formula_content = f.read()
161+
except FileNotFoundError:
162+
print("❌ Error: omnipkg.rb not found!")
163+
sys.exit(1)
164+
165+
updated_count = 0
166+
failed_count = 0
167+
168+
for i, dep in enumerate(deps, 1):
169+
print(f"🔄 [{i}/{len(deps)}] Processing {dep}...")
170+
73171
try:
74-
# Get latest version from PyPI API
75-
with urllib.request.urlopen(f'https://pypi.org/pypi/{dep}/json') as response:
172+
# Add small delay to be nice to PyPI API
173+
if i > 1:
174+
time.sleep(0.5)
175+
176+
with urllib.request.urlopen(f'https://pypi.org/pypi/{dep}/json', timeout=30) as response:
76177
data = json.loads(response.read())
77178
latest_version = data['info']['version']
78179
@@ -86,31 +187,103 @@ jobs:
86187
break
87188
88189
if sdist_url and sha256_hash:
89-
print(f"Updating {dep} to {latest_version}")
190+
print(f" ✅ Found {dep} v{latest_version}")
90191
91-
# Update the resource block
92-
pattern = f'(resource "{dep}" do.*?url ")(.*?)(".*?sha256 ")(.*?)(")'
192+
# Update the resource block with more robust regex
193+
pattern = f'(resource "{re.escape(dep)}" do.*?url ")(.*?)(".*?sha256 ")(.*?)(")'
93194
replacement = f'\\g<1>{sdist_url}\\g<3>{sha256_hash}\\g<5>'
195+
196+
old_formula = formula_content
94197
formula_content = re.sub(pattern, replacement, formula_content, flags=re.DOTALL)
198+
199+
if formula_content != old_formula:
200+
updated_count += 1
201+
print(f" 📝 Updated {dep}")
202+
else:
203+
print(f" ⚠️ Pattern not found for {dep} (might already be current)")
204+
else:
205+
print(f" ⚠️ No source distribution found for {dep}")
206+
failed_count += 1
95207
208+
except (HTTPError, URLError) as e:
209+
print(f" ❌ HTTP error for {dep}: {e}")
210+
failed_count += 1
211+
except json.JSONDecodeError as e:
212+
print(f" ❌ JSON decode error for {dep}: {e}")
213+
failed_count += 1
96214
except Exception as e:
97-
print(f"Warning: Could not update {dep}: {e}")
215+
print(f" ❌ Unexpected error for {dep}: {e}")
216+
failed_count += 1
217+
98218
# Write the updated formula
99-
with open('omnipkg.rb', 'w') as f:
100-
f.write(formula_content)
219+
try:
220+
with open('omnipkg.rb', 'w') as f:
221+
f.write(formula_content)
222+
print(f"📊 Summary: {updated_count} updated, {failed_count} failed")
223+
except Exception as e:
224+
print(f"❌ Error writing formula: {e}")
225+
sys.exit(1)
101226
EOF
102227
228+
- name: Verify updated formula
229+
run: |
230+
cd homebrew-tap
231+
232+
echo "🔍 Verifying updated formula..."
233+
echo "=== First 30 lines of updated formula ==="
234+
head -30 omnipkg.rb
235+
236+
echo ""
237+
echo "=== Checking for obvious issues ==="
238+
239+
# Basic syntax checks
240+
if grep -q 'sha256 ""' omnipkg.rb; then
241+
echo "❌ Found empty SHA256 - this will cause issues!"
242+
exit 1
243+
fi
244+
245+
if grep -q 'url ""' omnipkg.rb; then
246+
echo "❌ Found empty URL - this will cause issues!"
247+
exit 1
248+
fi
249+
250+
echo "✅ Basic validation passed"
251+
103252
- name: Commit and push changes
104253
run: |
105254
cd homebrew-tap
255+
256+
# Configure git
106257
git config --local user.email "action@github.com"
107-
git config --local user.name "GitHub Action"
108-
git add omnipkg.rb
258+
git config --local user.name "GitHub Action Bot"
109259
110-
if git diff --staged --quiet; then
111-
echo "No changes to commit"
112-
else
113-
git commit -m "Update omnipkg to version ${{ env.VERSION }}"
114-
git push
115-
echo "Successfully updated Homebrew formula to version ${{ env.VERSION }}"
260+
# Check if there are any changes
261+
if git diff --quiet omnipkg.rb; then
262+
echo "ℹ️ No changes detected in omnipkg.rb"
263+
exit 0
116264
fi
265+
266+
echo "📝 Changes detected, committing..."
267+
git add omnipkg.rb
268+
269+
# Create detailed commit message
270+
commit_msg="Update omnipkg to version ${{ env.VERSION }}
271+
272+
- Updated main package to v${{ env.VERSION }}
273+
- Updated SHA256 hash: ${{ env.SHA256 }}
274+
- Refreshed dependency versions from PyPI
275+
276+
Auto-generated by GitHub Actions"
277+
278+
git commit -m "$commit_msg"
279+
280+
echo "🚀 Pushing changes to homebrew tap..."
281+
git push
282+
283+
echo "🎉 Successfully updated Homebrew formula to version ${{ env.VERSION }}!"
284+
echo ""
285+
echo "🍺 Users can now install with:"
286+
echo " brew install 1minds3t/omnipkg/omnipkg"
287+
echo ""
288+
echo "🔄 Or update existing installations with:"
289+
echo " brew upgrade omnipkg"

0 commit comments

Comments
 (0)