Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the release flow to use release branches #2253

Merged
merged 40 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ca22c78
What happens if we comment out the runtime crate version from gradle.…
LukeMathWalker Jan 26, 2023
1d045ea
Allow running the release and the CI workflows from an arbitrary commit.
LukeMathWalker Jan 26, 2023
37bc560
Does a fake version work?
LukeMathWalker Jan 26, 2023
a8a6ff2
Pass `git_ref` from the release workflow.
LukeMathWalker Jan 26, 2023
219f125
It needs to be a valid semver version.
LukeMathWalker Jan 26, 2023
9394c6b
Sketch new command to upgrade version in gradle.properties
LukeMathWalker Jan 26, 2023
6ee191d
Command implementation
LukeMathWalker Jan 26, 2023
9d997d1
Plug the new publisher command into the `release` action.
LukeMathWalker Jan 27, 2023
8a8713a
Plumb end-to-end
LukeMathWalker Jan 27, 2023
9cadab2
Fix copyright header.
LukeMathWalker Jan 27, 2023
93dcf7b
Fix lint.
LukeMathWalker Jan 27, 2023
d163264
Temporarily comment out the sanity check.
LukeMathWalker Jan 27, 2023
91b2978
Ignore sanity check
LukeMathWalker Jan 27, 2023
63b3a56
Add a command that prints out the template for CHANGELOG.next.toml
LukeMathWalker Jan 30, 2023
aa2a7eb
Add branch check + empty TOML generation.
LukeMathWalker Jan 30, 2023
cfea8dc
Merge branch 'main' into patches
LukeMathWalker Jan 30, 2023
14c4118
Add copyright headers.
LukeMathWalker Jan 30, 2023
99b6ece
Fix imports.
LukeMathWalker Jan 30, 2023
f8de002
Remove sanity check.
LukeMathWalker Jan 31, 2023
dd472e4
Move script to a file.
LukeMathWalker Jan 31, 2023
5dd621d
Merge branch 'main' into patches
LukeMathWalker Jan 31, 2023
7841f53
Add a check to validate the tag.
LukeMathWalker Jan 31, 2023
e07e0cd
Remove second build step.
LukeMathWalker Jan 31, 2023
815ffc5
Move to .github/scripts folder.
LukeMathWalker Feb 1, 2023
4851010
Make the script easier to run locally
LukeMathWalker Feb 1, 2023
a439fc5
Fail if anything fails.
LukeMathWalker Feb 1, 2023
a318f04
Add comment.
LukeMathWalker Feb 1, 2023
42fc4fb
Update .github/scripts/get-or-create-release-branch.sh
LukeMathWalker Feb 1, 2023
7751de1
Update .github/scripts/get-or-create-release-branch.sh
LukeMathWalker Feb 1, 2023
3a52ed7
Update .github/scripts/get-or-create-release-branch.sh
LukeMathWalker Feb 1, 2023
0414cce
Update .github/workflows/ci.yml
LukeMathWalker Feb 1, 2023
e3c0bc2
Remove touch.
LukeMathWalker Feb 1, 2023
9a739ba
Fix indentation and branch name.
LukeMathWalker Feb 1, 2023
c95e895
Update .github/workflows/ci.yml
LukeMathWalker Feb 1, 2023
b7dab07
Update .github/workflows/release.yml
LukeMathWalker Feb 1, 2023
53bb4cc
Update .github/workflows/release.yml
LukeMathWalker Feb 1, 2023
7806c72
Explicit flags.
LukeMathWalker Feb 1, 2023
62e0518
Use the path that was provided.
LukeMathWalker Feb 1, 2023
2526b89
Format
LukeMathWalker Feb 1, 2023
5b2fa2b
Merge branch 'main' into patches
LukeMathWalker Feb 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/scripts/get-or-create-release-branch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
#
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#
set -e

# Compute the name of the release branch starting from the version that needs to be released ($SEMANTIC_VERSION).
# If it's the beginning of a new release series, the branch is created and pushed to the remote (chosen according to
# the value $DRY_RUN).
# If it isn't the beginning of a new release series, the script makes sure that the commit that will be tagged is at
# the tip of the (pre-existing) release branch.
#
# The script populates an output file with key-value pairs that are needed in the release CI workflow to carry out
# the next steps in the release flow: the name of the release branch and a boolean flag that is set to 'true' if this
# is the beginning of a new release series.

