1818 os : [ubuntu-latest, windows-latest, macos-latest]
1919 python-version : ['3.10', '3.11', '3.12']
2020
21+ # Services should be at job level, not under strategy
22+ services :
23+ redis :
24+ image : redis
25+ ports :
26+ - 6379:6379
27+ # Add health check for Redis
28+ options : >-
29+ --health-cmd "redis-cli ping"
30+ --health-interval 10s
31+ --health-timeout 5s
32+ --health-retries 3
33+
2134 steps :
2235 - name : Checkout code
2336 uses : actions/checkout@v4
@@ -33,45 +46,87 @@ jobs:
3346 - name : Install conda-build and anaconda-client
3447 shell : bash -l {0}
3548 run : |
49+ conda install conda-build anaconda-client -y
50+
51+ - name : Prepare package metadata
52+ shell : bash -l {0}
53+ run : |
54+ # Determine version based on trigger event
3655 if [ "${{ github.event_name }}" == "release" ]; then
3756 VERSION="${{ github.event.release.tag_name }}"
38- VERSION="${VERSION#v}"
57+ VERSION="${VERSION#v}" # Remove 'v' prefix if present
3958 else
4059 VERSION="${{ github.event.inputs.version }}"
4160 fi
4261
43- # --- START THE FIX: THE RESILIENT RETRY LOOP ---
62+ echo "Building version: $VERSION"
63+ echo "VERSION=$VERSION" >> $GITHUB_ENV
64+
65+ # Resilient download with retry logic
4466 max_attempts=10
4567 attempt=1
4668 url="https://pypi.org/packages/source/o/omnipkg/omnipkg-$VERSION.tar.gz"
4769
4870 echo "Attempting to download source from $url..."
4971
5072 while [ $attempt -le $max_attempts ]; do
51- # Use --fail to make curl return a non-zero exit code on 404
52- curl -L --fail -o "omnipkg-$VERSION.tar.gz" "$url"
73+ echo "Attempt $attempt of $max_attempts..."
5374
54- if [ $? -eq 0 ] ; then
55- echo "✅ Download successful on attempt $attempt. "
75+ if curl -L --fail --connect-timeout 30 --max-time 300 -o "omnipkg-$VERSION.tar.gz" "$url" ; then
76+ echo "✅ Download successful on attempt $attempt"
5677 break
5778 else
58- echo "⚠️ Attempt $attempt failed. PyPI might not be ready yet. Retrying in 15 seconds..."
59- sleep 15
79+ echo "⚠️ Attempt $attempt failed. PyPI might not be ready yet."
80+ if [ $attempt -lt $max_attempts ]; then
81+ echo "Retrying in 30 seconds..."
82+ sleep 30
83+ fi
6084 attempt=$((attempt + 1))
6185 fi
6286 done
6387
6488 if [ $attempt -gt $max_attempts ]; then
65- echo "❌ Failed to download source after $max_attempts attempts. Aborting."
89+ echo "❌ Failed to download source after $max_attempts attempts"
90+ exit 1
91+ fi
92+
93+ # Verify file was downloaded and calculate SHA256
94+ if [ ! -f "omnipkg-$VERSION.tar.gz" ]; then
95+ echo "❌ Downloaded file not found"
6696 exit 1
6797 fi
6898
69- # CORRECTED: Use Python for a truly cross-platform SHA256 calculation.
99+ file_size=$(wc -c < "omnipkg-$VERSION.tar.gz")
100+ echo "Downloaded file size: $file_size bytes"
101+
102+ if [ "$file_size" -lt 1000 ]; then
103+ echo "❌ Downloaded file seems too small, might be an error page"
104+ exit 1
105+ fi
106+
107+ # Calculate SHA256 using Python for cross-platform compatibility
70108 echo "Calculating SHA256 hash..."
71- SHA256=$(python -c "import hashlib; print(hashlib.sha256(open('omnipkg-$VERSION.tar.gz', 'rb').read()).hexdigest())")
109+ SHA256=$(python -c "
110+ import hashlib
111+ with open('omnipkg-$VERSION.tar.gz', 'rb') as f:
112+ content = f.read()
113+ print(hashlib.sha256(content).hexdigest())
114+ ")
115+
116+ echo "SHA256: $SHA256"
117+ echo "SHA256=$SHA256" >> $GITHUB_ENV
72118
73- # Update the version and sha256 in meta.yaml (cross-platform sed)
74- # Note: The macOS sed requires an empty string '' after -i
119+ # Clean up downloaded file
120+ rm "omnipkg-$VERSION.tar.gz"
121+
122+ - name : Update conda recipe
123+ shell : bash -l {0}
124+ run : |
125+ # Create recipe directory if it doesn't exist
126+ mkdir -p omnipkg/conda-recipe
127+
128+ # Update meta.yaml with version and hash
129+ # Handle different sed syntax for macOS vs Linux
75130 if [[ "$RUNNER_OS" == "macOS" ]]; then
76131 sed -i '' "s/{% set version = \".*\" %}/{% set version = \"$VERSION\" %}/" omnipkg/conda-recipe/meta.yaml
77132 sed -i '' "s/sha256: .*/sha256: $SHA256/" omnipkg/conda-recipe/meta.yaml
@@ -80,64 +135,125 @@ jobs:
80135 sed -i "s/sha256: .*/sha256: $SHA256/" omnipkg/conda-recipe/meta.yaml
81136 fi
82137
83- echo "Updated version to $VERSION with SHA256: $SHA256"
84- echo "VERSION=$VERSION" >> $GITHUB_ENV
138+ echo "Updated meta.yaml with version $VERSION and SHA256 $SHA256"
85139
86- # Show the updated meta.yaml for debugging
87- echo "=== Updated meta.yaml ==="
88- head -15 omnipkg/conda-recipe/meta.yaml
140+ # Display updated meta.yaml for verification
141+ echo "=== Updated meta.yaml content ==="
142+ head -20 omnipkg/conda-recipe/meta.yaml || echo "meta.yaml not found or empty"
89143
90144 - name : Build conda package
91145 shell : bash -l {0}
92146 run : |
147+ # Create output directory
148+ mkdir -p ./conda-dist
149+
150+ # Build the package
151+ echo "Building conda package..."
93152 conda build omnipkg/conda-recipe --output-folder ./conda-dist
153+
154+ # List built packages for verification
155+ echo "=== Built packages ==="
156+ find ./conda-dist -name "*.tar.bz2" -o -name "*.conda" | head -10
94157
95158 - name : Upload to Anaconda Cloud
96159 shell : bash -l {0}
97160 run : |
98- anaconda -t ${{ secrets.ANACONDA_TOKEN }} upload ./conda-dist/**/*.tar.bz2 --force
161+ # Find all built packages
162+ packages=$(find ./conda-dist -name "*.tar.bz2" -o -name "*.conda")
163+
164+ if [ -z "$packages" ]; then
165+ echo "❌ No conda packages found to upload"
166+ exit 1
167+ fi
168+
169+ echo "Uploading packages to Anaconda Cloud..."
170+ for package in $packages; do
171+ echo "Uploading: $package"
172+ anaconda -t ${{ secrets.ANACONDA_TOKEN }} upload "$package" --force
173+ done
99174 env :
100175 ANACONDA_TOKEN : ${{ secrets.ANACONDA_TOKEN }}
101176
102- # Alternative job for conda-forge feedstock update
177+ # Separate job for conda-forge feedstock update
103178 update-feedstock :
104179 runs-on : ubuntu-latest
105180 if : github.event_name == 'release'
106- steps :
107- - name : Checkout feedstock
108- uses : actions/checkout@v4
109- with :
110- repository : conda-forge/omnipkg-feedstock
111- token : ${{ secrets.FEEDSTOCK_TOKEN }}
112- path : feedstock
181+ needs : build-and-upload # Wait for main build to complete
113182
183+ steps :
114184 - name : Setup Python
115185 uses : actions/setup-python@v4
116186 with :
117187 python-version : ' 3.11'
118188
119189 - name : Install dependencies
120190 run : |
121- pip install pyyaml requests
191+ pip install pyyaml requests packaging
192+
193+ - name : Checkout feedstock
194+ uses : actions/checkout@v4
195+ with :
196+ repository : conda-forge/omnipkg-feedstock
197+ token : ${{ secrets.FEEDSTOCK_TOKEN }}
198+ path : feedstock
122199
123- - name : Update feedstock
200+ - name : Update feedstock recipe
124201 run : |
125202 cd feedstock
203+
204+ # Extract version from release tag
126205 VERSION="${{ github.event.release.tag_name }}"
127- VERSION="${VERSION#v}"
206+ VERSION="${VERSION#v}" # Remove 'v' prefix if present
128207
129- # CORRECTED: Use curl and Python for consistency and reliability.
130- echo "Downloading source to get SHA256..."
131- curl -L -o "omnipkg-$VERSION.tar.gz" "https://pypi.org/packages/source/o/omnipkg/omnipkg-$VERSION.tar.gz"
132- SHA256=$(python -c "import hashlib; print(hashlib.sha256(open('omnipkg-$VERSION.tar.gz', 'rb').read()).hexdigest())")
208+ echo "Updating feedstock to version $VERSION"
209+
210+ # Download source package to get SHA256
211+ echo "Downloading source package..."
212+ curl -L --fail --connect-timeout 30 --max-time 300 \
213+ -o "omnipkg-$VERSION.tar.gz" \
214+ "https://pypi.org/packages/source/o/omnipkg/omnipkg-$VERSION.tar.gz"
215+
216+ # Calculate SHA256
217+ SHA256=$(python -c "
218+ import hashlib
219+ with open('omnipkg-$VERSION.tar.gz', 'rb') as f:
220+ content = f.read()
221+ print(hashlib.sha256(content).hexdigest())
222+ ")
223+
224+ echo "Version: $VERSION"
225+ echo "SHA256: $SHA256"
133226
134227 # Update recipe/meta.yaml
135- sed -i "s/{% set version = \".*\" %}/{% set version = \"$VERSION\" %}/" recipe/meta.yaml
136- sed -i "s/sha256: .*/sha256: $SHA256/" recipe/meta.yaml
228+ if [ -f "recipe/meta.yaml" ]; then
229+ sed -i "s/{% set version = \".*\" %}/{% set version = \"$VERSION\" %}/" recipe/meta.yaml
230+ sed -i "s/sha256: .*/sha256: $SHA256/" recipe/meta.yaml
231+
232+ echo "=== Updated recipe/meta.yaml ==="
233+ head -20 recipe/meta.yaml
234+ else
235+ echo "❌ recipe/meta.yaml not found"
236+ exit 1
237+ fi
137238
138- # Commit and push
239+ # Clean up downloaded file
240+ rm "omnipkg-$VERSION.tar.gz"
241+
242+ - name : Commit and push changes
243+ run : |
244+ cd feedstock
245+
246+ # Configure git
139247 git config --local user.email "action@github.com"
140248 git config --local user.name "GitHub Action"
249+
250+ # Check if there are changes to commit
251+ if git diff --quiet recipe/meta.yaml; then
252+ echo "No changes to commit"
253+ exit 0
254+ fi
255+
256+ # Commit and push changes
141257 git add recipe/meta.yaml
142- git commit -m "Update to version $VERSION" || exit 0
258+ git commit -m "Update to version ${{ github.event.release.tag_name }}"
143259 git push
0 commit comments