From ecf155c01dd42836673152eb3e4394120388dc55 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Thu, 1 Oct 2026 15:18:53 +0900 Subject: [PATCH 1/2] fix(ci): skip existing release assets on publication retry --- .github/scripts/upload-release-assets.sh | 21 +++++++++++++++++++++ .github/workflows/CI.yml | 17 +++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 .github/scripts/upload-release-assets.sh diff --git a/.github/scripts/upload-release-assets.sh b/.github/scripts/upload-release-assets.sh new file mode 100644 index 0000000..fbc3e1a --- /dev/null +++ b/.github/scripts/upload-release-assets.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +upload_url="$1" +shift +release_id="${upload_url#*/releases/}" +release_id="${release_id%%/*}" +[[ "$release_id" =~ ^[0-9]+$ ]] || { echo "Invalid release upload URL" >&2; exit 1; } + +release_tag=$(gh api "repos/$GITHUB_REPOSITORY/releases/$release_id" --jq .tag_name) +existing_assets=$(gh api "repos/$GITHUB_REPOSITORY/releases/$release_id/assets" --paginate --jq '.[].name') + +for asset in "$@"; do + [[ -f "$asset" ]] || { echo "Missing release asset: $asset" >&2; exit 1; } + asset_name=$(basename -- "$asset") + if grep -Fxq -- "$asset_name" <<< "$existing_assets"; then + echo "::notice::$asset_name is already uploaded; skipping." + continue + fi + gh release upload "$release_tag" "$asset" --repo "$GITHUB_REPOSITORY" +done diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4706068..a0c8372 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -362,10 +362,10 @@ jobs: publish_package "$RUNNER_TEMP/npm-publish/cli/"*.tgz working-directory: bridge/node - name: Upload Asset - uses: owjs3901/upload-github-release-asset@main - with: - upload_url: ${{ fromJson(needs.changepacks.outputs.release_assets_urls)['bridge/node/package.json'] }} - asset_path: bridge/node/npm/*/dependency-check-updates.*.node + env: + GH_TOKEN: ${{ github.token }} + RELEASE_UPLOAD_URL: ${{ fromJson(needs.changepacks.outputs.release_assets_urls)['bridge/node/package.json'] }} + run: bash .github/scripts/upload-release-assets.sh "$RELEASE_UPLOAD_URL" bridge/node/npm/*/dependency-check-updates.*.node python-publish: name: Python Publish @@ -379,6 +379,7 @@ jobs: contents: write attestations: write steps: + - uses: actions/checkout@v7 - uses: actions/download-artifact@v8 - name: Generate artifact attestation uses: actions/attest-build-provenance@v4 @@ -394,10 +395,10 @@ jobs: - name: List wheels run: ls -R . - name: Upload Asset - uses: owjs3901/upload-github-release-asset@main - with: - upload_url: ${{ fromJson(needs.changepacks.outputs.release_assets_urls)['bridge/python/pyproject.toml'] }} - asset_path: "*/*.whl" + env: + GH_TOKEN: ${{ github.token }} + RELEASE_UPLOAD_URL: ${{ fromJson(needs.changepacks.outputs.release_assets_urls)['bridge/python/pyproject.toml'] }} + run: bash .github/scripts/upload-release-assets.sh "$RELEASE_UPLOAD_URL" wheels-*/*.whl finalize-releases: name: Finalize published releases From ee87dfd92b4ac6dba584dacfdecdd7b0823aad64 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Thu, 1 Oct 2026 15:20:55 +0900 Subject: [PATCH 2/2] fix(ci): skip only completed nonempty release assets --- .github/scripts/upload-release-assets.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/scripts/upload-release-assets.sh b/.github/scripts/upload-release-assets.sh index fbc3e1a..c4d548c 100644 --- a/.github/scripts/upload-release-assets.sh +++ b/.github/scripts/upload-release-assets.sh @@ -8,7 +8,9 @@ release_id="${release_id%%/*}" [[ "$release_id" =~ ^[0-9]+$ ]] || { echo "Invalid release upload URL" >&2; exit 1; } release_tag=$(gh api "repos/$GITHUB_REPOSITORY/releases/$release_id" --jq .tag_name) -existing_assets=$(gh api "repos/$GITHUB_REPOSITORY/releases/$release_id/assets" --paginate --jq '.[].name') +# Failed uploads can retain a name in the starter state. Only completed, +# nonempty binary/wheel assets may be skipped; collisions otherwise fail safely. +existing_assets=$(gh api "repos/$GITHUB_REPOSITORY/releases/$release_id/assets" --paginate --jq '.[] | select(.state == "uploaded" and .size > 0) | .name') for asset in "$@"; do [[ -f "$asset" ]] || { echo "Missing release asset: $asset" >&2; exit 1; }