if [ -z "$SEMANTIC_VERSION" ]; then
echo "'SEMANTIC_VERSION' must be populated."
exit 1
fi

if [ -z "$1" ]; then
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
echo "You need to specify the path of the file where you want to collect the output"
exit 1
else
output_file="$1"
fi

# Split on the dots
version_array=(${SEMANTIC_VERSION//./ })
major=${version_array[0]}
minor=${version_array[1]}
patch=${version_array[2]}
if [[ "${major}" == "" || "${minor}" == "" || "${patch}" == "" ]]; then
echo "'${SEMANTIC_VERSION}' is not a valid semver tag"
exit 1
fi
if [[ $major == 0 ]]; then
branch_name="smithy-rs-release-${major}.${minor}.x"
if [[ $patch == 0 ]]; then
echo "new_release_series=true" >"${output_file}"
fi
else
branch_name="smithy-rs-release-${major}.x.y"
if [[ $minor == 0 && $patch == 0 ]]; then
echo "new_release_series=true" >"${output_file}"
fi
fi

if [[ "${DRY_RUN}" == "true" ]]; then
branch_name="${branch_name}-preview"
fi
echo "release_branch=${branch_name}" >"${output_file}"

if [[ "${DRY_RUN}" == "true" ]]; then
git push --force origin "HEAD:${branch_name}"
else
commit_sha=$(git rev-parse --short HEAD)
if git ls-remote --exit-code --heads origin "${branch_name}"; then
# The release branch already exists, we need to make sure that our commit is its current tip
branch_head_sha=$(git rev-parse --verify --short "refs/heads/${branch_name}")
if [[ "${branch_head_sha}" != "${commit_sha}" ]]; then
echo "The release branch - ${branch_name} - already exists. ${commit_sha}, the commit you chose when "
echo "launching this release, is not its current HEAD (${branch_head_sha}). This is not allowed: you "
echo "MUST release from the HEAD of the release branch if it already exists."
exit 1
fi
else
# The release branch does not exist.
# We need to make sure that the commit SHA that we are releasing is on `main`.
git fetch origin main
if git branch --contains "${commit_sha}" | grep main; then
# We can then create the release branch and set the current commit as its tip
git checkout -b "${branch_name}"
git push origin "${branch_name}"
else
echo "You must choose a commit from main to create a new release series!"
exit 1
fi
fi
fi
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ on:
required: false
default: false
type: boolean
git_ref:
description: |
The git reference that all checks should be run against. It can be a branch, a tag or a commit SHA.
If unspecified, it will default to the git reference or SHA that triggered the execution of this workflow.
required: false
type: string
default: ""

env:
rust_version: 1.62.1
Expand All @@ -39,6 +46,7 @@ jobs:
- uses: actions/checkout@v3
with:
path: smithy-rs
ref: ${{ inputs.git_ref }}
# The models from aws-sdk-rust are needed to generate the full SDK for CI
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -84,6 +92,7 @@ jobs:
- uses: actions/checkout@v3
with:
path: smithy-rs
ref: ${{ inputs.git_ref }}
- name: Run ${{ matrix.test.action }}
uses: ./smithy-rs/.github/actions/docker-build
with:
Expand Down Expand Up @@ -113,6 +122,7 @@ jobs:
- uses: actions/checkout@v3
with:
path: smithy-rs
ref: ${{ inputs.git_ref }}
- name: Run ${{ matrix.test.action }}
uses: ./smithy-rs/.github/actions/docker-build
with:
Expand All @@ -128,6 +138,8 @@ jobs:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v3
with:
ref: ${{ inputs.git_ref }}
# Pinned to the commit hash of v2.1.0
- uses: Swatinem/rust-cache@b894d59a8d236e2979b247b80dac8d053ab340dd
with:
Expand Down Expand Up @@ -190,6 +202,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.git_ref }}
# Pinned to the commit hash of v2.1.0
- uses: Swatinem/rust-cache@b894d59a8d236e2979b247b80dac8d053ab340dd
with:
Expand Down Expand Up @@ -258,6 +272,7 @@ jobs:
- uses: actions/checkout@v3
with:
path: smithy-rs
ref: ${{ inputs.git_ref }}
- name: Run ${{ matrix.actions.action }}
uses: ./smithy-rs/.github/actions/docker-build
with:
Expand Down
135 changes: 106 additions & 29 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,44 @@

