== Spring Cloud Release Tools

Spring Cloud projects reuse the same pattern of building and deploying the applications.
That's why this tool makes it easy to automate the release / dependency update process of our applications.

=== Releasing through Jenkins

NOTE: Whenever a release process is broken, Jenkins marks it with a red 'X' and breaks the build.
Whenever a post-release action went wrong but the release is successful, Jenkins marks the build with a yellow exclamation and marks the build as unstable.


==== Releasing a Single Project

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:

```bash
$ git clone git@github.com:spring-cloud/spring-cloud-release.git
$ cd spring-cloud-release
$ 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:

```bash
// setting the release train value
$ ./mvnw versions:set -DnewVersion=Hoxton.M1 -DgenerateBackupPoms=false -DprocessAllModules=true
// Update all parent versions
$ ./mvnw versions:update-parent -DgenerateBackupPoms=false -DprocessAllModules=true
// Setting the necessary dependencies
$ ./mvnw versions:set-property -Dproperty=spring-cloud-commons.version -DnewVersion=1.2.3.BUILD-SNAPSHOT -pl spring-cloud-dependencies -DgenerateBackupPoms=false
// NOTE!!!
// Verify that the versions set by Maven are correct!!
$ git diff
// commit and push the branch
$ 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.

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::https://raw.githubusercontent.com/spring-cloud/spring-cloud-release-tools/main/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:

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-release-tools/main/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:

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-release-tools/main/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 `main`) 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`.

You are done!

As a post action, do not forget to remove the branch.
The following example shows how to do so:

```bash
// to synchronize any deleted branches (don't run this if you want leave any deleted branches that were deleted in the origin)
$ git fetch -p
$ git branch -d springCloudBuildRelease
$ git push origin --delete springCloudBuildRelease
```

==== Releasing a Release Train

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 following example shows how to do so:

```bash
$ git clone git@github.com:spring-cloud/spring-cloud-release.git
$ cd spring-cloud-release
$ 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:

```bash
$ 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:

```bash
$ 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-commons]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-function]=2.0.2.RELEASE
releaser.fixed-versions[spring-cloud-stream]=Fishtown.SR3
releaser.fixed-versions[spring-cloud-aws]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-bus]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-task]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-config]=2.1.3.RELEASE
releaser.fixed-versions[spring-cloud-netflix]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-cloudfoundry]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-kubernetes]=1.0.2.RELEASE
releaser.fixed-versions[spring-cloud-openfeign]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-consul]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-gateway]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-security]=2.1.3.RELEASE
releaser.fixed-versions[spring-cloud-sleuth]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-zookeeper]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-contract]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-gcp]=1.1.2.RELEASE
releaser.fixed-versions[spring-cloud-vault]=2.1.2.RELEASE
releaser.fixed-versions[spring-cloud-release]=Greenwich.SR2" >> greenwich_sr2.properties
$ git add greenwich_sr2.properties && git commit -m "Added Greenwich.SR2 properties" && git push origin jenkins-releaser-config
```

Since the project is prepared, go to Jenkins and select the https://jenkins.spring.io/view/Spring%20Cloud/view/Releaser/[Releaser view], as the following image shows:

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-release-tools/main/docs/src/main/asciidoc/images/releasersForMetaRelease.png[Releaser view]

. Pick the proper meta-releaser project (for example, `spring-cloud-meta-releaser`), as the following image shows:

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-release-tools/main/docs/src/main/asciidoc/images/springCloudMetaRelease.png[Spring Cloud Meta Releaser - build with parameters]

. Next, click `Build with parameters`.

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-release-tools/main/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.

. Finally, click `Build`.

You are done!

=== What does it do?

==== Single project

For a single project, by default if you opt in to all tasks

- 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)
* 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
* 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)
- Creates a tag for the release / milestone (ONLY FOR NON-SNAPSHOT VERSIONS)
- Runs the deployment of the artifacts
- 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)
- 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, otherwise the application will fail to start

After project release

- Generates an email template under `target/email.txt` (ONLY FOR NON-SNAPSHOT VERSIONS)
- Generates a blog template under `target/blog.md` (ONLY FOR NON-SNAPSHOT VERSIONS)
- Generates a tweet template under `target/tweet.txt` (ONLY FOR NON-SNAPSHOT VERSIONS)
- Generates a release notes template under `target/notes.md` (ONLY FOR NON-SNAPSHOT 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 start.spring.io under https://github.com/spring-io/start.spring.io/issues/
- 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`)

