Refactoring to batch (#181)

The rationale of this pull request is to

* have more maintainable and granular code
* not maintain the custom made job engine
* allow the users to customize the defaults of the releaser more easy
* allow the users to create their own steps without the need to change any existing code
* allow the users to fully change the flows and tasks logic
* abstract underlying batch mechanism (Spring Batch) so it doesn't leak to production code
* allow parallelization of the release process and release tasks
This commit is contained in:
Marcin Grzejszczak
2019-12-23 13:49:58 +01:00
committed by GitHub
parent ea85372e05
commit 8992e45321
2130 changed files with 12441 additions and 6429 deletions

View File

@@ -9,44 +9,33 @@ Edit the files in the src/main/asciidoc/ directory instead.
:repo: spring-cloud-release-tools :repo: spring-cloud-release-tools
:branch: master :branch: master
image::https://circleci.com/gh/{org}/{repo}/tree/{branch}.svg?style=svg["CircleCI", link="https://circleci.com/gh/{org}/{repo}/tree/{branch}"] image::https://circleci.com/gh/{org}/{repo}/tree/{branch}.svg?style=svg["CircleCI",link="https://circleci.com/gh/{org}/{repo}/tree/{branch}"]
image::https://codecov.io/gh/{org}/{repo}/branch/{branch}/graph/badge.svg["codecov", link="https://codecov.io/gh/{org}/{repo}"] image::https://codecov.io/gh/{org}/{repo}/branch/{branch}/graph/badge.svg["codecov",link="https://codecov.io/gh/{org}/{repo}"]
:github-tag: master
:org: spring-cloud
:repo: spring-cloud-release-tools
:github-repo: {org}/{repo}
:github-raw: https://raw.github.com/{github-repo}/{github-tag}
:github-code: https://github.com/{github-repo}/tree/{github-tag}
:toc: left
:toclevels: 8
:nofooter:
== Spring Cloud Release Tools == Spring Cloud Release Tools
Spring Cloud projects reuse the same pattern of building and deploying the applications. That's Spring Cloud projects reuse the same pattern of building and deploying the applications.
why this tool makes it easy to automate the release / dependency update process of our applications. That's why this tool makes it easy to automate the release / dependency update process of our applications.
=== What does it do? === What does it do?
==== Single project ==== Single project
For a single project For a single project, by default if you opt in to all tasks
- Clones the Spring Cloud Release project and picks all versions (Boot + Cloud projects) - Clones the BOM project and picks all versions
- Modifies the project versions with values from a BOM (e.g. for Spring Cloud it's Spring Cloud Release) - Modifies the project versions with values from a BOM (e.g. for Spring Cloud it's Spring Cloud Release)
* throws an exception when we bump versions to release and there's a SNAPSHOT version referenced in the POM * throws an exception when we bump versions to release and there's a SNAPSHOT version referenced in the POM
- Performs the build and checks if the `docs` modules have properly created the documentation - Performs the build and checks if the `docs` modules have properly created the documentation
* throws an exception when in the `docs` module there's an unresolved tag in any HTML file * throws an exception when in the `docs` module there's an unresolved tag in any HTML file
- Commits changed poms (ONLY FOR NON-SNAPSHOT VERSIONS) - Commits changed poms (ONLY FOR NON-SNAPSHOT VERSIONS)
- Creates a tag for the release / milestone (ONLY FOR NON-SNAPSHOT VERSIONS) - Creates a tag for the release / milestone (ONLY FOR NON-SNAPSHOT VERSIONS)
- Runs the deployment of the artifacts - Runs the deployment of the artifacts
- Publishes the docs (to `spring-cloud-static` for non-snapshots, to `gh-pages` for snapshots) - Publishes the docs (for Spring Cloud to `spring-cloud-static` for non-snapshots, to `gh-pages` for snapshots)
- Reverts back to snapshots, bumps the version by a patch (`1.0.1.RELEASE` -> `1.0.2.BUILD-SNAPSHOT`) (ONLY FOR RELEASE VERSIONS) - Reverts back to snapshots, bumps the version by a patch (`1.0.1.RELEASE` -> `1.0.2.BUILD-SNAPSHOT`) (ONLY FOR RELEASE VERSIONS)
- Closes the milestone on Github (e.g. `v1.0.1.RELEASE`) (ONLY FOR NON-SNAPSHOT VERSIONS) - Closes the milestone on Github (e.g. `v1.0.1.RELEASE`) (ONLY FOR NON-SNAPSHOT VERSIONS)
IMPORTANT: Starting with version that does Sagan integration, you MUST pass the OAuth token, IMPORTANT: Starting with version that does Sagan integration, you MUST pass the OAuth token, otherwise the application will fail to start
otherwise the application will fail to start
After project release After project release
@@ -57,11 +46,13 @@ After project release
- Updates project information in Sagan (https://spring.io) (ONLY FOR SNAPSHOT / RELEASE VERSIONS) - Updates project information in Sagan (https://spring.io) (ONLY FOR SNAPSHOT / RELEASE VERSIONS)
- For `GA`/ `SR` release will create an issue in Spring Guides under https://github.com/spring-guides/getting-started-guides/issues/ - For `GA`/ `SR` release will create an issue in Spring Guides under https://github.com/spring-guides/getting-started-guides/issues/
- For `GA`/ `SR` release will create an issue in start.spring.io under https://github.com/spring-io/start.spring.io/issues/ - For `GA`/ `SR` release will create an issue in start.spring.io under https://github.com/spring-io/start.spring.io/issues/
- For `GA`/ `SR` release will update the links under https://github.com/spring-cloud/spring-cloud-static/tree/gh-pages/current - For `GA`/ `SR` release will update the documentation links (for Spring Cloud https://github.com/spring-cloud/spring-cloud-static/tree/gh-pages/current)
- Will update the release train project page (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud`) - Will update the release train project page (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud`)
==== Meta-release ==== Meta-release
All the tasks are opt in, so if you do opt in for everything you'll get:
- Uses the fixed versions to clone and check out each project (e.g. `spring-cloud-sleuth: 2.1.0.RELEASE`) - Uses the fixed versions to clone and check out each project (e.g. `spring-cloud-sleuth: 2.1.0.RELEASE`)
- From the version analyzes the branch and checks it out. E.g. - From the version analyzes the branch and checks it out. E.g.
** for `spring-cloud-release`'s `Finchley.RELEASE` version will resolve either `Finchley` branch or will fallback to `master` if there's no `Finchley` branch. ** for `spring-cloud-release`'s `Finchley.RELEASE` version will resolve either `Finchley` branch or will fallback to `master` if there's no `Finchley` branch.
@@ -72,13 +63,141 @@ After project release
- Will clone provided test samples and will update all versions to the latest ones - Will clone provided test samples and will update all versions to the latest ones
- Will clone the release train wiki and update it with the latest release versions (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud.wiki.git`) - Will clone the release train wiki and update it with the latest release versions (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud.wiki.git`)
IMPORTANT: For the meta-releaser to work we assume that the path to the IMPORTANT: For the meta-releaser to work we assume that the path to the custom configuration file for each project is always `config/releaser.yml`.
custom configuration file for each project is always `config/releaser.yml`.
NOTE: If you want to run some projects in parallel you have to set the `releaser.meta-release.release-groups` property to state which projects should be released in parallel. Example:
```properties
releaser.meta-release.release-groups[0]=projectA,projectB,projectC
```
If in the list of projects you have `projectA,projectB,projectC,projectD,projectE`, then `projectA,projectB,projectC` will be released in parallel and then `projectD` and `projectE` sequentially.
=== How can I extend it?
The project consists of the following main modules
* `releaser-core` - with the core logic for doing releases
* `relaser-spring` - with the Spring setup of tasks and a flow execution
* `projects`
** where each project has their configuration properties and additional tasks
You can create your own project's module and
* if you want to completely rewrite the flow of the release, just set `releaser.flow.default-enabled` to `false` and create the whole flow from scratch
* if you want to modify the current flow, you can add new tasks by just creating a bean of a given type that extends the `ReleaserTask` and set its order accordingly.
Example of creating a new `ReleaseReleaserTask` called `BuildCustomStuffTask`:
```java
package releaser.my_project;
//...
import releaser.internal.Releaser;
import releaser.internal.spring.Arguments;
import releaser.internal.spring.ExecutionResult;
import releaser.internal.tasks.ReleaseReleaserTask;
@Component
public class BuildCustomStuffTask implements ReleaseReleaserTask {
/**
* Order of this task. The higher value, the lower order.
*/
public static final int ORDER = 45;
@Override
public String name() {
return "build_custom_stuff";
}
@Override
public String shortName() {
return "bcf";
}
@Override
public String header() {
return "BUILDING CUSTOM STUFF";
}
@Override
public String description() {
return "Builds custom stuff";
}
@Override
public ExecutionResult runTask(Arguments args) {
// do some custom stuff basing on the arguments
return ExecutionResult.success();
}
@Override
public int getOrder() {
return BuildCustomStuffTask.ORDER;
}
}
```
Each release or post release task can implement one of the following interfaces
* `ReleaserTask` - marker interface for all release tasks
* `ReleaseReleaserTask` - if a task is part of the main release process. That means that if it breaks, the whole release process should stop at once.
* `PostReleaseReleaserTask` - marker interface for a post release task. If a post release task fails - the build continues but will be unstable.
* `SingleProjectReleaserTask` - a release task for a single project.
* `ProjectPostReleaseReleaserTask` - a post release task for a single project.
* `DryRunReleaseReleaserTask` - a release task that should be executed during dry run mode.
* `TrainPostReleaseReleaserTask` - a post release task that should be executed after the whole release train.
* `CompositeReleaserTask` - a task that delegates work to other tasks.
In addition, your project can provide the following beans:
* `CustomBomParser` - if you need to perform some additional BOM parsing. E.g. Spring Cloud adds `spring-boot` and `spring-cloud-build` versions when parsing the BOM project.
* `CustomProjectDocumentationUpdater` - if you need to perform some custom logic when updating the project's documentation.
* `CustomGithubIssues` - if you need to perform additional logic when dealing with Github issues.
To run the project you should create your main class preferably under the `releaser` package and extend the `ReleaserCommandLineRunner` class.
```java
package releaser;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ReleaserApplication extends ReleaserCommandLineRunner {
public ReleaserApplication(SpringReleaser releaser,
ExecutionResultHandler executionResultHandler, Parser parser) {
super(releaser, executionResultHandler, parser);
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(ReleaserApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
}
```
You can also extend the way the projects and tasks are parsed, flows are executed and the result is analyzed together with the printed report. To do that you should implement the following interfaces as beans:
* `SpringReleaser` - performs the release, given the provided options
* `FlowRunner` - knows how to execute a release and post release flow
* `ExecutionResultHandler` - handles the result of the release
=== What should I do first? === What should I do first?
Members of the Spring Cloud Team typically use this tool as follows. They first Members of the Spring Cloud Team typically use this tool as follows.
clone the releaser locally and build the jar manually They first clone the releaser locally and build the jar manually
[source,bash] [source,bash]
---- ----
@@ -87,8 +206,8 @@ $ cd spring-cloud-release-tools
$ ./mvnw clean install $ ./mvnw clean install
---- ----
IMPORTANT: You must set the value of the OAuth token. You can do it either via IMPORTANT: You must set the value of the OAuth token.
the command line `--releaser.git.oauth-token=...` or put it as an env variable in `.bashrc` You can do it either via the command line `--releaser.git.oauth-token=...` or put it as an env variable in `.bashrc`
or `.zshrc` e.g. `export RELEASER_GIT_OAUTH_TOKEN=...` or `.zshrc` e.g. `export RELEASER_GIT_OAUTH_TOKEN=...`
=== How to run it (interactive mode) === How to run it (interactive mode)
@@ -100,13 +219,13 @@ Go to your project (e.g. Spring Cloud Sleuth)
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git $ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth $ cd spring-cloud-sleuth
$ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser $ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser $ java -jar ~/repo/spring-cloud-release-tools/projects/spring-cloud/target/spring-cloud-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser
---- ----
The application will start running from your working directory. Running this code The application will start running from your working directory.
follows the convention that you have the OAuth token environment variable set. It also assumes Running this code follows the convention that you have the OAuth token environment variable set.
that you might have some custom configuration in `config/releaser.yml` file. This setting is optional - if It also assumes that you might have some custom configuration in `config/releaser.yml` file.
you don't have that file, nothing will happen. This setting is optional - if you don't have that file, nothing will happen.
TIP: It is important that you clone the repository you are going to release using SSH in order for the TIP: It is important that you clone the repository you are going to release using SSH in order for the
`releaser` to be able to push tags and commit changes automatically. `releaser` to be able to push tags and commit changes automatically.
@@ -136,8 +255,10 @@ You can execute given tasks by providing a comma separated list of tasks - e.g.
You can press 'q' to quit You can press 'q' to quit
---- ----
Just pick a number and continue! Pick either a full release or single steps. You can also pick Just pick a number and continue!
ranges or multiple steps. You can also provide the range only with the starting step Pick either a full release or single steps.
You can also pick ranges or multiple steps.
You can also provide the range only with the starting step
- that you will execute all steps starting from the given one. - that you will execute all steps starting from the given one.
TIP: Read before picking a number cause it might have changed between tool releases ;) TIP: Read before picking a number cause it might have changed between tool releases ;)
@@ -152,7 +273,7 @@ flag.
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git $ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth $ cd spring-cloud-sleuth
$ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser $ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -h $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -h
---- ----
You will see a help screen looking like more or less like this You will see a help screen looking like more or less like this
@@ -213,9 +334,11 @@ Range 'docs' -> 'push'
java -jar releaser.jar -r o-p java -jar releaser.jar -r o-p
---- ----
The Releaser can use two sets of options. The configuration options like `releaser.pom.branch` The Releaser can use two sets of options.
and the task switches. For the tasks you can use either the full names or short switches. For example The configuration options like `releaser.pom.branch`
providing range of tasks via switches `o-p` is equivalent to full name `docs-push`. and the task switches.
For the tasks you can use either the full names or short switches.
For example providing range of tasks via switches `o-p` is equivalent to full name `docs-push`.
A couple of examples: A couple of examples:
@@ -225,52 +348,49 @@ A couple of examples:
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git $ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth $ cd spring-cloud-sleuth
$ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser $ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release
---- ----
.Doing the full release in non interactive mode (automatic release) .Doing the full release in non interactive mode (automatic release)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release --interactive=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release --interactive=false
---- ----
.Updating pom, closing milestone & createTemplates in interactive mode .Updating pom, closing milestone & createTemplates in interactive mode
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -u -m -t $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -u -m -t
---- ----
.Running all tasks starting from 'push' (automatic) .Running all tasks starting from 'push' (automatic)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -a push -i=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -a push -i=false
---- ----
.Running tasks from 'docs' (inclusive) to 'push' (inclusive) (automatic) .Running tasks from 'docs' (inclusive) to 'push' (inclusive) (automatic)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -r d-p -i=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -r d-p -i=false
---- ----
.Running single task 'closeMilestone' (automatic) .Running single task 'closeMilestone' (automatic)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --closeMilestone -i=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --closeMilestone -i=false
---- ----
=== How to run meta-release (automatic-mode) === How to run meta-release (automatic-mode)
All you have to do is run the jar with the releaser and pass the All you have to do is run the jar with the releaser and pass the
`-x=true` option to turn on meta-release and a list of fixed versions `-x=true` option to turn on meta-release and a list of fixed versions in the `--"releaser.fixed-versions[project-name]=project-version" format
in the `--"releaser.fixed-versions[project-name]=project-version" format
``` ```
$ java -jar spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --spring.config.name=releaser -x=true --"releaser.fixed-versions[spring-cloud-sleuth]=2.0.1.BUILD-SNAPSHOT" $ java -jar projects/spring-cloud/target/spring-cloud-1.0.0.BUILD-SNAPSHOT.jar --spring.config.name=releaser -x=true --"releaser.fixed-versions[spring-cloud-sleuth]=2.0.1.BUILD-SNAPSHOT"
``` ```
IMPORTANT: For the meta release the `startFrom` or `taskNames` take into consideration IMPORTANT: For the meta release the `startFrom` or `taskNames` take into consideration the project names, not task names. E.g. you can start from `spring-cloud-netflix` project, or build only tasks with names `spring-cloud-build,spring-cloud-sleuth`.
the project names, not task names. E.g. you can start from `spring-cloud-netflix` project,
or build only tasks with names `spring-cloud-build,spring-cloud-sleuth`.
=== Project options === Project options
@@ -287,24 +407,25 @@ Below you can find a table with all the releaser options.
|releaser.bash.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property. |releaser.bash.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property.
|releaser.bash.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish. |releaser.bash.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish.
|releaser.fixed-versions | | Project name to its version - overrides all versions retrieved from a release train repository like Spring Cloud Release. |releaser.fixed-versions | | Project name to its version - overrides all versions retrieved from a release train repository like Spring Cloud Release.
|releaser.flow.default-enabled | true | Should the default flow of jobs be preserved. If set to {@code false} will not register any jobs as beans, and it will be up to you to set the whole configuration of jobs.
|releaser.git.all-test-sample-urls | | Project to urls mapping. For each project will clone the test project and will update its versions. |releaser.git.all-test-sample-urls | | Project to urls mapping. For each project will clone the test project and will update its versions.
|releaser.git.clone-destination-dir | | Where should the release train repo get cloned to. If {@code null} defaults to a temporary directory. |releaser.git.clone-destination-dir | | Where should the release train repo get cloned to. If {@code null} defaults to a temporary directory.
|releaser.git.documentation-branch | gh-pages | Branch to check out for the documentation project. |releaser.git.documentation-branch | | Branch to check out for the documentation project.
|releaser.git.documentation-url | https://github.com/spring-cloud/spring-cloud-static | URL to the documentation Git repository. |releaser.git.documentation-url | | URL to the documentation Git repository.
|releaser.git.fetch-versions-from-git | true | If {@code true} then should fill the map of versions from Git. If {@code false} then picks fixed versions. |releaser.git.fetch-versions-from-git | true | If {@code true} then should fill the map of versions from Git. If {@code false} then picks fixed versions.
|releaser.git.number-of-checked-milestones | 50 | In order not to iterate endlessly over milestones we introduce a threshold of milestones that we will go through to find the matching milestone. |releaser.git.number-of-checked-milestones | 50 | In order not to iterate endlessly over milestones we introduce a threshold of milestones that we will go through to find the matching milestone.
|releaser.git.oauth-token | | GitHub OAuth token to be used to interact with GitHub repo. |releaser.git.oauth-token | | GitHub OAuth token to be used to interact with GitHub repo.
|releaser.git.password | | Optional Git password. If not passed keys will be used for authentication. |releaser.git.password | | Optional Git password. If not passed keys will be used for authentication.
|releaser.git.release-train-bom-url | https://github.com/spring-cloud/spring-cloud-release | URL to a release train repository. |releaser.git.release-train-bom-url | | URL to a release train repository.
|releaser.git.release-train-docs-branch | master | Branch to check out for the release train docs. |releaser.git.release-train-docs-branch | | Branch to check out for the release train docs.
|releaser.git.release-train-docs-url | https://github.com/spring-cloud-samples/scripts | URL to the release train documentation. |releaser.git.release-train-docs-url | | URL to the release train documentation.
|releaser.git.release-train-wiki-page-prefix | Spring-Cloud | Page prefix for the release train wiki. E.g. for [Spring-Cloud-Finchley-Release-Notes] it would be [Spring-Cloud]. |releaser.git.release-train-wiki-page-prefix | | Page prefix for the release train wiki. E.g. for [Spring-Cloud-Finchley-Release-Notes] it would be [Spring-Cloud].
|releaser.git.release-train-wiki-url | https://github.com/spring-projects/spring-cloud.wiki | URL to the release train wiki. |releaser.git.release-train-wiki-url | | URL to the release train wiki.
|releaser.git.run-updated-samples | false | If set to {@code false}, will not update the test samples. |releaser.git.run-updated-samples | false | If set to {@code false}, will not update the test samples.
|releaser.git.spring-project-branch | gh-pages | Branch to check out for the release train project. |releaser.git.spring-project-branch | | Branch to check out for the release train project.
|releaser.git.spring-project-url | https://github.com/spring-projects/spring-cloud | URL to the release train project page repository. |releaser.git.spring-project-url | | URL to the release train project page repository.
|releaser.git.test-samples-branch | master | Branch to check out for the test samples. |releaser.git.test-samples-branch | | Branch to check out for the test samples.
|releaser.git.test-samples-project-url | https://github.com/spring-cloud/spring-cloud-core-tests | URL to test samples. |releaser.git.test-samples-project-url | | URL to test samples.
|releaser.git.update-all-test-samples | false | If set to {@code false}, will not clone and update the samples for all projects. |releaser.git.update-all-test-samples | false | If set to {@code false}, will not clone and update the samples for all projects.
|releaser.git.update-documentation-repo | false | If {@code false}, will not update the documentation repository. |releaser.git.update-documentation-repo | false | If {@code false}, will not update the documentation repository.
|releaser.git.update-github-milestones | false | If set to {@code false}, will not update Github milestones. |releaser.git.update-github-milestones | false | If set to {@code false}, will not update Github milestones.
@@ -317,10 +438,10 @@ Below you can find a table with all the releaser options.
|releaser.gradle.build-command | ./gradlew clean build publishToMavenLocal --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build the project If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating. |releaser.gradle.build-command | ./gradlew clean build publishToMavenLocal --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build the project If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating.
|releaser.gradle.deploy-command | ./gradlew publish --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to deploy a built project. |releaser.gradle.deploy-command | ./gradlew publish --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to deploy a built project.
|releaser.gradle.deploy-guides-command | ./gradlew clean build deployGuides --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build and deploy guides project only. |releaser.gradle.deploy-guides-command | ./gradlew clean build deployGuides --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build and deploy guides project only.
|releaser.gradle.generate-release-train-docs-command | echo 'TODO' | Command to be executed to generate release train documentation. |releaser.gradle.generate-release-train-docs-command | ./gradlew generateReleaseTrainDocs --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to generate release train documentation.
|releaser.gradle.gradle-props-substitution | | A mapping that should be applied to {@code gradle.properties} in order to perform a substitution of properties. The mapping is from a property inside {@code gradle.properties} to the projects name. Example. In {@code gradle.properties} you have {@code verifierVersion=1.0.0} . You want this property to get updated with the value of {@code spring-cloud-contract} version. Then it's enough to do the mapping like this for this Releaser's property: {@code verifierVersion=spring-cloud-contract}. |releaser.gradle.gradle-props-substitution | | A mapping that should be applied to {@code gradle.properties} in order to perform a substitution of properties. The mapping is from a property inside {@code gradle.properties} to the projects name. Example. In {@code gradle.properties} you have {@code verifierVersion=1.0.0} . You want this property to get updated with the value of {@code spring-cloud-contract} version. Then it's enough to do the mapping like this for this Releaser's property: {@code verifierVersion=spring-cloud-contract}.
|releaser.gradle.ignored-gradle-regex | | List of regular expressions of ignored gradle props. Defaults to test projects and samples. |releaser.gradle.ignored-gradle-regex | | List of regular expressions of ignored gradle props. Defaults to test projects and samples.
|releaser.gradle.publish-docs-commands | [echo 'TODO'] | Command to be executed to publish documentation. If present "{{version}}" will be replaced by the provided version. |releaser.gradle.publish-docs-commands | [./gradlew publishDocs --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}}] | Command to be executed to publish documentation. If present "{{version}}" will be replaced by the provided version.
|releaser.gradle.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property. |releaser.gradle.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property.
|releaser.gradle.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish. |releaser.gradle.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish.
|releaser.maven.build-command | ./mvnw clean install -B -Pdocs {{systemProps}} | Command to be executed to build the project. If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating. |releaser.maven.build-command | ./mvnw clean install -B -Pdocs {{systemProps}} | Command to be executed to build the project. If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating.
@@ -331,57 +452,59 @@ Below you can find a table with all the releaser options.
|releaser.maven.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property. |releaser.maven.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property.
|releaser.maven.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish. |releaser.maven.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish.
|releaser.meta-release.enabled | false | Are we releasing the whole suite of apps or only one? |releaser.meta-release.enabled | false | Are we releasing the whole suite of apps or only one?
|releaser.meta-release.git-org-url | https://github.com/spring-cloud | The URL of the Git organization. We'll append each project's name to it. |releaser.meta-release.git-org-url | | The URL of the Git organization. We'll append each project's name to it.
|releaser.meta-release.projects-to-skip | | Names of projects to skip deployment for meta-release. |releaser.meta-release.projects-to-skip | | Names of projects to skip deployment for meta-release.
|releaser.meta-release.release-group-thread-count | 4 | Number of threads per release group. E.g. for thread count of 4 if there are 6 projects in a release group, 4 of them will be executed in parallel and 2 will wait for their turn.
|releaser.meta-release.release-group-timeout-in-minutes | 180 | Timeout in minutes during which we're waiting for a single composite task per a project to be executed. That means that if set to e.g. 180 then a release process for a single project should take at most 180 minutes.
|releaser.meta-release.release-groups | | If provided, allows to provide groups of projects that can be ran in parallel. E.g. {@code --releaser.meta-release.release-groups[0]=projectA,projectB,projectC} {@code --releaser.meta-release.release-groups[1]=projectD,projectE} {@code --releaser.meta-release.release-groups[2]=projectF,projectG} The order is still provided by the list of versions passed to the releaser. Basing on that order, and this value we are able to build a flow with projects.
|releaser.meta-release.release-train-dependency-names | | All the names of dependencies that should be updated with the release train project version. |releaser.meta-release.release-train-dependency-names | | All the names of dependencies that should be updated with the release train project version.
|releaser.meta-release.release-train-project-name | spring-cloud-release | Name of the release train project. |releaser.meta-release.release-train-project-name | | Name of the release train project.
|releaser.pom.bom-version-pattern | ^(spring-cloud-.*)\.version$ | The pattern to match a version property in a BOM. |releaser.pom.bom-version-pattern | | The pattern to match a version property in a BOM. Remember to catch the dependency name in a group. E.g. "^(spring-cloud-.*)\\.version$".
|releaser.pom.branch | master | Which branch of release train BOM should be checked out. Defaults to {@code master}. |releaser.pom.branch | master | Which branch of release train BOM should be checked out. Defaults to {@code master}.
|releaser.pom.ignored-pom-regex | | List of regular expressions of ignored poms. Defaults to test projects and samples. |releaser.pom.ignored-pom-regex | ^.*\.git/.*$ | List of regular expressions of ignored poms. Defaults to test projects and samples.
|releaser.pom.pom-with-boot-starter-parent | spring-cloud-starter-parent/pom.xml | Subfolder of the pom that contains the {@code spring-boot-starer-parent} dependency. |releaser.pom.pom-with-boot-starter-parent | | Subfolder of the pom that contains the {@code spring-boot-starer-parent} dependency.
|releaser.pom.this-train-bom | spring-cloud-dependencies/pom.xml | Subfolder of the pom that contains the versions for the release train. |releaser.pom.this-train-bom | | Subfolder of the pom that contains the versions for the release train.
|releaser.post-release-tasks-only | false | If set to {@code true} will run only post release tasks. |releaser.post-release-tasks-only | false | If set to {@code true} will run only post release tasks.
|releaser.sagan.base-url | https://spring.io | URL to the Sagan API. |releaser.sagan.base-url | https://spring.io | URL to the Sagan API.
|releaser.sagan.boot-section-file-name | sagan-boot.adoc | Name of the ascii doc file with boot part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}. |releaser.sagan.boot-section-file-name | sagan-boot.adoc | Name of the ascii doc file with boot part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}.
|releaser.sagan.docs-adocs-file | docs/src/main/asciidoc | Folder with asciidoctor files for docs. |releaser.sagan.docs-adocs-file | docs/src/main/asciidoc | Folder with asciidoctor files for docs.
|releaser.sagan.index-section-file-name | sagan-index.adoc | Name of the ascii doc file with core part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}. |releaser.sagan.index-section-file-name | sagan-index.adoc | Name of the ascii doc file with core part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}.
|releaser.sagan.update-sagan | false | If set to {@code false} will not update Sagan. |releaser.sagan.update-sagan | false | If set to {@code false} will not update Sagan.
|releaser.template.template-folder | cloud | Folder in which blog, email etc. templates are stored. |releaser.skip-post-release-tasks | false | If set to {@code true} will not run post release tasks.
|releaser.template.enabled | false | Should template generation be enabled.
|releaser.template.template-folder | | Folder in which blog, email etc. templates are stored.
|releaser.versions.all-versions-file-url | https://raw.githubusercontent.com/spring-io/start.spring.io/master/start-site/src/main/resources/application.yml | Url to a file containing all the versions. Defaults to YAML from start.spring.io. |releaser.versions.all-versions-file-url | https://raw.githubusercontent.com/spring-io/start.spring.io/master/start-site/src/main/resources/application.yml | Url to a file containing all the versions. Defaults to YAML from start.spring.io.
|releaser.versions.bom-name | spring-cloud | Name in the YAML from initilizr for BOM mappings. |releaser.versions.bom-name | | Name in the YAML from initilizr for BOM mappings.
|releaser.working-dir | | By default Releaser assumes running the program from the current working directory. If you want to change this behaviour - just change this value. |releaser.working-dir | | By default Releaser assumes running the program from the current working directory. If you want to change this behaviour - just change this value.
|=== |===
TIP: You can pass the options either via system properties or via application arguments. TIP: You can pass the options either via system properties or via application arguments.
Example for system properties: `java -Dreleaser.pom.branch=Camden.SR6 -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar` Example for system properties: `java -Dreleaser.pom.branch=Camden.SR6 -jar target/releaser-spring-1.0.0.M1.jar`
Example for application arguments: `java -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6` Example for application arguments: `java -jar target/releaser-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6`
IMPORTANT: For the GA release to be successful, it's important that if the `build` / `deploy` command IMPORTANT: For the GA release to be successful, it's important that if the `build` / `deploy` command run a script (e.g. `scripts/foo.sh`) then inside `foo.sh` if you call a Maven build `./mvnw clean install`
run a script (e.g. `scripts/foo.sh`) then inside `foo.sh` if you call a Maven build `./mvnw clean install` then *remember to pass all arguments of the script there too*.
then *remember to pass all arguments of the script there too*. E.g. `./mvnw clean install ${@}`. That's because E.g. `./mvnw clean install ${@}`.
the releaser will pass any system properties to the `build` / `deploy` command, such as system properties That's because the releaser will pass any system properties to the `build` / `deploy` command, such as system properties with keys and we need them to be passed inside the command executed by the releaser.
with keys and we need them to be passed inside the command executed by the releaser.
=== Examples === Examples
==== Keeping configuration in the project ==== Keeping configuration in the project
If your project has some custom configuration (e.g. Spring Cloud Contract needs a script to be executed If your project has some custom configuration (e.g. Spring Cloud Contract needs a script to be executed to build the project and properly merge the docs) then you can put a file named e.g. `releaser.yml` under `config`
to build the project and properly merge the docs) then you can put a file named e.g. `releaser.yml` under `config`
folder and run your application like this: folder and run your application like this:
[source,bash] [source,bash]
---- ----
$ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/spring-cloud-release-tools-spring/1.0.0.M1/spring-cloud-release-tools-spring-1.0.0.M1.jar -O ../spring-cloud-release-tools-spring-1.0.0.M1.jar $ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/releaser-spring/1.0.0.M1/releaser-spring-1.0.0.M1.jar -O ../releaser-spring-1.0.0.M1.jar
$ java -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar --spring.config.name=releaser $ java -jar target/releaser-spring-1.0.0.M1.jar --spring.config.name=releaser
---- ----
TIP: Notice that we're downloading the jar to a parent folder, not to `target`. That's because `target` get cleaned TIP: Notice that we're downloading the jar to a parent folder, not to `target`.
during the build process That's because `target` get cleaned during the build process
IMPORTANT: For the meta-releaser to work we assume that the path to the IMPORTANT: For the meta-releaser to work we assume that the path to the configuration file is always `config/releaser.yml`.
configuration file is always `config/releaser.yml`.
==== Specifying A Branch ==== Specifying A Branch
@@ -390,39 +513,47 @@ If you would like to use another branch you can specify it using the `releaser.p
[source,bash] [source,bash]
---- ----
$ java -jar spring-cloud-release-tools-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6 $ java -jar releaser-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6
---- ----
==== Using Environment Variables ==== Using Environment Variables
In some cases it might be easier to specify environment variables instead of passing parameters to In some cases it might be easier to specify environment variables instead of passing parameters to
`releaser`. For example, you might want to use environment variables if you are going to be `releaser`.
releasing multiple projects, this keeps you from having to specify the same parameters for For example, you might want to use environment variables if you are going to be releasing multiple projects, this keeps you from having to specify the same parameters for each release
each release
[source,bash] [source,bash]
---- ----
$ export RELEASER_POM_BRANCH=Dalston.RELEASE $ export RELEASER_POM_BRANCH=Dalston.RELEASE
$ export RELEASER_GIT_OAUTH_TOKEN=... $ export RELEASER_GIT_OAUTH_TOKEN=...
$ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/spring-cloud-release-tools-spring/1.0.0.M1/spring-cloud-release-tools-spring-1.0.0.M1.jar -O spring-cloud-release-tools-spring-1.0.0.M1.jar $ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/releaser-spring/1.0.0.M1/releaser-spring-1.0.0.M1.jar -O releaser-spring-1.0.0.M1.jar
$ java -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar --releaser.working-dir=/path/to/project/root $ java -jar target/releaser-spring-1.0.0.M1.jar --releaser.working-dir=/path/to/project/root
---- ----
=== Releasing through Jenkins === Releasing through Jenkins
NOTE: Whenever a release process is broken, Jenkins marks it with a red ball and breaks the build. Whenever a post-release action went wrong but the release is successful, Jenkins marks the build with a yellow ball and marks the build as unstable. NOTE: Whenever a release process is broken, Jenkins marks it with a red ball and breaks the build.
Whenever a post-release action went wrong but the release is successful, Jenkins marks the build with a yellow ball and marks the build as unstable.
==== Releasing a Single Project ==== Releasing a Single Project
Let us assume that we are to release `spring-cloud-build` project. We need to do the following steps: Let us assume that we are to release `spring-cloud-build` project.
We need to do the following steps:
. Create a branch (for example, `springCloudBuildRelease`) in a project that contains a BOM (for example, https://github.com/spring-cloud/spring-cloud-release/[spring-cloud-release]).
The following example shows how to do so:
. Create a branch (for example, `springCloudBuildRelease`) in a project that contains a BOM (for example, https://github.com/spring-cloud/spring-cloud-release/[spring-cloud-release]). The following example shows how to do so:
```bash ```bash
$ git clone git@github.com:spring-cloud/spring-cloud-release.git $ git clone git@github.com:spring-cloud/spring-cloud-release.git
$ cd spring-cloud-release $ cd spring-cloud-release
$ git checkout -b springCloudBuildRelease $ git checkout -b springCloudBuildRelease
``` ```
. Update *all* versions as if you were doing a release train. We need to update the project's versions, Boot version, and dependencies versions, too. Let us assume that we will eventually be doing a release train for the `Hoxton.M1` release, Spring Boot to the latest available one, and `spring-cloud-commons` to `1.2.3.BUILD-SNAPSHOT`. The following example shows how to do so:
. Update *all* versions as if you were doing a release train.
We need to update the project's versions, Boot version, and dependencies versions, too.
Let us assume that we will eventually be doing a release train for the `Hoxton.M1` release, Spring Boot to the latest available one, and `spring-cloud-commons` to `1.2.3.BUILD-SNAPSHOT`.
The following example shows how to do so:
```bash ```bash
// setting the release train value // setting the release train value
$ ./mvnw versions:set -DnewVersion=Hoxton.M1 -DgenerateBackupPoms=false -DprocessAllModules=true $ ./mvnw versions:set -DnewVersion=Hoxton.M1 -DgenerateBackupPoms=false -DprocessAllModules=true
@@ -436,27 +567,32 @@ $ git diff
// commit and push the branch // commit and push the branch
$ git add . && git commit -m "Updating project for Spring Cloud Build release" && git push origin springCloudBuildRelease $ git add . && git commit -m "Updating project for Spring Cloud Build release" && git push origin springCloudBuildRelease
``` ```
IMPORTANT: If you're doing a e.g. `M1` release, remember to not have any snapshot versions in this branch. IMPORTANT: If you're doing a e.g. `M1` release, remember to not have any snapshot versions in this branch.
Since the project is prepared, go to Jenkins and select the https://jenkins.spring.io/view/Spring%20Cloud/view/Releaser/[Releaser view], which the following image shows: Since the project is prepared, go to Jenkins and select the https://jenkins.spring.io/view/Spring%20Cloud/view/Releaser/[Releaser view], which the following image shows:
image::{github-raw}/docs/src/main/asciidoc/images/releasers.png[Releaser view] image::{github-raw}/docs/src/main/asciidoc/images/releasers.png[Releaser view]
. Pick the proper releaser project (for example, `spring-cloud-build-releaser`). The following image shows the settings for this example: . Pick the proper releaser project (for example, `spring-cloud-build-releaser`).
The following image shows the settings for this example:
image::{github-raw}/docs/src/main/asciidoc/images/scBuildReleaser.png[Spring Cloud Build Releaser - build with parameters] image::{github-raw}/docs/src/main/asciidoc/images/scBuildReleaser.png[Spring Cloud Build Releaser - build with parameters]
. Next, click `Build with parameters`. The following image shows the UI for doing so: . Next, click `Build with parameters`.
The following image shows the UI for doing so:
image::{github-raw}/docs/src/main/asciidoc/images/runningScBuildReleaser.png[Updated `RELEASER_POM_BRANCH`] image::{github-raw}/docs/src/main/asciidoc/images/runningScBuildReleaser.png[Updated `RELEASER_POM_BRANCH`]
Pick from which branch you would like the project (for example, `spring-cloud-build` - defaults to `master`) to be built and update the `RELEASER_POM_BRANCH` to point to the checked-out branch of Spring Cloud Release (for example, `springCloudBuildRelease`). You can pick whether you want to perform only post-release tasks or the whole release. Pick from which branch you would like the project (for example, `spring-cloud-build` - defaults to `master`) to be built and update the `RELEASER_POM_BRANCH` to point to the checked-out branch of Spring Cloud Release (for example, `springCloudBuildRelease`).
You can pick whether you want to perform only post-release tasks or the whole release.
. Finally, click `Build`. . Finally, click `Build`.
You are done! You are done!
As a post action, do not forget to remove the branch. The following example shows how to do so: As a post action, do not forget to remove the branch.
The following example shows how to do so:
```bash ```bash
// to synchronize any deleted branches (don't run this if you want leave any deleted branches that were deleted in the origin) // to synchronize any deleted branches (don't run this if you want leave any deleted branches that were deleted in the origin)
@@ -467,19 +603,31 @@ $ git push origin --delete springCloudBuildRelease
==== Releasing a Release Train ==== Releasing a Release Train
We call a release train a `meta-release`. In order to perform one, you need to: We call a release train a `meta-release`.
In order to perform one, you need to:
. In your project (which must contain a BOM, such as `spring-cloud-release`) you have to have a branch, where you store properties with versions of your projects.
For example, the branch name can be https://github.com/spring-cloud/spring-cloud-release/tree/jenkins-releaser-config[jenkins-releaser-config]).
The folloiwng example shows how to do so:
. In your project (which must contain a BOM, such as `spring-cloud-release`) you have to have a branch, where you store properties with versions of your projects. For example, the branch name can be https://github.com/spring-cloud/spring-cloud-release/tree/jenkins-releaser-config[jenkins-releaser-config]). The folloiwng example shows how to do so:
```bash ```bash
$ git clone git@github.com:spring-cloud/spring-cloud-release.git $ git clone git@github.com:spring-cloud/spring-cloud-release.git
$ cd spring-cloud-release $ cd spring-cloud-release
$ git checkout jenkins-releaser-config $ git checkout jenkins-releaser-config
``` ```
. Create a file that contains all properties for a given release train. The name of the release train should be lowercase, and dots should be converted to underscores. For example, for the `Greenwich.SR2` release train we need to have a file named `greenwich_sr2.properties`. The following example shows how to do so:
. Create a file that contains all properties for a given release train.
The name of the release train should be lowercase, and dots should be converted to underscores.
For example, for the `Greenwich.SR2` release train we need to have a file named `greenwich_sr2.properties`.
The following example shows how to do so:
```bash ```bash
$ touch greenwich_sr2.properties $ touch greenwich_sr2.properties
``` ```
. We need to update the file with all versions for the release train. The properties file contains an *ordered* list of `releaser.fixed-versions[project-name]=project-version` entries, as the following listing shows:
. We need to update the file with all versions for the release train.
The properties file contains an *ordered* list of `releaser.fixed-versions[project-name]=project-version` entries, as the following listing shows:
```bash ```bash
$ echo "releaser.fixed-versions[spring-boot]=2.1.5.RELEASE $ echo "releaser.fixed-versions[spring-boot]=2.1.5.RELEASE
releaser.fixed-versions[spring-cloud-build]=2.1.5.RELEASE releaser.fixed-versions[spring-cloud-build]=2.1.5.RELEASE
@@ -518,7 +666,8 @@ image::{github-raw}/docs/src/main/asciidoc/images/springCloudMetaRelease.png[Spr
image::{github-raw}/docs/src/main/asciidoc/images/runningSpringCloudMetaReleaser.png[Spring Cloud Meta Releaser view] image::{github-raw}/docs/src/main/asciidoc/images/runningSpringCloudMetaReleaser.png[Spring Cloud Meta Releaser view]
You have quite a few options to pick, but the most important one is to set the value of the `RELEASE_VERSION` to the given release train version (for example, `Greenwich.SR2`). Continue updating the rest of the fields if necessary and read the field descriptions and this documentation for more information. You have quite a few options to pick, but the most important one is to set the value of the `RELEASE_VERSION` to the given release train version (for example, `Greenwich.SR2`).
Continue updating the rest of the fields if necessary and read the field descriptions and this documentation for more information.
. Finally, click `Build`. . Finally, click `Build`.
@@ -648,10 +797,11 @@ The generated eclipse projects can be imported by selecting `import existing pro
from the `file` menu. from the `file` menu.
IMPORTANT: There are 2 different versions of language level used in Spring Cloud Sleuth. Java 1.7 is used for main sources and IMPORTANT: There are 2 different versions of language level used in Spring Cloud Sleuth.
Java 1.8 is used for tests. When importing your project to an IDE please activate the `ide` Maven profile to turn on Java 1.7 is used for main sources and Java 1.8 is used for tests.
Java 1.8 for both main and test sources. Of course remember that you MUST NOT use Java 1.8 features in the main sources. If you do When importing your project to an IDE please activate the `ide` Maven profile to turn on Java 1.8 for both main and test sources.
so your app will break during the Maven build. Of course remember that you MUST NOT use Java 1.8 features in the main sources.
If you do so your app will break during the Maven build.
== Contributing == Contributing

