diff --git a/.gitea/workflows/package-extension.yml b/.gitea/workflows/package-extension.yml index e25cc79..731bc40 100644 --- a/.gitea/workflows/package-extension.yml +++ b/.gitea/workflows/package-extension.yml @@ -33,9 +33,110 @@ jobs: cd extension zip -r "../dist/browser-cli-extension-v${{ steps.version.outputs.version }}.zip" . - - name: Upload extension artifact - uses: actions/upload-artifact@v4 - with: - name: browser-cli-extension-v${{ steps.version.outputs.version }} - path: dist/browser-cli-extension-v${{ steps.version.outputs.version }}.zip - if-no-files-found: error + - name: Publish extension release asset + env: + ACTION_ACCESS_TOKEN: ${{ secrets.ACTION_ACCESS_TOKEN }} + ASSET_NAME: browser-cli-extension-v${{ steps.version.outputs.version }}.zip + EXTENSION_VERSION: ${{ steps.version.outputs.version }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_SHA: ${{ github.sha }} + run: | + set -euo pipefail + + asset_path="dist/browser-cli-extension-v${EXTENSION_VERSION}.zip" + asset_name="$(basename "$asset_path")" + tag_name="v${EXTENSION_VERSION}" + api_base="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" + + if [ ! -f "$asset_path" ]; then + echo "Missing asset: $asset_path" >&2 + exit 1 + fi + + release_response="$(curl --silent --show-error \ + --header "Authorization: token ${ACTION_ACCESS_TOKEN}" \ + --header "Accept: application/json" \ + "${api_base}/releases/tags/${tag_name}")" + + release_id="$(printf '%s' "$release_response" | python - <<'PY' + import json + import sys + + try: + data = json.load(sys.stdin) + except json.JSONDecodeError: + print("") + raise SystemExit(0) + + print(data.get("id", "")) + PY + )" + + if [ -z "$release_id" ]; then + create_payload="$(python - <<'PY' + import json + import os + + version = os.environ["EXTENSION_VERSION"] + sha = os.environ["GITHUB_SHA"] + + print(json.dumps({ + "tag_name": f"v{version}", + "target_commitish": sha, + "name": f"v{version}", + "draft": False, + "prerelease": False, + })) + PY + )" + + release_response="$(curl --silent --show-error \ + --request POST \ + --header "Authorization: token ${ACTION_ACCESS_TOKEN}" \ + --header "Accept: application/json" \ + --header "Content-Type: application/json" \ + --data "$create_payload" \ + "${api_base}/releases")" + + release_id="$(printf '%s' "$release_response" | python - <<'PY' + import json + import sys + + data = json.load(sys.stdin) + print(data["id"]) + PY + )" + fi + + existing_asset_id="$(printf '%s' "$release_response" | python - <<'PY' + import json + import os + import sys + + data = json.load(sys.stdin) + asset_name = os.environ["ASSET_NAME"] + + for asset in data.get("assets", []): + if asset.get("name") == asset_name: + print(asset["id"]) + break + else: + print("") + PY + )" + + if [ -n "$existing_asset_id" ]; then + curl --silent --show-error \ + --request DELETE \ + --header "Authorization: token ${ACTION_ACCESS_TOKEN}" \ + --header "Accept: application/json" \ + "${api_base}/releases/${release_id}/assets/${existing_asset_id}" + fi + + curl --silent --show-error \ + --request POST \ + --header "Authorization: token ${ACTION_ACCESS_TOKEN}" \ + --header "Accept: application/json" \ + --form "attachment=@${asset_path}" \ + "${api_base}/releases/${release_id}/assets?name=${asset_name}"