Skip to content

Commit

Permalink
chore: automate the release process (#984)
Browse files Browse the repository at this point in the history
* fix: tendermint-types keywords

* feat: add release.yaml to CI

* chore: update RELEASES.md

* add newline at the end of files

* fix: apply reviewer suggestions

* minor fix and lints for release script

* rm braces on individually quoted variables

---------

Co-authored-by: Ranadeep Biswas <[email protected]>
  • Loading branch information
Farhad-Shabani and rnbguy authored Nov 24, 2023
1 parent 8c1766f commit 3703e29
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 10 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Attempts to perform a release when a particular tag is pushed. This uses the
# `./scripts/release.sh`, and assumes that the CRATES_TOKEN secret has been set
# and contains an API token with which we can publish our crates to crates.io.
#
# If release operation fails partway through due to a temporary error (e.g. the
# crate being published depends on the crate published just prior, but the prior
# crate isn't yet available via crates.io), one can simply rerun this workflow.
# The release.sh script aims to be an idempotent operation, skipping the
# publishing of crates that have already been published.
name: Release

on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v0.26.0, v1.0.0
- "v[0-9]+.[0-9]+.[0-9]+-pre.[0-9]+" # e.g. v0.26.0-pre.1

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Publish crates
run: ./scripts/release.sh
env:
CRATES_TOKEN: ${{ secrets.CRATES_TOKEN }}
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ members = [
"ibc-clients/ics07-tendermint/types",
"ibc-clients/ics07-tendermint",
"ibc-clients",
"ibc-core/ics24-host/cosmos",
"ibc-apps/ics20-transfer/types",
"ibc-apps/ics20-transfer",
"ibc-apps",
"ibc-core/ics24-host/cosmos",
"ibc-data-types",
"ibc",
"ibc-query",
Expand Down Expand Up @@ -68,7 +68,6 @@ ibc-core = { version = "0.48.0", path = "./ibc-core", default-feature
ibc-clients = { version = "0.48.0", path = "./ibc-clients", default-features = false }
ibc-apps = { version = "0.48.0", path = "./ibc-apps", default-features = false }
ibc-primitives = { version = "0.48.0", path = "./ibc-primitives", default-features = false }
ibc-testkit = { version = "0.48.0", path = "./ibc-testkit" }
ibc-derive = { version = "0.4.0", path = "./ibc-derive" }

ibc-core-client = { version = "0.48.0", path = "./ibc-core/ics02-client", default-features = false }
Expand Down
25 changes: 18 additions & 7 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Our release process is as follows:
2. Publish `ibc-derive` with `cargo publish -p ibc-derive`
4. Bump the versions of all crates to the new version in their Cargo.toml and in
the root `Cargo.toml` as well, and push these changes to the release PR.
- If you released a new version of `ibc-derive` in step 3, make sure to
- If you released a new version of `ibc-derive` in step 3, make sure to
update that dependency.
5. Run `cargo doc -p ibc --all-features --open` locally to double-check that all
the documentation compiles and seems up-to-date and coherent. Fix any
Expand All @@ -32,14 +32,25 @@ Our release process is as follows:
work. Fix any potential issues here and push them to the release PR.
7. Mark the PR as **Ready for Review** and incorporate feedback on the release.
8. Once approved, merge the PR, and pull the `main` branch.
9. Publish each package to crates.io by running `cargo publish -p <PACKAGE_NAME>`
in the order specified in the workspace `Cargo.toml`.
10. Create a signed tag and push it to GitHub: `git tag -s -a vX.Y.Z`. In the
tag message, write the version and the link to the corresponding section of
the changelog.
- Push the tag with `git push --tags`
9. Create a signed tag `git tag -s -a vX.Y.Z`. In the tag message, write the
version and the link to the corresponding section of the changelog. Then push
the tag to GitHub with `git push --tags`.
- The [release workflow][release.yml] will run the [`release.sh`] script in a
CI worker.
10. If some crates have not been released, check the cause of the failure and
act accordingly:
1. In case of intermittent problems with the registry, rerun the script
locally to publish any missing crates from this release. This step
requires the appropriate privileges to push crates to [crates.io].
2. In case the problems arise from the source files, fix them, bump a new
patch version (e.g. `v0.48.1`) and repeat the process with its
corresponding new tag.
11. Once the tag is pushed, create a GitHub release and append
`[📖CHANGELOG](https://github.com/cosmos/ibc-rs/blob/main/CHANGELOG.md#vXYZ)`
to the release description.

All done! 🎉

[crates.io]: https://crates.io
[`release.sh`]: https://github.com/cosmos/ibc-rs/blob/main/scripts/release.sh
[release.yml]: https://github.com/cosmos/ibc-rs/blob/main/.github/workflows/release.yml
2 changes: 1 addition & 1 deletion ibc-clients/ics07-tendermint/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = { workspace = true }
rust-version = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
keywords = ["blockchain", "cosmos", "ibc", "transfer", "ics20", "types"]
keywords = ["blockchain", "cosmos", "ibc", "tendermint", "types"]
readme = "./../../README.md"
description = """
Maintained by `ibc-rs`, encapsulates essential ICS-07 Tendermint Client data structures and domain types,
Expand Down
107 changes: 107 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/bash

# release.sh will hopefully allow us to publish all of the necessary crates in
# this repo in the right order. It is assumed that only one person will be
# releasing all crates at the same time.

set -euo pipefail

# A space-separated list of all the crates we want to publish, in the order in
# which they must be published. It's important to respect this order, since
# each subsequent crate depends on one or more of the preceding ones.
DEFAULT_CRATES=(
"ibc-primitives"
"ibc-core-host-types"
"ibc-core-router-types"
"ibc-core-commitment-types"
"ibc-core-client-types"
"ibc-core-connection-types"
"ibc-core-channel-types"
"ibc-core-handler-types"
"ibc-core-client-context"
"ibc-core-host"
"ibc-core-router"
"ibc-core-client"
"ibc-core-connection"
"ibc-core-channel"
"ibc-core-handler"
"ibc-core"
"ibc-client-tendermint-types"
"ibc-client-tendermint"
"ibc-clients"
"ibc-app-transfer-types"
"ibc-app-transfer"
"ibc-apps"
"ibc-core-host-cosmos"
"ibc-data-types"
"ibc"
"ibc-query"
"ibc-testkit"
)

# Allows us to override the crates we want to publish.
CRATES=("${@:-${DEFAULT_CRATES[@]}}")

# Additional flags to pass to the "cargo publish" operation for every crate we
# publish.
CARGO_PUBLISH_FLAGS=""

# Allow us to specify a crates.io API token via environment variables. Mostly
# for CI use.
if [ "$CRATES_TOKEN" != "" ]; then
CARGO_PUBLISH_FLAGS="${CARGO_PUBLISH_FLAGS} --token ${CRATES_TOKEN}"
fi

get_manifest_path() {
cargo metadata --format-version 1 | jq -r '.packages[]|select(.name == "'"${1}"'")|.manifest_path'
}

get_local_version() {
cargo metadata --format-version 1 | jq -r '.packages[]|select(.name == "'"${1}"'")|.version'
}

check_version_online() {
curl -s "https://crates.io/api/v1/crates/${1}" | jq -r 'try .versions[]|select(.num == "'"${2}"'").updated_at'
}

publish() {
echo "Publishing crate $1..."
cargo publish --manifest-path "$(get_manifest_path "${1}")" "$CARGO_PUBLISH_FLAGS"
echo ""
}

wait_until_available() {
echo "Waiting for crate ${1} to become available via crates.io..."
for retry in {1..5}; do
sleep 5
ONLINE_DATE="$(check_version_online "${1}" "${2}")"
if [ "$ONLINE_DATE" != "" ]; then
echo "Crate ${crate} is now available online"
break
else
if [ "$retry" == 5 ]; then
echo "ERROR: Crate should have become available by now"
exit 1
else
echo "Not available just yet. Waiting a few seconds..."
fi
fi
done
echo "Waiting an additional 10 seconds for crate to propagate through CDN..."
sleep 10
}

echo "Attempting to publish crate(s): ${CRATES}"

for crate in "$CRATES"; do
VERSION="$(get_local_version "$crate")"
ONLINE_DATE="$(check_version_online "$crate" "$VERSION")"
echo "${crate} version number: ${VERSION}"
if [ "$ONLINE_DATE" != "" ]; then
echo "${crate} ${VERSION} has already been published at ${ONLINE_DATE}, skipping"
continue
fi

publish "$crate"
wait_until_available "$crate" "$VERSION"
done

0 comments on commit 3703e29

Please sign in to comment.