Skip to content

Commit

Permalink
feat: add release.yaml to CI
Browse files Browse the repository at this point in the history
  • Loading branch information
Farhad-Shabani committed Nov 24, 2023
1 parent c767370 commit ff8ffc0
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 2 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
105 changes: 105 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/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 -e

# 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 [ -n "${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 [ -n "${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 [ -n "${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 ff8ffc0

Please sign in to comment.