==== 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`)
- 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 `main` if there's no `Finchley` branch.
** for `spring-cloud-sleuth`'s `2.1.0.RELEASE` version will resolve `2.1.x` branch
- Performs the release tasks per each project
- Performs the post release tasks at the end of the release
- Will update and run smoke test samples (for Spring Cloud it will be `https://github.com/spring-cloud/spring-cloud-core-tests`)
- 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`)

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

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?

Members of the Spring Cloud Team typically use this tool as follows.
They first clone the releaser locally and build the jar manually

[source,bash]
----
$ git clone git@github.com:spring-cloud/spring-cloud-release-tools.git
$ cd spring-cloud-release-tools
$ ./mvnw clean install
----

IMPORTANT: You must set the value of the OAuth token.
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=...`

=== How to run it (interactive mode)

Go to your project (e.g. Spring Cloud Sleuth)

[source,bash]
----
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth
$ # 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/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 follows the convention that you have the OAuth token environment variable set.
It also assumes that you might have some custom configuration in `config/releaser.yml` file.
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
`releaser` to be able to push tags and commit changes automatically.

You will see text similar to this one

[source]
----
=== WHAT DO YOU WANT TO DO? ===

0) Perform a full release of this project without interruptions
1) Perform a full release of this project in a verbose mode (you'll be asked about skipping steps)
2) Update poms with versions from Spring Cloud Release
3) Build the project
4) Commit, tag and push the tag
5) Deploy the artifacts
6) Publish the docs
7) Go back to snapshots and bump originalVersion by patch
8) Push the commits
9) Close the milestone at Github
10) Create email / blog / tweet etc. templates

You can pick a range of options by using the hyphen - e.g. '2-4' will execute jobs [2,3,4]
You can execute all tasks starting from a job by using a hyphen and providing only one number - e.g. '8-' will execute jobs [8,9,10]
You can execute given tasks by providing a comma separated list of tasks - e.g. '3,7,8' will execute jobs [3,7,8]

You can press 'q' to quit
----

Just pick a number and continue!
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.

TIP: Read before picking a number cause it might have changed between tool releases ;)

=== How to run it (automatic mode)

Go to your project (e.g. Spring Cloud Sleuth) and execute the application with `-h` or `--help`
flag.

[source,bash]
----
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth
$ # 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/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

[source,bash]
----
Here you can find the list of tasks in order

[release,releaseVerbose,metaRelease,postRelease,updatePoms,build,commit,deploy,docs,snapshots,push,closeMilestone,updateSagan,createTemplates,updateGuides,updateDocumentation]


Option                                Description
------                                -----------
-a, --start-from <String>             Starts all release task starting from the
                                        given task. Requires passing the task
                                        name (either one letter or the full
                                        name)
-b, --build [String]                  Build the project
-c, --commit [String]                 Commit, tag and push the tag
-d, --deploy [String]                 Deploy the artifacts
-f, --full-release [Boolean]          Do you want to do the full release of a
                                        single project? (default: false)
-g, --updateSagan [String]            Updating Sagan with release info
-h, --help [String]
-i, --interactive <Boolean>           Do you want to set the properties from
                                        the command line of a single project?
                                        (default: true)
-m, --closeMilestone [String]         Close the milestone at Github
-o, --docs [String]                   Publish the docs
-p, --push [String]                   Push the commits
-r, --range <String>                  Runs release tasks from the given range.
                                        Requires passing the task names with a
                                        hyphen. The first task is inclusive,
                                        the second inclusive. E.g. 's-m' would
                                        mean running 'snapshot', 'push' and
                                        'milestone' tasks
-s, --snapshots [String]              Go back to snapshots and bump
                                        originalVersion by patch
-t, --createTemplates [String]        Create email / blog / tweet etc. templates
--task-names, --tn <String>           Starts all release task for the given
                                        task names