View File

@@ -4,10 +4,10 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.springframework.cloud.internal</groupId> <groupId>org.springframework.cloud.internal</groupId>
<artifactId>spring-cloud-release-tools-parent</artifactId> <artifactId>releaser-parent</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version> <version>1.0.0.BUILD-SNAPSHOT</version>
</parent> </parent>
<artifactId>spring-cloud-release-tools-docs</artifactId> <artifactId>releaser-docs</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<properties> <properties>
<docs.main>spring-cloud-release-tools</docs.main> <docs.main>spring-cloud-release-tools</docs.main>
@@ -23,12 +23,12 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>spring-cloud-release-tools-core</artifactId> <artifactId>releaser-core</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>spring-cloud-release-tools-spring</artifactId> <artifactId>releaser-spring</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -3,8 +3,8 @@
:repo: spring-cloud-release-tools :repo: spring-cloud-release-tools
:branch: master :branch: master
image::https://circleci.com/gh/{org}/{repo}/tree/{branch}.svg?style=svg["CircleCI", link="https://circleci.com/gh/{org}/{repo}/tree/{branch}"] image::https://circleci.com/gh/{org}/{repo}/tree/{branch}.svg?style=svg["CircleCI",link="https://circleci.com/gh/{org}/{repo}/tree/{branch}"]
image::https://codecov.io/gh/{org}/{repo}/branch/{branch}/graph/badge.svg["codecov", link="https://codecov.io/gh/{org}/{repo}"] image::https://codecov.io/gh/{org}/{repo}/branch/{branch}/graph/badge.svg["codecov",link="https://codecov.io/gh/{org}/{repo}"]
include::spring-cloud-release-tools.adoc[] include::spring-cloud-release-tools.adoc[]
@@ -12,10 +12,11 @@ include::spring-cloud-release-tools.adoc[]
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building.adoc[] include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building.adoc[]
IMPORTANT: There are 2 different versions of language level used in Spring Cloud Sleuth. Java 1.7 is used for main sources and IMPORTANT: There are 2 different versions of language level used in Spring Cloud Sleuth.
Java 1.8 is used for tests. When importing your project to an IDE please activate the `ide` Maven profile to turn on Java 1.7 is used for main sources and Java 1.8 is used for tests.
Java 1.8 for both main and test sources. Of course remember that you MUST NOT use Java 1.8 features in the main sources. If you do When importing your project to an IDE please activate the `ide` Maven profile to turn on Java 1.8 for both main and test sources.
so your app will break during the Maven build. Of course remember that you MUST NOT use Java 1.8 features in the main sources.
If you do so your app will break during the Maven build.
== Contributing == Contributing

View File

