Skip to content

Add release automation #346

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

Merged
merged 28 commits into from
May 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
98296da
Add release automation
LegNeato Apr 9, 2019
1e98e12
Add CI support for release dry run
LegNeato May 12, 2019
c915f36
Update cargo-make to use fork
LegNeato May 12, 2019
2c5db72
Fix up automation test
LegNeato May 12, 2019
eb82502
Fix cargo command
LegNeato May 12, 2019
452eace
Use `--no-confirm` for `release-local-test`
LegNeato May 12, 2019
5ca077e
Fix missing no-confirm
LegNeato May 12, 2019
cb4a19d
Override all internal tasks
LegNeato May 12, 2019
16be139
Fix git config
LegNeato May 12, 2019
57cc07a
Fix path
LegNeato May 12, 2019
fb269b8
Make local changes a different step
LegNeato May 12, 2019
0472437
Revert "Fix path"
LegNeato May 12, 2019
856b600
Fix typo
LegNeato May 12, 2019
323a247
Fix git log output
LegNeato May 12, 2019
4774e09
Remove old file
LegNeato May 12, 2019
880b3e1
Try to fix working directory
LegNeato May 12, 2019
8cc93d4
Run build and tests on local release changes
LegNeato May 12, 2019
229008e
Better release replacements
LegNeato May 12, 2019
37ed884
Change blank release message
LegNeato May 12, 2019
15ed4a4
Remove replacements for crate that no longer exists
LegNeato May 12, 2019
233cb00
Make juniper actually use the makefile
LegNeato May 12, 2019
9cecc6a
Support both types of replacements
LegNeato May 12, 2019
0067336
Fix typo
LegNeato May 12, 2019
7473764
Don't replace all versions
LegNeato May 12, 2019
f11fdc2
More replacements
LegNeato May 12, 2019
9c10e5f
Fix regex
LegNeato May 12, 2019
fd8267a
Rearrange cargo.toml for warp
LegNeato May 12, 2019
5cd07ab
Comment file and move release stuff to bottom
LegNeato May 12, 2019
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
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ env:
before_script:
- |
if [ "$TRAVIS_OS_NAME" = 'windows' ]; then
powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.15.3" -target "x86_64-pc-windows-msvc"
powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.19.1" -target "x86_64-pc-windows-msvc"
fi
- |
if [ "$TRAVIS_OS_NAME" = 'linux' ]; then
_build/cargo-make.sh "0.15.3" "x86_64-unknown-linux-musl"
_build/cargo-make.sh "0.19.1" "x86_64-unknown-linux-musl"
fi
- |
if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
_build/cargo-make.sh "0.15.3" "x86_64-apple-darwin"
_build/cargo-make.sh "0.19.1" "x86_64-apple-darwin"
fi
script:
- cargo make workspace-ci-flow --no-workspace
Expand Down
87 changes: 79 additions & 8 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,87 @@
[env]
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = "true"

# Run `cargo make release` to push a new minor release of every crate.
#
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release` to push a new release of every crate.
# Run `RELEASE_LEVEL=(patch|major|minor) CARGO_MAKE_WORKSPACE_SKIP_MEMBERS="crate1;crate2;" cargo make release`
# to push a new release of some crates.
#

[tasks.release]
args = ["release", "--config", "../_build/release.toml"]
condition = { env_set = [ "RELEASE_LEVEL" ] }
workspace = false
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
run_task = { name = "release-INTERNAL", fork = true }


[tasks.release-some]
condition = { env_set = [ "RELEASE_LEVEL", "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" ] }
workspace = false
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
run_task = { name = "release-some-INTERNAL", fork = true }

# Hack to filter out crates we do not want to release.
# See <https://github.com/sagiegurari/cargo-make/issues/212#issuecomment-481123564>
[tasks.release-INTERNAL]
private = true
condition = { env_set = [ "RELEASE_LEVEL" ] }
command = "cargo-release"
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "${RELEASE_LEVEL}"]

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

# Run `cargo make release-dry-run` to do a dry run.
#
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-dry-run` to do a dry run.
# Run `RELEASE_LEVEL=(patch|major|minor) CARGO_MAKE_WORKSPACE_SKIP_MEMBERS="crate1;crate2;" cargo make release-some-dry-run`
# to do a dry run with some crates.
#

[tasks.release-dry-run]
condition = { env_set = [ "RELEASE_LEVEL" ] }
workspace = false
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
run_task = { name = "release-dry-run-INTERNAL", fork = true }

[tasks.release-some-dry-run]
condition = { env_set = [ "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS", "RELEASE_LEVEL" ] }
workspace = false
run_task = { name = "release-some-dry-run-INTERNAL", fork = true }


