diff --git a/.github/workflows/release-typescript-sdk.yml b/.github/workflows/release-typescript-sdk.yml index 5376bbc..0ff821f 100644 --- a/.github/workflows/release-typescript-sdk.yml +++ b/.github/workflows/release-typescript-sdk.yml @@ -13,6 +13,7 @@ on: type: boolean permissions: + actions: read contents: read id-token: write @@ -205,7 +206,7 @@ jobs: run: pnpm pack --pack-destination ../../../dist/npm publish-sdk: - if: ${{ always() && needs.verify.result == 'success' }} + if: ${{ !cancelled() && needs.verify.result == 'success' }} needs: - verify - publish-native @@ -243,24 +244,75 @@ jobs: echo "value=false" >> "${GITHUB_OUTPUT}" fi + - name: Check native publish job conclusions + id: native-publish-status + if: needs.verify.outputs.publish_release == 'true' && steps.sdk-package-presence.outputs.value != 'true' + env: + GITHUB_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + + jobs_api="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs?per_page=100" + jobs_json="$(curl --fail --silent --show-error \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + "${jobs_api}")" + + cancelled="$(node -e ' + const payload = JSON.parse(process.argv[1]); + const nativeJobs = payload.jobs.filter((job) => job.name.startsWith("publish-native (")); + process.stdout.write(nativeJobs.some((job) => job.conclusion === "cancelled") ? "true" : "false"); + ' "${jobs_json}")" + + echo "cancelled=${cancelled}" >> "${GITHUB_OUTPUT}" + + if [[ "${cancelled}" == "true" ]]; then + echo "::warning::Skipping SDK publish because one or more native publish jobs were cancelled." + fi + - name: Install workspace dependencies - if: needs.verify.outputs.publish_release != 'true' || steps.sdk-package-presence.outputs.value != 'true' + if: needs.verify.outputs.publish_release != 'true' || (steps.sdk-package-presence.outputs.value != 'true' && steps.native-publish-status.outputs.cancelled != 'true') run: pnpm install --frozen-lockfile - name: Wait for native packages to index on npm - if: needs.verify.outputs.publish_release == 'true' && steps.sdk-package-presence.outputs.value != 'true' + if: needs.verify.outputs.publish_release == 'true' && steps.sdk-package-presence.outputs.value != 'true' && steps.native-publish-status.outputs.cancelled != 'true' + env: + GITHUB_TOKEN: ${{ github.token }} shell: bash run: | set -euo pipefail + trap 'echo "::warning::Cancellation received; stopping SDK publish wait."; exit 130' INT TERM + version="${{ needs.verify.outputs.sdk_version }}" packages="$(node -p "JSON.stringify(Object.keys(require('./${SDK_DIRECTORY}/package.json').optionalDependencies).sort())")" missing_packages=() indexed_packages=() + native_jobs_cancelled() { + local jobs_api + local jobs_json + jobs_api="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs?per_page=100" + jobs_json="$(curl --fail --silent --show-error \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + "${jobs_api}")" + + node -e ' + const payload = JSON.parse(process.argv[1]); + const nativeJobs = payload.jobs.filter((job) => job.name.startsWith("publish-native (")); + process.exit(nativeJobs.some((job) => job.conclusion === "cancelled") ? 0 : 1); + ' "${jobs_json}" + } + wait_until_indexed() { local pkg="$1" local attempt for attempt in $(seq 1 30); do + if native_jobs_cancelled; then + echo "::warning::Stopping SDK publish wait because one or more native publish jobs were cancelled." + return 2 + fi if pnpm view "${pkg}@${version}" version >/dev/null 2>&1; then echo ">>> ${pkg}@${version} is visible on npm" return 0 @@ -277,6 +329,8 @@ jobs: for package_name in "${native_packages[@]}"; do if wait_until_indexed "${package_name}"; then indexed_packages+=("${package_name}") + elif [[ $? -eq 2 ]]; then + exit 0 else missing_packages+=("${package_name}") fi @@ -292,7 +346,7 @@ jobs: fi - name: Publish TypeScript SDK - if: needs.verify.outputs.publish_release == 'true' && steps.sdk-package-presence.outputs.value != 'true' + if: needs.verify.outputs.publish_release == 'true' && steps.sdk-package-presence.outputs.value != 'true' && steps.native-publish-status.outputs.cancelled != 'true' working-directory: ${{ env.SDK_DIRECTORY }} env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}