@@ -9,24 +9,25 @@
|releaser.bash.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property. |releaser.bash.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property.
|releaser.bash.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish. |releaser.bash.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish.
|releaser.fixed-versions | | Project name to its version - overrides all versions retrieved from a release train repository like Spring Cloud Release. |releaser.fixed-versions | | Project name to its version - overrides all versions retrieved from a release train repository like Spring Cloud Release.
|releaser.flow.default-enabled | true | Should the default flow of jobs be preserved. If set to {@code false} will not register any jobs as beans, and it will be up to you to set the whole configuration of jobs.
|releaser.git.all-test-sample-urls | | Project to urls mapping. For each project will clone the test project and will update its versions. |releaser.git.all-test-sample-urls | | Project to urls mapping. For each project will clone the test project and will update its versions.
|releaser.git.clone-destination-dir | | Where should the release train repo get cloned to. If {@code null} defaults to a temporary directory. |releaser.git.clone-destination-dir | | Where should the release train repo get cloned to. If {@code null} defaults to a temporary directory.
|releaser.git.documentation-branch | gh-pages | Branch to check out for the documentation project. |releaser.git.documentation-branch | | Branch to check out for the documentation project.
|releaser.git.documentation-url | https://github.com/spring-cloud/spring-cloud-static | URL to the documentation Git repository. |releaser.git.documentation-url | | URL to the documentation Git repository.
|releaser.git.fetch-versions-from-git | true | If {@code true} then should fill the map of versions from Git. If {@code false} then picks fixed versions. |releaser.git.fetch-versions-from-git | true | If {@code true} then should fill the map of versions from Git. If {@code false} then picks fixed versions.
|releaser.git.number-of-checked-milestones | 50 | In order not to iterate endlessly over milestones we introduce a threshold of milestones that we will go through to find the matching milestone. |releaser.git.number-of-checked-milestones | 50 | In order not to iterate endlessly over milestones we introduce a threshold of milestones that we will go through to find the matching milestone.
|releaser.git.oauth-token | | GitHub OAuth token to be used to interact with GitHub repo. |releaser.git.oauth-token | | GitHub OAuth token to be used to interact with GitHub repo.
|releaser.git.password | | Optional Git password. If not passed keys will be used for authentication. |releaser.git.password | | Optional Git password. If not passed keys will be used for authentication.
|releaser.git.release-train-bom-url | https://github.com/spring-cloud/spring-cloud-release | URL to a release train repository. |releaser.git.release-train-bom-url | | URL to a release train repository.
|releaser.git.release-train-docs-branch | master | Branch to check out for the release train docs. |releaser.git.release-train-docs-branch | | Branch to check out for the release train docs.
|releaser.git.release-train-docs-url | https://github.com/spring-cloud-samples/scripts | URL to the release train documentation. |releaser.git.release-train-docs-url | | URL to the release train documentation.
|releaser.git.release-train-wiki-page-prefix | Spring-Cloud | Page prefix for the release train wiki. E.g. for [Spring-Cloud-Finchley-Release-Notes] it would be [Spring-Cloud]. |releaser.git.release-train-wiki-page-prefix | | Page prefix for the release train wiki. E.g. for [Spring-Cloud-Finchley-Release-Notes] it would be [Spring-Cloud].
|releaser.git.release-train-wiki-url | https://github.com/spring-projects/spring-cloud.wiki | URL to the release train wiki. |releaser.git.release-train-wiki-url | | URL to the release train wiki.
|releaser.git.run-updated-samples | false | If set to {@code false}, will not update the test samples. |releaser.git.run-updated-samples | false | If set to {@code false}, will not update the test samples.
|releaser.git.spring-project-branch | gh-pages | Branch to check out for the release train project. |releaser.git.spring-project-branch | | Branch to check out for the release train project.
|releaser.git.spring-project-url | https://github.com/spring-projects/spring-cloud | URL to the release train project page repository. |releaser.git.spring-project-url | | URL to the release train project page repository.
|releaser.git.test-samples-branch | master | Branch to check out for the test samples. |releaser.git.test-samples-branch | | Branch to check out for the test samples.
|releaser.git.test-samples-project-url | https://github.com/spring-cloud/spring-cloud-core-tests | URL to test samples. |releaser.git.test-samples-project-url | | URL to test samples.
|releaser.git.update-all-test-samples | false | If set to {@code false}, will not clone and update the samples for all projects. |releaser.git.update-all-test-samples | false | If set to {@code false}, will not clone and update the samples for all projects.
|releaser.git.update-documentation-repo | false | If {@code false}, will not update the documentation repository. |releaser.git.update-documentation-repo | false | If {@code false}, will not update the documentation repository.
|releaser.git.update-github-milestones | false | If set to {@code false}, will not update Github milestones. |releaser.git.update-github-milestones | false | If set to {@code false}, will not update Github milestones.
@@ -39,10 +40,10 @@
|releaser.gradle.build-command | ./gradlew clean build publishToMavenLocal --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build the project If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating. |releaser.gradle.build-command | ./gradlew clean build publishToMavenLocal --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build the project If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating.
|releaser.gradle.deploy-command | ./gradlew publish --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to deploy a built project. |releaser.gradle.deploy-command | ./gradlew publish --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to deploy a built project.
|releaser.gradle.deploy-guides-command | ./gradlew clean build deployGuides --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build and deploy guides project only. |releaser.gradle.deploy-guides-command | ./gradlew clean build deployGuides --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to build and deploy guides project only.
|releaser.gradle.generate-release-train-docs-command | echo 'TODO' | Command to be executed to generate release train documentation. |releaser.gradle.generate-release-train-docs-command | ./gradlew generateReleaseTrainDocs --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}} | Command to be executed to generate release train documentation.
|releaser.gradle.gradle-props-substitution | | A mapping that should be applied to {@code gradle.properties} in order to perform a substitution of properties. The mapping is from a property inside {@code gradle.properties} to the projects name. Example. In {@code gradle.properties} you have {@code verifierVersion=1.0.0} . You want this property to get updated with the value of {@code spring-cloud-contract} version. Then it's enough to do the mapping like this for this Releaser's property: {@code verifierVersion=spring-cloud-contract}. |releaser.gradle.gradle-props-substitution | | A mapping that should be applied to {@code gradle.properties} in order to perform a substitution of properties. The mapping is from a property inside {@code gradle.properties} to the projects name. Example. In {@code gradle.properties} you have {@code verifierVersion=1.0.0} . You want this property to get updated with the value of {@code spring-cloud-contract} version. Then it's enough to do the mapping like this for this Releaser's property: {@code verifierVersion=spring-cloud-contract}.
|releaser.gradle.ignored-gradle-regex | | List of regular expressions of ignored gradle props. Defaults to test projects and samples. |releaser.gradle.ignored-gradle-regex | | List of regular expressions of ignored gradle props. Defaults to test projects and samples.
|releaser.gradle.publish-docs-commands | [echo 'TODO'] | Command to be executed to publish documentation. If present "{{version}}" will be replaced by the provided version. |releaser.gradle.publish-docs-commands | [./gradlew publishDocs --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}}] | Command to be executed to publish documentation. If present "{{version}}" will be replaced by the provided version.
|releaser.gradle.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property. |releaser.gradle.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property.
|releaser.gradle.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish. |releaser.gradle.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish.
|releaser.maven.build-command | ./mvnw clean install -B -Pdocs {{systemProps}} | Command to be executed to build the project. If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating. |releaser.maven.build-command | ./mvnw clean install -B -Pdocs {{systemProps}} | Command to be executed to build the project. If present "{{version}}" will be replaced by the provided version. "{{nextVersion}}" with the bumped snapshot version and "{{oldVersion}}" with the version before version updating.
@@ -53,24 +54,29 @@
|releaser.maven.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property. |releaser.maven.system-properties | | Additional system properties that should be passed to the build / deploy commands. If present in other commands "{{systemProps}}" will be substituted with this property.
|releaser.maven.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish. |releaser.maven.wait-time-in-minutes | 20 | Max wait time in minutes for the process to finish.
|releaser.meta-release.enabled | false | Are we releasing the whole suite of apps or only one? |releaser.meta-release.enabled | false | Are we releasing the whole suite of apps or only one?
|releaser.meta-release.git-org-url | https://github.com/spring-cloud | The URL of the Git organization. We'll append each project's name to it. |releaser.meta-release.git-org-url | | The URL of the Git organization. We'll append each project's name to it.
|releaser.meta-release.projects-to-skip | | Names of projects to skip deployment for meta-release. |releaser.meta-release.projects-to-skip | | Names of projects to skip deployment for meta-release.
|releaser.meta-release.release-group-thread-count | 4 | Number of threads per release group. E.g. for thread count of 4 if there are 6 projects in a release group, 4 of them will be executed in parallel and 2 will wait for their turn.
|releaser.meta-release.release-group-timeout-in-minutes | 180 | Timeout in minutes during which we're waiting for a single composite task per a project to be executed. That means that if set to e.g. 180 then a release process for a single project should take at most 180 minutes.
|releaser.meta-release.release-groups | | If provided, allows to provide groups of projects that can be ran in parallel. E.g. {@code --releaser.meta-release.release-groups[0]=projectA,projectB,projectC} {@code --releaser.meta-release.release-groups[1]=projectD,projectE} {@code --releaser.meta-release.release-groups[2]=projectF,projectG} The order is still provided by the list of versions passed to the releaser. Basing on that order, and this value we are able to build a flow with projects.
|releaser.meta-release.release-train-dependency-names | | All the names of dependencies that should be updated with the release train project version. |releaser.meta-release.release-train-dependency-names | | All the names of dependencies that should be updated with the release train project version.
|releaser.meta-release.release-train-project-name | spring-cloud-release | Name of the release train project. |releaser.meta-release.release-train-project-name | | Name of the release train project.
|releaser.pom.bom-version-pattern | ^(spring-cloud-.*)\.version$ | The pattern to match a version property in a BOM. |releaser.pom.bom-version-pattern | | The pattern to match a version property in a BOM. Remember to catch the dependency name in a group. E.g. "^(spring-cloud-.*)\\.version$".
|releaser.pom.branch | master | Which branch of release train BOM should be checked out. Defaults to {@code master}. |releaser.pom.branch | master | Which branch of release train BOM should be checked out. Defaults to {@code master}.
|releaser.pom.ignored-pom-regex | | List of regular expressions of ignored poms. Defaults to test projects and samples. |releaser.pom.ignored-pom-regex | ^.*\.git/.*$ | List of regular expressions of ignored poms. Defaults to test projects and samples.
|releaser.pom.pom-with-boot-starter-parent | spring-cloud-starter-parent/pom.xml | Subfolder of the pom that contains the {@code spring-boot-starer-parent} dependency. |releaser.pom.pom-with-boot-starter-parent | | Subfolder of the pom that contains the {@code spring-boot-starer-parent} dependency.
|releaser.pom.this-train-bom | spring-cloud-dependencies/pom.xml | Subfolder of the pom that contains the versions for the release train. |releaser.pom.this-train-bom | | Subfolder of the pom that contains the versions for the release train.
|releaser.post-release-tasks-only | false | If set to {@code true} will run only post release tasks. |releaser.post-release-tasks-only | false | If set to {@code true} will run only post release tasks.
|releaser.sagan.base-url | https://spring.io | URL to the Sagan API. |releaser.sagan.base-url | https://spring.io | URL to the Sagan API.
|releaser.sagan.boot-section-file-name | sagan-boot.adoc | Name of the ascii doc file with boot part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}. |releaser.sagan.boot-section-file-name | sagan-boot.adoc | Name of the ascii doc file with boot part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}.
|releaser.sagan.docs-adocs-file | docs/src/main/asciidoc | Folder with asciidoctor files for docs. |releaser.sagan.docs-adocs-file | docs/src/main/asciidoc | Folder with asciidoctor files for docs.
|releaser.sagan.index-section-file-name | sagan-index.adoc | Name of the ascii doc file with core part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}. |releaser.sagan.index-section-file-name | sagan-index.adoc | Name of the ascii doc file with core part of this project's Sagan project page. Linked with {@link this#docsAdocsFile}.
|releaser.sagan.update-sagan | false | If set to {@code false} will not update Sagan. |releaser.sagan.update-sagan | false | If set to {@code false} will not update Sagan.
|releaser.template.template-folder | cloud | Folder in which blog, email etc. templates are stored. |releaser.skip-post-release-tasks | false | If set to {@code true} will not run post release tasks.
|releaser.template.enabled | false | Should template generation be enabled.
|releaser.template.template-folder | | Folder in which blog, email etc. templates are stored.
|releaser.versions.all-versions-file-url | https://raw.githubusercontent.com/spring-io/start.spring.io/master/start-site/src/main/resources/application.yml | Url to a file containing all the versions. Defaults to YAML from start.spring.io. |releaser.versions.all-versions-file-url | https://raw.githubusercontent.com/spring-io/start.spring.io/master/start-site/src/main/resources/application.yml | Url to a file containing all the versions. Defaults to YAML from start.spring.io.
|releaser.versions.bom-name | spring-cloud | Name in the YAML from initilizr for BOM mappings. |releaser.versions.bom-name | | Name in the YAML from initilizr for BOM mappings.
|releaser.working-dir | | By default Releaser assumes running the program from the current working directory. If you want to change this behaviour - just change this value. |releaser.working-dir | | By default Releaser assumes running the program from the current working directory. If you want to change this behaviour - just change this value.
|=== |===

View File