# Hack to filter out crates we do not want to release.
# See <https://github.com/sagiegurari/cargo-make/issues/212#issuecomment-481123564>
[tasks.release-dry-run-INTERNAL]
private = true
condition = { env_set = [ "RELEASE_LEVEL" ] }
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
description = "Run `cargo-release --dry-run` for every crate"
command = "${HOME}/src/cargo-release/target/debug/cargo-release"
args = ["release", "--config", "../_build/release.toml", "--dry-run"]
command = "cargo-release"
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--dry-run", "${RELEASE_LEVEL}"]

#
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-local-test` to do actually make changes locally but
# not push them up to crates.io or Github.
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-some-local-test` to do actually make changes locally but
# not push some crates up to crates.io or Github.
#

[tasks.release-local-test]
condition = { env_set = [ "RELEASE_LEVEL" ] }
workspace = false
env = { "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS" = "integration_tests/*" }
run_task = { name = "release-local-test-INTERNAL", fork = true }


[tasks.release-some-local-test]
condition = { env_set = [ "CARGO_MAKE_WORKSPACE_SKIP_MEMBERS", "RELEASE_LEVEL" ] }
workspace = false
run_task = { name = "release-some-local-test-INTERNAL", fork = true }


# Hack to filter out crates we do not want to release.
# See <https://github.com/sagiegurari/cargo-make/issues/212#issuecomment-481123564>
[tasks.release-local-test-INTERNAL]
private = true
condition = { env_set = [ "RELEASE_LEVEL" ] }
description = "Run `cargo-release` for every crate, but only make changes locally"
command = "cargo-release"
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"]
72 changes: 72 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# How to release new crate versions

## Prerequisites

We use [`cargo-make`](cargo-make) and [`cargo-release`](cargo-release) to automate crate releases. You will need to install them locally:

- `cargo install -f cargo-make`
- `cargo install -f cargo-release`

## Preparing for a release

There are two general classes of release and each require running different automation commands:

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]`._

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]`._

## Determine new release level

For each crate, determine the desired release level (`patch`, `minor`, `major`). Set the `RELEASE_LEVEL` env variable to the desired release level.

## Determine which crates to exclude

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
variable to filter out specific workspace crates. The value is a list of semicolon-delineated crate names or a regular expression.

**Important:** You likely want to always exclude `integration_tests/*`.

## Dry run

It is a good idea to do a dry run to sanity check what actions will be performed.

- For case #1 above, run `cargo make release-dry-run`.

If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.

- For case #2 above, run `cargo make release-some-dry-run`.

If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL` or `CARGO_MAKE_WORKSPACE_SKIP_MEMBERS`.

## Local test

Not everything is captured in the dry run. It is a good idea to run a local test.
In a local test, all the release actions are performed on your local checkout
but nothing is pushed to Github or crates.io.

- For case #1 above, run `cargo make release-local-test`.

If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.

- For case #2 above, run `cargo make release-some-local-test`.

If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL` or `CARGO_MAKE_WORKSPACE_SKIP_MEMBERS`.

After, your local git repository should have the changes ready to push to Github.
Use `git rebase -i HEAD~10` and drop the new commits.

## Release

After testing locally and via a dry run, it is time to release. A release
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.

- For case #1 above, run `cargo make release`.

If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.

- For case #2 above, run `cargo make release-some`.