# Allow only one release to run at a time
concurrency:
group: release-smithy-rs
group: release-smithy-rs-${{ inputs.dry_run }}
cancel-in-progress: true

env:
rust_version: 1.62.1

name: Release smithy-rs
run-name: ${{ github.workflow }} - ${{ inputs.dry_run && 'Dry run' || 'Production run' }}
run-name: ${{ github.workflow }} ${{ inputs.semantic_version }} (${{ inputs.commit_sha }}) - ${{ inputs.dry_run && 'Dry run' || 'Production run' }}
on:
workflow_dispatch:
inputs:
commit_sha:
description: The SHA of the git commit that you want to release (e.g. b2318b0)
required: true
type: string
semantic_version:
description: The semver tag that you want to release (e.g. 0.52.1)
required: true
type: string
dry_run:
description: Dry runs will only produce release artifacts, but will not cut a release tag in GitHub nor publish to crates.io
description: Dry runs will only produce release artifacts, but they will not cut a release tag in GitHub nor publish to crates.io
required: true
type: boolean
default: true

jobs:
main-branch-check:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way we could check that the versions we will be publishing in gradle.properties aren't already published? Would be a nice sanity check that the gradle.properties was correctly updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be quite cumbersome.
Things can fail at any step, including publishing - leaving us with some unpublished runtime crates. I'm opting for building the workflow in such a way that all steps are idempotent, therefore allowing us to retry any transient failure by re-triggering the workflow from the right commit.

name: Check that workflow is running in main
runs-on: ubuntu-latest
steps:
- name: Main branch check
if: ${{ github.ref_name != 'main' }}
uses: actions/github-script@v6
with:
script: |
core.setFailed("The release workflow can only be ran on main (current branch: ${{ github.ref_name }})")

# If a release is kicked off before an image is built after push to main,
# or if a dry-run release is kicked off against a non-main branch to test
# automation changes, we'll need to build a base image to work against.
# This job will be a no-op if an image was already built on main.
# We'll need to build a base image to work against if:
# - a release was kicked off before the image build step triggered by a push to the release branch/main completed
# - a dry-run release was kicked off against a feature branch to test automation changes
# This job will be a no-op if an image had already been built.
acquire-base-image:
name: Acquire Base Image
needs:
- main-branch-check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
path: smithy-rs
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: Acquire base image
id: acquire
Expand All @@ -61,17 +57,74 @@ jobs:

release-ci:
name: Prerelease checks
if: inputs.dry_run == false
needs:
- acquire-base-image
uses: ./.github/workflows/ci.yml
with:
run_sdk_examples: false
git_ref: ${{ inputs.commit_sha }}

get-or-create-release-branch:
name: Get or create a release branch
needs:
- release-ci
outputs:
release_branch: ${{ steps.branch-push.outputs.release_branch }}
new_release_series: ${{ steps.branch-push.outputs.new_release_series }}
steps:
- uses: actions/checkout@v3
with:
ref: ${{ inputs.commit_sha }}
token: ${{ secrets.RELEASE_AUTOMATION_BOT_PAT }}
- name: Get or create release branch
id: branch-push
shell: bash
env:
SEMANTIC_VERSION: ${{ inputs.semantic_version }}
DRY_RUN: ${{ inputs.dry_run }}
run: |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider pulling this out to a separate shell script file so that it can be easily tested locally

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in dd472e4
Shellcheck found a lot of issues 😅 Thanks for pointing it out.

set -e

./.github/scripts/get-or-create-release-branch.sh output
cat output > $GITHUB_OUTPUT

