= Test, Build and Deploy
:toc:
:gradle-home: http://gradle.org[Gradle]
:gradle-userguide: https://docs.gradle.org/current/userguide/userguide.html[gradle userguide]
:gradle-wrapper: https://docs.gradle.org/current/userguide/gradle_wrapper.html[gradle wrapper]
:jacoco-web: http://www.eclemma.org/jacoco/[jacoco]
:coveralls: https://coveralls.io/github/jbake-org/jbake[coveralls]
:sdkman: http://sdkman.io[sdkman]

...and other useful stuff you can do with the {gradle-home} build system.

The project uses {gradle-home} as the build system.
This is just a little collection of the common tasks you need to know to develop, build and deploy JBake. For more detailed information about gradle have a look at the {gradle-userguide}.

To execute the tasks use the {gradle-wrapper}. That way you do not need to install
 gradle for yourself and can be sure you are using the exact version everyone else is using to build JBake.

You can execute the build using one of the following commands from the root of the project:

* `./gradlew <task>` (on Unix-like platforms such as Linux and Mac OS X)

* `gradlew <task>` (on Windows using the gradlew.bat batch file)

To get an overview of all available tasks with a short description run `./gradlew tasks`

== Structure

There are 4 projects:

root aka. jbake-base::
    configures subprojects, jacoco execution aggregation and coveralls

jbake-core::
    - the core library. produces jbake-core-{version}.jar (`build/libs`)
    - publishes to bintray maven repository jbake-core

jbake-maven-plugin::
    - the JBake maven plugin, build by Gradle too

jbake-dist::
    - bundles the cli to an distribution (`build/distribution`)
    - publishes to bintray binary repository jbake
    - publish to sdkman

If you want to run a task in a specific project from root run `./gradlew :jbake-core:test` for example.


== Test

=== run the tests
While developing this is the most common task you should execute.

----
./gradlew test
----

This task compiles and executes all tests within `src/test` and produces a report afterwards.

You can find the report at `jbake-core/build/reports/tests/test/index.html` and can view it with your browser.
This is very useful if something went wrong.
You find the full stacktrace and output there.

=== know what's going on

The task is not very verbose. An successful execution looks like the following listing.

.successful test execution
----
./gradlew test

BUILD SUCCESSFUL in 53s
6 actionable tasks: 6 executed
----

You can set different log levels with the command option `-i` for info or `-d` for debug. (e.g.: `./gradlew -i test`)

=== enable continuous testing

To execute the tests as soon as some input file changes run the task with
 `-t` option.

----
./gradlew -t test
Continuous build is an incubating feature.

BUILD SUCCESSFUL in 0s
6 actionable tasks: 1 executed, 5 up-to-date

Waiting for changes to input files of tasks... (ctrl-d to exit)
<-------------> 0% WAITING
> IDLE
----

=== smoke tests

The `jbake-dist` module has a task called `smokeTest`.
It executes the produced application, initializes a jbake project for each supported example project and bake it.

The `check` task depends on the `smokeTest` task and is part of the travis CI execution.
You can find the report at `jbake-dist/build/reports/tests/smokeTest/`

=== code coverage

To generate a nice code coverage report run the following task.

----
./gradlew jacocoRootReport
----

It compiles your code, execute your tests, collect data and generate a report with {jacoco-web}. It produces XML and html reports. The xml file is used to trigger the {coveralls} service with the `coveralls` task.

The reports can be found at `build/reports/jacoco/jacocoRootReport/html`.

[NOTE]
====
This is an aggregation of all project modules.

You can generate coverage reports for each module with `./gradlew jacocoTestReport`
or for a particular module `./gradlew :jbake-core:jacocoTestReport`.

The report can be found at `<module>/build/reports/jacoco/test/html/`
====

plugin:: https://docs.gradle.org/current/userguide/jacoco_plugin.html
// TODO: write something about smokeTests and check

== Build

=== run the build

The `build` task assembles and tests the project.

----
./gradlew build
----

It clones the example projects from github, creates zip files, generates start scripts for *NIX and Windows, bundles a distribution package, signs archives (if signing is configured properly), generates javadocs, assemble the packages and runs checks.

----
./gradlew build

BUILD SUCCESSFUL in 47s
28 actionable tasks: 10 executed, 18 up-to-date
----

If successful you can find everything in the `jbake-dist/build` directory.
The distribution package can be found at `jbake-dist/build/distributions` and is called `jbake-{version}-bin.zip`

=== install local

You can install the distribution locally.

----
./gradlew installDist
----

The distribution can be found in an exploded directory called `jbake-dist/build/install/jbake`.

NOTE: This task does not run checks. It just compiles and bundles the distribution.

plugin:: https://docs.gradle.org/current/userguide/application_plugin.html

== Deploy

WARNING: Never add credentials to the repository

