Skip to content

chore: bump smithyVersion to 1.73.0 (#2244) #94

chore: bump smithyVersion to 1.73.0 (#2244)

chore: bump smithyVersion to 1.73.0 (#2244) #94

name: create-release-pr
on:
push:
branches:
- main
jobs:
version:
name: Create Release PR
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
outputs:
# Set only when there were changesets to consume, and then on both the
# create and the update path, so the approve job can key off its presence
# to tell "there is a release PR to approve runs on" from "there was
# nothing to version". Notably it is empty on the push that merges the
# release PR, since `changeset version` already consumed the changesets.
pull-request-number: ${{ steps.version.outputs.pr-number }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: "yarn"
- name: Install dependencies
run: yarn install
- name: Create Release Pull Request
id: version
uses: changesets/action@22ccf9aa43179fe9e27dc62e575971d28cce197c # v2.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
version-script: yarn changeset version
commit-message: "Version NPM packages"
pr-title: "Version NPM packages"
# The release PR is opened and updated by github-actions[bot] authenticating as
# GITHUB_TOKEN, above. Runs on such a pull request are created in an
# approval-required state and wait for a maintainer, so this job approves them.
#
# It has to live in this workflow rather than one triggered by the release PR
# itself. Events raised by GITHUB_TOKEN do not create workflow runs, and the
# only exception is the `pull_request` event with the opened, synchronize or
# reopened activity types - which is exactly the carve-out that produces the
# approval-required runs in the first place. `pull_request_target` gets no such
# exception and is never dispatched for this PR at all, so it cannot be used to
# approve them. This workflow is instead triggered by the human merge that
# pushed to main, which is an ordinary trigger, and it runs on every such push,
# so it covers the release PR being updated as well as opened. See
# https://docs.github.com/en/actions/concepts/security/github_token and
# https://github.blog/changelog/2026-06-11-bot-created-pull-requests-can-run-workflows-if-approved/.
#
# Kept a separate job so that a failure to approve is not mistaken for a
# failure to create the release PR, which by then has already succeeded.
approve:
name: Approve pending runs on the release PR
needs: version
if: needs.version.outputs.pull-request-number != ''
runs-on: ubuntu-latest
permissions:
actions: write
pull-requests: read
env:
RELEASE_BRANCH: changeset-release/main
# Workflows that must leave the approval queue before this job is done. They
# all trigger on `pull_request` to main with no path filters, so they always
# run on the release PR; keep this list in step with them. Other pending runs
# are still approved, just not waited for.
EXPECTED_WORKFLOWS: ci npm-package-existence release-dry-run
steps:
- name: Approve workflow runs awaiting approval
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
PR_NUMBER: ${{ needs.version.outputs.pull-request-number }}
run: |
set -euo pipefail
# The head SHA is read back from the pull request rather than from the
# local checkout: the changesets action commits and pushes the release
# branch itself, so this job - which does not check anything out - has
# no other view of what the runs to approve are keyed on.
head="$(gh api "repos/$REPO/pulls/$PR_NUMBER" --jq '{sha: .head.sha, ref: .head.ref, repo: .head.repo.full_name}')"
head_sha="$(jq -r '.sha' <<< "$head")"
# Assert this is the release branch in this repository before approving
# anything. The pull request number comes from the changesets action, so
# this should always hold; it is checked so that a change in that
# action's behaviour cannot turn this into an approval of arbitrary runs.
if [ "$(jq -r '.ref' <<< "$head")" != "$RELEASE_BRANCH" ] \
|| [ "$(jq -r '.repo' <<< "$head")" != "$REPO" ]; then
echo "::error::PR #$PR_NUMBER is not $REPO:$RELEASE_BRANCH; refusing to approve its runs."
exit 1
fi
echo "Approving runs on PR #$PR_NUMBER at $head_sha"
attempts=18
interval=10
approved=0
# Runs appear around the same time as this one, so poll until every
# expected workflow has left the approval queue instead of waiting a
# fixed window. A just-approved run only reads as non-pending on a later
# poll, so this always costs one poll more than the last approval.
for attempt in $(seq 1 "$attempts"); do
# Match head repository and branch as well as SHA, so a fork PR that
# happens to share a commit with the release branch can never pick up
# an approval here. The SHA is re-checked rather than left to the query
# parameter alone: if that filter ever stopped applying, an
# already-approved run from an earlier commit on this branch could
# satisfy the wait below while this commit's runs stayed stuck. A run
# awaiting approval reports status "completed" with conclusion
# "action_required", so the conclusion alone decides `pending`.
runs="$(
gh api \
--method GET "repos/$REPO/actions/runs" \
-f "head_sha=$head_sha" \
-f "per_page=100" \
| jq --arg repo "$REPO" --arg branch "$RELEASE_BRANCH" --arg sha "$head_sha" '
[ .workflow_runs[]
| select(.event == "pull_request")
| select(.head_sha == $sha)
| select(.head_branch == $branch)
| select(.head_repository.full_name == $repo)
| {
id,
name,
pending: (.conclusion == "action_required"),
} ]'
)"
for id in $(jq -r '.[] | select(.pending) | .id' <<< "$runs"); do
echo "Approving run $id"
gh api --method POST "repos/$REPO/actions/runs/$id/approve"
approved=$((approved + 1))
done
# A workflow counts as cleared once any of its runs is no longer
# pending, not only when this job approved it, so a run a maintainer
# approved first - or one that started on its own - counts too.
missing=""
for workflow in $EXPECTED_WORKFLOWS; do
jq -e --arg workflow "$workflow" \
'any(.[]; .name == $workflow and (.pending | not))' > /dev/null <<< "$runs" \
|| missing="$missing $workflow"
done
if [ -z "$missing" ]; then
echo "All expected workflows are running for $head_sha." \
"Approved $approved run(s)."
exit 0
fi
echo "Attempt $attempt/$attempts," \
"waiting for these workflows to leave the approval queue:$missing"
sleep "$interval"
done
echo "::error::Timed out after approving $approved run(s);" \
"these workflows never left the approval queue for $head_sha:$missing"
exit 1