upgrade-gradle-properties:
name: Upgrade gradle.properties
if: inputs.dry_run == false
needs:
- get-or-create-release-branch
outputs:
commit_sha: ${{ steps.gradle-push.outputs.commit_sha }}
release_branch: ${{ needs.get-or-create-release-branch.outputs.release_branch }}
steps:
- uses: actions/checkout@v3
with:
ref: ${{ inputs.release_branch }}
token: ${{ secrets.RELEASE_AUTOMATION_BOT_PAT }}
- name: Upgrade gradle.properties
uses: ./smithy-rs/.github/actions/docker-build
with:
action: upgrade-gradle-smithy-rs-release ${{ inputs.semantic_version }}
- name: Push gradle.properties changes
id: gradle-push
shell: bash
env:
SEMANTIC_VERSION: ${{ inputs.semantic_version }}
DRY_RUN: ${{ inputs.dry_run }}
run: |
if [[ git diff-index --quiet HEAD ]]; then
# The file was actually changed, we need to commit and push the changes
git commit gradle.properties --message "Upgrade the smithy-rs runtime crates version to ${SEMANTIC_VERSION}"
echo "Pushing upgraded gradle.properties commit..."
git push origin
fi
echo "commit_sha=$(git rev-parse --short HEAD)" > $GITHUB_OUTPUT

release:
name: Release
needs:
- acquire-base-image
- release-ci
- upgrade-gradle-properties
runs-on: ubuntu-latest
steps:
- name: Install Rust
Expand All @@ -81,6 +134,7 @@ jobs:
- name: Checkout smithy-rs
uses: actions/checkout@v3
with:
ref: ${{ needs.upgrade-gradle-properties.outputs.release_branch }}
path: smithy-rs
token: ${{ secrets.RELEASE_AUTOMATION_BOT_PAT }}
- name: Generate release artifacts
Expand All @@ -93,13 +147,8 @@ jobs:
shell: bash
working-directory: smithy-rs-release/smithy-rs
run: |
if [[ "${{ inputs.dry_run }}" == "true" ]]; then
echo "Pushing a preview of the release to the smithy-rs-release-preview branch"
git push --force origin HEAD:smithy-rs-release-preview
else
echo "Pushing release commits..."
git push origin
fi
echo "Pushing release commits..."
git push origin
- name: Tag release
uses: actions/github-script@v6
with:
Expand Down Expand Up @@ -133,3 +182,31 @@ jobs:
else
publisher publish -y --location .
fi

trim-changelog-next-on-main:
name: Remove released entries from CHANGELOG.next.toml on the main branch
if: inputs.dry_run == false && needs.get-or-create-release-branch.outputs.new_release_series == true
Comment on lines +186 to +188
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDK changelog entries need to end up in aws/SDK_CHANGELOG.next.json upon release so that the SDK changelog can be generated when it is released. It currently uses the changelogger split subcommand to accomplish this. Does this new release process preserve that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - the aws/SDK_CHANGELOG.next.json will be on the release branch and it's generated in the previous step of the workflow.

needs:
- get-or-create-release-branch
- release
runs-on: ubuntu-latest
steps:
- name: Checkout smithy-rs
uses: actions/checkout@v3
with:
ref: ${{ inputs.commit_sha }}
token: ${{ secrets.RELEASE_AUTOMATION_BOT_PAT }}
- name: Empty CHANGELOG.next.toml
uses: ./smithy-rs/.github/actions/docker-build
with:
action: generate-new-changelog-next-toml
- name: Push smithy-rs changes
shell: bash
run: |
# This will fail if other commits have been pushed to `main` after `commit_sha`
# In particular, this will ALWAYS fail if you are creating a new release series from
# a commit that is not the current tip of `main`.
# We can build more refined automation to handle this case in the future - until then, it'll require
# a manual PR to edit the current CHANGELOG.next.toml file and remove the released entries.
git commit CHANGELOG.next.toml --message "Remove released entries from \`CHANGELOG.next.toml\`"
git push origin main
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ rust.msrv=1.62.1
org.gradle.jvmargs=-Xmx1024M

# Version number to use for the generated runtime crates
smithy.rs.runtime.crate.version=0.54.1
smithy.rs.runtime.crate.version=0.0.0-smithy-rs-head

kotlin.code.style=official

Expand Down
16 changes: 16 additions & 0 deletions tools/changelogger/src/init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

use crate::render::EXAMPLE_ENTRY;
use clap::Parser;
use std::io::Write;

#[derive(Parser, Debug, Eq, PartialEq)]
pub struct InitArgs {}

pub fn subcommand_init(_args: &InitArgs) -> anyhow::Result<()> {
writeln!(std::io::stdout(), "{}", EXAMPLE_ENTRY)?;
Ok(())
}
1 change: 1 addition & 0 deletions tools/changelogger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
*/

pub mod entry;
pub mod init;
pub mod render;
pub mod split;
Loading