-u, --updatePoms [String]             Update poms with versions from Spring
                                        Cloud Release
--ud, --updateDocumentation [String]  Updating documentation repository
--ug, --updateGuides [String]         Updating Spring Guides
-x, --meta-release <Boolean>          Do you want to do the meta release?
                                        (default: false)

Examples of usage:

Run 'build' & 'commit' & 'deploy'
java -jar jar.jar -b -c -d

Start from 'push'
java -jar releaser.jar -a push

Range 'docs' -> 'push'
java -jar releaser.jar -r o-p
----

The Releaser can use two sets of options.
The configuration options like `releaser.pom.branch`
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:

.Doing the full release in interactive mode (asking for skipping steps)
[source,bash]
----
$ git clone git@github.com:spring-cloud/spring-cloud-sleuth.git
$ cd spring-cloud-sleuth
$ # 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/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)
[source,bash]
----
$ 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
[source,bash]
----
$ 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)
[source,bash]
----
$ 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)
[source,bash]
----
$ 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)
[source,bash]
----
$ 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)

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 in the `--"releaser.fixed-versions[project-name]=project-version" format

```
$ 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 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

Below you can find a table with all the releaser options.

include::_configprops.adoc[]

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/releaser-spring-1.0.0.M1.jar`
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 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*.
E.g. `./mvnw clean install ${@}`.
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.

=== Examples

==== Keeping configuration in the project

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`
folder and run your application like this:

[source,bash]
----
$ 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/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 during the build process

IMPORTANT: For the meta-releaser to work we assume that the path to the configuration file is always `config/releaser.yml`.

==== Specifying A Branch

By deafult the releaser will default to using the `main` branch of `spring-cloud-release`.
If you would like to use another branch you can specify it using the `releaser.pom.branch` property.

[source,bash]
----
$ java -jar releaser-spring-1.0.0.M1.jar --releaser.pom.branch=Camden.SR6
----

==== Using Environment Variables

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 releasing multiple projects, this keeps you from having to specify the same parameters for each release

[source,bash]
----
$ export RELEASER_POM_BRANCH=Dalston.RELEASE
$ export RELEASER_GIT_OAUTH_TOKEN=...
$ 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/releaser-spring-1.0.0.M1.jar --releaser.working-dir=/path/to/project/root
----

=== FAQ

==== JSchException: Auth fail

You may get an exception similar to the following:

[source]
----
Caused by: org.eclipse.jgit.errors.TransportException: git@github.com:spring-cloud/spring-cloud-sleuth.git: Auth fail
	at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:160) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:137) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	at org.eclipse.jgit.transport.TransportGitSsh$SshPushConnection.<init>(TransportGitSsh.java:322) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	at org.eclipse.jgit.transport.TransportGitSsh.openPush(TransportGitSsh.java:167) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	at org.eclipse.jgit.transport.PushProcess.execute(PushProcess.java:160) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	at org.eclipse.jgit.transport.Transport.push(Transport.java:1275) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	at org.eclipse.jgit.api.PushCommand.call(PushCommand.java:161) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	... 25 common frames omitted
Caused by: com.jcraft.jsch.JSchException: Auth fail
	at com.jcraft.jsch.Session.connect(Session.java:512) ~[jsch-0.1.53.jar!/:na]
	at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:117) ~[org.eclipse.jgit-4.6.0.201612231935-r.jar!/:4.6.0.201612231935-r]
	... 31 common frames omitted
----

To fix that just call, run the following commands before running the app:

[source,bash]
----
# to run the agent
$ eval `ssh-agent`
# to store the pass in the agent
$ ssh-add ~/.ssh/id_rsa
----

==== Skipping version check

If you know what you're doing and want to skip snapshot / milestone version check for poms or any other files, just set the following comment [`@releaser:version-check-off`] in the same line where the version appears. Example:

[source,xml]
----
	<properties>
		<zipkin.version>1.19.2-M2</zipkin.version><!-- @releaser:version-check-off -->
		<zipkin-reporter.version>0.6.12</zipkin-reporter.version>
	</properties>
----