=== github release

Bump desired project version in the projects `gradle.properties` file.

Like

----
version = 2.7.0
----

Commit and push to origin at github.

----
./gradlew signArchives
./gradlew githubRelease
----

The task will create a tag for you and create a release. Additionaly it uploads the binary distribution and the corresponding signature to the release.

[NOTE]
====
You need to add some properties to your local gradle.properties file (_~/.gradle/gradle.properties_)

----
github.token=<access token>
github.release.owner=jbake-org
github.release.repo=jbake
----

It's also possible to dry-run this task. Execute `export GITHUB_RELEASE_DRY_RUN=true` in your terminal.
====

plugin:: https://github.com/BreadMoirai/github-release-gradle-plugin

=== publish to nexus sonatype

You can publish to nexus with

----
./gradlew publishToSonatype
----

The task will create a staging repository. You need to close and publish it manually.
You can automate this process with the other tasks like `closeSonatypeStagingRepository` and `closeAndReleaseSonatypeStagingRepository`.

For more information see:

* https://github.com/gradle-nexus/publish-plugin
* https://central.sonatype.org/pages/ossrh-guide.html

You need to add two properties to your local gradle.properties file (_~/.gradle/gradle.properties_).

    sonatypeUsername=username
    sonatypePassword=secret

plugin:: https://plugins.gradle.org/plugin/io.github.gradle-nexus.publish-plugin

=== publish to sdkman

To release, set to default and announce a new candidate of JBake to {sdkman} run

    ./gradlew sdkMajorRelease

Add the following properties to your local _gradle.properties_ file (_~/.gradle/gradle.properties_):

    sdkman_consumer_key=key
    sdkman_consumer_token=token

plugin:: https://plugins.gradle.org/plugin/io.sdkman.vendors

=== signing

To enable code signing you need to add some more properties to your local _gradle.properties_ file (_~/.gradle/gradle.properties_):

    signing.keyId=24875D73
    signing.password=secret
    signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg

To skip signing on purpose add `-PskipSigning=true`.

plugin:: https://docs.gradle.org/current/userguide/signing_plugin.html

== Other useful tasks

=== check code convention violations

The Checkstyle Plugin is configured to use our code conventions defined in `config/checkstyle/checkstyle.xml`.

It gets executed with the `check` Task and prints warnings about violations to the console.
A report can be found at jbake-core/build/reports/checkstyle/.

plugin:: https://docs.gradle.org/current/userguide/checkstyle_plugin.html

=== keep the dependencies up-to-date

It's sometimes hard to keep track of the latest versions for your dependencies.
Fear not.

----
./gradlew dependencyUpdates
:dependencyUpdates
Download https://jcenter.bintray.com/org/assertj/assertj-core/3.8.0/assertj-core-3.8.0.pom

------------------------------------------------------------
: Project Dependency Updates (report to plain text file)
------------------------------------------------------------

The following dependencies are using the latest milestone version:
 - args4j:args4j:2.33
 - org.asciidoctor:asciidoctorj:1.5.5
 - commons-configuration:commons-configuration:1.10
 - commons-io:commons-io:2.5
 - org.apache.commons:commons-lang3:3.5
 - org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.1
 - org.freemarker:freemarker:2.3.26-incubating
 - com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3
 - com.github.ben-manes:gradle-versions-plugin:0.14.0
 - org.codehaus.groovy:groovy:2.4.11
 - org.codehaus.groovy:groovy-templates:2.4.11
 - de.neuland-bfi:jade4j:1.2.5
 - org.eclipse.jetty:jetty-server:9.4.5.v20170502
 - com.googlecode.json-simple:json-simple:1.1.1
 - org.slf4j:jul-to-slf4j:1.7.25
 - junit:junit:4.12
 - ch.qos.logback:logback-classic:1.2.3
 - ch.qos.logback:logback-core:1.2.3
 - org.mockito:mockito-core:2.8.9
 - com.orientechnologies:orientdb-graphdb:2.2.20
 - org.slf4j:slf4j-api:1.7.25
 - org.thymeleaf:thymeleaf:3.0.6.RELEASE

The following dependencies exceed the version found at the milestone revision level:
 - org.pegdown:pegdown [1.6.0 <- 1.5.0]

The following dependencies have later milestone versions:
 - org.assertj:assertj-core [3.7.0 -> 3.8.0]
 - org.apache.commons:commons-vfs2 [2.1 -> 2.1.1744488.1]

Failed to determine the latest version for the following dependencies (use --info for details):
 - gradle.plugin.io.sdkman:gradle-sdkvendor-plugin

Generated report file build/dependencyUpdates/report.txt

BUILD SUCCESSFUL

Total time: 6.721 secs
----

plugin:: https://plugins.gradle.org/plugin/com.github.ben-manes.versions
