diff --git a/.github/workflows/build-node-fibers.yml b/.github/workflows/build-node-fibers.yml index 697163b712a288..de6db6cd75e46a 100644 --- a/.github/workflows/build-node-fibers.yml +++ b/.github/workflows/build-node-fibers.yml @@ -22,6 +22,7 @@ jobs: env: NODE_VERSION: v20.18.3 + REPO: ${{ github.repository }} steps: - name: Debug Matrix Values @@ -78,10 +79,33 @@ jobs: tar -czf "$ARCHIVE_NAME" -C "$(dirname "$FIBERS_DIR")" "$(basename "$FIBERS_DIR")" - name: Upload archive to release - uses: softprops/action-gh-release@v1 - with: - name: node-${{ env.NODE_VERSION }}-LATEST - tag_name: node-${{ env.NODE_VERSION }}-release - files: ${{ env.ARCHIVE_NAME }} + # Attach the built node-fibers archive to the same node-${NODE_VERSION}-release + # release that hosts the corresponding Node binaries. + # + # Normally this workflow runs after Build Node via workflow_run, so the + # release already exists by the time we get here. But workflow_dispatch can + # fire it independently (release may not yet exist), and the matrix still + # runs both arms (linux-x64, linux-arm64) in parallel — so both arms can + # race to create the release. The view-or-create guard with the trailing + # `|| gh release view` tolerates "already exists" from a losing racer and + # propagates any other create failure through the final view. + # + # `--clobber` makes re-uploads idempotent on asset name collisions by + # deleting the existing asset before uploading. If the new upload fails + # after the delete, just re-run the job to rebuild. + # + # `gh release edit --title` after upload keeps the release title + # deterministically derived from NODE_VERSION, overriding any manual rename + # in the GitHub UI. env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + TAG="node-${NODE_VERSION}-release" + RELEASE_NAME="node-${NODE_VERSION}-LATEST" + if ! gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1; then + gh release create "$TAG" --title "$RELEASE_NAME" --notes "" --repo "$REPO" \ + || gh release view "$TAG" --repo "$REPO" >/dev/null + fi + gh release upload "$TAG" "$ARCHIVE_NAME" --clobber --repo "$REPO" + gh release edit "$TAG" --title "$RELEASE_NAME" --repo "$REPO" diff --git a/.github/workflows/build-node-openssl-fips.yml b/.github/workflows/build-node-openssl-fips.yml index 524f20d42cb787..64ee386bf9b844 100644 --- a/.github/workflows/build-node-openssl-fips.yml +++ b/.github/workflows/build-node-openssl-fips.yml @@ -46,6 +46,7 @@ jobs: env: S3_BUCKET: your-bucket-name AWS_REGION: us-east-1 + REPO: ${{ github.repository }} steps: - name: Checkout Node fork @@ -148,10 +149,35 @@ jobs: path: artifacts/${{ env.NODE_ARCHIVE_LATEST }} - name: Upload Node archive to release - uses: softprops/action-gh-release@v1 - with: - name: node-${{ env.NODE_VERSION }}-fips-static-LATEST - tag_name: node-${{ env.NODE_VERSION }}-fips-static-release - files: ./artifacts/${{ env.NODE_ARCHIVE_LATEST }} + # Publish the FIPS-static Node build to its own release tag + # (node-${NODE_VERSION}-fips-static-release), separate from the default + # Node release so consumers can select the FIPS variant explicitly rather + # than relying on filename conventions inside a shared release. + # + # This workflow is workflow_dispatch-only, and the matrix has two arms + # (linux-x64, linux-arm64) running in parallel — on the first invocation + # for a new NODE_VERSION both arms race to create the release. The + # view-or-create guard with the trailing `|| gh release view` tolerates + # "already exists" from the losing racer and propagates any other create + # failure through the final view. + # + # `--clobber` makes re-uploads idempotent on asset name collisions by + # deleting the existing asset before uploading. If the new upload fails + # after the delete, just re-run the job. + # + # `gh release edit --title` after upload keeps the release title + # deterministically derived from NODE_VERSION, overriding any manual + # rename in the GitHub UI. env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + TAG="node-${NODE_VERSION}-fips-static-release" + RELEASE_NAME="node-${NODE_VERSION}-fips-static-LATEST" + FILE="./artifacts/${NODE_ARCHIVE_LATEST}" + if ! gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1; then + gh release create "$TAG" --title "$RELEASE_NAME" --notes "" --repo "$REPO" \ + || gh release view "$TAG" --repo "$REPO" >/dev/null + fi + gh release upload "$TAG" "$FILE" --clobber --repo "$REPO" + gh release edit "$TAG" --title "$RELEASE_NAME" --repo "$REPO" diff --git a/.github/workflows/build-node.yml b/.github/workflows/build-node.yml index b74f4af4973deb..99dd3209f450f9 100644 --- a/.github/workflows/build-node.yml +++ b/.github/workflows/build-node.yml @@ -26,6 +26,7 @@ jobs: env: S3_BUCKET: your-bucket-name AWS_REGION: us-east-1 + REPO: ${{ github.repository }} steps: - name: Checkout Node fork @@ -97,10 +98,36 @@ jobs: path: artifacts/${{ env.NODE_ARCHIVE_LATEST }} - name: Upload Node archive to release - uses: softprops/action-gh-release@v1 - with: - name: node-${{ env.NODE_VERSION }}-LATEST - tag_name: node-${{ env.NODE_VERSION }}-release - files: ./artifacts/${{ env.NODE_ARCHIVE_LATEST }} + # Publish the built Node archive to the node-${NODE_VERSION}-release release. + # This is the first uploader in the pipeline; build-node-packages and + # build-node-fibers attach additional artifacts to the same release later. + # + # Matrix concurrency: both matrix arms (linux-x64, linux-arm64) hit this step + # in parallel. On the first run for a new NODE_VERSION the release does not + # yet exist, so both arms race to create it. The view-or-create guard with + # the trailing `|| gh release view` tolerates "already exists" from the + # losing arm (as long as the release now exists); any other create failure + # propagates through that second view. + # + # `--clobber` makes re-uploads idempotent on asset name collisions: an + # existing asset with the same name is deleted before the new one uploads. + # Acceptable here because the -LATEST assets are always reproducible from + # the build inputs; if the upload fails after the delete, just re-run the + # job. + # + # `gh release edit --title` after upload keeps the release title + # deterministically derived from NODE_VERSION even if someone renames the + # release in the GitHub UI. env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + TAG="node-${NODE_VERSION}-release" + RELEASE_NAME="node-${NODE_VERSION}-LATEST" + FILE="./artifacts/${NODE_ARCHIVE_LATEST}" + if ! gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1; then + gh release create "$TAG" --title "$RELEASE_NAME" --notes "" --repo "$REPO" \ + || gh release view "$TAG" --repo "$REPO" >/dev/null + fi + gh release upload "$TAG" "$FILE" --clobber --repo "$REPO" + gh release edit "$TAG" --title "$RELEASE_NAME" --repo "$REPO"