From a7dbf52ef15652f0af6243327ac49f1c656e3d62 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 15 May 2026 09:58:54 -0700 Subject: [PATCH 1/6] ci: add Rust publish workflow for releases/rust/db_esdk Publishes the aws-db-esdk crate to crates.io via GitHub Actions using a crates.io API token issued under the Crypto Tools CI bot account (stored as the CARGO_REGISTRY_TOKEN repo secret, gated by the crates-io-publish environment). Manual workflow_dispatch only. Version is taken from Cargo.toml; the optional input acts as a typo safeguard. Towards: P432256706 --- .github/workflows/rust-release.yml | 78 ++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/rust-release.yml diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml new file mode 100644 index 000000000..a49aef55e --- /dev/null +++ b/.github/workflows/rust-release.yml @@ -0,0 +1,78 @@ +name: Rust Release (publish to crates.io) + +# Publishes the Rust crate in releases/rust/db_esdk/ to crates.io. +# +# Manual-only trigger. The version to publish is taken from +# releases/rust/db_esdk/Cargo.toml; the workflow_dispatch input is an +# optional safety check. +# +# Authenticates with a long-lived crates.io API token issued under the +# Crypto Tools CI bot account. The token is stored in a repository secret +# named CARGO_REGISTRY_TOKEN, gated by the `crates-io-publish` GitHub +# environment (configure required reviewers on the environment to add +# human approval at run time). + +on: + workflow_dispatch: + inputs: + version: + description: "Optional. If provided, must match Cargo.toml version exactly (e.g. '1.2.5', no leading 'v'). Used as a typo safeguard; if omitted, the version in releases/rust/db_esdk/Cargo.toml is published as-is." + required: false + type: string + +permissions: {} + +jobs: + publish: + name: Publish aws-db-esdk to crates.io + runs-on: ubuntu-22.04 + environment: crates-io-publish + permissions: + contents: read + defaults: + run: + working-directory: releases/rust/db_esdk + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + cache: false + + - name: Read crate version from Cargo.toml + id: cargo + run: | + set -euo pipefail + CRATE_VERSION="$(cargo metadata --no-deps --format-version=1 \ + | python3 -c "import json, sys; print(json.load(sys.stdin)['packages'][0]['version'])")" + CRATE_NAME="$(cargo metadata --no-deps --format-version=1 \ + | python3 -c "import json, sys; print(json.load(sys.stdin)['packages'][0]['name'])")" + echo "version=${CRATE_VERSION}" >> "$GITHUB_OUTPUT" + echo "name=${CRATE_NAME}" >> "$GITHUB_OUTPUT" + echo "Will publish ${CRATE_NAME} v${CRATE_VERSION}" + + - name: Verify input version matches Cargo.toml (if provided) + if: ${{ inputs.version != '' }} + env: + INPUT_VERSION: ${{ inputs.version }} + CARGO_VERSION: ${{ steps.cargo.outputs.version }} + run: | + set -euo pipefail + # Strip an optional leading 'v' from the input for convenience. + NORMALIZED_INPUT="${INPUT_VERSION#v}" + if [ "${NORMALIZED_INPUT}" != "${CARGO_VERSION}" ]; then + echo "::error::Input version '${INPUT_VERSION}' (normalized: '${NORMALIZED_INPUT}') does not match Cargo.toml version '${CARGO_VERSION}'." + echo "Either fix the input or update Cargo.toml in a separate PR." + exit 1 + fi + echo "Input version matches Cargo.toml: ${CARGO_VERSION}" + + - name: Cargo publish (dry run) + run: cargo publish --dry-run --locked || cargo publish --dry-run + + - name: Cargo publish + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish --locked || cargo publish From e6b8be2d4394db78814ece4019692b43fc00de32 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 15 May 2026 10:06:23 -0700 Subject: [PATCH 2/6] ci: align rust-release.yml with RELEASE.md and existing CI style - Match existing repo workflow style (Setup Rust Toolchain naming, explicit shell: bash, longpaths step, actions/checkout@v6 unnamed). - Drop --locked: releases/rust/db_esdk/ does not commit Cargo.lock per start_release.sh; --locked would always fail. - Replace fragile python3 cargo metadata parsing with jq. - Run `./test_published.sh` after publishing (RELEASE.md step 9), with AWS creds for the KMS/DDB calls in examples/main.rs. - Poll crates.io for the new version before running test_published.sh to mitigate index propagation lag. --- .github/workflows/rust-release.yml | 92 +++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index a49aef55e..e10ada306 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -1,22 +1,20 @@ -name: Rust Release (publish to crates.io) - -# Publishes the Rust crate in releases/rust/db_esdk/ to crates.io. +# This workflow publishes the aws-db-esdk crate to crates.io. # -# Manual-only trigger. The version to publish is taken from -# releases/rust/db_esdk/Cargo.toml; the workflow_dispatch input is an -# optional safety check. +# It corresponds to steps 7 and 9 of DynamoDbEncryption/runtimes/rust/RELEASE.md +# (i.e. `cargo publish` and `./test_published.sh N.N.N`); steps 1-6 (regenerating +# `releases/rust/db_esdk/` via `start_release.sh` and getting that PR reviewed) +# happen offline before this workflow is dispatched. # -# Authenticates with a long-lived crates.io API token issued under the -# Crypto Tools CI bot account. The token is stored in a repository secret -# named CARGO_REGISTRY_TOKEN, gated by the `crates-io-publish` GitHub -# environment (configure required reviewers on the environment to add -# human approval at run time). +# Authenticates to crates.io with a long-lived API token issued under the +# Crypto Tools CI bot account, stored in the CARGO_REGISTRY_TOKEN repo +# secret and gated by the `crates-io-publish` GitHub environment. +name: Rust Release on: workflow_dispatch: inputs: version: - description: "Optional. If provided, must match Cargo.toml version exactly (e.g. '1.2.5', no leading 'v'). Used as a typo safeguard; if omitted, the version in releases/rust/db_esdk/Cargo.toml is published as-is." + description: "Optional. If provided, must match releases/rust/db_esdk/Cargo.toml version exactly (N.N.N format, e.g. '1.2.5'). Used as a typo safeguard; if omitted, the version in Cargo.toml is published as-is." required: false type: string @@ -28,35 +26,37 @@ jobs: runs-on: ubuntu-22.04 environment: crates-io-publish permissions: + id-token: write contents: read - defaults: - run: - working-directory: releases/rust/db_esdk steps: - - name: Checkout repository - uses: actions/checkout@v6 + - name: Support longpaths on Git checkout + run: | + git config --global core.longpaths true + + - uses: actions/checkout@v6 - - name: Setup Rust toolchain + - name: Setup Rust Toolchain for GitHub CI uses: actions-rust-lang/setup-rust-toolchain@v1 with: - cache: false + components: rustfmt, clippy - name: Read crate version from Cargo.toml id: cargo + shell: bash + working-directory: releases/rust/db_esdk run: | set -euo pipefail - CRATE_VERSION="$(cargo metadata --no-deps --format-version=1 \ - | python3 -c "import json, sys; print(json.load(sys.stdin)['packages'][0]['version'])")" - CRATE_NAME="$(cargo metadata --no-deps --format-version=1 \ - | python3 -c "import json, sys; print(json.load(sys.stdin)['packages'][0]['name'])")" + CRATE_VERSION="$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].version')" + CRATE_NAME="$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].name')" echo "version=${CRATE_VERSION}" >> "$GITHUB_OUTPUT" echo "name=${CRATE_NAME}" >> "$GITHUB_OUTPUT" echo "Will publish ${CRATE_NAME} v${CRATE_VERSION}" - name: Verify input version matches Cargo.toml (if provided) - if: ${{ inputs.version != '' }} + if: ${{ github.event.inputs.version != '' }} + shell: bash env: - INPUT_VERSION: ${{ inputs.version }} + INPUT_VERSION: ${{ github.event.inputs.version }} CARGO_VERSION: ${{ steps.cargo.outputs.version }} run: | set -euo pipefail @@ -64,15 +64,51 @@ jobs: NORMALIZED_INPUT="${INPUT_VERSION#v}" if [ "${NORMALIZED_INPUT}" != "${CARGO_VERSION}" ]; then echo "::error::Input version '${INPUT_VERSION}' (normalized: '${NORMALIZED_INPUT}') does not match Cargo.toml version '${CARGO_VERSION}'." - echo "Either fix the input or update Cargo.toml in a separate PR." exit 1 fi echo "Input version matches Cargo.toml: ${CARGO_VERSION}" - name: Cargo publish (dry run) - run: cargo publish --dry-run --locked || cargo publish --dry-run + shell: bash + working-directory: releases/rust/db_esdk + run: cargo publish --dry-run - name: Cargo publish + shell: bash + working-directory: releases/rust/db_esdk env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo publish --locked || cargo publish + run: cargo publish + + - name: Configure AWS Credentials for test_published.sh + uses: aws-actions/configure-aws-credentials@v6 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-DDBEC-Dafny-Role-us-west-2 + role-session-name: DDBEC-Rust-Release-TestPublished + special-characters-workaround: "true" + + - name: Wait for new version to be available on crates.io + shell: bash + env: + CRATE_NAME: ${{ steps.cargo.outputs.name }} + CRATE_VERSION: ${{ steps.cargo.outputs.version }} + run: | + set -euo pipefail + # crates.io can take a few seconds to surface a freshly-published + # version via the sparse index. Poll for up to 5 minutes. + for i in $(seq 1 60); do + if curl -fsSL "https://crates.io/api/v1/crates/${CRATE_NAME}/${CRATE_VERSION}" >/dev/null 2>&1; then + echo "${CRATE_NAME} v${CRATE_VERSION} is available on crates.io" + exit 0 + fi + echo "Attempt ${i}: ${CRATE_NAME} v${CRATE_VERSION} not yet available; sleeping 5s" + sleep 5 + done + echo "::error::${CRATE_NAME} v${CRATE_VERSION} did not appear on crates.io within 5 minutes" + exit 1 + + - name: Test the published crate + shell: bash + working-directory: DynamoDbEncryption/runtimes/rust + run: ./test_published.sh "${{ steps.cargo.outputs.version }}" From 52d90e31bb8eb2b4ba9e4f143df6d649e713d85d Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 15 May 2026 10:11:34 -0700 Subject: [PATCH 3/6] ci: add rust-start-release workflow and tighten version validation - Add rust-start-release.yml that runs DynamoDbEncryption/runtimes/rust/ start_release.sh end-to-end on a CI runner and opens a release PR, removing the need to run start_release.sh on a developer laptop (RELEASE.md steps 1-6). - rust-release.yml continues to handle steps 7-10 (cargo publish + test_published.sh) and is intended to be dispatched on the release PR's branch before merging, per RELEASE.md. - Drop the silent leading-'v' strip in rust-release.yml's version check; N.N.N is the only valid form (per start_release.sh's regex), so accepting 'v1.2.5' contradicted the input description. --- .github/workflows/rust-release.yml | 22 ++-- .github/workflows/rust-start-release.yml | 154 +++++++++++++++++++++++ 2 files changed, 167 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/rust-start-release.yml diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index e10ada306..27b137ca3 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -1,9 +1,15 @@ -# This workflow publishes the aws-db-esdk crate to crates.io. +# This workflow publishes the aws-db-esdk crate to crates.io and runs +# the post-publish smoke test against the published version. # -# It corresponds to steps 7 and 9 of DynamoDbEncryption/runtimes/rust/RELEASE.md -# (i.e. `cargo publish` and `./test_published.sh N.N.N`); steps 1-6 (regenerating -# `releases/rust/db_esdk/` via `start_release.sh` and getting that PR reviewed) -# happen offline before this workflow is dispatched. +# It corresponds to RELEASE.md steps 7-10 (`cargo publish` and +# `./test_published.sh N.N.N`); steps 1-6 (regenerating +# `releases/rust/db_esdk/` and opening a release PR) are automated by +# the `Rust Start Release` workflow (rust-start-release.yml) and should +# be run before this workflow. +# +# Per RELEASE.md, this workflow should be dispatched on the release PR's +# branch (head ref) BEFORE the PR is merged, so a failed publish or +# failed smoke test leaves the unmerged PR for cleanup. # # Authenticates to crates.io with a long-lived API token issued under the # Crypto Tools CI bot account, stored in the CARGO_REGISTRY_TOKEN repo @@ -60,10 +66,8 @@ jobs: CARGO_VERSION: ${{ steps.cargo.outputs.version }} run: | set -euo pipefail - # Strip an optional leading 'v' from the input for convenience. - NORMALIZED_INPUT="${INPUT_VERSION#v}" - if [ "${NORMALIZED_INPUT}" != "${CARGO_VERSION}" ]; then - echo "::error::Input version '${INPUT_VERSION}' (normalized: '${NORMALIZED_INPUT}') does not match Cargo.toml version '${CARGO_VERSION}'." + if [ "${INPUT_VERSION}" != "${CARGO_VERSION}" ]; then + echo "::error::Input version '${INPUT_VERSION}' does not match Cargo.toml version '${CARGO_VERSION}'." exit 1 fi echo "Input version matches Cargo.toml: ${CARGO_VERSION}" diff --git a/.github/workflows/rust-start-release.yml b/.github/workflows/rust-start-release.yml new file mode 100644 index 000000000..6c5e0d598 --- /dev/null +++ b/.github/workflows/rust-start-release.yml @@ -0,0 +1,154 @@ +# This workflow automates RELEASE.md steps 1-6 for the aws-db-esdk crate: +# regenerating `releases/rust/db_esdk/` via `start_release.sh`, committing +# the result on a release branch, and opening a PR back to main. +# +# Steps 7-10 (cargo publish + test_published.sh) live in rust-release.yml +# and should be dispatched after this PR is reviewed and merged. +# +# This workflow does NOT need any crates.io credentials; it only writes to +# the repo (via secrets.GITHUB_TOKEN) and assumes AWS via OIDC for the +# tests that start_release.sh runs. +name: Rust Start Release + +on: + workflow_dispatch: + inputs: + version: + description: "New aws-db-esdk version in N.N.N format (e.g. '1.2.5')." + required: true + type: string + +permissions: {} + +jobs: + start-release: + name: Run start_release.sh and open a release PR + runs-on: ubuntu-22.04 + permissions: + id-token: write + contents: write + pull-requests: write + env: + RUST_MIN_STACK: 838860800 + steps: + - name: Validate version input + shell: bash + env: + VERSION: ${{ github.event.inputs.version }} + run: | + set -euo pipefail + if ! [[ "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Version '${VERSION}' must be in N.N.N format (e.g. '1.2.5')." + exit 1 + fi + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v6 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-DDBEC-Dafny-Role-us-west-2 + role-session-name: DDBEC-Rust-Start-Release + special-characters-workaround: "true" + + - name: Support longpaths on Git checkout + run: | + git config --global core.longpaths true + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Init Submodules + shell: bash + run: | + git submodule update --init --recursive submodules/smithy-dafny + git submodule update --init --recursive submodules/MaterialProviders + + - name: Setup Rust Toolchain for GitHub CI + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt, clippy + + - name: Setup Dafny + uses: ./submodules/MaterialProviders/.github/actions/setup_dafny/ + with: + dafny-version: 4.10.0 + + - name: Setup Java 17 for codegen + uses: actions/setup-java@v5 + with: + distribution: "corretto" + java-version: "17" + + - name: Install Smithy-Dafny codegen dependencies + uses: ./submodules/MaterialProviders/.github/actions/install_smithy_dafny_codegen_dependencies + with: + mpl-submodule-path: ./submodules/MaterialProviders/ + + - name: Configure Git + shell: bash + run: | + git config --global user.name "GitHub Actions" + git config --global user.email "actions@github.com" + + - name: Create release branch + id: branch + shell: bash + env: + VERSION: ${{ github.event.inputs.version }} + run: | + set -euo pipefail + BRANCH="release/db_esdk/v${VERSION}" + git checkout -b "${BRANCH}" + echo "name=${BRANCH}" >> "$GITHUB_OUTPUT" + + - name: Run start_release.sh + shell: bash + working-directory: DynamoDbEncryption/runtimes/rust + env: + VERSION: ${{ github.event.inputs.version }} + run: ./start_release.sh "${VERSION}" + + - name: Commit regenerated releases/rust/db_esdk + shell: bash + env: + VERSION: ${{ github.event.inputs.version }} + run: | + set -euo pipefail + # Submodule dirs and other transient state must not be committed. + git add releases/rust/db_esdk DynamoDbEncryption/runtimes/rust/Cargo.toml + if git diff --cached --quiet; then + echo "::error::start_release.sh produced no changes; nothing to release." + exit 1 + fi + git commit -m "chore(release): aws-db-esdk v${VERSION}" + + - name: Push release branch + shell: bash + env: + BRANCH: ${{ steps.branch.outputs.name }} + run: | + set -euo pipefail + git push origin "${BRANCH}" + + - name: Open release PR + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: ${{ steps.branch.outputs.name }} + VERSION: ${{ github.event.inputs.version }} + run: | + set -euo pipefail + gh pr create \ + --base main \ + --head "${BRANCH}" \ + --title "chore(release): aws-db-esdk v${VERSION}" \ + --body "Automated release PR generated by \`rust-start-release.yml\` for aws-db-esdk v${VERSION}. + + Reviewer checklist (from RELEASE.md): + - Update \`CHANGELOG.md\` in the root directory with the changes for this version. + - If this is a major version bump, update \`SUPPORT_POLICY.rst\` for Rust. + - After approval, dispatch the \`Rust Release\` workflow on this branch (or after merging) to publish to crates.io and run \`test_published.sh\`. + + Do NOT merge this PR before publishing per RELEASE.md." From 1ba2bc5aba844b446e896df9c0d4149e887f2f09 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 15 May 2026 10:23:00 -0700 Subject: [PATCH 4/6] ci: drop RELEASE.md references from Rust release workflows --- .github/workflows/rust-release.yml | 17 ++++++++--------- .github/workflows/rust-start-release.yml | 21 +++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index 27b137ca3..fffc8bc87 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -1,15 +1,14 @@ # This workflow publishes the aws-db-esdk crate to crates.io and runs -# the post-publish smoke test against the published version. +# the post-publish smoke test against the published version +# (`cargo publish` and `./test_published.sh N.N.N`). # -# It corresponds to RELEASE.md steps 7-10 (`cargo publish` and -# `./test_published.sh N.N.N`); steps 1-6 (regenerating -# `releases/rust/db_esdk/` and opening a release PR) are automated by -# the `Rust Start Release` workflow (rust-start-release.yml) and should -# be run before this workflow. +# Regenerating `releases/rust/db_esdk/` and opening a release PR is +# automated by the `Rust Start Release` workflow (rust-start-release.yml) +# and should be run before this workflow. # -# Per RELEASE.md, this workflow should be dispatched on the release PR's -# branch (head ref) BEFORE the PR is merged, so a failed publish or -# failed smoke test leaves the unmerged PR for cleanup. +# This workflow should be dispatched on the release PR's branch +# (head ref) BEFORE the PR is merged, so a failed publish or failed +# smoke test leaves the unmerged PR for cleanup. # # Authenticates to crates.io with a long-lived API token issued under the # Crypto Tools CI bot account, stored in the CARGO_REGISTRY_TOKEN repo diff --git a/.github/workflows/rust-start-release.yml b/.github/workflows/rust-start-release.yml index 6c5e0d598..62dffad70 100644 --- a/.github/workflows/rust-start-release.yml +++ b/.github/workflows/rust-start-release.yml @@ -1,13 +1,14 @@ -# This workflow automates RELEASE.md steps 1-6 for the aws-db-esdk crate: -# regenerating `releases/rust/db_esdk/` via `start_release.sh`, committing -# the result on a release branch, and opening a PR back to main. +# This workflow regenerates `releases/rust/db_esdk/` for a new version +# of the aws-db-esdk crate by running +# DynamoDbEncryption/runtimes/rust/start_release.sh, committing the +# result on a release branch, and opening a PR back to main. # -# Steps 7-10 (cargo publish + test_published.sh) live in rust-release.yml -# and should be dispatched after this PR is reviewed and merged. +# `cargo publish` and `test_published.sh` live in rust-release.yml and +# should be dispatched on the resulting PR's branch before merging. # -# This workflow does NOT need any crates.io credentials; it only writes to -# the repo (via secrets.GITHUB_TOKEN) and assumes AWS via OIDC for the -# tests that start_release.sh runs. +# This workflow does NOT need any crates.io credentials; it only writes +# to the repo (via secrets.GITHUB_TOKEN) and assumes AWS via OIDC for +# the tests that start_release.sh runs. name: Rust Start Release on: @@ -146,9 +147,9 @@ jobs: --title "chore(release): aws-db-esdk v${VERSION}" \ --body "Automated release PR generated by \`rust-start-release.yml\` for aws-db-esdk v${VERSION}. - Reviewer checklist (from RELEASE.md): + Reviewer checklist: - Update \`CHANGELOG.md\` in the root directory with the changes for this version. - If this is a major version bump, update \`SUPPORT_POLICY.rst\` for Rust. - After approval, dispatch the \`Rust Release\` workflow on this branch (or after merging) to publish to crates.io and run \`test_published.sh\`. - Do NOT merge this PR before publishing per RELEASE.md." + Do NOT merge this PR before publishing." From 4571521ddb77ee3cd9f517a75e4ff1714b0505cd Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 15 May 2026 10:42:48 -0700 Subject: [PATCH 5/6] ci(rust-start-release): pin to default branch and open PR as CI bot Address PR review feedback: - Drop the misleading 'or after merging' option from the generated PR body; rust-release.yml must run on the unmerged PR's branch. - Hard-fail dispatch on a non-default branch via 'if' guard, and pass ref: main explicitly to actions/checkout to avoid mixing in unrelated branch changes when someone dispatches from a feature branch. - Push the release branch and open the PR using the Crypto Tools CI bot's PAT (pulled from AWS Secrets Manager via the existing GitHub-CI-CI-Bot-Credential-Access-Role) instead of the default GITHUB_TOKEN, so the resulting pull_request event triggers the repo's normal required-checks workflows. Mirrors semantic_release.yml. --- .github/workflows/rust-start-release.yml | 66 ++++++++++++++++-------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/.github/workflows/rust-start-release.yml b/.github/workflows/rust-start-release.yml index 62dffad70..514448b74 100644 --- a/.github/workflows/rust-start-release.yml +++ b/.github/workflows/rust-start-release.yml @@ -1,14 +1,15 @@ -# This workflow regenerates `releases/rust/db_esdk/` for a new version -# of the aws-db-esdk crate by running -# DynamoDbEncryption/runtimes/rust/start_release.sh, committing the -# result on a release branch, and opening a PR back to main. +# This workflow regenerates `releases/rust/db_esdk/` for a new version of the +# aws-db-esdk crate by running DynamoDbEncryption/runtimes/rust/start_release.sh, +# committing the result on a release branch, and opening a PR back to main. # # `cargo publish` and `test_published.sh` live in rust-release.yml and # should be dispatched on the resulting PR's branch before merging. # -# This workflow does NOT need any crates.io credentials; it only writes -# to the repo (via secrets.GITHUB_TOKEN) and assumes AWS via OIDC for -# the tests that start_release.sh runs. +# This workflow only ever runs against the default branch (`main`); the +# version input must be in N.N.N form. The release branch is pushed and +# the release PR is opened as the Crypto Tools CI bot (via a PAT pulled +# from AWS Secrets Manager) so that the resulting PR's `pull_request` +# event triggers required-checks workflows on the release PR. name: Rust Start Release on: @@ -24,11 +25,14 @@ permissions: {} jobs: start-release: name: Run start_release.sh and open a release PR + # Disallow dispatching from anywhere but the default branch; the workflow + # checks out main below regardless of github.ref, but failing fast here + # avoids confusion. + if: github.ref == 'refs/heads/main' runs-on: ubuntu-22.04 permissions: id-token: write contents: write - pull-requests: write env: RUST_MIN_STACK: 838860800 steps: @@ -43,7 +47,7 @@ jobs: exit 1 fi - - name: Configure AWS Credentials + - name: Configure AWS Credentials for tests uses: aws-actions/configure-aws-credentials@v6 with: aws-region: us-west-2 @@ -57,8 +61,8 @@ jobs: - uses: actions/checkout@v6 with: + ref: main fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - name: Init Submodules shell: bash @@ -117,7 +121,6 @@ jobs: VERSION: ${{ github.event.inputs.version }} run: | set -euo pipefail - # Submodule dirs and other transient state must not be committed. git add releases/rust/db_esdk DynamoDbEncryption/runtimes/rust/Cargo.toml if git diff --cached --quiet; then echo "::error::start_release.sh produced no changes; nothing to release." @@ -125,22 +128,43 @@ jobs: fi git commit -m "chore(release): aws-db-esdk v${VERSION}" - - name: Push release branch - shell: bash - env: - BRANCH: ${{ steps.branch.outputs.name }} - run: | - set -euo pipefail - git push origin "${BRANCH}" + # Switch from the testing role to the CI-bot-credential-access role so + # we can pull the CI bot's PAT and push/open the PR as the bot. This + # makes the resulting PR fire the repo's normal pull_request CI. + - name: Configure AWS Credentials for CI bot creds + uses: aws-actions/configure-aws-credentials@v6 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::587316601012:role/GitHub-CI-CI-Bot-Credential-Access-Role-us-west-2 + role-session-name: CI_Bot_RustStartRelease + special-characters-workaround: "true" - - name: Open release PR + - name: Get CI Bot Creds Secret + uses: aws-actions/aws-secretsmanager-get-secrets@v2 + with: + secret-ids: Github/aws-crypto-tools-ci-bot + parse-json-secrets: true + + - name: Push release branch and open release PR as CI bot shell: bash env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BRANCH: ${{ steps.branch.outputs.name }} VERSION: ${{ github.event.inputs.version }} run: | set -euo pipefail + # Authenticate gh as the CI bot. Following the pattern used by + # semantic_release.yml, write the token to a temp file and feed it + # to `gh auth login --with-token`. + echo '${{ env.GITHUB_AWS_CRYPTO_TOOLS_CI_BOT_ESDK_RELEASE_TOKEN }}' > token.txt + gh auth login --with-token < token.txt + rm token.txt + gh auth status + + # Push using the bot PAT so the push event is attributed to the bot + # and required pull_request CI workflows fire on the resulting PR. + REMOTE="https://x-access-token:$(gh auth token)@github.com/${GITHUB_REPOSITORY}.git" + git push "${REMOTE}" "${BRANCH}" + gh pr create \ --base main \ --head "${BRANCH}" \ @@ -150,6 +174,6 @@ jobs: Reviewer checklist: - Update \`CHANGELOG.md\` in the root directory with the changes for this version. - If this is a major version bump, update \`SUPPORT_POLICY.rst\` for Rust. - - After approval, dispatch the \`Rust Release\` workflow on this branch (or after merging) to publish to crates.io and run \`test_published.sh\`. + - After approval and BEFORE merging, dispatch the \`Rust Release\` workflow on this branch to publish to crates.io and run \`test_published.sh\`. Do NOT merge this PR before publishing." From c4a828ca1b5f182afdfae8a24aab9cc4d6a4fee7 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 15 May 2026 10:50:32 -0700 Subject: [PATCH 6/6] ci(rust-release): strengthen ordering language to MUST --- .github/workflows/rust-release.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index fffc8bc87..ea5bd266a 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -4,11 +4,14 @@ # # Regenerating `releases/rust/db_esdk/` and opening a release PR is # automated by the `Rust Start Release` workflow (rust-start-release.yml) -# and should be run before this workflow. +# and MUST be run before this workflow. Dispatching this workflow without +# first running `Rust Start Release` (and reviewing/approving the +# resulting release PR) will publish whatever happens to be committed at +# `releases/rust/db_esdk/` and is unsupported. # -# This workflow should be dispatched on the release PR's branch -# (head ref) BEFORE the PR is merged, so a failed publish or failed -# smoke test leaves the unmerged PR for cleanup. +# This workflow MUST be dispatched on the release PR's branch (head ref) +# BEFORE the PR is merged, so a failed publish or failed smoke test +# leaves the unmerged PR for cleanup. # # Authenticates to crates.io with a long-lived API token issued under the # Crypto Tools CI bot account, stored in the CARGO_REGISTRY_TOKEN repo