Skip to content

Commit 794568e

Browse files
authored
Add release automation (#346)
See `RELEASING.md` for directions
1 parent edd1b26 commit 794568e

File tree

16 files changed

+254
-44
lines changed

16 files changed

+254
-44
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ env:
2626
before_script:
2727
- |
2828
if [ "$TRAVIS_OS_NAME" = 'windows' ]; then
29-
powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.15.3" -target "x86_64-pc-windows-msvc"
29+
powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.19.1" -target "x86_64-pc-windows-msvc"
3030
fi
3131
- |
3232
if [ "$TRAVIS_OS_NAME" = 'linux' ]; then
33-
_build/cargo-make.sh "0.15.3" "x86_64-unknown-linux-musl"
33+
_build/cargo-make.sh "0.19.1" "x86_64-unknown-linux-musl"
3434
fi
3535
- |
3636
if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
37-
_build/cargo-make.sh "0.15.3" "x86_64-apple-darwin"
37+
_build/cargo-make.sh "0.19.1" "x86_64-apple-darwin"
3838
fi
3939
script:
4040
- cargo make workspace-ci-flow --no-workspace

Makefile.toml

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,87 @@
22
[env]
33
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = "true"
44

5-
# Run `cargo make release` to push a new minor release of every crate.
5+
#
6+
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release` to push a new release of every crate.
7+
# Run `RELEASE_LEVEL=(patch|major|minor) CARGO_MAKE_WORKSPACE_SKIP_MEMBERS="crate1;crate2;" cargo make release`
8+
# to push a new release of some crates.
9+
#
10+
611
[tasks.release]
7-
args = ["release", "--config", "../_build/release.toml"]
12+
condition = { env_set = [ "RELEASE_LEVEL" ] }
13+
workspace = false
14+
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
15+
run_task = { name = "release-INTERNAL", fork = true }
16+
17+
18+
[tasks.release-some]
19+
condition = { env_set = [ "RELEASE_LEVEL", "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" ] }
20+
workspace = false
21+
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
22+
run_task = { name = "release-some-INTERNAL", fork = true }
23+
24+
# Hack to filter out crates we do not want to release.
25+
# See <https://github.com/sagiegurari/cargo-make/issues/212#issuecomment-481123564>
26+
[tasks.release-INTERNAL]
27+
private = true
28+
condition = { env_set = [ "RELEASE_LEVEL" ] }
29+
command = "cargo-release"
30+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "${RELEASE_LEVEL}"]
831

9-
# Run `cargo make release-patch` to push a new patch release of every crate.
10-
[tasks.release-patch]
11-
args = ["release", "--config", "../_build/release.toml", "patch"]
1232

13-
# Run `cargo make release-dry-run` to do a dry run.
33+
#
34+
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-dry-run` to do a dry run.
35+
# Run `RELEASE_LEVEL=(patch|major|minor) CARGO_MAKE_WORKSPACE_SKIP_MEMBERS="crate1;crate2;" cargo make release-some-dry-run`
36+
# to do a dry run with some crates.
37+
#
38+
1439
[tasks.release-dry-run]
40+
condition = { env_set = [ "RELEASE_LEVEL" ] }
41+
workspace = false
42+
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
43+
run_task = { name = "release-dry-run-INTERNAL", fork = true }
44+
45+
[tasks.release-some-dry-run]
46+
condition = { env_set = [ "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS", "RELEASE_LEVEL" ] }
47+
workspace = false
48+
run_task = { name = "release-some-dry-run-INTERNAL", fork = true }
49+
50+
51+
# Hack to filter out crates we do not want to release.
52+
# See <https://github.com/sagiegurari/cargo-make/issues/212#issuecomment-481123564>
53+
[tasks.release-dry-run-INTERNAL]
54+
private = true
55+
condition = { env_set = [ "RELEASE_LEVEL" ] }
56+
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
1557
description = "Run `cargo-release --dry-run` for every crate"
16-
command = "${HOME}/src/cargo-release/target/debug/cargo-release"
17-
args = ["release", "--config", "../_build/release.toml", "--dry-run"]
58+
command = "cargo-release"
59+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--dry-run", "${RELEASE_LEVEL}"]
60+
61+
#
62+
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-local-test` to do actually make changes locally but
63+
# not push them up to crates.io or Github.
64+
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-some-local-test` to do actually make changes locally but
65+
# not push some crates up to crates.io or Github.
66+
#
67+
68+
[tasks.release-local-test]
69+
condition = { env_set = [ "RELEASE_LEVEL" ] }
70+
workspace = false
71+
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
72+
run_task = { name = "release-local-test-INTERNAL", fork = true }
73+
74+
75+
[tasks.release-some-local-test]
76+
condition = { env_set = [ "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS", "RELEASE_LEVEL" ] }
77+
workspace = false
78+
run_task = { name = "release-some-local-test-INTERNAL", fork = true }
79+
80+
81+
# Hack to filter out crates we do not want to release.
82+
# See <https://github.com/sagiegurari/cargo-make/issues/212#issuecomment-481123564>
83+
[tasks.release-local-test-INTERNAL]
84+
private = true
85+
condition = { env_set = [ "RELEASE_LEVEL" ] }
86+
description = "Run `cargo-release` for every crate, but only make changes locally"
87+
command = "cargo-release"
88+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"]

RELEASING.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# How to release new crate versions
2+
3+
## Prerequisites
4+
5+
We use [`cargo-make`](cargo-make) and [`cargo-release`](cargo-release) to automate crate releases. You will need to install them locally:
6+
7+
- `cargo install -f cargo-make`
8+
- `cargo install -f cargo-release`
9+
10+
## Preparing for a release
11+
12+
There are two general classes of release and each require running different automation commands:
13+
14+
1. All public workspace crates should be released and all share the same release level ("patch", "minor", "major"). _These commands take the form `release-[whatever]`._
15+
16+
2. A subset of workspace crates need to be released, or not all crate releases share the same release level. _These commands start with `release-skip-[whatever]`._
17+
18+
## Determine new release level
19+
20+
For each crate, determine the desired release level (`patch`, `minor`, `major`). Set the `RELEASE_LEVEL` env variable to the desired release level.
21+
22+
## Determine which crates to exclude
23+
24+
If a subset of workspace crates need to be released, or not all crate releases share the same release level, set the `CARGO_MAKE_WORKSPACE_SKIP_MEMBERS` env
25+
variable to filter out specific workspace crates. The value is a list of semicolon-delineated crate names or a regular expression.
26+
27+
**Important:** You likely want to always exclude `integration_tests/*`.
28+
29+
## Dry run
30+
31+
It is a good idea to do a dry run to sanity check what actions will be performed.
32+
33+
- For case #1 above, run `cargo make release-dry-run`.
34+
35+
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.
36+
37+
- For case #2 above, run `cargo make release-some-dry-run`.
38+
39+
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL` or `CARGO_MAKE_WORKSPACE_SKIP_MEMBERS`.
40+
41+
## Local test
42+
43+
Not everything is captured in the dry run. It is a good idea to run a local test.
44+
In a local test, all the release actions are performed on your local checkout
45+
but nothing is pushed to Github or crates.io.
46+
47+
- For case #1 above, run `cargo make release-local-test`.
48+
49+
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.
50+
51+
- For case #2 above, run `cargo make release-some-local-test`.
52+
53+
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL` or `CARGO_MAKE_WORKSPACE_SKIP_MEMBERS`.
54+
55+
After, your local git repository should have the changes ready to push to Github.
56+
Use `git rebase -i HEAD~10` and drop the new commits.
57+
58+
## Release
59+
60+
After testing locally and via a dry run, it is time to release. A release
61+
consists of bumping versions, starting a new changelog section, pushing a tag to Github, and updating crates.io. This should all be handled by running the automated commands.
62+
63+
- For case #1 above, run `cargo make release`.
64+
65+
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.
66+
67+
- For case #2 above, run `cargo make release-some`.
68+
69+
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL` or `CARGO_MAKE_WORKSPACE_SKIP_MEMBERS`.
70+
71+
[cargo-make]: https://github.com/sagiegurari/cargo-make
72+
[cargo-release]: https://github.com/sunng87/cargo-release

_build/azure-pipelines-template.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ jobs:
3636
displayName: Query rust and cargo versions
3737
- ${{ if eq(parameters.name, 'Linux') }}:
3838
# Linux.
39-
- script: _build/cargo-make.sh "0.15.3" "x86_64-unknown-linux-musl"
39+
- script: _build/cargo-make.sh "0.19.1" "x86_64-unknown-linux-musl"
4040
displayName: Install cargo-make binary
4141
- ${{ if eq(parameters.name, 'macOS') }}:
4242
# Mac.
43-
- script: _build/cargo-make.sh "0.15.3" "x86_64-apple-darwin"
43+
- script: _build/cargo-make.sh "0.19.1" "x86_64-apple-darwin"
4444
displayName: Install cargo-make binary
4545
- ${{ if eq(parameters.name, 'Windows') }}:
4646
# Windows.
47-
- script: powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.15.3" -target "x86_64-pc-windows-msvc"
47+
- script: powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.19.1" -target "x86_64-pc-windows-msvc"
4848
displayName: Install cargo-make binary
4949
- script: cargo make workspace-ci-flow --no-workspace
5050
env: { CARGO_MAKE_RUN_CODECOV: true }

_build/release.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
44
tag-message = "Release {{crate_name}} {{version}}"
55
upload-doc = false
66
pre-release-replacements = [
7-
{file="CHANGELOG.md", search="# master", replace="# master\n\n- No changes yet\n\n# [[{{version}}] {{date}}](https://github.com/graphql-rust/juniper/releases/tag/{{crate_name}}-{{version}})"},
7+
{file="CHANGELOG.md", search="# master", replace="# master\n\n- Compatibility with the latest `juniper`.\n\n# [[{{version}}] {{date}}](https://github.com/graphql-rust/juniper/releases/tag/{{crate_name}}-{{version}})"},
88
]

azure-pipelines.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
jobs:
2+
###################################################
3+
# Formatting
4+
###################################################
5+
26
- job: check_formatting
37
displayName: Check formatting
48
pool:
@@ -12,6 +16,10 @@ jobs:
1216
$HOME/.cargo/bin/cargo fmt -- --check
1317
displayName: Run rustfmt
1418
19+
###################################################
20+
# Book
21+
###################################################
22+
1523
- job: run_book_tests
1624
displayName: Book code example tests
1725
pool:
@@ -42,6 +50,10 @@ jobs:
4250
- script: |
4351
./docs/book/ci-build.sh master
4452
53+
###################################################
54+
# Main Builds
55+
###################################################
56+
4557
- template: _build/azure-pipelines-template.yml
4658
parameters:
4759
name: Linux
@@ -56,3 +68,38 @@ jobs:
5668
parameters:
5769
name: Windows
5870
vmImage: vs2017-win2016
71+
72+
###################################################
73+
# Releases
74+
###################################################
75+
76+
- job: check_release_automation
77+
displayName: Check release automation
78+
pool:
79+
vmImage: ubuntu-16.04
80+
steps:
81+
- script: |
82+
curl https://sh.rustup.rs -sSf | sh -s -- -y
83+
displayName: Install stable Rust
84+
- script: |
85+
_build/cargo-make.sh "0.19.1" "x86_64-unknown-linux-musl"
86+
displayName: Install cargo-make binary
87+
- script: |
88+
$HOME/.cargo/bin/cargo install cargo-release
89+
displayName: Install cargo-release binary
90+
- script: |
91+
git config --local user.name "Release Test Bot"
92+
git config --local user.email "[email protected]"
93+
displayName: Set up git
94+
- script: |
95+
RELEASE_LEVEL="minor" "$HOME/.cargo/bin/cargo" make release-dry-run
96+
displayName: Dry run mode
97+
- script: |
98+
RELEASE_LEVEL="minor" "$HOME/.cargo/bin/cargo" make release-local-test
99+
displayName: Local test mode
100+
- script: |
101+
git --no-pager log -p HEAD...HEAD~20
102+
displayName: Echo local changes
103+
- script: |
104+
cargo make workspace-ci-flow --no-workspace
105+
displayName: Make sure build and tests still work

integration_tests/juniper_tests/Makefile.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ args = ["test", "--verbose"]
77

88
[tasks.release]
99
disabled = true
10-
11-
[tasks.release-patch]
10+
[tasks.release-some]
11+
disabled = true
12+
[tasks.release-local-test]
13+
disabled = true
14+
[tasks.release-some-local-test]
1215
disabled = true
13-
1416
[tasks.release-dry-run]
1517
disabled = true
18+
[tasks.release-some-dry-run]
19+
disabled = true

juniper/Makefile.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
[tasks.release]
2-
args = ["release"]
1+
# This is needed as the release config is at a different path than the top-level
2+
# release config.
33

4-
[tasks.release-patch]
5-
args = ["release", "patch"]
4+
[tasks.release-INTERNAL]
5+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "${RELEASE_LEVEL}"]
66

7-
[tasks.release-dry-run]
8-
args = ["release", "--dry-run"]
7+
[tasks.release-dry-run-INTERNAL]
8+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"]
9+
10+
[tasks.release-local-test-INTERNAL]
11+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"]

juniper/release.toml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@ pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
44
tag-message = "Release {{crate_name}} {{version}}"
55
upload-doc = false
66
pre-release-replacements = [
7+
# Juniper's changelog
78
{file="CHANGELOG.md", search="# master", replace="# master\n\n- No changes yet\n\n# [[{{version}}] {{date}}](https://github.com/graphql-rust/juniper/releases/tag/{{crate_name}}-{{version}})"},
8-
{file="../integration_tests/juniper_tests/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
9-
{file="../juniper_hyper/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
10-
{file="../juniper_iron/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
11-
{file="../juniper_rocket/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
12-
{file="../juniper_tests/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
13-
{file="../juniper_warp/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
14-
{file="release.toml", search="0.11.0", replace="{{version}}"},
9+
# Tests.
10+
{file="../integration_tests/juniper_tests/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
11+
# Hyper
12+
{file="../juniper_hyper/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
13+
{file="../juniper_hyper/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},
14+
# Iron
15+
{file="../juniper_iron/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
16+
{file="../juniper_iron/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},
17+
# Rocket
18+
{file="../juniper_rocket/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
19+
{file="../juniper_rocket/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},
20+
# Warp
21+
{file="../juniper_warp/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
22+
{file="../juniper_warp/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},
23+
1524
]

juniper_codegen/Makefile.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
[tasks.release]
2-
args = ["release"]
1+
# This is needed as the release config is at a different path than the top-level
2+
# release config.
33

4-
[tasks.release-patch]
5-
args = ["release", "patch"]
4+
[tasks.release-INTERNAL]
5+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "${RELEASE_LEVEL}"]
66

7-
[tasks.release-dry-run]
8-
args = ["release", "--dry-run"]
7+
[tasks.release-dry-run-INTERNAL]
8+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"]
9+
10+
[tasks.release-local-test-INTERNAL]
11+
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"]

juniper_codegen/release.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
44
tag-message = "Release {{crate_name}} {{version}}"
55
upload-doc = false
66
pre-release-replacements = [
7-
{file="../juniper/Cargo.toml", search="juniper_codegen = { version = \"0.11.0\"", replace="juniper_codegen = { version = \"{{version}}\""},
8-
{file="release.toml", search="0.11.0", replace="{{version}}"},
7+
{file="../juniper/Cargo.toml", search="juniper_codegen = \\{ version = \"[^\"]+\"", replace="juniper_codegen = { version = \"{{version}}\""},
98
]

juniper_hyper/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# master
22

3+
- Compatibility with the latest `juniper`.
4+
35
# 0.2.0 [2018-12-18]
46

57
## Breaking changes

juniper_iron/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# master
22

3-
- No changes yet
3+
- Compatibility with the latest `juniper`.
44

55
# [0.3.0] 2018-12-17
66

juniper_rocket/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# master
22

3-
- No changes yet
3+
- Compatibility with the latest `juniper`.
44

55
# [0.2.0] 2018-12-17
66

0 commit comments

Comments
 (0)