Skip to content

Commit 3330ecc

Browse files
lucasmcdonald3Lucas McDonaldrishav-karanjitShubhamChaturvedi7sharmabikram
authored
ci: add Rust release workflows for aws-db-esdk (#2280)
* 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 * 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. * 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. * ci: drop RELEASE.md references from Rust release workflows * 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. * ci(rust-release): strengthen ordering language to MUST * Update .github/workflows/rust-release.yml Co-authored-by: Shubham Chaturvedi <anotherosscontributor@gmail.com> --------- Co-authored-by: Lucas McDonald <lucmcdon@amazon.com> Co-authored-by: Rishav karanjit <karanjitrishav4@gmail.com> Co-authored-by: Shubham Chaturvedi <anotherosscontributor@gmail.com> Co-authored-by: sharmabikram <sharmabikram111@gmail.com>
1 parent be7843b commit 3330ecc

2 files changed

Lines changed: 299 additions & 0 deletions

File tree

.github/workflows/rust-release.yml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# This workflow publishes the aws-db-esdk crate to crates.io and runs
2+
# the post-publish smoke test against the published version
3+
# (`cargo publish` and `./test_published.sh N.N.N`).
4+
#
5+
# Regenerating `releases/rust/db_esdk/` and opening a release PR is
6+
# automated by the `Rust Start Release` workflow (rust-start-release.yml)
7+
# and MUST be run before this workflow. Dispatching this workflow without
8+
# first running `Rust Start Release` (and reviewing/approving the
9+
# resulting release PR) will publish whatever happens to be committed at
10+
# `releases/rust/db_esdk/`.
11+
#
12+
# This workflow MUST be dispatched on the release PR's branch (head ref)
13+
# BEFORE the PR is merged, so a failed publish or failed smoke test
14+
# leaves the unmerged PR for cleanup.
15+
#
16+
# Authenticates to crates.io with a long-lived API token issued under the
17+
# Crypto Tools CI bot account, stored in the CARGO_REGISTRY_TOKEN repo
18+
# secret and gated by the `crates-io-publish` GitHub environment.
19+
name: Rust Release
20+
21+
on:
22+
workflow_dispatch:
23+
inputs:
24+
version:
25+
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."
26+
required: false
27+
type: string
28+
29+
permissions: {}
30+
31+
jobs:
32+
publish:
33+
name: Publish aws-db-esdk to crates.io
34+
runs-on: ubuntu-22.04
35+
environment: crates-io-publish
36+
permissions:
37+
id-token: write
38+
contents: read
39+
steps:
40+
- name: Support longpaths on Git checkout
41+
run: |
42+
git config --global core.longpaths true
43+
44+
- uses: actions/checkout@v6
45+
46+
- name: Setup Rust Toolchain for GitHub CI
47+
uses: actions-rust-lang/setup-rust-toolchain@v1
48+
with:
49+
components: rustfmt, clippy
50+
51+
- name: Read crate version from Cargo.toml
52+
id: cargo
53+
shell: bash
54+
working-directory: releases/rust/db_esdk
55+
run: |
56+
set -euo pipefail
57+
CRATE_VERSION="$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].version')"
58+
CRATE_NAME="$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].name')"
59+
echo "version=${CRATE_VERSION}" >> "$GITHUB_OUTPUT"
60+
echo "name=${CRATE_NAME}" >> "$GITHUB_OUTPUT"
61+
echo "Will publish ${CRATE_NAME} v${CRATE_VERSION}"
62+
63+
- name: Verify input version matches Cargo.toml (if provided)
64+
if: ${{ github.event.inputs.version != '' }}
65+
shell: bash
66+
env:
67+
INPUT_VERSION: ${{ github.event.inputs.version }}
68+
CARGO_VERSION: ${{ steps.cargo.outputs.version }}
69+
run: |
70+
set -euo pipefail
71+
if [ "${INPUT_VERSION}" != "${CARGO_VERSION}" ]; then
72+
echo "::error::Input version '${INPUT_VERSION}' does not match Cargo.toml version '${CARGO_VERSION}'."
73+
exit 1
74+
fi
75+
echo "Input version matches Cargo.toml: ${CARGO_VERSION}"
76+
77+
- name: Cargo publish (dry run)
78+
shell: bash
79+
working-directory: releases/rust/db_esdk
80+
run: cargo publish --dry-run
81+
82+
- name: Cargo publish
83+
shell: bash
84+
working-directory: releases/rust/db_esdk
85+
env:
86+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
87+
run: cargo publish
88+
89+
- name: Configure AWS Credentials for test_published.sh
90+
uses: aws-actions/configure-aws-credentials@v6
91+
with:
92+
aws-region: us-west-2
93+
role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-DDBEC-Dafny-Role-us-west-2
94+
role-session-name: DDBEC-Rust-Release-TestPublished
95+
special-characters-workaround: "true"
96+
97+
- name: Wait for new version to be available on crates.io
98+
shell: bash
99+
env:
100+
CRATE_NAME: ${{ steps.cargo.outputs.name }}
101+
CRATE_VERSION: ${{ steps.cargo.outputs.version }}
102+
run: |
103+
set -euo pipefail
104+
# crates.io can take a few seconds to surface a freshly-published
105+
# version via the sparse index. Poll for up to 5 minutes.
106+
for i in $(seq 1 60); do
107+
if curl -fsSL "https://crates.io/api/v1/crates/${CRATE_NAME}/${CRATE_VERSION}" >/dev/null 2>&1; then
108+
echo "${CRATE_NAME} v${CRATE_VERSION} is available on crates.io"
109+
exit 0
110+
fi
111+
echo "Attempt ${i}: ${CRATE_NAME} v${CRATE_VERSION} not yet available; sleeping 5s"
112+
sleep 5
113+
done
114+
echo "::error::${CRATE_NAME} v${CRATE_VERSION} did not appear on crates.io within 5 minutes"
115+
exit 1
116+
117+
- name: Test the published crate
118+
shell: bash
119+
working-directory: DynamoDbEncryption/runtimes/rust
120+
run: ./test_published.sh "${{ steps.cargo.outputs.version }}"
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# This workflow regenerates `releases/rust/db_esdk/` for a new version of the
2+
# aws-db-esdk crate by running DynamoDbEncryption/runtimes/rust/start_release.sh,
3+
# committing the result on a release branch, and opening a PR back to main.
4+
#
5+
# `cargo publish` and `test_published.sh` live in rust-release.yml and
6+
# should be dispatched on the resulting PR's branch before merging.
7+
#
8+
# This workflow only ever runs against the default branch (`main`); the
9+
# version input must be in N.N.N form. The release branch is pushed and
10+
# the release PR is opened as the Crypto Tools CI bot (via a PAT pulled
11+
# from AWS Secrets Manager) so that the resulting PR's `pull_request`
12+
# event triggers required-checks workflows on the release PR.
13+
name: Rust Start Release
14+
15+
on:
16+
workflow_dispatch:
17+
inputs:
18+
version:
19+
description: "New aws-db-esdk version in N.N.N format (e.g. '1.2.5')."
20+
required: true
21+
type: string
22+
23+
permissions: {}
24+
25+
jobs:
26+
start-release:
27+
name: Run start_release.sh and open a release PR
28+
# Disallow dispatching from anywhere but the default branch; the workflow
29+
# checks out main below regardless of github.ref, but failing fast here
30+
# avoids confusion.
31+
if: github.ref == 'refs/heads/main'
32+
runs-on: ubuntu-22.04
33+
permissions:
34+
id-token: write
35+
contents: write
36+
env:
37+
RUST_MIN_STACK: 838860800
38+
steps:
39+
- name: Validate version input
40+
shell: bash
41+
env:
42+
VERSION: ${{ github.event.inputs.version }}
43+
run: |
44+
set -euo pipefail
45+
if ! [[ "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
46+
echo "::error::Version '${VERSION}' must be in N.N.N format (e.g. '1.2.5')."
47+
exit 1
48+
fi
49+
50+
- name: Configure AWS Credentials for tests
51+
uses: aws-actions/configure-aws-credentials@v6
52+
with:
53+
aws-region: us-west-2
54+
role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-DDBEC-Dafny-Role-us-west-2
55+
role-session-name: DDBEC-Rust-Start-Release
56+
special-characters-workaround: "true"
57+
58+
- name: Support longpaths on Git checkout
59+
run: |
60+
git config --global core.longpaths true
61+
62+
- uses: actions/checkout@v6
63+
with:
64+
ref: main
65+
fetch-depth: 0
66+
67+
- name: Init Submodules
68+
shell: bash
69+
run: |
70+
git submodule update --init --recursive submodules/smithy-dafny
71+
git submodule update --init --recursive submodules/MaterialProviders
72+
73+
- name: Setup Rust Toolchain for GitHub CI
74+
uses: actions-rust-lang/setup-rust-toolchain@v1
75+
with:
76+
components: rustfmt, clippy
77+
78+
- name: Setup Dafny
79+
uses: ./submodules/MaterialProviders/.github/actions/setup_dafny/
80+
with:
81+
dafny-version: 4.10.0
82+
83+
- name: Setup Java 17 for codegen
84+
uses: actions/setup-java@v5
85+
with:
86+
distribution: "corretto"
87+
java-version: "17"
88+
89+
- name: Install Smithy-Dafny codegen dependencies
90+
uses: ./submodules/MaterialProviders/.github/actions/install_smithy_dafny_codegen_dependencies
91+
with:
92+
mpl-submodule-path: ./submodules/MaterialProviders/
93+
94+
- name: Configure Git
95+
shell: bash
96+
run: |
97+
git config --global user.name "GitHub Actions"
98+
git config --global user.email "actions@github.com"
99+
100+
- name: Create release branch
101+
id: branch
102+
shell: bash
103+
env:
104+
VERSION: ${{ github.event.inputs.version }}
105+
run: |
106+
set -euo pipefail
107+
BRANCH="release/db_esdk/v${VERSION}"
108+
git checkout -b "${BRANCH}"
109+
echo "name=${BRANCH}" >> "$GITHUB_OUTPUT"
110+
111+
- name: Run start_release.sh
112+
shell: bash
113+
working-directory: DynamoDbEncryption/runtimes/rust
114+
env:
115+
VERSION: ${{ github.event.inputs.version }}
116+
run: ./start_release.sh "${VERSION}"
117+
118+
- name: Commit regenerated releases/rust/db_esdk
119+
shell: bash
120+
env:
121+
VERSION: ${{ github.event.inputs.version }}
122+
run: |
123+
set -euo pipefail
124+
git add releases/rust/db_esdk DynamoDbEncryption/runtimes/rust/Cargo.toml
125+
if git diff --cached --quiet; then
126+
echo "::error::start_release.sh produced no changes; nothing to release."
127+
exit 1
128+
fi
129+
git commit -m "chore(release): aws-db-esdk v${VERSION}"
130+
131+
# Switch from the testing role to the CI-bot-credential-access role so
132+
# we can pull the CI bot's PAT and push/open the PR as the bot. This
133+
# makes the resulting PR fire the repo's normal pull_request CI.
134+
- name: Configure AWS Credentials for CI bot creds
135+
uses: aws-actions/configure-aws-credentials@v6
136+
with:
137+
aws-region: us-west-2
138+
role-to-assume: arn:aws:iam::587316601012:role/GitHub-CI-CI-Bot-Credential-Access-Role-us-west-2
139+
role-session-name: CI_Bot_RustStartRelease
140+
special-characters-workaround: "true"
141+
142+
- name: Get CI Bot Creds Secret
143+
uses: aws-actions/aws-secretsmanager-get-secrets@v2
144+
with:
145+
secret-ids: Github/aws-crypto-tools-ci-bot
146+
parse-json-secrets: true
147+
148+
- name: Push release branch and open release PR as CI bot
149+
shell: bash
150+
env:
151+
BRANCH: ${{ steps.branch.outputs.name }}
152+
VERSION: ${{ github.event.inputs.version }}
153+
run: |
154+
set -euo pipefail
155+
# Authenticate gh as the CI bot. Following the pattern used by
156+
# semantic_release.yml, write the token to a temp file and feed it
157+
# to `gh auth login --with-token`.
158+
echo '${{ env.GITHUB_AWS_CRYPTO_TOOLS_CI_BOT_ESDK_RELEASE_TOKEN }}' > token.txt
159+
gh auth login --with-token < token.txt
160+
rm token.txt
161+
gh auth status
162+
163+
# Push using the bot PAT so the push event is attributed to the bot
164+
# and required pull_request CI workflows fire on the resulting PR.
165+
REMOTE="https://x-access-token:$(gh auth token)@github.com/${GITHUB_REPOSITORY}.git"
166+
git push "${REMOTE}" "${BRANCH}"
167+
168+
gh pr create \
169+
--base main \
170+
--head "${BRANCH}" \
171+
--title "chore(release): aws-db-esdk v${VERSION}" \
172+
--body "Automated release PR generated by \`rust-start-release.yml\` for aws-db-esdk v${VERSION}.
173+
174+
Reviewer checklist:
175+
- Update \`CHANGELOG.md\` in the root directory with the changes for this version.
176+
- If this is a major version bump, update \`SUPPORT_POLICY.rst\` for Rust.
177+
- After approval and BEFORE merging, dispatch the \`Rust Release\` workflow on this branch to publish to crates.io and run \`test_published.sh\`.
178+
179+
Do NOT merge this PR before publishing."

0 commit comments

Comments
 (0)