@@ -1,38 +1,27 @@
:github-tag: master
:org: spring-cloud
:repo: spring-cloud-release-tools
:github-repo: {org}/{repo}
:github-raw: https://raw.github.com/{github-repo}/{github-tag}
:github-code: https://github.com/{github-repo}/tree/{github-tag}
:toc: left
:toclevels: 8
:nofooter:
== Spring Cloud Release Tools == Spring Cloud Release Tools
Spring Cloud projects reuse the same pattern of building and deploying the applications. That's Spring Cloud projects reuse the same pattern of building and deploying the applications.
why this tool makes it easy to automate the release / dependency update process of our applications. That's why this tool makes it easy to automate the release / dependency update process of our applications.
=== What does it do? === What does it do?
==== Single project ==== Single project
For a single project For a single project, by default if you opt in to all tasks
- Clones the Spring Cloud Release project and picks all versions (Boot + Cloud projects) - Clones the BOM project and picks all versions
- Modifies the project versions with values from a BOM (e.g. for Spring Cloud it's Spring Cloud Release) - Modifies the project versions with values from a BOM (e.g. for Spring Cloud it's Spring Cloud Release)
* throws an exception when we bump versions to release and there's a SNAPSHOT version referenced in the POM * throws an exception when we bump versions to release and there's a SNAPSHOT version referenced in the POM
- Performs the build and checks if the `docs` modules have properly created the documentation - Performs the build and checks if the `docs` modules have properly created the documentation
* throws an exception when in the `docs` module there's an unresolved tag in any HTML file * throws an exception when in the `docs` module there's an unresolved tag in any HTML file
- Commits changed poms (ONLY FOR NON-SNAPSHOT VERSIONS) - Commits changed poms (ONLY FOR NON-SNAPSHOT VERSIONS)
- Creates a tag for the release / milestone (ONLY FOR NON-SNAPSHOT VERSIONS) - Creates a tag for the release / milestone (ONLY FOR NON-SNAPSHOT VERSIONS)
- Runs the deployment of the artifacts - Runs the deployment of the artifacts
- Publishes the docs (to `spring-cloud-static` for non-snapshots, to `gh-pages` for snapshots) - Publishes the docs (for Spring Cloud to `spring-cloud-static` for non-snapshots, to `gh-pages` for snapshots)
- Reverts back to snapshots, bumps the version by a patch (`1.0.1.RELEASE` -> `1.0.2.BUILD-SNAPSHOT`) (ONLY FOR RELEASE VERSIONS) - Reverts back to snapshots, bumps the version by a patch (`1.0.1.RELEASE` -> `1.0.2.BUILD-SNAPSHOT`) (ONLY FOR RELEASE VERSIONS)
- Closes the milestone on Github (e.g. `v1.0.1.RELEASE`) (ONLY FOR NON-SNAPSHOT VERSIONS) - Closes the milestone on Github (e.g. `v1.0.1.RELEASE`) (ONLY FOR NON-SNAPSHOT VERSIONS)
IMPORTANT: Starting with version that does Sagan integration, you MUST pass the OAuth token, IMPORTANT: Starting with version that does Sagan integration, you MUST pass the OAuth token, otherwise the application will fail to start
otherwise the application will fail to start
After project release After project release
@@ -43,11 +32,13 @@ After project release
- Updates project information in Sagan (https://spring.io) (ONLY FOR SNAPSHOT / RELEASE VERSIONS) - Updates project information in Sagan (https://spring.io) (ONLY FOR SNAPSHOT / RELEASE VERSIONS)
- For `GA`/ `SR` release will create an issue in Spring Guides under https://github.com/spring-guides/getting-started-guides/issues/ - For `GA`/ `SR` release will create an issue in Spring Guides under https://github.com/spring-guides/getting-started-guides/issues/
- For `GA`/ `SR` release will create an issue in start.spring.io under https://github.com/spring-io/start.spring.io/issues/ - For `GA`/ `SR` release will create an issue in start.spring.io under https://github.com/spring-io/start.spring.io/issues/
- For `GA`/ `SR` release will update the links under https://github.com/spring-cloud/spring-cloud-static/tree/gh-pages/current - For `GA`/ `SR` release will update the documentation links (for Spring Cloud https://github.com/spring-cloud/spring-cloud-static/tree/gh-pages/current)
- Will update the release train project page (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud`) - Will update the release train project page (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud`)
==== Meta-release ==== Meta-release
All the tasks are opt in, so if you do opt in for everything you'll get:
- Uses the fixed versions to clone and check out each project (e.g. `spring-cloud-sleuth: 2.1.0.RELEASE`) - Uses the fixed versions to clone and check out each project (e.g. `spring-cloud-sleuth: 2.1.0.RELEASE`)
- From the version analyzes the branch and checks it out. E.g. - From the version analyzes the branch and checks it out. E.g.
** for `spring-cloud-release`'s `Finchley.RELEASE` version will resolve either `Finchley` branch or will fallback to `master` if there's no `Finchley` branch. ** for `spring-cloud-release`'s `Finchley.RELEASE` version will resolve either `Finchley` branch or will fallback to `master` if there's no `Finchley` branch.
@@ -58,13 +49,141 @@ After project release
- Will clone provided test samples and will update all versions to the latest ones - Will clone provided test samples and will update all versions to the latest ones
- Will clone the release train wiki and update it with the latest release versions (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud.wiki.git`) - Will clone the release train wiki and update it with the latest release versions (for Spring Cloud it will be `https://github.com/spring-projects/spring-cloud.wiki.git`)
IMPORTANT: For the meta-releaser to work we assume that the path to the IMPORTANT: For the meta-releaser to work we assume that the path to the custom configuration file for each project is always `config/releaser.yml`.
custom configuration file for each project is always `config/releaser.yml`.
NOTE: If you want to run some projects in parallel you have to set the `releaser.meta-release.release-groups` property to state which projects should be released in parallel. Example:
```properties
releaser.meta-release.release-groups[0]=projectA,projectB,projectC
```
If in the list of projects you have `projectA,projectB,projectC,projectD,projectE`, then `projectA,projectB,projectC` will be released in parallel and then `projectD` and `projectE` sequentially.
=== How can I extend it?
The project consists of the following main modules
* `releaser-core` - with the core logic for doing releases
* `relaser-spring` - with the Spring setup of tasks and a flow execution
* `projects`
** where each project has their configuration properties and additional tasks
You can create your own project's module and
* if you want to completely rewrite the flow of the release, just set `releaser.flow.default-enabled` to `false` and create the whole flow from scratch
* if you want to modify the current flow, you can add new tasks by just creating a bean of a given type that extends the `ReleaserTask` and set its order accordingly.
Example of creating a new `ReleaseReleaserTask` called `BuildCustomStuffTask`:
```java
package releaser.my_project;
//...
import releaser.internal.Releaser;
import releaser.internal.spring.Arguments;
import releaser.internal.spring.ExecutionResult;
import releaser.internal.tasks.ReleaseReleaserTask;
@Component
public class BuildCustomStuffTask implements ReleaseReleaserTask {
/**
* Order of this task. The higher value, the lower order.
*/
public static final int ORDER = 45;
@Override
public String name() {
return "build_custom_stuff";
}
@Override
public String shortName() {
return "bcf";
}
@Override
public String header() {
return "BUILDING CUSTOM STUFF";
}
@Override
public String description() {
return "Builds custom stuff";
}
@Override
public ExecutionResult runTask(Arguments args) {
// do some custom stuff basing on the arguments
return ExecutionResult.success();
}
@Override
public int getOrder() {
return BuildCustomStuffTask.ORDER;
}
}
```
Each release or post release task can implement one of the following interfaces
* `ReleaserTask` - marker interface for all release tasks
* `ReleaseReleaserTask` - if a task is part of the main release process. That means that if it breaks, the whole release process should stop at once.
* `PostReleaseReleaserTask` - marker interface for a post release task. If a post release task fails - the build continues but will be unstable.
* `SingleProjectReleaserTask` - a release task for a single project.
* `ProjectPostReleaseReleaserTask` - a post release task for a single project.
* `DryRunReleaseReleaserTask` - a release task that should be executed during dry run mode.
* `TrainPostReleaseReleaserTask` - a post release task that should be executed after the whole release train.
* `CompositeReleaserTask` - a task that delegates work to other tasks.
In addition, your project can provide the following beans:
* `CustomBomParser` - if you need to perform some additional BOM parsing. E.g. Spring Cloud adds `spring-boot` and `spring-cloud-build` versions when parsing the BOM project.
* `CustomProjectDocumentationUpdater` - if you need to perform some custom logic when updating the project's documentation.
* `CustomGithubIssues` - if you need to perform additional logic when dealing with Github issues.
To run the project you should create your main class preferably under the `releaser` package and extend the `ReleaserCommandLineRunner` class.
```java
package releaser;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ReleaserApplication extends ReleaserCommandLineRunner {
public ReleaserApplication(SpringReleaser releaser,
ExecutionResultHandler executionResultHandler, Parser parser) {
super(releaser, executionResultHandler, parser);
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(ReleaserApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
}
```
You can also extend the way the projects and tasks are parsed, flows are executed and the result is analyzed together with the printed report. To do that you should implement the following interfaces as beans:
* `SpringReleaser` - performs the release, given the provided options
* `FlowRunner` - knows how to execute a release and post release flow
* `ExecutionResultHandler` - handles the result of the release
=== What should I do first? === What should I do first?
Members of the Spring Cloud Team typically use this tool as follows. They first Members of the Spring Cloud Team typically use this tool as follows.
clone the releaser locally and build the jar manually They first clone the releaser locally and build the jar manually
[source,bash] [source,bash]
---- ----
@@ -73,8 +192,8 @@ $ cd spring-cloud-release-tools
$ ./mvnw clean install $ ./mvnw clean install
---- ----
IMPORTANT: You must set the value of the OAuth token. You can do it either via IMPORTANT: You must set the value of the OAuth token.
the command line `--releaser.git.oauth-token=...` or put it as an env variable in `.bashrc` You can do it either via the command line `--releaser.git.oauth-token=...` or put it as an env variable in `.bashrc`
or `.zshrc` e.g. `export RELEASER_GIT_OAUTH_TOKEN=...` or `.zshrc` e.g. `export RELEASER_GIT_OAUTH_TOKEN=...`
=== How to run it (interactive mode) === How to run it (interactive mode)
@@ -86,13 +205,13 @@ Go to your project (e.g. Spring Cloud Sleuth)
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git $ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth $ cd spring-cloud-sleuth
$ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser $ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser $ java -jar ~/repo/spring-cloud-release-tools/projects/spring-cloud/target/spring-cloud-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser
---- ----
The application will start running from your working directory. Running this code The application will start running from your working directory.
follows the convention that you have the OAuth token environment variable set. It also assumes Running this code follows the convention that you have the OAuth token environment variable set.
that you might have some custom configuration in `config/releaser.yml` file. This setting is optional - if It also assumes that you might have some custom configuration in `config/releaser.yml` file.
you don't have that file, nothing will happen. This setting is optional - if you don't have that file, nothing will happen.
TIP: It is important that you clone the repository you are going to release using SSH in order for the TIP: It is important that you clone the repository you are going to release using SSH in order for the
`releaser` to be able to push tags and commit changes automatically. `releaser` to be able to push tags and commit changes automatically.
@@ -122,8 +241,10 @@ You can execute given tasks by providing a comma separated list of tasks - e.g.
You can press 'q' to quit You can press 'q' to quit
---- ----
Just pick a number and continue! Pick either a full release or single steps. You can also pick Just pick a number and continue!
ranges or multiple steps. You can also provide the range only with the starting step Pick either a full release or single steps.
You can also pick ranges or multiple steps.
You can also provide the range only with the starting step
- that you will execute all steps starting from the given one. - that you will execute all steps starting from the given one.
TIP: Read before picking a number cause it might have changed between tool releases ;) TIP: Read before picking a number cause it might have changed between tool releases ;)
@@ -138,7 +259,7 @@ flag.
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git $ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth $ cd spring-cloud-sleuth
$ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser $ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -h $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -h
---- ----
You will see a help screen looking like more or less like this You will see a help screen looking like more or less like this
@@ -199,9 +320,11 @@ Range 'docs' -> 'push'
java -jar releaser.jar -r o-p java -jar releaser.jar -r o-p
---- ----
The Releaser can use two sets of options. The configuration options like `releaser.pom.branch` The Releaser can use two sets of options.
and the task switches. For the tasks you can use either the full names or short switches. For example The configuration options like `releaser.pom.branch`
providing range of tasks via switches `o-p` is equivalent to full name `docs-push`. and the task switches.
For the tasks you can use either the full names or short switches.
For example providing range of tasks via switches `o-p` is equivalent to full name `docs-push`.
A couple of examples: A couple of examples:
@@ -211,52 +334,49 @@ A couple of examples:
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git $ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth $ cd spring-cloud-sleuth
$ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser $ # example of running the releaser agains Dalston.SR1 tag with 1.0.0.BUILD-SNAPSHOT version of the releaser
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release
---- ----
.Doing the full release in non interactive mode (automatic release) .Doing the full release in non interactive mode (automatic release)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release --interactive=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --full-release --interactive=false
---- ----
.Updating pom, closing milestone & createTemplates in interactive mode .Updating pom, closing milestone & createTemplates in interactive mode
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -u -m -t $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -u -m -t
---- ----
.Running all tasks starting from 'push' (automatic) .Running all tasks starting from 'push' (automatic)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -a push -i=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -a push -i=false
---- ----
.Running tasks from 'docs' (inclusive) to 'push' (inclusive) (automatic) .Running tasks from 'docs' (inclusive) to 'push' (inclusive) (automatic)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -r d-p -i=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser -r d-p -i=false
---- ----
.Running single task 'closeMilestone' (automatic) .Running single task 'closeMilestone' (automatic)
[source,bash] [source,bash]
---- ----
$ java -jar ~/repo/spring-cloud-release-tools/spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --closeMilestone -i=false $ java -jar ~/repo/spring-cloud-release-tools/releaser-spring/target/releaser-spring-1.0.0.BUILD-SNAPSHOT.jar --releaser.pom.branch=vDalston.SR1 --spring.config.name=releaser --closeMilestone -i=false
---- ----
=== How to run meta-release (automatic-mode) === How to run meta-release (automatic-mode)
All you have to do is run the jar with the releaser and pass the All you have to do is run the jar with the releaser and pass the
`-x=true` option to turn on meta-release and a list of fixed versions `-x=true` option to turn on meta-release and a list of fixed versions in the `--"releaser.fixed-versions[project-name]=project-version" format
in the `--"releaser.fixed-versions[project-name]=project-version" format
``` ```
$ java -jar spring-cloud-release-tools-spring/target/spring-cloud-release-tools-spring-1.0.0.BUILD-SNAPSHOT.jar --spring.config.name=releaser -x=true --"releaser.fixed-versions[spring-cloud-sleuth]=2.0.1.BUILD-SNAPSHOT" $ java -jar projects/spring-cloud/target/spring-cloud-1.0.0.BUILD-SNAPSHOT.jar --spring.config.name=releaser -x=true --"releaser.fixed-versions[spring-cloud-sleuth]=2.0.1.BUILD-SNAPSHOT"
``` ```
IMPORTANT: For the meta release the `startFrom` or `taskNames` take into consideration IMPORTANT: For the meta release the `startFrom` or `taskNames` take into consideration the project names, not task names. E.g. you can start from `spring-cloud-netflix` project, or build only tasks with names `spring-cloud-build,spring-cloud-sleuth`.
the project names, not task names. E.g. you can start from `spring-cloud-netflix` project,
or build only tasks with names `spring-cloud-build,spring-cloud-sleuth`.
=== Project options === Project options
@@ -265,34 +385,31 @@ Below you can find a table with all the releaser options.
include::_configprops.adoc[] include::_configprops.adoc[]
TIP: You can pass the options either via system properties or via application arguments. TIP: You can pass the options either via system properties or via application arguments.
Example for system properties: `java -Dreleaser.pom.branch=Camden.SR6 -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar` Example for system properties: `java -Dreleaser.pom.branch=Camden.SR6 -jar target/releaser-spring-1.0.0.M1.jar`
Example for application arguments: `java -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6` Example for application arguments: `java -jar target/releaser-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6`
IMPORTANT: For the GA release to be successful, it's important that if the `build` / `deploy` command IMPORTANT: For the GA release to be successful, it's important that if the `build` / `deploy` command run a script (e.g. `scripts/foo.sh`) then inside `foo.sh` if you call a Maven build `./mvnw clean install`
run a script (e.g. `scripts/foo.sh`) then inside `foo.sh` if you call a Maven build `./mvnw clean install` then *remember to pass all arguments of the script there too*.
then *remember to pass all arguments of the script there too*. E.g. `./mvnw clean install ${@}`. That's because E.g. `./mvnw clean install ${@}`.
the releaser will pass any system properties to the `build` / `deploy` command, such as system properties That's because the releaser will pass any system properties to the `build` / `deploy` command, such as system properties with keys and we need them to be passed inside the command executed by the releaser.
with keys and we need them to be passed inside the command executed by the releaser.
=== Examples === Examples
==== Keeping configuration in the project ==== Keeping configuration in the project
If your project has some custom configuration (e.g. Spring Cloud Contract needs a script to be executed If your project has some custom configuration (e.g. Spring Cloud Contract needs a script to be executed to build the project and properly merge the docs) then you can put a file named e.g. `releaser.yml` under `config`
to build the project and properly merge the docs) then you can put a file named e.g. `releaser.yml` under `config`
folder and run your application like this: folder and run your application like this:
[source,bash] [source,bash]
---- ----
$ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/spring-cloud-release-tools-spring/1.0.0.M1/spring-cloud-release-tools-spring-1.0.0.M1.jar -O ../spring-cloud-release-tools-spring-1.0.0.M1.jar $ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/releaser-spring/1.0.0.M1/releaser-spring-1.0.0.M1.jar -O ../releaser-spring-1.0.0.M1.jar
$ java -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar --spring.config.name=releaser $ java -jar target/releaser-spring-1.0.0.M1.jar --spring.config.name=releaser
---- ----
TIP: Notice that we're downloading the jar to a parent folder, not to `target`. That's because `target` get cleaned TIP: Notice that we're downloading the jar to a parent folder, not to `target`.
during the build process That's because `target` get cleaned during the build process
IMPORTANT: For the meta-releaser to work we assume that the path to the IMPORTANT: For the meta-releaser to work we assume that the path to the configuration file is always `config/releaser.yml`.
configuration file is always `config/releaser.yml`.
==== Specifying A Branch ==== Specifying A Branch
@@ -301,39 +418,47 @@ If you would like to use another branch you can specify it using the `releaser.p
[source,bash] [source,bash]
---- ----
$ java -jar spring-cloud-release-tools-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6 $ java -jar releaser-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6
---- ----
==== Using Environment Variables ==== Using Environment Variables
In some cases it might be easier to specify environment variables instead of passing parameters to In some cases it might be easier to specify environment variables instead of passing parameters to
`releaser`. For example, you might want to use environment variables if you are going to be `releaser`.
releasing multiple projects, this keeps you from having to specify the same parameters for For example, you might want to use environment variables if you are going to be releasing multiple projects, this keeps you from having to specify the same parameters for each release
each release
[source,bash] [source,bash]
---- ----
$ export RELEASER_POM_BRANCH=Dalston.RELEASE $ export RELEASER_POM_BRANCH=Dalston.RELEASE
$ export RELEASER_GIT_OAUTH_TOKEN=... $ export RELEASER_GIT_OAUTH_TOKEN=...
$ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/spring-cloud-release-tools-spring/1.0.0.M1/spring-cloud-release-tools-spring-1.0.0.M1.jar -O spring-cloud-release-tools-spring-1.0.0.M1.jar $ wget https://repo.spring.io/libs-milestone/org/springframework/cloud/internal/releaser-spring/1.0.0.M1/releaser-spring-1.0.0.M1.jar -O releaser-spring-1.0.0.M1.jar
$ java -jar target/spring-cloud-release-tools-spring-1.0.0.M1.jar --releaser.working-dir=/path/to/project/root $ java -jar target/releaser-spring-1.0.0.M1.jar --releaser.working-dir=/path/to/project/root
---- ----
=== Releasing through Jenkins === Releasing through Jenkins
NOTE: Whenever a release process is broken, Jenkins marks it with a red ball and breaks the build. Whenever a post-release action went wrong but the release is successful, Jenkins marks the build with a yellow ball and marks the build as unstable. NOTE: Whenever a release process is broken, Jenkins marks it with a red ball and breaks the build.
Whenever a post-release action went wrong but the release is successful, Jenkins marks the build with a yellow ball and marks the build as unstable.
==== Releasing a Single Project ==== Releasing a Single Project
Let us assume that we are to release `spring-cloud-build` project. We need to do the following steps: Let us assume that we are to release `spring-cloud-build` project.
We need to do the following steps:
. Create a branch (for example, `springCloudBuildRelease`) in a project that contains a BOM (for example, https://github.com/spring-cloud/spring-cloud-release/[spring-cloud-release]).
The following example shows how to do so:
. Create a branch (for example, `springCloudBuildRelease`) in a project that contains a BOM (for example, https://github.com/spring-cloud/spring-cloud-release/[spring-cloud-release]). The following example shows how to do so:
```bash ```bash
$ git clone git@github.com:spring-cloud/spring-cloud-release.git $ git clone git@github.com:spring-cloud/spring-cloud-release.git
$ cd spring-cloud-release $ cd spring-cloud-release
$ git checkout -b springCloudBuildRelease $ git checkout -b springCloudBuildRelease
``` ```
. Update *all* versions as if you were doing a release train. We need to update the project's versions, Boot version, and dependencies versions, too. Let us assume that we will eventually be doing a release train for the `Hoxton.M1` release, Spring Boot to the latest available one, and `spring-cloud-commons` to `1.2.3.BUILD-SNAPSHOT`. The following example shows how to do so:
. Update *all* versions as if you were doing a release train.
We need to update the project's versions, Boot version, and dependencies versions, too.
Let us assume that we will eventually be doing a release train for the `Hoxton.M1` release, Spring Boot to the latest available one, and `spring-cloud-commons` to `1.2.3.BUILD-SNAPSHOT`.
The following example shows how to do so:
```bash ```bash
// setting the release train value // setting the release train value
$ ./mvnw versions:set -DnewVersion=Hoxton.M1 -DgenerateBackupPoms=false -DprocessAllModules=true $ ./mvnw versions:set -DnewVersion=Hoxton.M1 -DgenerateBackupPoms=false -DprocessAllModules=true
@@ -347,27 +472,32 @@ $ git diff
// commit and push the branch // commit and push the branch
$ git add . && git commit -m "Updating project for Spring Cloud Build release" && git push origin springCloudBuildRelease $ git add . && git commit -m "Updating project for Spring Cloud Build release" && git push origin springCloudBuildRelease
``` ```
IMPORTANT: If you're doing a e.g. `M1` release, remember to not have any snapshot versions in this branch. IMPORTANT: If you're doing a e.g. `M1` release, remember to not have any snapshot versions in this branch.
Since the project is prepared, go to Jenkins and select the https://jenkins.spring.io/view/Spring%20Cloud/view/Releaser/[Releaser view], which the following image shows: Since the project is prepared, go to Jenkins and select the https://jenkins.spring.io/view/Spring%20Cloud/view/Releaser/[Releaser view], which the following image shows:
image::{github-raw}/docs/src/main/asciidoc/images/releasers.png[Releaser view] image::{github-raw}/docs/src/main/asciidoc/images/releasers.png[Releaser view]
. Pick the proper releaser project (for example, `spring-cloud-build-releaser`). The following image shows the settings for this example: . Pick the proper releaser project (for example, `spring-cloud-build-releaser`).
The following image shows the settings for this example:
image::{github-raw}/docs/src/main/asciidoc/images/scBuildReleaser.png[Spring Cloud Build Releaser - build with parameters] image::{github-raw}/docs/src/main/asciidoc/images/scBuildReleaser.png[Spring Cloud Build Releaser - build with parameters]
. Next, click `Build with parameters`. The following image shows the UI for doing so: . Next, click `Build with parameters`.
The following image shows the UI for doing so:
image::{github-raw}/docs/src/main/asciidoc/images/runningScBuildReleaser.png[Updated `RELEASER_POM_BRANCH`] image::{github-raw}/docs/src/main/asciidoc/images/runningScBuildReleaser.png[Updated `RELEASER_POM_BRANCH`]
Pick from which branch you would like the project (for example, `spring-cloud-build` - defaults to `master`) to be built and update the `RELEASER_POM_BRANCH` to point to the checked-out branch of Spring Cloud Release (for example, `springCloudBuildRelease`). You can pick whether you want to perform only post-release tasks or the whole release. Pick from which branch you would like the project (for example, `spring-cloud-build` - defaults to `master`) to be built and update the `RELEASER_POM_BRANCH` to point to the checked-out branch of Spring Cloud Release (for example, `springCloudBuildRelease`).
You can pick whether you want to perform only post-release tasks or the whole release.
. Finally, click `Build`. . Finally, click `Build`.
You are done! You are done!
As a post action, do not forget to remove the branch. The following example shows how to do so: As a post action, do not forget to remove the branch.
The following example shows how to do so:
```bash ```bash
// to synchronize any deleted branches (don't run this if you want leave any deleted branches that were deleted in the origin) // to synchronize any deleted branches (don't run this if you want leave any deleted branches that were deleted in the origin)
@@ -378,19 +508,31 @@ $ git push origin --delete springCloudBuildRelease
==== Releasing a Release Train ==== Releasing a Release Train
We call a release train a `meta-release`. In order to perform one, you need to: We call a release train a `meta-release`.
In order to perform one, you need to:
. In your project (which must contain a BOM, such as `spring-cloud-release`) you have to have a branch, where you store properties with versions of your projects.
For example, the branch name can be https://github.com/spring-cloud/spring-cloud-release/tree/jenkins-releaser-config[jenkins-releaser-config]).
The folloiwng example shows how to do so:
. In your project (which must contain a BOM, such as `spring-cloud-release`) you have to have a branch, where you store properties with versions of your projects. For example, the branch name can be https://github.com/spring-cloud/spring-cloud-release/tree/jenkins-releaser-config[jenkins-releaser-config]). The folloiwng example shows how to do so:
```bash ```bash
$ git clone git@github.com:spring-cloud/spring-cloud-release.git $ git clone git@github.com:spring-cloud/spring-cloud-release.git
$ cd spring-cloud-release $ cd spring-cloud-release
$ git checkout jenkins-releaser-config $ git checkout jenkins-releaser-config
``` ```
. Create a file that contains all properties for a given release train. The name of the release train should be lowercase, and dots should be converted to underscores. For example, for the `Greenwich.SR2` release train we need to have a file named `greenwich_sr2.properties`. The following example shows how to do so:
. Create a file that contains all properties for a given release train.
The name of the release train should be lowercase, and dots should be converted to underscores.
For example, for the `Greenwich.SR2` release train we need to have a file named `greenwich_sr2.properties`.
The following example shows how to do so:
```bash ```bash
$ touch greenwich_sr2.properties $ touch greenwich_sr2.properties
``` ```
. We need to update the file with all versions for the release train. The properties file contains an *ordered* list of `releaser.fixed-versions[project-name]=project-version` entries, as the following listing shows:
. We need to update the file with all versions for the release train.
The properties file contains an *ordered* list of `releaser.fixed-versions[project-name]=project-version` entries, as the following listing shows:
```bash ```bash
$ echo "releaser.fixed-versions[spring-boot]=2.1.5.RELEASE $ echo "releaser.fixed-versions[spring-boot]=2.1.5.RELEASE
releaser.fixed-versions[spring-cloud-build]=2.1.5.RELEASE releaser.fixed-versions[spring-cloud-build]=2.1.5.RELEASE
@@ -429,7 +571,8 @@ image::{github-raw}/docs/src/main/asciidoc/images/springCloudMetaRelease.png[Spr
image::{github-raw}/docs/src/main/asciidoc/images/runningSpringCloudMetaReleaser.png[Spring Cloud Meta Releaser view] image::{github-raw}/docs/src/main/asciidoc/images/runningSpringCloudMetaReleaser.png[Spring Cloud Meta Releaser view]
You have quite a few options to pick, but the most important one is to set the value of the `RELEASE_VERSION` to the given release train version (for example, `Greenwich.SR2`). Continue updating the rest of the fields if necessary and read the field descriptions and this documentation for more information. You have quite a few options to pick, but the most important one is to set the value of the `RELEASE_VERSION` to the given release train version (for example, `Greenwich.SR2`).
Continue updating the rest of the fields if necessary and read the field descriptions and this documentation for more information.
. Finally, click `Build`. . Finally, click `Build`.

26
pom.xml
View File

@@ -5,28 +5,46 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.cloud.internal</groupId> <groupId>org.springframework.cloud.internal</groupId>
<artifactId>spring-cloud-release-tools-parent</artifactId> <artifactId>releaser-parent</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version> <version>1.0.0.BUILD-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<parent> <parent>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId> <artifactId>spring-cloud-build</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version> <version>2.2.1.RELEASE</version>
<relativePath/> <relativePath/>
<!-- lookup parent from repository --> <!-- lookup parent from repository -->
</parent> </parent>
<modules> <modules>
<module>spring-cloud-release-tools-core</module> <module>releaser-core</module>
<module>spring-cloud-release-tools-spring</module> <module>releaser-spring</module>
<module>releaser-test</module>
<module>spring-cloud-info</module> <module>spring-cloud-info</module>
<module>projects</module>
<module>docs</module> <module>docs</module>
</modules> </modules>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<spring-cloud-bom.version>Hoxton.BUILD-SNAPSHOT</spring-cloud-bom.version> <spring-cloud-bom.version>Hoxton.BUILD-SNAPSHOT</spring-cloud-bom.version>
<jcabi-github.version>1.0</jcabi-github.version> <jcabi-github.version>1.0</jcabi-github.version>
<jsch-agent.version>0.0.9</jsch-agent.version>
<hibernate-validator.version>5.4.1.Final</hibernate-validator.version>
<org.eclipse.jgit-version>5.1.3.201810200350-r</org.eclipse.jgit-version>
<!-- Versions plugin uses this version -->
<maven-model.version>2.2.1</maven-model.version>
<versions-maven-plugin.version>2.3</versions-maven-plugin.version>
<handlebars.version>4.0.6</handlebars.version>
<initializr-metadata.version>0.8.0.BUILD-SNAPSHOT</initializr-metadata.version>
<awaitility.version>3.1.6</awaitility.version>
<sagan-site.version>1.0.0.BUILD-SNAPSHOT</sagan-site.version>
<javax.json.version>1.0.4</javax.json.version>
<jopt-simple.version>5.0.3</jopt-simple.version>
<fliptables.version>1.0.2</fliptables.version>
</properties> </properties>
<dependencyManagement> <dependencyManagement>

24
projects/pom.xml Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>releaser-projects</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-parent</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<modules>
<module>spring-cloud</module>
<module>spring-cloud-stream</module>
<module>reactor</module>
</modules>
</project>

96
projects/reactor/pom.xml Normal file
View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>reactor</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-projects</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-spring</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sonar</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
<destFile>${project.build.directory}/jacoco.exec</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ReleaserApplication extends ReleaserCommandLineRunner {
public ReleaserApplication(SpringReleaser releaser,
ExecutionResultHandler executionResultHandler, Parser parser) {
super(releaser, executionResultHandler, parser);
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(ReleaserApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
}

View File

@@ -0,0 +1,17 @@
spring:
main:
web-application-type: none
datasource:
url: jdbc:h2:mem:${random.uuid}
jackson:
deserialization:
FAIL_ON_UNKNOWN_PROPERTIES: true
releaser:
git:
release-train-bom-url: https://github.com/reactor/reactor
fetch-versions-from-git: true
meta-release:
release-train-project-name: reactor
release-train-dependency-names:
- reactor
git-org-url: https://github.com/reactor

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootTest(
classes = { ReleaserApplicationTests.Config.class, ReleaserApplication.class },
properties = { "releaser.sagan.update-sagan=false" })
class ReleaserApplicationTests {
@Test
void contextLoads() {
}
@Configuration
static class Config {
@Bean
SpringReleaser mockReleaser() {
return Mockito.mock(SpringReleaser.class);
}
@Bean
ExecutionResultHandler mockExecutionResultHandler() {
return Mockito.mock(ExecutionResultHandler.class);
}
@Bean
Parser mockParser() {
return Mockito.mock(Parser.class);
}
}
}

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-projects</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-spring</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sonar</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
<destFile>${project.build.directory}/jacoco.exec</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ReleaserApplication extends ReleaserCommandLineRunner {
public ReleaserApplication(SpringReleaser releaser,
ExecutionResultHandler executionResultHandler, Parser parser) {
super(releaser, executionResultHandler, parser);
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(ReleaserApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
}

View File

@@ -0,0 +1,42 @@
spring:
main:
web-application-type: none
datasource:
url: jdbc:h2:mem:${random.uuid}
jackson:
deserialization:
FAIL_ON_UNKNOWN_PROPERTIES: true
releaser:
git:
release-train-bom-url: https://github.com/spring-cloud/spring-cloud-stream-starters
documentation-url: https://github.com/spring-cloud/spring-cloud-static
number-of-checked-milestones: 50
update-github-milestones: true
pom:
branch: master
pom-with-boot-starter-parent: spring-cloud-starter-parent/pom.xml
this-train-bom: spring-cloud-stream-dependencies/pom.xml
bom-version-pattern: "^(spring-cloud-.*)\\.version$"
ignored-pom-regex:
- "^.*\\.git/.*$"
maven:
build-command: "./mvnw clean install -B -Pdocs {{systemProps}}"
deploy-command: "./mvnw deploy -DskipTests -B -Pfast,deploy {{systemProps}}"
deploy-guides-command: "./mvnw clean verify deploy -B -Pguides,integration -pl guides {{systemProps}}"
publish-docs-commands:
- "mkdir -p target"
- "wget https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/ghpages.sh -O target/gh-pages.sh"
- "chmod +x target/gh-pages.sh"
- "./target/gh-pages.sh -v {{version}} -c"
generate-release-train-docs-command: "bash release_train.sh --retrieveversions --version {{version}} --ghpages --auto"
sagan:
update-sagan: true
meta-release:
release-train-project-name: spring-cloud-stream-starters
release-train-dependency-names:
- spring-cloud-stream-dependencies
git-org-url: https://github.com/spring-cloud
projects-to-skip:
- spring-boot
- spring-cloud-build
- spring-cloud-function

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootTest(
classes = { ReleaserApplicationTests.Config.class, ReleaserApplication.class },
properties = { "releaser.sagan.update-sagan=false" })
class ReleaserApplicationTests {
@Test
void contextLoads() {
}
@Configuration
static class Config {
@Bean
SpringReleaser mockReleaser() {
return Mockito.mock(SpringReleaser.class);
}
@Bean
ExecutionResultHandler mockExecutionResultHandler() {
return Mockito.mock(ExecutionResultHandler.class);
}
@Bean
Parser mockParser() {
return Mockito.mock(Parser.class);
}
}
}

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-projects</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-spring</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud.internal</groupId>
<artifactId>releaser-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sonar</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
<destFile>${project.build.directory}/jacoco.exec</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ReleaserApplication extends ReleaserCommandLineRunner {
public ReleaserApplication(SpringReleaser releaser,
ExecutionResultHandler executionResultHandler, Parser parser) {
super(releaser, executionResultHandler, parser);
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(ReleaserApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
}

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.buildsystem; package releaser.cloud.buildsystem;
/** /**
* @author Marcin Grzejszczak * @author Marcin Grzejszczak

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.buildsystem; package releaser.cloud.buildsystem;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.buildsystem; package releaser.cloud.buildsystem;
import java.io.File; import java.io.File;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@@ -23,47 +23,38 @@ import java.util.Set;
import org.apache.maven.model.Model; import org.apache.maven.model.Model;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import releaser.internal.ReleaserProperties;
import releaser.internal.buildsystem.CustomBomParser;
import releaser.internal.buildsystem.VersionsFromBom;
import releaser.internal.buildsystem.VersionsFromBomBuilder;
import releaser.internal.project.Project;
import releaser.internal.tech.PomReader;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.buildsystem.CustomBomParser;
import org.springframework.cloud.release.internal.buildsystem.VersionsFromBom;
import org.springframework.cloud.release.internal.buildsystem.VersionsFromBomBuilder;
import org.springframework.cloud.release.internal.project.Project;
import org.springframework.cloud.release.internal.tech.PomReader;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.BOOT_DEPENDENCIES_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.BOOT_DEPENDENCIES_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.BOOT_STARTER_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.BOOT_STARTER_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.BOOT_STARTER_PARENT_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.BOOT_STARTER_PARENT_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.BUILD_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.BUILD_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.CLOUD_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.CLOUD_RELEASE_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_RELEASE_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.CLOUD_STARTER_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_STARTER_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.CLOUD_STARTER_PARENT_ARTIFACT_ID; import static releaser.cloud.buildsystem.SpringCloudBomConstants.CLOUD_STARTER_PARENT_ARTIFACT_ID;
import static org.springframework.cloud.release.cloud.buildsystem.SpringCloudBomConstants.SPRING_BOOT; import static releaser.cloud.buildsystem.SpringCloudBomConstants.SPRING_BOOT;
class SpringCloudMavenBomParser implements CustomBomParser { class SpringCloudMavenBomParser implements CustomBomParser {
private static final Logger log = LoggerFactory private static final Logger log = LoggerFactory
.getLogger(SpringCloudMavenBomParser.class); .getLogger(SpringCloudMavenBomParser.class);
@Override
public boolean isApplicable(File root, ReleaserProperties properties,
Set<Project> projects) {
return isMaven(root) && root.getName().startsWith("spring-cloud") || projects
.stream().anyMatch(project -> BUILD_ARTIFACT_ID.equals(project.name));
}
@Override @Override
public VersionsFromBom parseBom(File root, ReleaserProperties properties) { public VersionsFromBom parseBom(File root, ReleaserProperties properties) {
VersionsFromBom springCloudBuild = springCloudBuild(root, properties); VersionsFromBom springCloudBuild = springCloudBuild(root, properties);
VersionsFromBom boot = bootVersion(root, properties); VersionsFromBom boot = bootVersion(root, properties);
if (log.isDebugEnabled()) { log.debug("Added Spring Cloud Build [{}] and boot versions [{}]",
log.debug("Added Spring Cloud Build [{}] and boot versions [{}]", springCloudBuild, boot);
springCloudBuild, boot);
}
return new VersionsFromBomBuilder().thisProjectRoot(root) return new VersionsFromBomBuilder().thisProjectRoot(root)
.releaserProperties(properties).projects(springCloudBuild, boot).merged(); .releaserProperties(properties).projects(springCloudBuild, boot).merged();
} }
@@ -119,12 +110,10 @@ class SpringCloudMavenBomParser implements CustomBomParser {
} }
String bootArtifactId = model.getParent().getArtifactId(); String bootArtifactId = model.getParent().getArtifactId();
log.debug("Boot artifact id is equal to [{}]", bootArtifactId); log.debug("Boot artifact id is equal to [{}]", bootArtifactId);
if (!SpringCloudBomConstants.BOOT_STARTER_PARENT_ARTIFACT_ID if (!BOOT_STARTER_PARENT_ARTIFACT_ID.equals(bootArtifactId)) {
.equals(bootArtifactId)) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
throw new IllegalStateException("The pom doesn't have a [" throw new IllegalStateException("The pom doesn't have a ["
+ SpringCloudBomConstants.BOOT_STARTER_PARENT_ARTIFACT_ID + BOOT_STARTER_PARENT_ARTIFACT_ID + "] artifact id");
+ "] artifact id");
} }
return ""; return "";
} }

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.docs; package releaser.cloud.docs;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -23,12 +23,12 @@ import java.nio.file.Path;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import releaser.internal.ReleaserProperties;
import releaser.internal.docs.CustomProjectDocumentationUpdater;
import releaser.internal.git.ProjectGitHandler;
import releaser.internal.project.ProjectVersion;
import releaser.internal.project.Projects;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.docs.CustomProjectDocumentationUpdater;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
import org.springframework.util.FileSystemUtils; import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -51,13 +51,6 @@ class SpringCloudCustomProjectDocumentationUpdater
this.releaserProperties = releaserProperties; this.releaserProperties = releaserProperties;
} }
@Override
public boolean isApplicable(File clonedDocumentationProject,
ProjectVersion currentProject, String bomBranch) {
return clonedDocumentationProject.getName().startsWith("spring-cloud")
|| currentProject.projectName.startsWith("spring-cloud");
}
/** /**
* Updates the documentation repository if current release train version is greater or * Updates the documentation repository if current release train version is greater or
* equal than the one stored in the repo. * equal than the one stored in the repo.
@@ -67,7 +60,7 @@ class SpringCloudCustomProjectDocumentationUpdater
* used * used
*/ */
@Override @Override
public File updateDocsRepo(File clonedDocumentationProject, public File updateDocsRepoForReleaseTrain(File clonedDocumentationProject,
ProjectVersion currentProject, Projects projects, String bomBranch) { ProjectVersion currentProject, Projects projects, String bomBranch) {
log.debug("Cloning the doc project to [{}]", clonedDocumentationProject); log.debug("Cloning the doc project to [{}]", clonedDocumentationProject);
ProjectVersion releaseTrainProject = new ProjectVersion( ProjectVersion releaseTrainProject = new ProjectVersion(
@@ -79,28 +72,44 @@ class SpringCloudCustomProjectDocumentationUpdater
removeAFolderWithRedirection(currentReleaseFolder); removeAFolderWithRedirection(currentReleaseFolder);
File docsRepo = updateTheDocsRepo(releaseTrainProject, clonedDocumentationProject, File docsRepo = updateTheDocsRepo(releaseTrainProject, clonedDocumentationProject,
currentReleaseFolder); currentReleaseFolder);
log.info(
"Updating all current links to documentation for release train projects");
projects.forEach(projectVersion -> {
File currentProjectReleaseFolder = new File(clonedDocumentationProject,
currentFolder(projectVersion.projectName, projectVersion.version));
removeAFolderWithRedirection(currentProjectReleaseFolder);
try {
updateTheDocsRepo(projectVersion, clonedDocumentationProject,
currentProjectReleaseFolder);
log.info("Processed [{}] for project with name [{}]",
currentProjectReleaseFolder, projectVersion.projectName);
}
catch (Exception ex) {
log.warn(
"Exception occurred while trying o update the symlink of a project ["
+ projectVersion.projectName + "]",
ex);
}
});
return pushChanges(docsRepo); return pushChanges(docsRepo);
} }
/**
* Updates the documentation repository if current release train version is greater or
* equal than the one stored in the repo.
* @param currentProject project to update the docs repo for
* @return {@link File cloned temporary directory} - {@code null} if wrong version is
* used
*/
@Override
public File updateDocsRepoForSingleProject(File clonedDocumentationProject,
ProjectVersion currentProject, Projects projects) {
if (!projects.containsProject(currentProject.projectName)) {
log.warn(
"Can't update the documentation repo for project [{}] cause it's not present on the projects list {}",
currentProject.projectName, projects);
return clonedDocumentationProject;
}
log.info("Updating link to documentation for project [{}]",
currentProject.projectName);
ProjectVersion projectVersion = projects.forName(currentProject.projectName);
File currentProjectReleaseFolder = new File(clonedDocumentationProject,
currentFolder(projectVersion.projectName, projectVersion.version));
removeAFolderWithRedirection(currentProjectReleaseFolder);
try {
updateTheDocsRepo(projectVersion, clonedDocumentationProject,
currentProjectReleaseFolder);
log.info("Processed [{}] for project with name [{}]",
currentProjectReleaseFolder, projectVersion.projectName);
}
catch (Exception ex) {
log.warn("Exception occurred while trying o update the symlink of a project ["
+ projectVersion.projectName + "]", ex);
}
return pushChanges(clonedDocumentationProject);
}
private void removeAFolderWithRedirection(File currentReleaseFolder) { private void removeAFolderWithRedirection(File currentReleaseFolder) {
if (!isSymbolinkLink(currentReleaseFolder)) { if (!isSymbolinkLink(currentReleaseFolder)) {
FileSystemUtils.deleteRecursively(currentReleaseFolder); FileSystemUtils.deleteRecursively(currentReleaseFolder);
@@ -179,8 +188,7 @@ class SpringCloudCustomProjectDocumentationUpdater
log.warn("Failed to create parent directory of [{}]", log.warn("Failed to create parent directory of [{}]",
currentVersionFolder); currentVersionFolder);
} }
File newTarget = new File(documentationProject, File newTarget = new File(projectVersion.version);
concreteVersionFolder(projectVersion));
Files.createSymbolicLink(currentVersionFolder.toPath(), newTarget.toPath()); Files.createSymbolicLink(currentVersionFolder.toPath(), newTarget.toPath());
log.info("Updated the link [{}] to point to [{}]", log.info("Updated the link [{}] to point to [{}]",
currentVersionFolder.toPath(), currentVersionFolder.toPath(),

View File

@@ -14,10 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.docs; package releaser.cloud.docs;
import releaser.internal.ReleaserProperties;
import releaser.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2013-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,9 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.github; package releaser.cloud.github;
import releaser.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

View File

@@ -14,15 +14,15 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.github; package releaser.cloud.github;
import com.jcabi.github.Github; import com.jcabi.github.Github;
import releaser.internal.ReleaserProperties;
import releaser.internal.github.CustomGithubIssues;
import releaser.internal.github.GithubIssueFiler;
import releaser.internal.project.ProjectVersion;
import releaser.internal.project.Projects;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.github.CustomGithubIssues;
import org.springframework.cloud.release.internal.github.GithubIssueFiler;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
class SpringCloudGithubIssues implements CustomGithubIssues { class SpringCloudGithubIssues implements CustomGithubIssues {
@@ -43,13 +43,6 @@ class SpringCloudGithubIssues implements CustomGithubIssues {
this.properties = properties; this.properties = properties;
} }
@Override
public boolean isApplicable(ReleaserProperties properties, Projects projects,
ProjectVersion version) {
return projects.stream()
.anyMatch(project -> project.projectName.contains("spring-cloud-build"));
}
@Override @Override
public void fileIssueInSpringGuides(Projects projects, ProjectVersion version) { public void fileIssueInSpringGuides(Projects projects, ProjectVersion version) {
String user = "spring-guides"; String user = "spring-guides";

View File

@@ -0,0 +1,123 @@
spring:
main:
web-application-type: none
datasource:
url: jdbc:h2:mem:${random.uuid}
jackson:
deserialization:
FAIL_ON_UNKNOWN_PROPERTIES: true
releaser:
# working-dir:
post-release-tasks-only: false
skip-post-release-tasks: false
flow:
default-enabled: true
git:
release-train-bom-url: https://github.com/spring-cloud/spring-cloud-release
documentation-url: https://github.com/spring-cloud/spring-cloud-static
spring-project-url: https://github.com/spring-projects/spring-cloud
test-samples-project-url: https://github.com/spring-cloud/spring-cloud-core-tests
release-train-docs-url: https://github.com/spring-cloud-samples/scripts
release-train-wiki-url: https://github.com/spring-projects/spring-cloud.wiki
documentation-branch: gh-pages
spring-project-branch: gh-pages
test-samples-branch: master
release-train-docs-branch: master
release-train-wiki-page-prefix: Spring-Cloud
# clone-destination-dir:
fetch-versions-from-git: true
# oauth-token:
# username:
# password:
number-of-checked-milestones: 50
update-documentation-repo: true
update-github-milestones: true
update-spring-guides: true
update-start-spring-io: true
update-spring-project: true
run-updated-samples: true
update-release-train-docs: true
update-release-train-wiki: true
update-all-test-samples: true
all-test-sample-urls:
spring-cloud-sleuth:
- https://github.com/spring-cloud-samples/sleuth-issues
- https://github.com/spring-cloud-samples/sleuth-documentation-apps
spring-cloud-contract:
- https://github.com/spring-cloud-samples/spring-cloud-contract-samples
- https://github.com/spring-cloud-samples/the-legacy-app
- https://github.com/spring-cloud-samples/sc-contract-car-rental
pom:
branch: master
pom-with-boot-starter-parent: spring-cloud-starter-parent/pom.xml
this-train-bom: spring-cloud-dependencies/pom.xml
bom-version-pattern: "^(spring-cloud-.*)\\.version$"
ignored-pom-regex:
- "^.*\\.git/.*$"
- "^.*spring-cloud-contract-maven-plugin/src/test/projects/.*$"
- "^.*spring-cloud-contract-maven-plugin/target/.*$"
- "^.*src/test/bats/.*$"
- "^.*samples/standalone/[a-z]+/.*$"
maven:
build-command: "./mvnw clean install -B -Pdocs {{systemProps}}"
deploy-command: "./mvnw deploy -DskipTests -B -Pfast,deploy {{systemProps}}"
deploy-guides-command: "./mvnw clean verify deploy -B -Pguides,integration -pl guides {{systemProps}}"
publish-docs-commands:
- "mkdir -p target"
- "wget https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/ghpages.sh -O target/gh-pages.sh"
- "chmod +x target/gh-pages.sh"
- "./target/gh-pages.sh -v {{version}} -c"
generate-release-train-docs-command: "bash release_train.sh --retrieveversions --version {{version}} --ghpages --auto"
system-properties: ""
wait-time-in-minutes: 20
bash:
build-command: 'echo "{{systemProps}}"'
deploy-command: 'echo "{{systemProps}}"'
deploy-guides-command: 'echo "{{systemProps}}"'
publish-docs-commands:
- 'echo "{{systemProps}}"'
generate-release-train-docs-command: 'echo "{{systemProps}}"'
system-properties: ""
wait-time-in-minutes: 20
gradle:
gradle-props-substitution:
bootVersion: spring-boot
BOOT_VERSION: spring-boot
bomVersion: spring-cloud-release
BOM_VERSION: spring-cloud-release
springCloudBuildVersion: spring-cloud-build
ignored-gradle-regex:
- "^.*spring-cloud-contract-maven-plugin/src/test/projects/.*$"
- "^.*spring-cloud-contract-maven-plugin/target/.*$"
- "^.*src/test/bats/.*$"
- "^.*samples/standalone/[a-z]+/.*$"
build-command: "./gradlew clean build publishToMavenLocal --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}}"
deploy-command: "./gradlew publish --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}}"
deploy-guides-command: "./gradlew clean build deployGuides --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}}"
publish-docs-commands:
- "echo 'TODO'"
generate-release-train-docs-command: "echo 'TODO'"
system-properties: ""
wait-time-in-minutes: 20
sagan:
update-sagan: true
template:
enabled: true
template-folder: cloud
versions:
all-versions-file-url: https://raw.githubusercontent.com/spring-io/start.spring.io/master/start-site/src/main/resources/application.yml
bom-name: spring-cloud
# fixed-versions:
meta-release:
enabled: false
release-train-project-name: spring-cloud-release
release-train-dependency-names:
- spring-cloud
- spring-cloud-dependencies
- spring-cloud-starter
- spring-cloud-starter-build
git-org-url: https://github.com/spring-cloud
projects-to-skip:
- spring-boot
- spring-cloud-stream
- spring-cloud-task

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootTest(
classes = { ReleaserApplicationTests.Config.class, ReleaserApplication.class },
properties = { "releaser.sagan.update-sagan=false" })
class ReleaserApplicationTests {
@Test
void contextLoads() {
}
@Configuration
static class Config {
@Bean
SpringReleaser mockReleaser() {
return Mockito.mock(SpringReleaser.class);
}
@Bean
ExecutionResultHandler mockExecutionResultHandler() {
return Mockito.mock(ExecutionResultHandler.class);
}
@Bean
Parser mockParser() {
return Mockito.mock(Parser.class);
}
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser.cloud;
import java.io.File;
import java.net.URISyntaxException;
import java.util.Properties;
import java.util.stream.Collectors;
import releaser.internal.ReleaserProperties;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import org.springframework.core.io.FileSystemResource;
public class SpringCloudReleaserProperties {
public static ReleaserProperties get() {
try {
File releaserConfig = new File(SpringCloudReleaserProperties.class
.getResource("/application.yml").toURI());
YamlPropertiesFactoryBean yamlProcessor = new YamlPropertiesFactoryBean();
yamlProcessor.setResources(new FileSystemResource(releaserConfig));
Properties properties = yamlProcessor.getObject();
ReleaserProperties releaserProperties = new Binder(
new MapConfigurationPropertySource(properties.entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey().toString(),
e -> e.getValue().toString()))))
.bind("releaser", ReleaserProperties.class)
.get();
return releaserProperties;
}
catch (URISyntaxException e) {
throw new IllegalStateException(e);
}
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser.cloud.buildsystem;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import releaser.cloud.SpringCloudReleaserProperties;
import releaser.internal.buildsystem.CustomBomParser;
import releaser.internal.buildsystem.VersionsFromBom;
import releaser.internal.buildsystem.VersionsFromBomBuilder;
import releaser.internal.project.Project;
import static org.assertj.core.api.BDDAssertions.then;
/**
* @author Marcin Grzejszczak
*/
public class SpringCloudCustomMavenBomTests {
@Test
public void should_add_boot_to_versions_when_version_is_created() {
List<CustomBomParser> bomParsers = Collections
.singletonList(new SpringCloudMavenBomParser());
VersionsFromBom customVersionsFromBom = new VersionsFromBomBuilder()
.releaserProperties(SpringCloudReleaserProperties.get())
.parsers(bomParsers).projects(springCloudBuildProjects())
.retrieveFromBom();
customVersionsFromBom.setVersion("spring-boot", "1.2.3.RELEASE");
then(customVersionsFromBom.versionForProject("spring-boot"))
.isEqualTo("1.2.3.RELEASE");
then(customVersionsFromBom.versionForProject("spring-boot-starter-parent"))
.isEqualTo("1.2.3.RELEASE");
then(customVersionsFromBom.versionForProject("spring-boot-dependencies"))
.isEqualTo("1.2.3.RELEASE");
}
@Test
public void should_update_projects_for_boot() {
VersionsFromBom versionsFromBom = mixedVersions().setVersion("spring-boot",
"3.0.0");
then(versionsFromBom.versionForProject("spring-boot")).isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-boot-starter-parent"))
.isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-boot-dependencies"))
.isEqualTo("3.0.0");
versionsFromBom = mixedVersions().setVersion("spring-boot-starter-parent",
"3.0.0");
then(versionsFromBom.versionForProject("spring-boot")).isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-boot-starter-parent"))
.isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-boot-dependencies"))
.isEqualTo("3.0.0");
versionsFromBom = mixedVersions().setVersion("spring-boot-dependencies", "3.0.0");
then(versionsFromBom.versionForProject("spring-boot")).isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-boot-starter-parent"))
.isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-boot-dependencies"))
.isEqualTo("3.0.0");
}
@Test
public void should_update_projects_for_build() {
VersionsFromBom versionsFromBom = mixedVersions().setVersion("spring-cloud-build",
"3.0.0");
then(versionsFromBom.versionForProject("spring-cloud-build")).isEqualTo("3.0.0");
versionsFromBom = mixedVersions().setVersion("spring-cloud-build", "3.0.0");
then(versionsFromBom.versionForProject("spring-cloud-dependencies-parent"))
.isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-cloud-dependencies"))
.isEqualTo("Greenwich.RELEASE");
versionsFromBom = mixedVersions().setVersion("spring-cloud-dependencies-parent",
"3.0.0");
then(versionsFromBom.versionForProject("spring-cloud-build")).isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-cloud-dependencies-parent"))
.isEqualTo("3.0.0");
then(versionsFromBom.versionForProject("spring-cloud-dependencies"))
.isEqualTo("Greenwich.RELEASE");
}
private VersionsFromBom mixedVersions() {
return new VersionsFromBomBuilder()
.releaserProperties(SpringCloudReleaserProperties.get())
.parsers(Collections.singletonList(new SpringCloudMavenBomParser()))
.projects(mixedProjects()).merged();
}
Set<Project> springCloudBuildProjects() {
Set<Project> projects = new HashSet<>();
projects.add(new Project("spring-cloud-build", "1.2.3.BUILD-SNAPSHOT"));
return projects;
}
Set<Project> mixedProjects() {
Set<Project> projects = new HashSet<>();
projects.add(new Project("foo", "1.0.0.BUILD-SNAPSHOT"));
projects.add(new Project("fooBar", "1.0.0.RELEASE"));
projects.add(new Project("spring-boot", "1.0.0"));
projects.add(new Project("spring-cloud-build", "2.0.0"));
projects.add(new Project("spring-cloud-release", "Greenwich.RELEASE"));
projects.add(new Project("spring-cloud-dependencies", "Greenwich.RELEASE"));
projects.add(new Project("spring-cloud-stream-starters", "Fishtown.RELEASE"));
return projects;
}
}

View File

@@ -0,0 +1,171 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser.cloud.buildsystem;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import releaser.cloud.SpringCloudReleaserProperties;
import releaser.cloud.docs.TestUtils;
import releaser.internal.ReleaserProperties;
import releaser.internal.buildsystem.BomParser;
import releaser.internal.buildsystem.MavenBomParserAccessor;
import releaser.internal.buildsystem.VersionsFromBom;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.api.BDDAssertions.thenThrownBy;
/**
* @author Marcin Grzejszczak
*/
public class SpringCloudMavenBomParserTests {
@Rule
public TemporaryFolder tmp = new TemporaryFolder();
File tmpFolder;
File springCloudReleaseProject;
ReleaserProperties properties = SpringCloudReleaserProperties.get();
@Before
public void setup() throws URISyntaxException, IOException, GitAPIException {
this.tmpFolder = this.tmp.newFolder();
TestUtils.prepareLocalRepo();
FileSystemUtils.copyRecursively(file("/projects"), this.tmpFolder);
this.springCloudReleaseProject = new File(this.tmpFolder,
"/spring-cloud-release");
}
private File file(String relativePath) throws URISyntaxException {
return new File(
SpringCloudMavenBomParserTests.class.getResource(relativePath).toURI());
}
@Test
public void should_throw_exception_when_null_is_passed_to_boot() {
this.properties.getPom().setPomWithBootStarterParent(null);
this.properties.getPom().setThisTrainBom(null);
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
thenThrownBy(() -> parser.versionsFromBom(this.springCloudReleaseProject))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("Pom is not present");
}
@Test
public void should_populate_sc_release_version() {
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
String scReleaseVersion = parser.versionsFromBom(this.springCloudReleaseProject)
.versionForProject("spring-cloud-release");
then(scReleaseVersion).isNotBlank();
}
@Test
public void should_populate_boot_version() {
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
String bootVersion = parser.versionsFromBom(this.springCloudReleaseProject)
.versionForProject("spring-boot");
then(bootVersion).isNotBlank();
}
@Test
public void should_throw_exception_when_cloud_pom_is_missing() {
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
thenThrownBy(() -> parser.versionsFromBom(new File(".")))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("Pom is not present");
}
@Test
public void should_throw_exception_when_null_is_passed_to_cloud() {
this.properties.getPom().setPomWithBootStarterParent(null);
this.properties.getPom().setThisTrainBom(null);
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
thenThrownBy(() -> parser.versionsFromBom(this.springCloudReleaseProject))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("Pom is not present");
}
@Test
public void should_throw_exception_when_cloud_version_is_missing_in_pom() {
this.properties.getPom().setPomWithBootStarterParent("pom.xml");
this.properties.getPom().setThisTrainBom("pom.xml");
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
thenThrownBy(() -> parser.versionsFromBom(this.springCloudReleaseProject))
.isInstanceOf(IllegalStateException.class).hasMessageContaining(
"The pom doesn't have a [spring-cloud-dependencies-parent] artifact id");
}
@Test
public void should_populate_cloud_version() {
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
VersionsFromBom cloudVersionsFromBom = parser
.versionsFromBom(this.springCloudReleaseProject);
thenAllCloudVersionsSet(cloudVersionsFromBom);
}
private void thenAllCloudVersionsSet(VersionsFromBom cloudVersionsFromBom) {
Arrays.asList("spring-cloud-bus", "spring-cloud-contract",
"spring-cloud-cloudfoundry", "spring-cloud-commons",
"spring-cloud-config", "spring-cloud-netflix", "spring-cloud-security",
"spring-cloud-consul", "spring-cloud-sleuth", "spring-cloud-stream",
"spring-cloud-task", "spring-cloud-vault", "spring-cloud-zookeeper")
.forEach(s -> then(cloudVersionsFromBom.versionForProject(s))
.isNotBlank());
}
@Test
public void should_populate_boot_and_cloud_version() {
BomParser parser = MavenBomParserAccessor.bomParser(this.properties,
new SpringCloudMavenBomParser());
VersionsFromBom cloudVersionsFromBom = parser
.versionsFromBom(this.springCloudReleaseProject);
then(cloudVersionsFromBom.versionForProject("spring-boot")).isNotBlank();
then(cloudVersionsFromBom.versionForProject("spring-cloud-build")).isNotBlank();
thenAllCloudVersionsSet(cloudVersionsFromBom);
}
}

View File

@@ -14,30 +14,27 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.internal.buildsystem; package releaser.cloud.buildsystem;
import java.io.File;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.assertj.core.api.BDDAssertions; import org.assertj.core.api.BDDAssertions;
import org.junit.Test; import org.junit.Test;
import org.mockito.BDDMockito; import releaser.cloud.SpringCloudReleaserProperties;
import releaser.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.ReleaserProperties; import releaser.internal.buildsystem.MavenBomParserAccessor;
import org.springframework.cloud.release.internal.git.ProjectGitHandler; import releaser.internal.buildsystem.ProjectPomUpdater;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
/** /**
* @author Marcin Grzejszczak * @author Marcin Grzejszczak
*/ */
public class ProjectPomUpdaterTests { public class SpringCloudProjectPomUpdaterTests {
@Test @Test
public void should_convert_fixed_versions_to_updated_fixed_versions() { public void should_convert_fixed_versions_to_updated_fixed_versions() {
ReleaserProperties properties = new ReleaserProperties(); ReleaserProperties properties = SpringCloudReleaserProperties.get();
properties.getFixedVersions().put("spring-cloud-task", "2.0.0.RELEASE"); properties.getFixedVersions().put("spring-cloud-task", "2.0.0.RELEASE");
properties.getFixedVersions().put("spring-cloud-openfeign", properties.getFixedVersions().put("spring-cloud-openfeign",
"2.0.1.BUILD-SNAPSHOT"); "2.0.1.BUILD-SNAPSHOT");
@@ -67,8 +64,9 @@ public class ProjectPomUpdaterTests {
"Finchley.BUILD-SNAPSHOT"); "Finchley.BUILD-SNAPSHOT");
properties.getFixedVersions().put("spring-boot", "2.0.3.RELEASE"); properties.getFixedVersions().put("spring-boot", "2.0.3.RELEASE");
properties.getFixedVersions().put("spring-cloud-gateway", "2.0.1.BUILD-SNAPSHOT"); properties.getFixedVersions().put("spring-cloud-gateway", "2.0.1.BUILD-SNAPSHOT");
ProjectPomUpdater updater = new ProjectPomUpdater(properties, Collections ProjectPomUpdater updater = new ProjectPomUpdater(properties,
.singletonList(MavenBomParserAccessor.cloudMavenBomParser(properties))); Collections.singletonList(MavenBomParserAccessor.bomParser(properties,
new SpringCloudMavenBomParser())));
Map<String, String> fixedVersions = updater.fixedVersions().stream() Map<String, String> fixedVersions = updater.fixedVersions().stream()
.collect(Collectors.toMap(projectVersion -> projectVersion.projectName, .collect(Collectors.toMap(projectVersion -> projectVersion.projectName,
@@ -84,17 +82,4 @@ public class ProjectPomUpdaterTests {
.containsEntry("spring-cloud", "Finchley.BUILD-SNAPSHOT"); .containsEntry("spring-cloud", "Finchley.BUILD-SNAPSHOT");
} }
@Test
public void should_skip_any_steps_if_there_is_no_pom_xml() {
ReleaserProperties properties = new ReleaserProperties();
ProjectGitHandler handler = BDDMockito.mock(ProjectGitHandler.class);
ProjectPomUpdater updater = new ProjectPomUpdater(properties, Collections
.singletonList(MavenBomParserAccessor.cloudMavenBomParser(properties)));
updater.updateProjectFromReleaseTrain(new File("target"), new Projects(),
new ProjectVersion("foo", "1.0.0.RELEASE"), false);
BDDMockito.then(handler).shouldHaveZeroInteractions();
}
} }

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.docs; package releaser.cloud.docs;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -31,16 +31,16 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.mockito.BDDMockito; import org.mockito.BDDMockito;
import releaser.cloud.SpringCloudReleaserProperties;
import releaser.cloud.github.SpringCloudGithubIssuesAccessor;
import releaser.internal.ReleaserProperties;
import releaser.internal.docs.DocumentationUpdater;
import releaser.internal.git.ProjectGitHandler;
import releaser.internal.github.ProjectGitHubHandler;
import releaser.internal.project.ProjectVersion;
import releaser.internal.project.Projects;
import releaser.internal.template.TemplateGenerator;
import org.springframework.cloud.release.cloud.github.SpringCloudGithubIssuesAccessor;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.buildsystem.TestUtils;
import org.springframework.cloud.release.internal.docs.DocumentationUpdater;
import org.springframework.cloud.release.internal.git.ProjectGitHandler;
import org.springframework.cloud.release.internal.github.ProjectGitHubHandler;
import org.springframework.cloud.release.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.Projects;
import org.springframework.cloud.release.internal.template.TemplateGenerator;
import org.springframework.util.FileSystemUtils; import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.BDDAssertions.then; import static org.assertj.core.api.BDDAssertions.then;
@@ -63,7 +63,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
File clonedDocProject; File clonedDocProject;
ReleaserProperties properties = new ReleaserProperties(); ReleaserProperties properties = SpringCloudReleaserProperties.get();
@Before @Before
public void setup() throws IOException, URISyntaxException { public void setup() throws IOException, URISyntaxException {
@@ -85,7 +85,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
public void should_not_update_current_version_in_the_docs_if_current_release_is_not_ga_or_sr() { public void should_not_update_current_version_in_the_docs_if_current_release_is_not_ga_or_sr() {
ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-release", ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-release",
"Angel.M7"); "Angel.M7");
ReleaserProperties properties = new ReleaserProperties(); ReleaserProperties properties = SpringCloudReleaserProperties.get();
File updatedDocs = projectDocumentationUpdater(properties) File updatedDocs = projectDocumentationUpdater(properties)
.updateDocsRepo(projects(), releaseTrainVersion, "vAngel.M7"); .updateDocsRepo(projects(), releaseTrainVersion, "vAngel.M7");
@@ -118,16 +118,16 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
file("/projects/spring-cloud-static/").toURI().toString()); file("/projects/spring-cloud-static/").toURI().toString());
File updatedDocs = new SpringCloudCustomProjectDocumentationUpdater( File updatedDocs = new SpringCloudCustomProjectDocumentationUpdater(
new ProjectGitHandler(properties), properties).updateDocsRepo( new ProjectGitHandler(properties), properties)
this.clonedDocProject, releaseTrainVersion, projects(), .updateDocsRepoForReleaseTrain(this.clonedDocProject,
"vFinchley.SR33"); releaseTrainVersion, projects(), "vFinchley.SR33");
BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath()) BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath())
.doesNotExist(); .doesNotExist();
Path current = new File(updatedDocs, "current/").toPath(); Path current = new File(updatedDocs, "current/").toPath();
BDDAssertions.then(current).isSymbolicLink(); BDDAssertions.then(current).isSymbolicLink();
BDDAssertions.then(Files.readSymbolicLink(current).toString()) BDDAssertions.then(Files.readSymbolicLink(current).toString())
.endsWith("Finchley.SR33"); .isEqualTo("Finchley.SR33");
releaseTrainVersion = new ProjectVersion("spring-cloud-release", "Angel.SR33"); releaseTrainVersion = new ProjectVersion("spring-cloud-release", "Angel.SR33");
properties = new ReleaserProperties(); properties = new ReleaserProperties();
@@ -135,16 +135,16 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
file("/projects/spring-cloud-static/").toURI().toString()); file("/projects/spring-cloud-static/").toURI().toString());
updatedDocs = new SpringCloudCustomProjectDocumentationUpdater( updatedDocs = new SpringCloudCustomProjectDocumentationUpdater(
new ProjectGitHandler(properties), properties).updateDocsRepo( new ProjectGitHandler(properties), properties)
this.clonedDocProject, releaseTrainVersion, projects(), .updateDocsRepoForReleaseTrain(this.clonedDocProject,
"vAngel.SR33"); releaseTrainVersion, projects(), "vAngel.SR33");
BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath()) BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath())
.doesNotExist(); .doesNotExist();
current = new File(updatedDocs, "current/").toPath(); current = new File(updatedDocs, "current/").toPath();
BDDAssertions.then(current).isSymbolicLink(); BDDAssertions.then(current).isSymbolicLink();
BDDAssertions.then(Files.readSymbolicLink(current).toString()) BDDAssertions.then(Files.readSymbolicLink(current).toString())
.doesNotEndWith("Angel.SR33"); .isNotEqualTo("Angel.SR33");
} }
@Test @Test
@@ -156,8 +156,8 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
ProjectGitHandler handler = BDDMockito.spy(new ProjectGitHandler(properties)); ProjectGitHandler handler = BDDMockito.spy(new ProjectGitHandler(properties));
new SpringCloudCustomProjectDocumentationUpdater(handler, properties) new SpringCloudCustomProjectDocumentationUpdater(handler, properties)
.updateDocsRepo(this.clonedDocProject, releaseTrainVersion, projects(), .updateDocsRepoForReleaseTrain(this.clonedDocProject, releaseTrainVersion,
"vDalston.SR3"); projects(), "vDalston.SR3");
BDDMockito.then(handler).should(BDDMockito.never()) BDDMockito.then(handler).should(BDDMockito.never())
.commit(BDDMockito.any(File.class), BDDMockito.anyString()); .commit(BDDMockito.any(File.class), BDDMockito.anyString());
@@ -172,16 +172,16 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString()); properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
File updatedDocs = new SpringCloudCustomProjectDocumentationUpdater( File updatedDocs = new SpringCloudCustomProjectDocumentationUpdater(
new ProjectGitHandler(properties), properties).updateDocsRepo( new ProjectGitHandler(properties), properties)
this.clonedDocProject, releaseTrainVersion, projects(), .updateDocsRepoForReleaseTrain(this.clonedDocProject,
"Angel.SR33"); releaseTrainVersion, projects(), "Angel.SR33");
BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath()) BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath())
.doesNotExist(); .doesNotExist();
Path current = new File(updatedDocs, "current/").toPath(); Path current = new File(updatedDocs, "current/").toPath();
BDDAssertions.then(current).isSymbolicLink(); BDDAssertions.then(current).isSymbolicLink();
BDDAssertions.then(Files.readSymbolicLink(current).toString()) BDDAssertions.then(Files.readSymbolicLink(current).toString())
.doesNotEndWith("Angel.SR33"); .isNotEqualTo("Angel.SR33");
} }
@Test @Test
@@ -201,7 +201,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
Path current = new File(updatedDocs, "current/").toPath(); Path current = new File(updatedDocs, "current/").toPath();
BDDAssertions.then(current).isSymbolicLink(); BDDAssertions.then(current).isSymbolicLink();
BDDAssertions.then(Files.readSymbolicLink(current).toString()) BDDAssertions.then(Files.readSymbolicLink(current).toString())
.endsWith("spring-cloud-static/Finchley.SR33"); .isEqualTo("Finchley.SR33");
} }
@Test @Test
@@ -213,16 +213,21 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
properties.getGit().setUpdateDocumentationRepo(true); properties.getGit().setUpdateDocumentationRepo(true);
properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString()); properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString());
File updatedDocs = projectDocumentationUpdater(properties).updateDocsRepo( DocumentationUpdater updater = projectDocumentationUpdater(properties);
new Projects(new ProjectVersion("spring-cloud-sleuth", "2.0.0.RELEASE")), ProjectVersion sleuthVersion = new ProjectVersion("spring-cloud-sleuth",
releaseTrainVersion, "vFinchley.SR33"); "2.0.0.RELEASE");
Projects bom = new Projects(sleuthVersion);
File updatedDocs = updater.updateDocsRepo(bom, releaseTrainVersion,
"vFinchley.SR33");
BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath()) BDDAssertions.then(new File(updatedDocs, "current/index.html").toPath())
.doesNotExist(); .doesNotExist();
Path current = new File(updatedDocs, "current/").toPath(); Path current = new File(updatedDocs, "current/").toPath();
BDDAssertions.then(current).isSymbolicLink(); BDDAssertions.then(current).isSymbolicLink();
BDDAssertions.then(Files.readSymbolicLink(current).toString()) BDDAssertions.then(Files.readSymbolicLink(current).toString())
.endsWith("spring-cloud-static/Finchley.SR33"); .isEqualTo("Finchley.SR33");
updatedDocs = updater.updateDocsRepoForSingleProject(bom, sleuthVersion);
BDDAssertions.then( BDDAssertions.then(
new File(updatedDocs, "spring-cloud-sleuth/current/index.html").toPath()) new File(updatedDocs, "spring-cloud-sleuth/current/index.html").toPath())
@@ -230,7 +235,7 @@ public class SpringCloudCustomProjectDocumentationUpdaterTests {
current = new File(updatedDocs, "spring-cloud-sleuth/current/").toPath(); current = new File(updatedDocs, "spring-cloud-sleuth/current/").toPath();
BDDAssertions.then(current).isSymbolicLink(); BDDAssertions.then(current).isSymbolicLink();
BDDAssertions.then(Files.readSymbolicLink(current).toString()) BDDAssertions.then(Files.readSymbolicLink(current).toString())
.endsWith("spring-cloud-static/spring-cloud-sleuth/2.0.0.RELEASE"); .isEqualTo("2.0.0.RELEASE");
} }
@Test @Test

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.internal.buildsystem; package releaser.cloud.docs;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2013-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,12 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.cloud.github; package releaser.cloud.github;
import com.jcabi.github.Github; import com.jcabi.github.Github;
import releaser.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.ReleaserProperties; import releaser.internal.github.CustomGithubIssues;
import org.springframework.cloud.release.internal.github.CustomGithubIssues;
public class SpringCloudGithubIssuesAccessor { public class SpringCloudGithubIssuesAccessor {

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.release.internal.github; package releaser.cloud.github;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
@@ -30,12 +30,11 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.mockito.BDDMockito; import org.mockito.BDDMockito;
import releaser.cloud.SpringCloudReleaserProperties;
import org.springframework.boot.test.rule.OutputCapture; import releaser.internal.ReleaserProperties;
import org.springframework.cloud.release.cloud.github.SpringCloudGithubIssuesAccessor; import releaser.internal.github.CustomGithubIssues;
import org.springframework.cloud.release.internal.ReleaserProperties; import releaser.internal.project.ProjectVersion;
import org.springframework.cloud.release.internal.project.ProjectVersion; import releaser.internal.project.Projects;
import org.springframework.cloud.release.internal.project.Projects;
import static org.assertj.core.api.BDDAssertions.then; import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.api.BDDAssertions.thenThrownBy; import static org.assertj.core.api.BDDAssertions.thenThrownBy;
@@ -43,13 +42,12 @@ import static org.assertj.core.api.BDDAssertions.thenThrownBy;
/** /**
* @author Marcin Grzejszczak * @author Marcin Grzejszczak
*/ */
public class GithubIssuesTests { public class SpringCloudGithubIssuesTests {
@Rule @Rule
public TemporaryFolder folder = new TemporaryFolder(); public TemporaryFolder folder = new TemporaryFolder();
@Rule ReleaserProperties properties = SpringCloudReleaserProperties.get();
public OutputCapture capture = new OutputCapture();
MkGithub github; MkGithub github;
@@ -58,6 +56,7 @@ public class GithubIssuesTests {
@Before @Before
public void setup() throws IOException { public void setup() throws IOException {
this.github = github("spring-guides"); this.github = github("spring-guides");
this.properties.getGit().setOauthToken("a");
this.repo = createGettingStartedGuides(this.github); this.repo = createGettingStartedGuides(this.github);
} }
@@ -73,38 +72,22 @@ public class GithubIssuesTests {
@Test @Test
public void should_not_do_anything_for_non_release_train_version() { public void should_not_do_anything_for_non_release_train_version() {
Github github = BDDMockito.mock(Github.class); Github github = BDDMockito.mock(Github.class);
GithubIssues issues = new GithubIssues(withToken(), Collections.singletonList( CustomGithubIssues githubIssues = new SpringCloudGithubIssues(github, properties);
SpringCloudGithubIssuesAccessor.springCloud(github, withToken())));
issues.fileIssueInSpringGuides( githubIssues
new Projects(new ProjectVersion("foo", "1.0.0.BUILD-SNAPSHOT"), .fileIssueInSpringGuides(
new ProjectVersion("spring-cloud-build", "2.0.0.BUILD-SNAPSHOT")), new Projects(new ProjectVersion("foo", "1.0.0.BUILD-SNAPSHOT"),
new ProjectVersion("sc-release", "Edgware.BUILD-SNAPSHOT")); new ProjectVersion("spring-cloud-build",
"2.0.0.BUILD-SNAPSHOT")),
BDDMockito.then(github).shouldHaveZeroInteractions(); new ProjectVersion("sc-release", "Edgware.BUILD-SNAPSHOT"));
}
@Test
public void should_not_do_anything_if_not_applicable() {
Github github = BDDMockito.mock(Github.class);
ReleaserProperties properties = withToken();
properties.getGit().setUpdateSpringGuides(false);
GithubIssues issues = new GithubIssues(properties, Collections.singletonList(
SpringCloudGithubIssuesAccessor.springCloud(github, properties)));
issues.fileIssueInSpringGuides(
new Projects(new ProjectVersion("foo", "1.0.0.RELEASE"),
new ProjectVersion("bar", "2.0.0.RELEASE"),
new ProjectVersion("baz", "3.0.0.RELEASE")),
new ProjectVersion("sc-release", "Edgware.RELEASE"));
BDDMockito.then(github).shouldHaveZeroInteractions(); BDDMockito.then(github).shouldHaveZeroInteractions();
} }
@Test @Test
public void should_file_an_issue_for_release_version() throws IOException { public void should_file_an_issue_for_release_version() throws IOException {
GithubIssues issues = new GithubIssues(withToken(), Collections.singletonList( CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties);
SpringCloudGithubIssuesAccessor.springCloud(github, withToken()))); properties.getPom().setBranch("vEdgware.RELEASE");
issues.fileIssueInSpringGuides( issues.fileIssueInSpringGuides(
new Projects(new ProjectVersion("spring-cloud-foo", "1.0.0.RELEASE"), new Projects(new ProjectVersion("spring-cloud-foo", "1.0.0.RELEASE"),
@@ -113,8 +96,6 @@ public class GithubIssuesTests {
new ProjectVersion("baz", "3.0.0.RELEASE")), new ProjectVersion("baz", "3.0.0.RELEASE")),
new ProjectVersion("sc-release", "Edgware.RELEASE")); new ProjectVersion("sc-release", "Edgware.RELEASE"));
then(this.capture.toString())
.doesNotContain("Guide issue creation will occur only");
Issue issue = this.github.repos() Issue issue = this.github.repos()
.get(new Coordinates.Simple("spring-guides", "getting-started-guides")) .get(new Coordinates.Simple("spring-guides", "getting-started-guides"))
.issues().get(1); .issues().get(1);
@@ -129,9 +110,8 @@ public class GithubIssuesTests {
@Test @Test
public void should_throw_exception_when_no_token_was_passed() { public void should_throw_exception_when_no_token_was_passed() {
GithubIssues issues = new GithubIssues(new ReleaserProperties(), properties.getGit().setOauthToken("");
Collections.singletonList(SpringCloudGithubIssuesAccessor CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties);
.springCloud(new ReleaserProperties())));
thenThrownBy(() -> issues.fileIssueInSpringGuides( thenThrownBy(() -> issues.fileIssueInSpringGuides(
new Projects(Collections.singletonList( new Projects(Collections.singletonList(
@@ -146,8 +126,7 @@ public class GithubIssuesTests {
throws IOException { throws IOException {
setupStartSpringIo(); setupStartSpringIo();
Github github = BDDMockito.mock(Github.class); Github github = BDDMockito.mock(Github.class);
GithubIssues issues = new GithubIssues(withToken(), Collections.singletonList( CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties);
SpringCloudGithubIssuesAccessor.springCloud(github, withToken())));
issues.fileIssueInStartSpringIo( issues.fileIssueInStartSpringIo(
new Projects(new ProjectVersion("foo", "1.0.0.BUILD-SNAPSHOT"), new Projects(new ProjectVersion("foo", "1.0.0.BUILD-SNAPSHOT"),
@@ -157,31 +136,12 @@ public class GithubIssuesTests {
BDDMockito.then(github).shouldHaveZeroInteractions(); BDDMockito.then(github).shouldHaveZeroInteractions();
} }
@Test
public void should_not_do_anything_if_not_applicable_when_updating_startspringio()
throws IOException {
setupStartSpringIo();
Github github = BDDMockito.mock(Github.class);
ReleaserProperties properties = withToken();
properties.getGit().setUpdateStartSpringIo(false);
GithubIssues issues = new GithubIssues(properties, Collections.singletonList(
SpringCloudGithubIssuesAccessor.springCloud(github, properties)));
issues.fileIssueInStartSpringIo(
new Projects(new ProjectVersion("foo", "1.0.0.RELEASE"),
new ProjectVersion("bar", "2.0.0.RELEASE"),
new ProjectVersion("baz", "3.0.0.RELEASE")),
new ProjectVersion("sc-release", "Edgware.RELEASE"));
BDDMockito.then(github).shouldHaveZeroInteractions();
}
@Test @Test
public void should_file_an_issue_for_release_version_when_updating_startspringio() public void should_file_an_issue_for_release_version_when_updating_startspringio()
throws IOException { throws IOException {
setupStartSpringIo(); setupStartSpringIo();
GithubIssues issues = new GithubIssues(withToken(), Collections.singletonList( CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties);
SpringCloudGithubIssuesAccessor.springCloud(github, withToken()))); properties.getPom().setBranch("vEdgware.RELEASE");
issues.fileIssueInStartSpringIo( issues.fileIssueInStartSpringIo(
new Projects(new ProjectVersion("spring-cloud-foo", "1.0.0.RELEASE"), new Projects(new ProjectVersion("spring-cloud-foo", "1.0.0.RELEASE"),
@@ -191,7 +151,6 @@ public class GithubIssuesTests {
new ProjectVersion("spring-boot", "1.2.3.RELEASE")), new ProjectVersion("spring-boot", "1.2.3.RELEASE")),
new ProjectVersion("sc-release", "Edgware.RELEASE")); new ProjectVersion("sc-release", "Edgware.RELEASE"));
then(this.capture.toString()).doesNotContain("will occur only");
Issue issue = this.github.repos() Issue issue = this.github.repos()
.get(new Coordinates.Simple("spring-io", "start.spring.io")).issues() .get(new Coordinates.Simple("spring-io", "start.spring.io")).issues()
.get(1); .get(1);
@@ -206,9 +165,8 @@ public class GithubIssuesTests {
public void should_throw_exception_when_no_token_was_passed_when_updating_startspringio() public void should_throw_exception_when_no_token_was_passed_when_updating_startspringio()
throws IOException { throws IOException {
setupStartSpringIo(); setupStartSpringIo();
GithubIssues issues = new GithubIssues(new ReleaserProperties(), properties.getGit().setOauthToken("");
Collections.singletonList(SpringCloudGithubIssuesAccessor CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties);
.springCloud(new ReleaserProperties())));
thenThrownBy(() -> issues.fileIssueInStartSpringIo( thenThrownBy(() -> issues.fileIssueInStartSpringIo(
new Projects(Collections.singletonList( new Projects(Collections.singletonList(
@@ -232,7 +190,7 @@ public class GithubIssuesTests {
} }
ReleaserProperties withToken() { ReleaserProperties withToken() {
ReleaserProperties properties = new ReleaserProperties(); ReleaserProperties properties = SpringCloudReleaserProperties.get();
properties.getGit().setOauthToken("foo"); properties.getGit().setOauthToken("foo");
properties.getPom().setBranch("vEdgware.RELEASE"); properties.getPom().setBranch("vEdgware.RELEASE");
properties.getGit().setUpdateSpringGuides(true); properties.getGit().setUpdateSpringGuides(true);

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser.cloud.spring;
import java.io.File;
import java.util.Arrays;
import org.junit.Before;
import releaser.internal.buildsystem.TestUtils;
import releaser.internal.spring.AbstractSpringAcceptanceTests;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.BDDAssertions.then;
public class AbstractSpringCloudAcceptanceTests extends AbstractSpringAcceptanceTests {
public File springCloudConsulProject;
public File springCloudBuildProject;
@Before
public void setupCloud() throws Exception {
this.temporaryFolder = this.tmp.newFolder();
this.springCloudConsulProject = new File(AbstractSpringAcceptanceTests.class
.getResource("/projects/spring-cloud-consul").toURI());
this.springCloudBuildProject = new File(AbstractSpringAcceptanceTests.class
.getResource("/projects/spring-cloud-build").toURI());
TestUtils.prepareLocalRepo();
FileSystemUtils.copyRecursively(file("/projects/"), this.temporaryFolder);
}
public void consulPomParentVersionIsEqualTo(File project, String expected) {
pomParentVersionIsEqualTo(project, "spring-cloud-starter-consul", expected);
}
public void thenAllDryRunStepsWereExecutedForEachProject(
NonAssertingTestProjectGitHandler nonAssertingTestProjectGitHandler) {
nonAssertingTestProjectGitHandler.clonedProjects.stream()
.filter(f -> !f.getName().contains("angel")
&& !f.getName().equals("spring-cloud"))
.forEach(project -> {
then(Arrays.asList("spring-cloud-starter-build",
"spring-cloud-consul"))
.contains(pom(project).getArtifactId());
then(new File("/tmp/executed_build")).exists();
then(new File("/tmp/executed_deploy")).doesNotExist();
then(new File("/tmp/executed_docs")).doesNotExist();
});
}
public void assertThatClonedConsulProjectIsInSnapshots(File origin) {
pomVersionIsEqualTo(origin, "1.2.0.BUILD-SNAPSHOT");
consulPomParentVersionIsEqualTo(origin, "1.2.0.BUILD-SNAPSHOT");
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser.cloud.spring.meta;
import java.io.File;
import java.util.Arrays;
import org.junit.Before;
import releaser.internal.spring.meta.AbstractSpringMetaReleaseAcceptanceTests;
import static org.assertj.core.api.BDDAssertions.then;
public class AbstractSpringCloudMetaAcceptanceTests
extends AbstractSpringMetaReleaseAcceptanceTests {
public File springCloudConsulProject;
public File springCloudBuildProject;
@Before
public void setupCloud() throws Exception {
this.springCloudConsulProject = new File(
AbstractSpringCloudMetaAcceptanceTests.class
.getResource("/projects/spring-cloud-consul").toURI());
this.springCloudBuildProject = new File(
AbstractSpringCloudMetaAcceptanceTests.class
.getResource("/projects/spring-cloud-build").toURI());
}
public void consulPomParentVersionIsEqualTo(File project, String expected) {
pomParentVersionIsEqualTo(project, "spring-cloud-starter-consul", expected);
}
public void thenAllDryRunStepsWereExecutedForEachProject(
NonAssertingTestProjectGitHandler nonAssertingTestProjectGitHandler) {
nonAssertingTestProjectGitHandler.clonedProjects.stream()
.filter(f -> !f.getName().contains("angel")
&& !f.getName().equals("spring-cloud"))
.forEach(project -> {
then(Arrays.asList("spring-cloud-starter-build",
"spring-cloud-consul"))
.contains(pom(project).getArtifactId());
then(new File("/tmp/executed_build")).exists();
then(new File("/tmp/executed_deploy")).doesNotExist();
then(new File("/tmp/executed_docs")).doesNotExist();
});
}
public void assertThatClonedConsulProjectIsInSnapshots(File origin) {
pomVersionIsEqualTo(origin, "1.2.0.BUILD-SNAPSHOT");
consulPomParentVersionIsEqualTo(origin, "1.2.0.BUILD-SNAPSHOT");
}
}

View File

@@ -0,0 +1,447 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser.cloud.spring.meta;
import java.io.File;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.mockito.BDDMockito;
import releaser.internal.Releaser;
import releaser.internal.ReleaserProperties;
import releaser.internal.docs.CustomProjectDocumentationUpdater;
import releaser.internal.docs.DocumentationUpdater;
import releaser.internal.git.GitTestUtils;
import releaser.internal.git.ProjectGitHandler;
import releaser.internal.options.OptionsBuilder;
import releaser.internal.postrelease.PostReleaseActions;
import releaser.internal.project.Projects;
import releaser.internal.sagan.SaganClient;
import releaser.internal.sagan.SaganUpdater;
import releaser.internal.spring.ExecutionResult;
import releaser.internal.spring.SpringReleaser;
import releaser.internal.tasks.release.BuildProjectReleaseTask;
import releaser.internal.template.TemplateGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.BDDAssertions.then;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
/**
* @author Marcin Grzejszczak
*/
public class SpringMetaReleaseAcceptanceTests
extends AbstractSpringCloudMetaAcceptanceTests {
SpringApplicationBuilder runner = new SpringApplicationBuilder(
SpringMetaReleaseAcceptanceTests.MetaReleaseConfig.class,
SpringMetaReleaseAcceptanceTests.MetaReleaseScanningConfiguration.class)
.web(WebApplicationType.NONE).properties("spring.jmx.enabled=false");
@Test
public void should_perform_a_meta_release_of_sc_release_and_consul()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "Greenwich");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
run(this.runner,
properties("debug=true").properties("test.metarelease=true")
.properties(metaReleaseArgs(project).bomBranch("vGreenwich.SR2")
.addFixedVersions(edgwareSr10()).build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
NonAssertingTestProjectGitHandler nonAssertingTestProjectGitHandler = context
.getBean(NonAssertingTestProjectGitHandler.class);
SaganUpdater saganUpdater = context.getBean(SaganUpdater.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
PostReleaseActions postReleaseActions = context
.getBean(PostReleaseActions.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser
.release(new OptionsBuilder().metaRelease(true).options());
then(result.isFailureOrUnstable()).isFalse();
// consul, release, documentation
then(nonAssertingTestProjectGitHandler.clonedProjects).hasSize(3);
// don't want to verify the docs
thenAllStepsWereExecutedForEachProject(
nonAssertingTestProjectGitHandler);
thenSaganWasCalled(saganUpdater);
thenDocumentationWasUpdated(testDocumentationUpdater);
then(clonedProject(nonAssertingTestProjectGitHandler,
"spring-cloud-consul").tagList().call()).extracting("name")
.contains("refs/tags/v5.3.5.RELEASE");
thenRunUpdatedTestsWereCalled(postReleaseActions);
thenUpdateReleaseTrainDocsWasCalled(postReleaseActions);
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
@Test
public void should_perform_a_meta_release_of_sc_release_and_consul_in_parallel()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "Greenwich");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
run(this.runner, properties("debug=true").properties("test.metarelease=true")
.properties(metaReleaseArgsForParallel(project)
.bomBranch("vGreenwich.SR2").addFixedVersions(edgwareSr10())
.metaReleaseGroups("example1,example2",
"spring-cloud-build,spring-cloud-consul,spring-cloud-release")
.build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
NonAssertingTestProjectGitHandler nonAssertingTestProjectGitHandler = context
.getBean(NonAssertingTestProjectGitHandler.class);
SaganUpdater saganUpdater = context.getBean(SaganUpdater.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
PostReleaseActions postReleaseActions = context
.getBean(PostReleaseActions.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser
.release(new OptionsBuilder().metaRelease(true).options());
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
then(result.isFailureOrUnstable()).isFalse();
// TODO: Assert the steps
// build, consul, release, documentation
// then(nonAssertingTestProjectGitHandler.clonedProjects).hasSize(4);
// don't want to verify the docs
// thenAllStepsWereExecutedForEachProject(
// nonAssertingTestProjectGitHandler);
thenSaganWasCalled(saganUpdater);
thenDocumentationWasUpdated(testDocumentationUpdater);
then(clonedProject(nonAssertingTestProjectGitHandler,
"spring-cloud-consul").tagList().call()).extracting("name")
.contains("refs/tags/v5.3.5.RELEASE");
thenRunUpdatedTestsWereCalled(postReleaseActions);
thenUpdateReleaseTrainDocsWasCalled(postReleaseActions);
});
}
@Test
public void should_perform_a_meta_release_dry_run_of_sc_release_and_consul()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "Greenwich");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
run(this.runner,
properties("debug=true").properties("test.metarelease=true")
.properties(metaReleaseArgs(project).bomBranch("vGreenwich.SR2")
.addFixedVersions(edgwareSr10()).build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
NonAssertingTestProjectGitHandler nonAssertingTestProjectGitHandler = context
.getBean(NonAssertingTestProjectGitHandler.class);
SaganUpdater saganUpdater = context.getBean(SaganUpdater.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
PostReleaseActions postReleaseActions = context
.getBean(PostReleaseActions.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser.release(new OptionsBuilder()
.metaRelease(true).dryRun(true).options());
then(result.isFailureOrUnstable()).isFalse();
// consul, release
then(nonAssertingTestProjectGitHandler.clonedProjects).hasSize(2);
// only dry run tasks were called
thenAllDryRunStepsWereExecutedForEachProject(
nonAssertingTestProjectGitHandler);
thenSaganWasNotCalled(saganUpdater);
thenDocumentationWasNotUpdated(testDocumentationUpdater);
then(clonedProject(nonAssertingTestProjectGitHandler,
"spring-cloud-consul").tagList().call()).extracting("name")
.doesNotContain("refs/tags/v5.3.5.RELEASE");
thenRunUpdatedTestsWereNotCalled(postReleaseActions);
thenUpdateReleaseTrainDocsWasNotCalled(postReleaseActions);
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
@Test
public void should_not_release_any_projects_when_they_are_on_list_of_projects_to_skip()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "Greenwich");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
File temporaryDestination = this.tmp.newFolder();
run(this.runner,
properties("debug=true")
.properties("test.metarelease=true", "test.mockBuild=true")
.properties(metaReleaseArgs(project).bomBranch("Greenwich")
.addFixedVersions(consulAndReleaseSnapshots())
.updateReleaseTrainWiki(false)
.cloneDestinationDirectory(temporaryDestination)
.projectsToSkip("spring-cloud-consul").build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
BuildProjectReleaseTask build = context
.getBean(BuildProjectReleaseTask.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser
.release(new OptionsBuilder().metaRelease(true).options());
then(result.isFailureOrUnstable()).isFalse();
thenBuildWasNeverCalledFor(build, "spring-cloud-consul");
thenBuildWasCalledFor(build, "spring-cloud-release");
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
@Test
public void should_perform_a_meta_release_of_consul_only_when_run_from_got_passed()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "Greenwich");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
File temporaryDestination = this.tmp.newFolder();
run(this.runner,
properties("debug=true")
.properties("test.metarelease=true", "test.mockBuild=true")
.properties(metaReleaseArgs(project).bomBranch("Greenwich")
.addFixedVersions(releaseConsulBuildSnapshots())
.cloneDestinationDirectory(temporaryDestination).build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
BuildProjectReleaseTask build = context
.getBean(BuildProjectReleaseTask.class);
SaganUpdater saganUpdater = context.getBean(SaganUpdater.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser
.release(new OptionsBuilder().startFrom("spring-cloud-consul")
.metaRelease(true).options());
// release
then(result.isFailureOrUnstable()).isFalse();
thenBuildWasNeverCalledFor(build, "spring-cloud-build");
thenBuildWasCalledFor(build, "spring-cloud-consul");
thenBuildWasCalledFor(build, "spring-cloud-release");
// post release
thenSaganWasCalled(saganUpdater);
thenDocumentationWasUpdated(testDocumentationUpdater);
thenWikiPageWasUpdated(testDocumentationUpdater);
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
@Test
public void should_perform_a_meta_release_of_consul_only_when_task_names_got_passed()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "Greenwich");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
File temporaryDestination = this.tmp.newFolder();
run(this.runner,
properties("debug=true")
.properties("test.metarelease=true", "test.mockBuild=true")
.properties(metaReleaseArgs(project).bomBranch("Greenwich")
.addFixedVersions(releaseConsulBuildSnapshots())
.cloneDestinationDirectory(temporaryDestination).build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
BuildProjectReleaseTask build = context
.getBean(BuildProjectReleaseTask.class);
SaganUpdater saganUpdater = context.getBean(SaganUpdater.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser.release(new OptionsBuilder()
.taskNames(Collections.singletonList("spring-cloud-consul"))
.metaRelease(true).options());
// release
then(result.isFailureOrUnstable()).isFalse();
thenBuildWasNeverCalledFor(build, "spring-cloud-release");
thenBuildWasNeverCalledFor(build, "spring-cloud-build");
thenBuildWasCalledFor(build, "spring-cloud-consul");
// post release
thenSaganWasCalled(saganUpdater);
thenDocumentationWasUpdated(testDocumentationUpdater);
thenWikiPageWasUpdated(testDocumentationUpdater);
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
private void thenWikiPageWasUpdated(DocumentationUpdater documentationUpdater) {
BDDMockito.then(documentationUpdater).should()
.updateReleaseTrainWiki(BDDMockito.any(Projects.class));
}
private void thenBuildWasCalledFor(BuildProjectReleaseTask build,
String projectName) {
BDDMockito.then(build).should().apply(argThat(
argument -> argument.originalVersion.projectName.equals(projectName)
|| argument.project.getAbsolutePath().endsWith(projectName)));
}
private void thenBuildWasNeverCalledFor(BuildProjectReleaseTask build,
String projectName) {
BDDMockito.then(build).should(BDDMockito.never()).apply(argThat(
argument -> argument.originalVersion.projectName.equals(projectName)
|| argument.project.getAbsolutePath().endsWith(projectName)));
}
private Map<String, String> consulAndReleaseSnapshots() {
Map<String, String> versions = new LinkedHashMap<>();
versions.put("spring-cloud-consul", "1.1.2.BUILD-SNAPSHOT");
versions.put("spring-cloud-release", "Camden.BUILD-SNAPSHOT");
return versions;
}
private Map<String, String> releaseConsulBuildSnapshots() {
Map<String, String> versions = new LinkedHashMap<>();
versions.put("spring-cloud-release", "Camden.BUILD-SNAPSHOT");
versions.put("spring-cloud-build", "1.1.2.BUILD-SNAPSHOT");
versions.put("spring-cloud-consul", "1.1.2.BUILD-SNAPSHOT");
return versions;
}
@Configuration
@ConditionalOnProperty(value = "test.metarelease", havingValue = "true")
@EnableAutoConfiguration
static class MetaReleaseConfig extends DefaultTestConfiguration {
@Bean
SaganClient testSaganClient() {
SaganClient saganClient = BDDMockito.mock(SaganClient.class);
BDDMockito.given(saganClient.getProject(anyString()))
.willReturn(newProject());
return saganClient;
}
@Bean
@ConditionalOnProperty(value = "test.mockBuild", havingValue = "true")
BuildProjectReleaseTask mockedBuildProjectReleaseTask(Releaser releaser) {
return BDDMockito.spy(new BuildProjectReleaseTask(releaser));
}
@Bean
SaganUpdater testSaganUpdater(SaganClient saganClient,
ReleaserProperties properties) {
return BDDMockito.spy(new SaganUpdater(saganClient, properties));
}
@Bean
PostReleaseActions myPostReleaseActions() {
return BDDMockito.mock(PostReleaseActions.class);
}
@Bean
NonAssertingTestProjectGitHubHandler testProjectGitHubHandler(
ReleaserProperties releaserProperties) {
return new NonAssertingTestProjectGitHubHandler(releaserProperties);
}
@Bean
NonAssertingTestProjectGitHandler nonAssertingTestProjectGitHandler(
ReleaserProperties releaserProperties,
@Value("${test.projectName}") String projectName) {
return new NonAssertingTestProjectGitHandler(releaserProperties,
file -> FileSystemUtils
.deleteRecursively(new File(file, projectName)));
}
@Bean
TestDocumentationUpdater testDocumentationUpdater(
ProjectGitHandler projectGitHandler,
ReleaserProperties releaserProperties,
TemplateGenerator templateGenerator, @Autowired(
required = false) List<CustomProjectDocumentationUpdater> updaters) {
return BDDMockito.spy(new TestDocumentationUpdater(projectGitHandler,
releaserProperties, templateGenerator, updaters));
}
}
@Configuration
@ConditionalOnProperty(value = "test.metarelease", havingValue = "true",
matchIfMissing = true)
@ComponentScan({ "releaser.internal", "releaser.cloud" })
static class MetaReleaseScanningConfiguration {
}
}

View File

@@ -0,0 +1,419 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package releaser.cloud.spring.single;
import java.io.File;
import java.nio.file.Files;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.assertj.core.api.BDDAssertions;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
import org.mockito.BDDMockito;
import releaser.cloud.spring.AbstractSpringCloudAcceptanceTests;
import releaser.internal.ReleaserProperties;
import releaser.internal.docs.CustomProjectDocumentationUpdater;
import releaser.internal.git.GitTestUtils;
import releaser.internal.git.ProjectGitHandler;
import releaser.internal.github.ProjectGitHubHandler;
import releaser.internal.options.OptionsBuilder;
import releaser.internal.postrelease.PostReleaseActions;
import releaser.internal.project.ProjectVersion;
import releaser.internal.project.Projects;
import releaser.internal.sagan.SaganClient;
import releaser.internal.spring.ArgsBuilder;
import releaser.internal.spring.ExecutionResult;
import releaser.internal.spring.SpringReleaser;
import releaser.internal.template.TemplateGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.BDDAssertions.then;
import static org.mockito.ArgumentMatchers.anyString;
/**
* @author Marcin Grzejszczak
*/
public class SpringSingleProjectAcceptanceTests
extends AbstractSpringCloudAcceptanceTests {
SpringApplicationBuilder runner = new SpringApplicationBuilder(
SpringSingleProjectAcceptanceTests.SingleProjectReleaseConfig.class,
SpringSingleProjectAcceptanceTests.SingleProjectScanningConfiguration.class)
.web(WebApplicationType.NONE).properties("spring.jmx.enabled=false");
@Test
public void should_fail_to_perform_a_release_of_consul_when_sc_release_contains_snapshots()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release-with-snapshot/",
"vCamden.SR5.BROKEN");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
run(this.runner,
properties("debug=true").properties(new ArgsBuilder(project, this.tmp)
.releaseTrainUrl("/projects/spring-cloud-release-with-snapshot/")
.bomBranch("vCamden.SR5.BROKEN").expectedVersion("1.1.2.RELEASE")
.build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
BDDAssertions.thenThrownBy(releaser::release).hasMessageContaining(
"there is at least one SNAPSHOT library version in the Spring Cloud Release project");
});
}
@Test
public void should_perform_a_release_of_consul() throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "Greenwich");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
run(this.runner,
properties("debug=true").properties(new ArgsBuilder(project, this.tmp)
.releaseTrainUrl("/projects/spring-cloud-release/")
.bomBranch("vGreenwich.SR2").expectedVersion("2.1.2.RELEASE")
.build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
TestProjectGitHubHandler gitHubHandler = context
.getBean(TestProjectGitHubHandler.class);
SaganClient saganClient = context.getBean(SaganClient.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
PostReleaseActions postReleaseActions = context
.getBean(PostReleaseActions.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser
.release(new OptionsBuilder().interactive(true).options());
Iterable<RevCommit> commits = listOfCommits(project);
Iterator<RevCommit> iterator = commits.iterator();
tagIsPresentInOrigin(origin, "v2.1.2.RELEASE");
commitIsPresent(iterator,
"Bumping versions to 2.1.3.BUILD-SNAPSHOT after release");
commitIsPresent(iterator, "Going back to snapshots");
commitIsPresent(iterator, "Update SNAPSHOT to 2.1.2.RELEASE");
pomVersionIsEqualTo(project, "2.1.3.BUILD-SNAPSHOT");
consulPomParentVersionIsEqualTo(project, "2.1.3.BUILD-SNAPSHOT");
then(gitHubHandler.closedMilestones).isTrue();
then(emailTemplate()).doesNotExist();
then(blogTemplate()).doesNotExist();
then(tweetTemplate()).doesNotExist();
then(releaseNotesTemplate()).doesNotExist();
// once for updating GA
// second time to update SNAPSHOT
BDDMockito.then(saganClient).should(BDDMockito.times(2))
.updateRelease(BDDMockito.eq("spring-cloud-consul"),
BDDMockito.anyList());
BDDMockito.then(saganClient).should()
.deleteRelease("spring-cloud-consul", "2.1.2.BUILD-SNAPSHOT");
then(gitHubHandler.issueCreatedInSpringGuides).isFalse();
then(gitHubHandler.issueCreatedInStartSpringIo).isFalse();
then(Files.readSymbolicLink(
new File(testDocumentationUpdater.getDocumentationRepo(),
"spring-cloud-consul/current").toPath())
.toString()).isEqualTo("2.1.2.RELEASE");
thenRunUpdatedTestsWereNotCalled(postReleaseActions);
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
// issue #74
@Test
public void should_perform_a_release_of_sc_build() throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "vGreenwich.SR2");
File origin = cloneToTemporaryDirectory(this.springCloudBuildProject);
assertThatClonedBuildProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-build"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
run(this.runner,
properties("debug=true").properties(new ArgsBuilder(project, this.tmp)
.releaseTrainUrl("/projects/spring-cloud-release/")
.bomBranch("vGreenwich.SR2").projectName("spring-cloud-build")
.expectedVersion("2.1.6.RELEASE").build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
TestProjectGitHubHandler gitHubHandler = context
.getBean(TestProjectGitHubHandler.class);
SaganClient saganClient = context.getBean(SaganClient.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
PostReleaseActions postReleaseActions = context
.getBean(PostReleaseActions.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser
.release(new OptionsBuilder().interactive(true).options());
Iterable<RevCommit> commits = listOfCommits(project);
Iterator<RevCommit> iterator = commits.iterator();
tagIsPresentInOrigin(origin, "v2.1.6.RELEASE");
// we're running against camden sc-release
commitIsPresent(iterator,
"Bumping versions to 2.1.7.BUILD-SNAPSHOT after release");
commitIsPresent(iterator, "Going back to snapshots");
commitIsPresent(iterator, "Update SNAPSHOT to 2.1.6.RELEASE");
pomVersionIsEqualTo(project, "2.1.7.BUILD-SNAPSHOT");
pomParentVersionIsEqualTo(project, "spring-cloud-build-dependencies",
"2.1.6.RELEASE");
then(gitHubHandler.closedMilestones).isTrue();
then(emailTemplate()).doesNotExist();
then(blogTemplate()).doesNotExist();
then(tweetTemplate()).doesNotExist();
then(releaseNotesTemplate()).doesNotExist();
// once for updating GA
// second time to update SNAPSHOT
BDDMockito.then(saganClient).should(BDDMockito.times(2))
.updateRelease(BDDMockito.eq("spring-cloud-build"),
BDDMockito.anyList());
BDDMockito.then(saganClient).should()
.deleteRelease("spring-cloud-build", "2.1.6.BUILD-SNAPSHOT");
then(gitHubHandler.issueCreatedInSpringGuides).isFalse();
then(gitHubHandler.issueCreatedInStartSpringIo).isFalse();
then(Files.readSymbolicLink(
new File(testDocumentationUpdater.getDocumentationRepo(),
"spring-cloud-build/current").toPath())
.toString()).isEqualTo("2.1.6.RELEASE");
thenRunUpdatedTestsWereNotCalled(postReleaseActions);
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
@Test
public void should_perform_a_release_of_consul_rc1() throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "vDalston.RC1");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
run(this.runner,
properties("debug=true").properties(new ArgsBuilder(project, this.tmp)
.releaseTrainUrl("/projects/spring-cloud-release/")
.bomBranch("vDalston.RC1").expectedVersion("1.2.0.RC1").build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
TestProjectGitHubHandler gitHubHandler = context
.getBean(TestProjectGitHubHandler.class);
SaganClient saganClient = context.getBean(SaganClient.class);
TestDocumentationUpdater testDocumentationUpdater = context
.getBean(TestDocumentationUpdater.class);
PostReleaseActions postReleaseActions = context
.getBean(PostReleaseActions.class);
TestExecutionResultHandler testExecutionResultHandler = context
.getBean(TestExecutionResultHandler.class);
ExecutionResult result = releaser
.release(new OptionsBuilder().interactive(true).options());
Iterable<RevCommit> commits = listOfCommits(project);
tagIsPresentInOrigin(origin, "v1.2.0.RC1");
commitIsNotPresent(commits,
"Bumping versions to 1.2.1.BUILD-SNAPSHOT after release");
Iterator<RevCommit> iterator = listOfCommits(project).iterator();
commitIsPresent(iterator, "Going back to snapshots");
commitIsPresent(iterator, "Update SNAPSHOT to 1.2.0.RC1");
pomVersionIsEqualTo(project, "1.2.0.BUILD-SNAPSHOT");
consulPomParentVersionIsEqualTo(project, "1.2.0.BUILD-SNAPSHOT");
then(gitHubHandler.closedMilestones).isTrue();
then(emailTemplate()).doesNotExist();
then(blogTemplate()).doesNotExist();
then(tweetTemplate()).doesNotExist();
then(releaseNotesTemplate()).doesNotExist();
BDDMockito.then(saganClient).should().updateRelease(
BDDMockito.eq("spring-cloud-consul"), BDDMockito.anyList());
BDDMockito.then(saganClient).should()
.deleteRelease("spring-cloud-consul", "1.2.0.M8");
BDDMockito.then(saganClient).should()
.deleteRelease("spring-cloud-consul", "1.2.0.RC1");
// we update guides only for SR / RELEASE
then(gitHubHandler.issueCreatedInSpringGuides).isFalse();
then(gitHubHandler.issueCreatedInStartSpringIo).isFalse();
// haven't even checked out the branch
then(new File(testDocumentationUpdater.getDocumentationRepo(),
"current/index.html")).doesNotExist();
thenRunUpdatedTestsWereNotCalled(postReleaseActions);
// print results
testExecutionResultHandler.accept(result);
then(testExecutionResultHandler.exitedSuccessOrUnstable).isTrue();
});
}
@Test
public void should_not_clone_when_option_not_to_clone_was_switched_on()
throws Exception {
checkoutReleaseTrainBranch("/projects/spring-cloud-release/", "master");
File origin = cloneToTemporaryDirectory(this.springCloudConsulProject);
assertThatClonedConsulProjectIsInSnapshots(origin);
File project = cloneToTemporaryDirectory(tmpFile("spring-cloud-consul"));
GitTestUtils.setOriginOnProjectToTmp(origin, project);
final File temporaryDestination = this.tmp.newFolder();
run(this.runner,
properties("debug=true").properties(new ArgsBuilder(project, this.tmp)
.releaseTrainUrl("/projects/spring-cloud-release/")
.bomBranch("vCamden.SR5").expectedVersion("1.1.2.RELEASE")
// just build
.chosenOption("6").fetchVersionsFromGit(false)
.cloneDestinationDirectory(temporaryDestination)
.addFixedVersion("spring-cloud-release", "Finchley.RELEASE")
.addFixedVersion("spring-cloud-consul", "2.3.4.RELEASE").build()),
context -> {
SpringReleaser releaser = context.getBean(SpringReleaser.class);
releaser.release(new OptionsBuilder().interactive(true).options());
then(temporaryDestination.list()).isEmpty();
});
}
private void assertThatClonedBuildProjectIsInSnapshots(File origin) {
pomVersionIsEqualTo(origin, "1.3.7.BUILD-SNAPSHOT");
pomParentVersionIsEqualTo(origin, "spring-cloud-build-dependencies",
"1.5.9.RELEASE");
}
// @formatter:on
static class TestProjectGitHubHandler extends ProjectGitHubHandler {
final String expectedVersion;
final String projectName;
boolean closedMilestones = false;
boolean issueCreatedInSpringGuides = false;
boolean issueCreatedInStartSpringIo = false;
TestProjectGitHubHandler(ReleaserProperties properties, String expectedVersion,
String projectName) {
super(properties, Collections.emptyList());
this.expectedVersion = expectedVersion;
this.projectName = projectName;
}
@Override
public void closeMilestone(ProjectVersion releaseVersion) {
then(releaseVersion.projectName).isEqualTo(this.projectName);
then(releaseVersion.version).isEqualTo(this.expectedVersion);
this.closedMilestones = true;
}
@Override
public void createIssueInSpringGuides(Projects projects, ProjectVersion version) {
this.issueCreatedInSpringGuides = true;
}
@Override
public void createIssueInStartSpringIo(Projects projects,
ProjectVersion version) {
this.issueCreatedInStartSpringIo = true;
}
@Override
public String milestoneUrl(ProjectVersion releaseVersion) {
return "https://foo.bar.com/" + releaseVersion.toString();
}
}
@Configuration
@EnableAutoConfiguration
@ConditionalOnProperty(value = "test.metarelease", havingValue = "false",
matchIfMissing = true)
static class SingleProjectReleaseConfig extends DefaultTestConfiguration {
@Bean
SaganClient testSaganClient() {
SaganClient saganClient = BDDMockito.mock(SaganClient.class);
BDDMockito.given(saganClient.getProject(anyString()))
.willReturn(newProject());
return saganClient;
}
@Bean
PostReleaseActions myPostReleaseActions() {
return BDDMockito.mock(PostReleaseActions.class);
}
@Bean
TestProjectGitHubHandler testProjectGitHubHandler(
ReleaserProperties releaserProperties,
@Value("${test.expectedVersion}") String expectedVersion,
@Value("${test.projectName}") String projectName) {
return new TestProjectGitHubHandler(releaserProperties, expectedVersion,
projectName);
}
@Bean
NonAssertingTestProjectGitHandler nonAssertingTestProjectGitHandler(
ReleaserProperties releaserProperties,
@Value("${test.projectName}") String projectName) {
return new NonAssertingTestProjectGitHandler(releaserProperties,
file -> FileSystemUtils
.deleteRecursively(new File(file, projectName)));
}
@Bean
TestDocumentationUpdater testDocumentationUpdater(
ProjectGitHandler projectGitHandler,
ReleaserProperties releaserProperties,
TemplateGenerator templateGenerator, @Autowired(
required = false) List<CustomProjectDocumentationUpdater> updaters) {
return new TestDocumentationUpdater(projectGitHandler, releaserProperties,
templateGenerator, updaters);
}
}
@Configuration
@ConditionalOnProperty(value = "test.metarelease", havingValue = "false",
matchIfMissing = true)
@ComponentScan({ "releaser.internal", "releaser.cloud" })
static class SingleProjectScanningConfiguration {
}
}

View File

@@ -0,0 +1,25 @@
<!--
~ Copyright 2013-2019 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="releaser" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>

View File

@@ -0,0 +1,6 @@
releaser.maven.buildCommand: maven_build
releaser.bash.buildCommand: bash_build
releaser.gradle.buildCommand: gradle_build
releaser.gradle.gradlePropsSubstitution:
verifierVersion: spring-cloud-contract
bootVersion: spring-boot

View File

@@ -2,8 +2,7 @@
image:https://circleci.com/gh/spring-cloud/spring-cloud-build.svg?style=svg[link="https://travis-ci.org/spring-cloud/spring-cloud-build"] image:https://circleci.com/gh/spring-cloud/spring-cloud-build.svg?style=svg[link="https://travis-ci.org/spring-cloud/spring-cloud-build"]
Spring Cloud Build is a common utility project for Spring Cloud Spring Cloud Build is a common utility project for Spring Cloud to use for plugin and dependency management.
to use for plugin and dependency management.
== Building and Deploying == Building and Deploying
@@ -42,57 +41,49 @@ $ mvn deploy -P central -DaltReleaseDeploymentRepository=sonatype-nexus-staging:
== Contributing == Contributing
Spring Cloud is released under the non-restrictive Apache 2.0 license, Spring Cloud is released under the non-restrictive Apache 2.0 license, and follows a very standard Github development process, using Github tracker for issues and merging pull requests into master.
and follows a very standard Github development process, using Github If you want to contribute even something trivial please do not hesitate, but follow the guidelines below.
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
=== Sign the Contributor License Agreement === Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you to sign the Before we accept a non-trivial patch or pull request we will need you to sign the
https://cla.pivotal.io/sign/spring[Contributor License Agreement]. https://cla.pivotal.io/sign/spring[Contributor License Agreement].
Signing the contributor's agreement does not grant anyone commit rights to the main Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do.
repository, but it does mean that we can accept your contributions, and you will get an Active contributors might be asked to join the core team, and given the ability to merge pull requests.
author credit if we do. Active contributors might be asked to join the core team, and
given the ability to merge pull requests.
=== Code of Conduct === Code of Conduct
This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
conduct]. By participating, you are expected to uphold this code. Please report conduct].
unacceptable behavior to spring-code-of-conduct@pivotal.io. By participating, you are expected to uphold this code.
Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
=== Code Conventions and Housekeeping === Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
* Use the Spring Framework code format conventions. If you use Eclipse None of these is essential for a pull request, but they will all help.
you can import formatter settings using the They can also be added after the original pull request but before a merge.
* Use the Spring Framework code format conventions.
If you use Eclipse you can import formatter settings using the
`eclipse-code-formatter.xml` file from the `eclipse-code-formatter.xml` file from the
https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
Cloud Build] project. If using IntelliJ, you can use the Cloud Build] project.
If using IntelliJ, you can use the
https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
Plugin] to import the same file. Plugin] to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an * Make sure all new `.java` files to have a simple Javadoc class comment with at least an
`@author` tag identifying you, and preferably at least a paragraph on what the class is `@author` tag identifying you, and preferably at least a paragraph on what the class is for.
for. * Add the ASF license header comment to all new `.java` files (copy from existing files in the project)
* Add the ASF license header comment to all new `.java` files (copy from existing files * Add yourself as an `@author` to the .java files that you modify substantially (more than cosmetic changes).
in the project)
* Add yourself as an `@author` to the .java files that you modify substantially (more
than cosmetic changes).
* Add some Javadocs and, if you change the namespace, some XSD doc elements. * Add some Javadocs and, if you change the namespace, some XSD doc elements.
* A few unit tests would help a lot as well -- someone has to do it. * A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or * If no-one else is using your branch, please rebase it against the current master (or other target branch in the main project).
other target branch in the main project). * When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit message (where XXXX is the issue number).
* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
message (where XXXX is the issue number).
== Reusing the documentation == Reusing the documentation
Spring Cloud Build publishes its `spring-cloud-build-docs` module that contains Spring Cloud Build publishes its `spring-cloud-build-docs` module that contains helpful scripts (e.g. README generation ruby script) and css, xslt and images for the Spring Cloud documentation.
helpful scripts (e.g. README generation ruby script) and css, xslt and images If you want to follow the same convention approach of generating documentation just add these plugins to your `docs` module
for the Spring Cloud documentation. If you want to follow the same convention
approach of generating documentation just add these plugins to your `docs` module
[source,xml] [source,xml]
---- ----

View File

@@ -1,7 +1,6 @@
image:https://circleci.com/gh/spring-cloud/spring-cloud-build.svg?style=svg[link="https://travis-ci.org/spring-cloud/spring-cloud-build"] image:https://circleci.com/gh/spring-cloud/spring-cloud-build.svg?style=svg[link="https://travis-ci.org/spring-cloud/spring-cloud-build"]
Spring Cloud Build is a common utility project for Spring Cloud Spring Cloud Build is a common utility project for Spring Cloud to use for plugin and dependency management.
to use for plugin and dependency management.
== Building and Deploying == Building and Deploying
@@ -44,10 +43,8 @@ include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/maste
== Reusing the documentation == Reusing the documentation
Spring Cloud Build publishes its `spring-cloud-build-docs` module that contains Spring Cloud Build publishes its `spring-cloud-build-docs` module that contains helpful scripts (e.g. README generation ruby script) and css, xslt and images for the Spring Cloud documentation.
helpful scripts (e.g. README generation ruby script) and css, xslt and images If you want to follow the same convention approach of generating documentation just add these plugins to your `docs` module
for the Spring Cloud documentation. If you want to follow the same convention
approach of generating documentation just add these plugins to your `docs` module
[source,xml] [source,xml]
---- ----

View File

@@ -0,0 +1,72 @@
=== Basic Compile and Test
To build the source you will need to install JDK {jdkversion}.
Spring Cloud uses Maven for most build-related activities, and you should be able to get off the ground quite quickly by cloning the project you are interested in and typing
----
$ ./mvnw install
----
NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command in place of `./mvnw` in the examples below.
If you do that you also might need to add `-P spring` if your local Maven settings do not contain repository declarations for spring pre-release artifacts.
NOTE: Be aware that you might need to increase the amount of memory available to Maven by setting a `MAVEN_OPTS` environment variable with a value like `-Xmx512m -XX:MaxPermSize=128m`.
We try to cover this in the `.mvn` configuration, so if you find you have to do it to make a build succeed, please raise a ticket to get the settings added to source control.
For hints on how to build the project look in `.travis.yml` if there is one.
There should be a "script" and maybe "install" command.
Also look at the "services" section to see if any services need to be running locally (e.g. mongo or rabbit).
Ignore the git-related bits that you might find in "before_install" since they're related to setting git credentials and you already have those.
The projects that require middleware generally include a
`docker-compose.yml`, so consider using
https://compose.docker.io/[Docker Compose] to run the middeware servers in Docker containers.
See the README in the
https://github.com/spring-cloud-samples/scripts[scripts demo
repository] for specific instructions about the common cases of mongo, rabbit and redis.
NOTE: If all else fails, build with the command from `.travis.yml` (usually
`./mvnw install`).
=== Documentation
The spring-cloud-build module has a "docs" profile, and if you switch that on it will try to build asciidoc sources from
`src/main/asciidoc`.
As part of that process it will look for a
`README.adoc` and process it by loading all the includes, but not parsing or rendering it, just copying it to `${main.basedir}`
(defaults to `${basedir}`, i.e. the root of the project).
If there are any changes in the README it will then show up after a Maven build as a modified file in the correct place.
Just commit it and push the change.
=== Working with the code
If you don't have an IDE preference we would recommend that you use
https://www.springsource.com/developer/sts[Spring Tools Suite] or
https://eclipse.org[Eclipse] when working with the code.
We use the
https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support.
Other IDEs and tools should also work without issue as long as they use Maven 3.3.3 or better.
==== Importing into eclipse with m2eclipse
We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with eclipse.
If you don't already have m2eclipse installed it is available from the "eclipse marketplace".
NOTE: Older versions of m2e do not support Maven 3.3, so once the projects are imported into Eclipse you will also need to tell m2eclipse to use the right profile for the projects.
If you see many different errors related to the POMs in the projects, check that you have an up to date installation.
If you can't upgrade m2e, add the "spring" profile to your `settings.xml`.
Alternatively you can copy the repository settings from the "spring" profile of the parent pom into your `settings.xml`.
==== Importing into eclipse without m2eclipse
If you prefer not to use m2eclipse you can generate eclipse project metadata using the following command:
[indent=0]
----
$ ./mvnw eclipse:eclipse
----
The generated eclipse projects can be imported by selecting `import existing projects`
from the `file` menu.

View File

@@ -1,11 +1,9 @@
==== Adding Project Lombok Agent ==== Adding Project Lombok Agent
Spring Cloud uses https://projectlombok.org/features/index.html[Project Lombok] Spring Cloud uses https://projectlombok.org/features/index.html[Project Lombok]
to generate getters and setters etc. Compiling from the command line this to generate getters and setters etc.
shouldn't cause any problems, but in an IDE you need to add an agent Compiling from the command line this shouldn't cause any problems, but in an IDE you need to add an agent to the JVM. Full instructions can be found in the Lombok website.
to the JVM. Full instructions can be found in the Lombok website. The The sign that you need to do this is a lot of compiler errors to do with missing methods and fields, e.g.
sign that you need to do this is a lot of compiler errors to do with
missing methods and fields, e.g.
[indent=0] [indent=0]
---- ----
@@ -18,16 +16,22 @@ The method getLocation() is undefined for the type ProxyRouteLocator.ProxyRouteS
---- ----
==== Importing into Intellij ==== Importing into Intellij
Spring Cloud projects use annotation processing, particularly Lombok, which requires configuration
or you will encounter compile problems. It also needs a specific version of maven and a profile
enabled. Intellij 14.1+ requires some configuration to ensure these are setup properly.
1. Click Preferences, Plugins. *Ensure Lombok is installed* Spring Cloud projects use annotation processing, particularly Lombok, which requires configuration or you will encounter compile problems.
2. Click New, Project from Existing Sources, choose your spring-cloud project directory It also needs a specific version of maven and a profile enabled.
3. Choose Maven, and select Environment Settings. *Ensure you are using Maven 3.3.3* Intellij 14.1+ requires some configuration to ensure these are setup properly.
4. In the next screen, *Select the profile `spring`* click Next until Finish.
5. Click Preferences, "Build, Execution, Deployment", Compiler, Annotation Processors. *Click Enable Annotation Processing* 1. Click Preferences, Plugins.
6. Click Build, Rebuild Project, and you are ready to go! *Ensure Lombok is installed*
2. Click New, Project from Existing Sources, choose your spring-cloud project directory
3. Choose Maven, and select Environment Settings.
*Ensure you are using Maven 3.3.3*
4. In the next screen, *Select the profile `spring`* click Next until Finish.
5. Click Preferences, "Build, Execution, Deployment", Compiler, Annotation Processors.
*Click Enable Annotation Processing*
6. Click Build, Rebuild Project, and you are ready to go!
==== Importing into other IDEs ==== Importing into other IDEs
Maven is well supported by most Java IDEs. Refer to you vendor documentation.
Maven is well supported by most Java IDEs.
Refer to you vendor documentation.

View File

@@ -0,0 +1,28 @@
= Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project.
Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
This Code of Conduct is adapted from the
https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]

View File

@@ -0,0 +1,2 @@
NOTE: Spring Cloud is released under the non-restrictive Apache 2.0 license.
If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at {docslink}[github].

View File

@@ -1,44 +1,38 @@
Spring Cloud is released under the non-restrictive Apache 2.0 license, Spring Cloud is released under the non-restrictive Apache 2.0 license, and follows a very standard Github development process, using Github tracker for issues and merging pull requests into master.
and follows a very standard Github development process, using Github If you want to contribute even something trivial please do not hesitate, but follow the guidelines below.
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
=== Sign the Contributor License Agreement === Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you to sign the Before we accept a non-trivial patch or pull request we will need you to sign the
https://cla.pivotal.io/sign/spring[Contributor License Agreement]. https://cla.pivotal.io/sign/spring[Contributor License Agreement].
Signing the contributor's agreement does not grant anyone commit rights to the main Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do.
repository, but it does mean that we can accept your contributions, and you will get an Active contributors might be asked to join the core team, and given the ability to merge pull requests.
author credit if we do. Active contributors might be asked to join the core team, and
given the ability to merge pull requests.
=== Code of Conduct === Code of Conduct
This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
conduct]. By participating, you are expected to uphold this code. Please report conduct].
unacceptable behavior to spring-code-of-conduct@pivotal.io. By participating, you are expected to uphold this code.
Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
=== Code Conventions and Housekeeping === Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
* Use the Spring Framework code format conventions. If you use Eclipse None of these is essential for a pull request, but they will all help.
you can import formatter settings using the They can also be added after the original pull request but before a merge.
* Use the Spring Framework code format conventions.
If you use Eclipse you can import formatter settings using the
`eclipse-code-formatter.xml` file from the `eclipse-code-formatter.xml` file from the
https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
Cloud Build] project. If using IntelliJ, you can use the Cloud Build] project.
If using IntelliJ, you can use the
https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
Plugin] to import the same file. Plugin] to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an * Make sure all new `.java` files to have a simple Javadoc class comment with at least an
`@author` tag identifying you, and preferably at least a paragraph on what the class is `@author` tag identifying you, and preferably at least a paragraph on what the class is for.
for. * Add the ASF license header comment to all new `.java` files (copy from existing files in the project)
* Add the ASF license header comment to all new `.java` files (copy from existing files * Add yourself as an `@author` to the .java files that you modify substantially (more than cosmetic changes).
in the project)
* Add yourself as an `@author` to the .java files that you modify substantially (more
than cosmetic changes).
* Add some Javadocs and, if you change the namespace, some XSD doc elements. * Add some Javadocs and, if you change the namespace, some XSD doc elements.
* A few unit tests would help a lot as well -- someone has to do it. * A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or * If no-one else is using your branch, please rebase it against the current master (or other target branch in the main project).
other target branch in the main project). * When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit message (where XXXX is the issue number).
* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
message (where XXXX is the issue number).

Some files were not shown because too many files have changed in this diff Show More