If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL` or `CARGO_MAKE_WORKSPACE_SKIP_MEMBERS`.

[cargo-make]: https://github.com/sagiegurari/cargo-make
[cargo-release]: https://github.com/sunng87/cargo-release
6 changes: 3 additions & 3 deletions _build/azure-pipelines-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ jobs:
displayName: Query rust and cargo versions
- ${{ if eq(parameters.name, 'Linux') }}:
# Linux.
- script: _build/cargo-make.sh "0.15.3" "x86_64-unknown-linux-musl"
- script: _build/cargo-make.sh "0.19.1" "x86_64-unknown-linux-musl"
displayName: Install cargo-make binary
- ${{ if eq(parameters.name, 'macOS') }}:
# Mac.
- script: _build/cargo-make.sh "0.15.3" "x86_64-apple-darwin"
- script: _build/cargo-make.sh "0.19.1" "x86_64-apple-darwin"
displayName: Install cargo-make binary
- ${{ if eq(parameters.name, 'Windows') }}:
# Windows.
- script: powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.15.3" -target "x86_64-pc-windows-msvc"
- script: powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.19.1" -target "x86_64-pc-windows-msvc"
displayName: Install cargo-make binary
- script: cargo make workspace-ci-flow --no-workspace
env: { CARGO_MAKE_RUN_CODECOV: true }
Expand Down
2 changes: 1 addition & 1 deletion _build/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}"
upload-doc = false
pre-release-replacements = [
{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}})"},
{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}})"},
]
47 changes: 47 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
jobs:
###################################################
# Formatting
###################################################

- job: check_formatting
displayName: Check formatting
pool:
Expand All @@ -12,6 +16,10 @@ jobs:
$HOME/.cargo/bin/cargo fmt -- --check
displayName: Run rustfmt

###################################################
# Book
###################################################

- job: run_book_tests
displayName: Book code example tests
pool:
Expand Down Expand Up @@ -42,6 +50,10 @@ jobs:
- script: |
./docs/book/ci-build.sh master

###################################################
# Main Builds
###################################################

- template: _build/azure-pipelines-template.yml
parameters:
name: Linux
Expand All @@ -56,3 +68,38 @@ jobs:
parameters:
name: Windows
vmImage: vs2017-win2016

###################################################
# Releases
###################################################

- job: check_release_automation
displayName: Check release automation
pool:
vmImage: ubuntu-16.04
steps:
- script: |
curl https://sh.rustup.rs -sSf | sh -s -- -y
displayName: Install stable Rust
- script: |
_build/cargo-make.sh "0.19.1" "x86_64-unknown-linux-musl"
displayName: Install cargo-make binary
- script: |
$HOME/.cargo/bin/cargo install cargo-release
displayName: Install cargo-release binary
- script: |
git config --local user.name "Release Test Bot"
git config --local user.email "[email protected]"
displayName: Set up git
- script: |
RELEASE_LEVEL="minor" "$HOME/.cargo/bin/cargo" make release-dry-run
displayName: Dry run mode
- script: |
RELEASE_LEVEL="minor" "$HOME/.cargo/bin/cargo" make release-local-test
displayName: Local test mode
- script: |
git --no-pager log -p HEAD...HEAD~20
displayName: Echo local changes
- script: |
cargo make workspace-ci-flow --no-workspace
displayName: Make sure build and tests still work
10 changes: 7 additions & 3 deletions integration_tests/juniper_tests/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ args = ["test", "--verbose"]

[tasks.release]
disabled = true

[tasks.release-patch]
[tasks.release-some]
disabled = true
[tasks.release-local-test]
disabled = true
[tasks.release-some-local-test]
disabled = true

[tasks.release-dry-run]
disabled = true
[tasks.release-some-dry-run]
disabled = true
15 changes: 9 additions & 6 deletions juniper/Makefile.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
[tasks.release]
args = ["release"]
# This is needed as the release config is at a different path than the top-level
# release config.

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

[tasks.release-dry-run]
args = ["release", "--dry-run"]
[tasks.release-dry-run-INTERNAL]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"]

[tasks.release-local-test-INTERNAL]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"]
23 changes: 16 additions & 7 deletions juniper/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}"
upload-doc = false
pre-release-replacements = [
# Juniper's changelog
{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}})"},
{file="../integration_tests/juniper_tests/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_hyper/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_iron/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_rocket/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_tests/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_warp/Cargo.toml", search="juniper = { version = \"0.11.0\"", replace="juniper = { version = \"{{version}}\""},
{file="release.toml", search="0.11.0", replace="{{version}}"},
# Tests.
{file="../integration_tests/juniper_tests/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
# Hyper
{file="../juniper_hyper/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_hyper/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},
# Iron
{file="../juniper_iron/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_iron/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},
# Rocket
{file="../juniper_rocket/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_rocket/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},
# Warp
{file="../juniper_warp/Cargo.toml", search="juniper = \\{ version = \"[^\"]+\"", replace="juniper = { version = \"{{version}}\""},
{file="../juniper_warp/Cargo.toml", search="\\[dev-dependencies\\.juniper\\]\nversion = \"[^\"]+\"", replace="[dev-dependencies.juniper]\nversion = \"{{version}}\""},

]
15 changes: 9 additions & 6 deletions juniper_codegen/Makefile.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
[tasks.release]
args = ["release"]
# This is needed as the release config is at a different path than the top-level
# release config.

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

[tasks.release-dry-run]
args = ["release", "--dry-run"]
[tasks.release-dry-run-INTERNAL]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"]

[tasks.release-local-test-INTERNAL]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"]
3 changes: 1 addition & 2 deletions juniper_codegen/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}"
upload-doc = false
pre-release-replacements = [
{file="../juniper/Cargo.toml", search="juniper_codegen = { version = \"0.11.0\"", replace="juniper_codegen = { version = \"{{version}}\""},
{file="release.toml", search="0.11.0", replace="{{version}}"},
{file="../juniper/Cargo.toml", search="juniper_codegen = \\{ version = \"[^\"]+\"", replace="juniper_codegen = { version = \"{{version}}\""},
]
2 changes: 2 additions & 0 deletions juniper_hyper/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# master

- Compatibility with the latest `juniper`.

# 0.2.0 [2018-12-18]

## Breaking changes
Expand Down
2 changes: 1 addition & 1 deletion juniper_iron/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# master

- No changes yet
- Compatibility with the latest `juniper`.

# [0.3.0] 2018-12-17

Expand Down
2 changes: 1 addition & 1 deletion juniper_rocket/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# master

- No changes yet
- Compatibility with the latest `juniper`.

# [0.2.0] 2018-12-17

Expand Down
Loading