3333 permissions :
3434 contents : write
3535
36- outputs :
37- has_changes : ${{ steps.set_output.outputs.has_changes }}
38-
3936 steps :
4037 - name : Prepare container
4138 run : |
@@ -276,77 +273,74 @@ jobs:
276273
277274 rm -f private.pem
278275
279- - name : Upload binpkgs artifact
280- if : ${{ steps.changed.outputs.pkgs != '' || steps.changed.outputs.removed != '' }}
281- uses : actions/upload-artifact@v4
282- with :
283- name : binpkgs-${{ matrix.config.arch }}
284- path : void-packages/hostdir/binpkgs/
285- retention-days : 1
286-
287- - name : Set has_changes output
288- id : set_output
289- run : |
290- if [ -n "${{ steps.changed.outputs.pkgs }}" ] || [ -n "${{ steps.changed.outputs.removed }}" ]; then
291- echo "has_changes=true" >> "$GITHUB_OUTPUT"
292- else
293- echo "has_changes=false" >> "$GITHUB_OUTPUT"
294- fi
295-
296- release :
297- name : Update release (${{ matrix.config.arch }})
298- runs-on : ubuntu-latest
299- needs : build
300- if : needs.build.outputs.has_changes == 'true'
301- strategy :
302- fail-fast : false
303- matrix :
304- config : *build_matrix
305-
306- permissions :
307- contents : write
308-
309- steps :
310- - name : Download binpkgs artifact
311- uses : actions/download-artifact@v4
312- with :
313- name : binpkgs-${{ matrix.config.arch }}
314-
315276 - name : Update GitHub Release
277+ if : ${{ steps.changed.outputs.pkgs != '' || steps.changed.outputs.removed != '' }}
316278 env :
317279 GH_TOKEN : ${{ github.token }}
318- REPO : ${{ github.repository }}
280+ REPO_OWNER : ${{ github.repository_owner }}
281+ REPO_NAME : ${{ github.event.repository.name }}
319282 TAG : repository-${{ matrix.config.arch }}
320283 ARCH : ${{ matrix.config.arch }}
284+ API : https://api.github.com/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}
285+ UPLOADS : https://uploads.github.com/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}
286+ SHA : ${{ github.sha }}
287+ working-directory : void-packages/hostdir/binpkgs/
321288 run : |
322289 set -e
323- # Create release if it doesn't exist (tag at current commit)
324- if ! gh release view "$TAG" --repo "$REPO" &>/dev/null; then
325- echo "Creating release $TAG..."
326- gh release create "$TAG" \
327- --repo "$REPO" \
328- --target "${{ github.sha }}" \
329- --title "Binary repository for $ARCH" \
330- --notes "Automated binary repository. Add with: repository=https://github.com/$REPO/releases/download/$TAG"
290+ AUTH="Authorization: Bearer ${GH_TOKEN}"
291+ ACCEPT="Accept: application/vnd.github+json"
292+
293+ # Get or create release
294+ resp=$(curl -s -w "\n%{http_code}" -H "$AUTH" -H "$ACCEPT" "${API}/releases/tags/${TAG}" || true)
295+ code=$(echo "$resp" | tail -n1)
296+ body=$(echo "$resp" | sed '$d')
297+
298+ if [ "$code" = "404" ]; then
299+ echo "Creating release ${TAG}..."
300+ body=$(curl -s -X POST -H "$AUTH" -H "$ACCEPT" -H "Content-Type: application/json" \
301+ -d "{\"tag_name\":\"${TAG}\",\"target_commitish\":\"${SHA}\",\"name\":\"Binary repository for ${ARCH}\",\"body\":\"Add with: repository=https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/${TAG}\"}" \
302+ "${API}/releases")
331303 else
332304 # Point release at latest commit
333- gh release edit "$TAG" --repo "$REPO" --target "${{ github.sha }}" 2>/dev/null || true
305+ release_id=$(echo "$body" | jq -r '.id')
306+ curl -s -X PATCH -H "$AUTH" -H "$ACCEPT" -H "Content-Type: application/json" \
307+ -d "{\"target_commitish\":\"${SHA}\"}" \
308+ "${API}/releases/${release_id}" >/dev/null || true
334309 fi
335310
336- # List current repo files
311+ release_id=$(echo "$body" | jq -r '.id')
312+ [ "$release_id" = "null" ] && release_id=$(curl -s -H "$AUTH" -H "$ACCEPT" "${API}/releases/tags/${TAG}" | jq -r '.id')
313+
314+ # List current repo files (what we want on the release)
337315 ls -1 > /tmp/current_files.txt
338316
339- # Upload/update: add new assets and overwrite changed ones (--clobber).
317+ # Get existing asset ids by name
318+ existing_assets=$(curl -s -H "$AUTH" -H "$ACCEPT" "${API}/releases/${release_id}" | jq -c '.assets[] | {id: .id, name: .name}')
319+
320+ # Upload each file: delete existing asset with same name (API doesn't allow overwrite), then upload
340321 echo "Uploading current packages and index..."
341- gh release upload "$TAG" ./* --repo "$REPO" --clobber
322+ for f in *; do
323+ [ -f "$f" ] || continue
324+ name=$(basename "$f")
325+ asset_id=$(echo "$existing_assets" | jq -r --arg n "$name" 'select(.name == $n) | .id' | head -1)
326+ if [ -n "$asset_id" ] && [ "$asset_id" != "null" ]; then
327+ curl -s -X DELETE -H "$AUTH" -H "$ACCEPT" "${API}/releases/assets/${asset_id}" >/dev/null || true
328+ fi
329+ echo " Uploading $name"
330+ curl -s -X POST -H "$AUTH" -H "$ACCEPT" -H "Content-Type: application/octet-stream" \
331+ --data-binary "@${f}" \
332+ "${UPLOADS}/releases/${release_id}/assets?name=${name}" >/dev/null || true
333+ done
342334
343- # Remove only orphan assets: old package versions and packages for removed templates
335+ # Remove orphan assets ( old package versions, removed templates) - get fresh asset list after uploads
344336 echo "Removing obsolete release assets..."
345- while read -r name; do
337+ release_after=$(curl -s -H "$AUTH" -H "$ACCEPT" "${API}/releases/${release_id}")
338+ echo "$release_after" | jq -r '.assets[] | "\(.name)|\(.id)"' | while IFS='|' read -r name asset_id; do
346339 [ -z "$name" ] && continue
347340 if ! grep -qxF "$name" /tmp/current_files.txt; then
348341 echo " Deleting obsolete: $name"
349- gh release delete-asset "$TAG" "$name" --repo "$REPO" --yes 2 >/dev/null || true
342+ curl -s -X DELETE -H "$AUTH" -H "$ACCEPT" "${API}/releases/assets/${asset_id}" >/dev/null || true
350343 fi
351- done < <(gh release view "$TAG" --repo "$REPO" --json assets -q '.assets[].name')
352- echo "Release $TAG updated."
344+ done
345+
346+ echo "Release ${TAG} updated."
0 commit comments