diff --git a/.travis.yml b/.travis.yml index 2c946354..2ef163b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/Makefile.toml b/Makefile.toml index bfcca9a4..a5c5c7c5 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -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 } -# 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. +[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 `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}"] diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..1946f092 --- /dev/null +++ b/RELEASING.md @@ -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 diff --git a/_build/azure-pipelines-template.yml b/_build/azure-pipelines-template.yml index 2fc7a22b..8b023b1c 100644 --- a/_build/azure-pipelines-template.yml +++ b/_build/azure-pipelines-template.yml @@ -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 } diff --git a/_build/release.toml b/_build/release.toml index 8fb5cd4b..6aadd80b 100644 --- a/_build/release.toml +++ b/_build/release.toml @@ -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}})"}, ] diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 05a90675..7aaed6e0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,4 +1,8 @@ jobs: + ################################################### + # Formatting + ################################################### + - job: check_formatting displayName: Check formatting pool: @@ -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: @@ -42,6 +50,10 @@ jobs: - script: | ./docs/book/ci-build.sh master + ################################################### + # Main Builds + ################################################### + - template: _build/azure-pipelines-template.yml parameters: name: Linux @@ -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 "juniper@example.com" + 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 diff --git a/integration_tests/juniper_tests/Makefile.toml b/integration_tests/juniper_tests/Makefile.toml index 8c64aa89..814cb281 100644 --- a/integration_tests/juniper_tests/Makefile.toml +++ b/integration_tests/juniper_tests/Makefile.toml @@ -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 diff --git a/juniper/Makefile.toml b/juniper/Makefile.toml index 07a88af4..886e8abf 100644 --- a/juniper/Makefile.toml +++ b/juniper/Makefile.toml @@ -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}"] diff --git a/juniper/release.toml b/juniper/release.toml index 97144075..689c2096 100644 --- a/juniper/release.toml +++ b/juniper/release.toml @@ -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}}\""}, + ] diff --git a/juniper_codegen/Makefile.toml b/juniper_codegen/Makefile.toml index 07a88af4..886e8abf 100644 --- a/juniper_codegen/Makefile.toml +++ b/juniper_codegen/Makefile.toml @@ -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}"] diff --git a/juniper_codegen/release.toml b/juniper_codegen/release.toml index 8c0f4d0a..f6a76a92 100644 --- a/juniper_codegen/release.toml +++ b/juniper_codegen/release.toml @@ -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}}\""}, ] diff --git a/juniper_hyper/CHANGELOG.md b/juniper_hyper/CHANGELOG.md index f3fa8b0c..f6cd641a 100644 --- a/juniper_hyper/CHANGELOG.md +++ b/juniper_hyper/CHANGELOG.md @@ -1,5 +1,7 @@ # master +- Compatibility with the latest `juniper`. + # 0.2.0 [2018-12-18] ## Breaking changes diff --git a/juniper_iron/CHANGELOG.md b/juniper_iron/CHANGELOG.md index f0b36d41..713993e4 100644 --- a/juniper_iron/CHANGELOG.md +++ b/juniper_iron/CHANGELOG.md @@ -1,6 +1,6 @@ # master -- No changes yet +- Compatibility with the latest `juniper`. # [0.3.0] 2018-12-17 diff --git a/juniper_rocket/CHANGELOG.md b/juniper_rocket/CHANGELOG.md index ae8b5ebb..a2890b19 100644 --- a/juniper_rocket/CHANGELOG.md +++ b/juniper_rocket/CHANGELOG.md @@ -1,6 +1,6 @@ # master -- No changes yet +- Compatibility with the latest `juniper`. # [0.2.0] 2018-12-17 diff --git a/juniper_warp/CHANGELOG.md b/juniper_warp/CHANGELOG.md index 00998ec9..277fde70 100644 --- a/juniper_warp/CHANGELOG.md +++ b/juniper_warp/CHANGELOG.md @@ -1,6 +1,6 @@ # master -- No changes yet +- Compatibility with the latest `juniper`. # [0.2.0] 2018-12-17 diff --git a/juniper_warp/Cargo.toml b/juniper_warp/Cargo.toml index d35c7837..de3d05d9 100644 --- a/juniper_warp/Cargo.toml +++ b/juniper_warp/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] warp = "0.1.8" -juniper = { path = "../juniper", version = "0.11.0", default-features = false } +juniper = { version = "0.11.0", path = "../juniper", default-features = false } serde_json = "1.0.24" serde_derive = "1.0.75" failure = "0.1.2" @@ -19,7 +19,7 @@ serde = "1.0.75" tokio-threadpool = "0.1.7" [dev-dependencies] -juniper = { path = "../juniper", version = "0.11.0", features = ["expose-test-schema", "serde_json"] } +juniper = { version = "0.11.0", path = "../juniper", features = ["expose-test-schema", "serde_json"] } env_logger = "0.5.11" log = "0.4.3" percent-encoding = "1.0"