Release process and CI (#1240)

* Fix the crate versions

* release.toml: add cargo-release config

* CONTRIBUTING.md: Update Releasing section

* feat: add release github workflow

* feat: generate CHANGELOGs and create github releases in CI
This commit is contained in:
Meet Mangukiya 2022-05-14 01:40:05 +05:30 committed by GitHub
parent 135bca4680
commit 6d5bebd860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 182 additions and 74 deletions

37
.github/workflows/release-tag-from.js vendored Normal file
View File

@ -0,0 +1,37 @@
const semver = require("semver");
const previousVersion = (currentVersion, releaseType) => {
const parsedVersion = semver.parse(currentVersion);
switch (releaseType) {
case "major": {
return `v${parsedVersion.major - 1}.0.0`;
}
case "minor": {
return `v${parsedVersion.major}.${parsedVersion.minor - 1}.0`;
}
case "patch": {
return `v${parsedVersion.major}.${parsedVersion.minor}.${
parsedVersion.patch - 1
}`;
}
case "alpha": {
return `v${parsedVersion.major}.${parsedVersion.minor}.${
parsedVersion.patch
}-alpha.${parsedVersion.prerelease[1] - 1}`;
}
case "beta": {
return `v${parsedVersion.major}.${parsedVersion.minor}.${
parsedVersion.patch
}-beta.${parsedVersion.prerelease[1] - 1}`;
}
case "rc": {
return `v${parsedVersion.major}.${parsedVersion.minor}.${
parsedVersion.patch
}-rc.${parsedVersion.prerelease[1] - 1}`;
}
}
};
const [currentVersion, releaseType] = process.argv.slice(-2);
console.log(previousVersion(currentVersion, releaseType));

99
.github/workflows/releases.yml vendored Normal file
View File

@ -0,0 +1,99 @@
name: Release
on:
schedule:
- cron: "0 0 * * 0"
workflow_dispatch:
inputs:
release_type:
type: choice
description: Release type
options:
- major
- minor
- patch
- rc
- beta
- alpha
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
env:
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
RELEASE_TYPE: ${{ github.event.inputs.release_type }}
steps:
- name: Checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Configure git
run: |
git config user.name github-actions
git config user.email github-actions@github.com
- name: Rust stable
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- uses: Swatinem/rust-cache@v1
with:
cache-on-failure: true
- name: Install cargo-release
uses: actions-rs/install@v0.1
with:
crate: cargo-release
version: latest
- name: Cargo login
run: |
cargo login $CARGO_TOKEN
- name: Dry-run cargo release
run: |
cargo release --workspace ${RELEASE_TYPE:-alpha} --exclude ethers-wasm
- name: Publish release
run: |
cargo release --workspace ${RELEASE_TYPE:-alpha} --exclude ethers-wasm --execute --no-confirm
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 14
- run: |
npm i semver
- name: Install git-cliff
uses: actions-rs/install@v0.1
with:
crate: git-cliff
version: latest
- name: Publish changelog
id: changelog
run: |
current_version=$(git tag --contains HEAD -l "v*" | head -1)
from_version=$(node .github/workflows/release-tag-from.js $current_version $RELEASE_TYPE)
echo from $from_version to $current_version
echo "::set-output name=release_version::$(echo $current_version)"
if git rev-parse "$from_version" >/dev/null 2>&1; then
echo "tag exists, can generate changelog";
else
echo "tag does not exist, cannot generate changelog, publish github release manually"
exit 0
fi
git cliff $from_version..$current_version > GENERATED_CHANGELOG.md
cat GENERATED_CHANGELOG.md
- name: Create GitHub release
id: release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_VERSION: ${{ steps.changelog.outputs.release_version }}
with:
tag_name: ${{ env.RELEASE_VERSION }}
release_name: ${{ env.RELEASE_VERSION }}
body_path: GENERATED_CHANGELOG.md
prerelease: ${{ env.RELEASE_TYPE == 'alpha' }}

View File

@ -189,7 +189,7 @@ of `ethers-rs` will create an instance of `Provider` is by using
`Provider::<T>::try_from`, this is how the documentation test is structured. `Provider::<T>::try_from`, this is how the documentation test is structured.
Lines that start with `/// #` are removed when the documentation is generated. Lines that start with `/// #` are removed when the documentation is generated.
They are only there to get the test to run. They are only there to get the test to run.
### Commits ### Commits
@ -370,58 +370,28 @@ _Adapted from the [Tokio contributing guide](https://github.com/tokio-rs/tokio/b
Since the ethers-rs project consists of a number of crates, many of which depend on Since the ethers-rs project consists of a number of crates, many of which depend on
each other, releasing new versions to crates.io can involve some complexities. each other, releasing new versions to crates.io can involve some complexities.
When releasing a new version of a crate, follow these steps: We use [`cargo-release`](https://github.com/crate-ci/cargo-release) to manage these
complexities and the whole release process.
1. **Ensure that the release crate has no path dependencies.** When the HEAD When releasing the workspace:
version of a ethers-rs crate requires unreleased changes in another ethers-rs crate,
the crates.io dependency on the second crate will be replaced with a path
dependency. Crates with path dependencies cannot be published, so before
publishing the dependent crate, any path dependencies must also be published.
This should be done through a form of depth-first tree traversal:
1. Starting with the first path dependency in the crate to be released, 1. **Perform a final audit for breaking changes.** Compare the HEAD version of
inspect the `Cargo.toml` for the dependency. If the dependency has any
path dependencies of its own, repeat this step with the first such
dependency.
2. Begin the release process for the path dependency.
3. Once the path dependency has been published to crates.io, update the
dependent crate to depend on the crates.io version.
4. When all path dependencies have been published, the dependent crate may
be published.
To verify that a crate is ready to publish, run:
```bash
bin/publish --dry-run <CRATE NAME> <CRATE VERSION>
```
2. **Update Cargo metadata.** After releasing any path dependencies, update the
`version` field in `Cargo.toml` to the new version, and the `documentation`
field to the docs.rs URL of the new version.
3. **Update other documentation links.** Update the `#![doc(html_root_url)]`
attribute in the crate's `lib.rs` and the "Documentation" link in the crate's
`README.md` to point to the docs.rs URL of the new version.
4. **Update the changelog for the crate.** Each crate in the ethers-rs repository
has its own `CHANGELOG.md` in that crate's subdirectory. Any changes to that
crate since the last release should be added to the changelog. Change
descriptions may be taken from the Git history, but should be edited to
ensure a consistent format, based on [Keep A Changelog][keep-a-changelog].
Other entries in that crate's changelog may also be used for reference.
5. **Perform a final audit for breaking changes.** Compare the HEAD version of
crate with the Git tag for the most recent release version. If there are any crate with the Git tag for the most recent release version. If there are any
breaking API changes, determine if those changes can be made without breaking breaking API changes, determine if those changes can be made without breaking
existing APIs. If so, resolve those issues. Otherwise, if it is necessary to existing APIs. If so, resolve those issues and make a `minor` change
make a breaking release, update the version numbers to reflect this. release. Otherwise, if it is necessary to make a breaking release, make a
6. **Open a pull request with your changes.** Once that pull request has been `major` change release.
approved by a maintainer and the pull request has been merged, continue to 2. **Dry run the release** by running `cargo release --workspace <release_type>`
the next step. 3. **Update the changelog for the crate.** Changelog for all crates go in
7. **Release the crate.** Run the following command: [`CHANGELOG.md`](./CHANGELOG.md). Any unreleased changes changelogs should
be moved to respective crates released changelogs. Change descriptions
may be taken from the Git history, but should be edited to ensure a consistent
format, based on [Keep A Changelog][keep-a-changelog]. Other entries in that
crate's changelog may also be used for reference.
4. **Release the crate.** Run the following command:
```bash ```bash
bin/publish <NAME OF CRATE> <VERSION> cargo release --workspace <release_type> --execute
``` ```
Your editor and prompt you to edit a message for the tag. Copy the changelog
entry for that release version into your editor and close the window.
[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog/blob/master/CHANGELOG.md [keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog/blob/master/CHANGELOG.md

20
Cargo.lock generated
View File

@ -1150,7 +1150,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers" name = "ethers"
version = "0.6.0" version = "0.6.2"
dependencies = [ dependencies = [
"bytes", "bytes",
"ethers-addressbook", "ethers-addressbook",
@ -1181,7 +1181,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-contract" name = "ethers-contract"
version = "0.6.0" version = "0.6.2"
dependencies = [ dependencies = [
"ethers-contract-abigen", "ethers-contract-abigen",
"ethers-contract-derive", "ethers-contract-derive",
@ -1203,7 +1203,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-contract-abigen" name = "ethers-contract-abigen"
version = "0.6.0" version = "0.6.3"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"cfg-if 1.0.0", "cfg-if 1.0.0",
@ -1226,7 +1226,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-contract-derive" name = "ethers-contract-derive"
version = "0.6.0" version = "0.6.3"
dependencies = [ dependencies = [
"ethers-contract-abigen", "ethers-contract-abigen",
"ethers-core", "ethers-core",
@ -1239,7 +1239,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-core" name = "ethers-core"
version = "0.6.0" version = "0.6.3"
dependencies = [ dependencies = [
"arrayvec 0.7.2", "arrayvec 0.7.2",
"bincode", "bincode",
@ -1268,7 +1268,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-derive-eip712" name = "ethers-derive-eip712"
version = "0.2.0" version = "0.2.2"
dependencies = [ dependencies = [
"ethers-contract", "ethers-contract",
"ethers-contract-derive", "ethers-contract-derive",
@ -1282,7 +1282,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-etherscan" name = "ethers-etherscan"
version = "0.2.0" version = "0.2.2"
dependencies = [ dependencies = [
"ethers-core", "ethers-core",
"ethers-solc", "ethers-solc",
@ -1301,7 +1301,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-middleware" name = "ethers-middleware"
version = "0.6.0" version = "0.6.2"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"ethers-contract", "ethers-contract",
@ -1329,7 +1329,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-providers" name = "ethers-providers"
version = "0.6.0" version = "0.6.2"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"auto_impl", "auto_impl",
@ -1366,7 +1366,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-signers" name = "ethers-signers"
version = "0.6.0" version = "0.6.2"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"coins-bip32", "coins-bip32",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ethers" name = "ethers"
version = "0.6.0" version = "0.6.2"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2021" edition = "2021"
@ -150,4 +150,4 @@ required-features = ["trezor"]
[[example]] [[example]]
name = "yubi" name = "yubi"
path = "examples/yubi.rs" path = "examples/yubi.rs"
required-features = ["yubi"] required-features = ["yubi"]

View File

@ -8,4 +8,4 @@ once_cell = "1.10.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
ethers-core = { path = "../ethers-core" } ethers-core = { path = "../ethers-core", version = "^0.6.0" }

View File

@ -1,7 +1,7 @@
[package] [package]
name = "ethers-contract" name = "ethers-contract"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.6.0" version = "0.6.2"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Smart contract bindings for the ethers-rs crate" description = "Smart contract bindings for the ethers-rs crate"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ethers-contract-abigen" name = "ethers-contract-abigen"
version = "0.6.0" version = "0.6.3"
authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
@ -41,4 +41,4 @@ rustls = ["reqwest/rustls-tls"]
[dev-dependencies] [dev-dependencies]
tempfile = "3.2.0" tempfile = "3.2.0"
ethers-solc = { path = "../../ethers-solc", default-features = false, features = ["project-util"] } ethers-solc = { version = "^0.3.0", path = "../../ethers-solc", default-features = false, features = ["project-util"] }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ethers-contract-derive" name = "ethers-contract-derive"
version = "0.6.0" version = "0.6.3"
authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "ethers-core" name = "ethers-core"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.6.0" version = "0.6.3"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Core structures for the ethers-rs crate" description = "Core structures for the ethers-rs crate"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ethers-derive-eip712" name = "ethers-derive-eip712"
version = "0.2.0" version = "0.2.2"
edition = "2018" edition = "2018"
description = "Custom derive macro for EIP-712 typed data" description = "Custom derive macro for EIP-712 typed data"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ethers-etherscan" name = "ethers-etherscan"
version = "0.2.0" version = "0.2.2"
authors = ["Matthias Seitz <matthias.seitz@outlook.de>", "Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Matthias Seitz <matthias.seitz@outlook.de>", "Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2018" edition = "2018"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "ethers-middleware" name = "ethers-middleware"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.6.0" version = "0.6.2"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Middleware implementations for the ethers-rs crate" description = "Middleware implementations for the ethers-rs crate"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "ethers-providers" name = "ethers-providers"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.6.0" version = "0.6.2"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Provider implementations for the ethers-rs crate" description = "Provider implementations for the ethers-rs crate"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "ethers-signers" name = "ethers-signers"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.6.0" version = "0.6.2"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Signer implementations for the ethers-rs crate" description = "Signer implementations for the ethers-rs crate"
@ -42,7 +42,7 @@ home = { version = "0.5.3", optional = true }
[dev-dependencies] [dev-dependencies]
ethers-contract = { version = "^0.6.0", path = "../ethers-contract", features = ["eip712", "abigen"]} ethers-contract = { version = "^0.6.0", path = "../ethers-contract", features = ["eip712", "abigen"]}
ethers-derive-eip712 = { version = "0.2.0", path = "../ethers-core/ethers-derive-eip712" } ethers-derive-eip712 = { version = "^0.2.0", path = "../ethers-core/ethers-derive-eip712" }
serde_json = { version = "1.0.64" } serde_json = { version = "1.0.64" }
tracing-subscriber = "0.3.11" tracing-subscriber = "0.3.11"
yubihsm = { version = "0.40.0", features = ["secp256k1", "usb", "mockhsm"] } yubihsm = { version = "0.40.0", features = ["secp256k1", "usb", "mockhsm"] }

View File

@ -44,8 +44,8 @@ path-slash = "0.1.4"
home = "0.5.3" home = "0.5.3"
# SVM is not WASM compatible yet. # SVM is not WASM compatible yet.
# svm = { package = "svm-rs", default-features = false, version = "0.2.7", optional = true } # svm = { package = "svm-rs", default-features = false, version = "0.2.7", optional = true }
svm = { package = "svm-rs", default-features = false, git = "https://github.com/roynalnaruto/svm-rs", optional = true, features = ["blocking"] } svm = { package = "svm-rs", version = "0.2.9", default-features = false, git = "https://github.com/roynalnaruto/svm-rs", optional = true, features = ["blocking"] }
svm-builds = { package = "svm-rs-builds", git = "https://github.com/roynalnaruto/svm-rs", optional = true} svm-builds = { package = "svm-rs-builds", version = "0.1.0", git = "https://github.com/roynalnaruto/svm-rs", optional = true}
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
# NOTE: this enables wasm compatibility for getrandom indirectly # NOTE: this enables wasm compatibility for getrandom indirectly

View File

@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"]
default = ["console_error_panic_hook"] default = ["console_error_panic_hook"]
[dependencies] [dependencies]
ethers = { path = "../..", features = ["abigen", "legacy", "ws"] } ethers = { path = "../..", version = "0.6.0", features = ["abigen", "legacy", "ws"] }
serde_derive = "1.0.126" serde_derive = "1.0.126"
wasm-bindgen-futures = "0.4.30" wasm-bindgen-futures = "0.4.30"
serde_json = "1.0.64" serde_json = "1.0.64"

2
release.toml Normal file
View File

@ -0,0 +1,2 @@
consolidate-commits = false
consolidate-pushes = true