Git Product home page Git Product logo

gradle-base-plugins's Introduction

gradle-base-plugins

Build Status

Plugins to configure Gradle to build projects (including other Gradle pluging) developed by FIDATA. They provide reasonable defaults and sane environment for all our projects.

These plugins are highly opinionated and for internal use only. They are not to be published to Maven Central or Gradle Plugins portal. However, you are free to fork, modify or use it as an example according to LGPL v3.0+ license.

If you are contributing to other FIDATA plugins the best choice is to join FIDATA organization and use all available infrastructure including our Artifactory repository where these plugins live.

org.fidata.project plugin

General, language-agnostic project.

Lifecycle

Basic build lifecycle is assemblecheckrelease.

assemble, check and, also, clean tasks are provided by applied lifecycle-base plugin.

release task is provided by applied de.gliderpilot.semantic-release plugin.

Prerequisites Lifecycle

Dependency Resolution

  • Adds Maven repository hosted on FIDATA Artifactory

    For releases, it is always -release repository, so releases cannot have snapshot dependencies. Otherwise it is -snapshot repository, so snapshot versions could be used during development (but won't by default - see below).

  • Turns off changing modules caching, so that SNAPSHOT dependencies are updated on each run

  • Configures dependency resolution changing Ivy status from release to milestone for artifacts having pre-release labels in version

  • Adds property status to each ExternalModuleDependency instance. It should be used to configure desired status of dependency. By default all dependencies are resolved to releases, even if you use version ranges. If you want to get bleeding edge SNAPSHOT version you could use this property, like this:

    dependencies {
      compile('com.example:next-generation-library:[1, 2[').status = 'integration'
    }
    

    Of course, if there is more recent release with appropriate version then it will be used instead of old SNAPSHOT.

    Custom status schemes are not supported.

Documentation

Code Quality

  • Provides lint task

    check task depends on all Test tasks and new lint task.

  • Applies codenarc plugin

  • Provides codenarc and pmd tasks that run all PMD and CodeNarc tasks respectively.

    Includes these tasks in execution list for lint task.

  • Provides codenarcBuildSrc task for build.gradle itself and accompanying Groovy scripts

  • Sets default configuration for all codenarc tasks

    Adds disabledRules property to each task, so that specific rules could be disabled per task.

Artifacts Publishing

  • Applies signing plugin

    By default, Java-based implementation of PGP is used. Secret keyring should be placed at GnuPG home in secring.gpg file.

    If you want to use GnuPG for signing, properties for this are already set. Switch can be made with signing.useGpgCmd() .

  • Provides read-only isRelease and changeLog project properties for working with semantic release

  • Provides publicReleases project property used by other plugins

    Setting it to true turns on all public-release tasks: publishing artifacts to Maven Central, JCenter and so on.

    By default it is false.

Reports

  • Provides read-only project properties:

    • reportsDir
    • htmlReportsDir
    • xmlReportsDir
    • jsonReportsDir
    • txtReportsDir
  • Applies and configures reporting-base plugin

    Redirects all reports to build/reports/<format> directory.

    Known limitation: gradle --profile reports are not redirected. They stay in build/reports/profile directory for now. See #1

Build Diagnostics and Troubleshooting

  • Applies plugins:

  • Provides inputsOutputs task which generates reports about all task file inputs and outputs

All these tasks are put into Diagnostics group.

Other features

  • Applies and configures com.jfrog.artifactory plugin

    Allows us to publish artifacts and build info to FIDATA Artifactory .

  • Sets project's group to org.fidata if it hasn't been set already

  • Provides license property used by other plugins

    It should be set with SPDX license identifier .

  • Provides generateChangelog and generateChangelogTxt tasks that generate changelog in Markdown and text formats in build/changelog directory

    The main usage is to check generated changelog during release preparation to make sure that everything is correct.

  • Provides tags property used by other plugins

  • Applies nebula.contacts plugin

    Provides contacts extension.

Git Workflow

Earlier in the history we tried to use GitFlow. But it didn't work out well. GitHub doesn't support fast-forward merges. So, there was a big mess each time we merged from develop to master. Also, this led to unnecessary rebuilds on Jenkins.

Our current workflow resembles GitHub workflow and OneFlow.

  • We make all development in feature/… and hotfix/… branches, and maybe branches with some other prefixes

  • All work is merged to master via PRs with merge commits

  • master should be release-able any time. But actual releases are manually triggered. Gradle's release task will make a release only when shouldRelease project property is passed and set to true. This could be done from command line, like ./gradlew release -PshouldRelease=true, of manually via parameter of Jenkins build.

  • We don't have develop branch with the same purpose as in GitFlow. But we can use develop branch for general/various improvements when there is no unique feature or hotfix to describe changes. In this case we merge PR with rebase merging

  • We don't use release branches and don't support several major/minor releases simultaneously

buildSrc projects

Plugin can be applied to buildSrc projects. However, buildSrc projects can't have releases and documentation, so all related features are turned off. They also don't publish build info to Artifactory.

They could have code quality and diagnostic tasks, but usage of them is discouraged. Note that all buildSrc's Gradle and Groovy scripts are already covered by codenarcBuildSrc task.

Project gets isBuildSrc read-only property which will be set to true when buildSrc project is detected.

Supported tools versions:

  • Requires Gradle >= 5.1

  • Built and tested with JDK 8

  • Requires GnuPG >= 2.1

    gpg-agent should have allow-preset-passphrase option turned on if GPG key with passphrase is used. It is usually achieved by adding this string into gpg-agent.conf file in GPG home directory.

    gpg-preset-passphrase should be available in the path.

org.fidata.base.jvm plugin

Project which uses JVM-based language. This plugin should not be applied manually.

Applies org.fidata.project plugin, and also:

  • Applies java-base and java-library plugins

  • Provides jvm extension. This extension has one property javadocLinks.

    It contains links to external documentation used by javadoc and groovydoc. If a dependency is added automatically, its documentation is also added here automatically. Otherwise, you add link manually, like this:

    jvm.javadocLinks['com.example.super.cool.external.library'] = uri('https://example.com/javadoc/com/example/super.cool.external.library/1.0/')
    
  • Adds mavenJava publication (except when org.fidata.plugin is applied)

Testing

  • Adds JUnit dependency to testImplementation configuration

  • Adds and configures functionalTest source set and task which uses Spock framework

    Also adds Spock Reports.

    JUnit is also available whenever Spock is.

Artifact Publishing

  • Applies maven-publish plugin

    Configures Maven publication to Artifactory.

    If publicReleases is on — configures publication to Maven Central.

  • If publicReleases is on — applies com.jfrog.bintray plugin and configures publication to JCenter

Code Quality

  • Provides findbugs and jdepend tasks that run all FindBugs and JDepend tasks respectively.

    Includes these tasks in execution list for lint task.

Other features

  • Adds license file(s) into JAR META-INF directory

org.fidata.project.java plugin

Java language project.

Applies org.fidata.base.jvm plugin, and also:

  • Applies java plugin

  • Applies io.franzbecker.gradle-lombok plugin providing Lombok for Java sources

  • Configures javadoc to parse sources through Delombok first

  • Adds javadoc output to GitHub Pages publication

  • Provides checkstyle task that run all Checkstyle tasks.

    Includes this task in execution list for lint task.

org.fidata.base.groovy plugin

Project which uses Groovy language. This plugin should not be applied manually.

Applies org.fidata.base.jvm plugin, and also:

org.fidata.project.groovy plugin

Groovy language project.

Applies org.fidata.base.groovy plugin, and also:

  • Applies groovy plugin

  • Adds local Groovy to api configuration

  • Adds groovydoc output to GitHub Pages publication

org.fidata.plugin plugin

Gradle plugin project.

This plugin depends on at least one of JVM-based project plugins:

or others developed later.

They have to be applied manually depending on the language(s) used in the project.

Properties

Should be provided in standard Gradle ways .

PropertyRequiring PluginUsageNotes
artifactoryUser org.fidata.projectGetting build tools and dependencies from Artifactory; use Gradle cache 
artifactoryPassword It is actually API key
gitUsername Git push during release 
gitPassword  
ghToken Create release on GitHub 
gpgKeyId Sign artifacts, git commits and git tags 
gpgKeyPassphrase Not required. Assumes no passphrase if not provided
mavenCentralUsernameorg.fidata.base.jvm for public releasesRelease to Bintray 
mavenCentralPassword  
bintrayUser org.fidata.base.jvm for public releasesRelease to Bintray 
bintrayAPIKey  
gradlePluginsKey org.fidata.plugin for public releasesRelease to Gradle Plugins portal 
gradlePluginsSecret  

All properties except gpgKeyPassphrase are required. The plugin won't work if they are not set.

Multi-project Builds (a.k.a Monorepo)

These plugins supports multi-project builds in the following configuration:

  1. All child projects have the same version as the root one. This is the limitation imposed by de.gliderpilot.semantic-release plugin.

  2. org.fidata.project should be applied to root. It applies itself to each subproject

  3. de.gliderpilot.semantic-release and org.ajoberstar.git-publish plugins are applied to root only.

  4. The following properties are available for root project only:

    • isBuildSrc
    • isRelease
    • changeLog
    • changeLogTxt
    • issuesUrl
    • vcsUrl

    Except these, all other is configurable per project.

    Note that subprojects can have different licenses, and license file(s) (being included in JARs) are per project.

  5. Reports for all subprojects are redirected to build/reports/<format>/<subproject> directory. This is made for convenient usage under CI (Jenkins)

Development

This is self-applying plugin. That means that build script requires the plugin itself (just compiled, not released to the repository). So, if there are any errors during compilation or plugin applying, Gradle build script just doesn't work. If it is a compilation error, you can run ../gradlew build in buildSrc directory to figure out what's going on.

Upgrading Gradle Version

Whenever new Gradle version is released, the way to upgrade is this:

  1. Read Release Notes and make necessary changes to the code
  2. Run ./gradlew stutterWriteLock
  3. Run ./gradlew compatTest<new Gradle version>
  4. Change Gradle version for wrapper task in plugin code
  5. Run ./gradlew wrapper && ./gradlew wrapper

If a new version of a plugin won't be compatible with previous Gradle versions:

  1. Update ProjectPlugin.GRADLE_MINIMUM_SUPPORTED_VERSION value
  2. Run ./gradlew stutterWriteLock
  3. Update required Gradle version in this README file

Copyright © Basil Peace

This file is part of gradle-base-plugins.

Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.

gradle-base-plugins's People

Contributors

grv87 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

gradle-base-plugins's Issues

Move `gradle --profile` reports to correct directory

gradle --profile reports are not redirected. There is no built-in way to do this. They stay in build/reports/profile directory. See org.gradle.profile.ReportGeneratingProfileListener source code.
But we still could move them where they should be.

Mark some classes as non-public API

So that changes in them wouldn't be considered as breaking changes.
Like Dependee classes.
For example, put @groovy.transform.Internal annotation.

Maybe, find a tool to detect public API changes and use its mechanism.

Scan each Gradle build

build scan plugin 1.12+ ?

buildScan {
    termsOfServiceUrl = 'https://gradle.com/terms-of-service'
    termsOfServiceAgree = 'yes'
	publishAlwaysIf(boolean)
	tag ?
	
	extra info ?
}

Don't use latest.release versions

Use ranges with fixed major instead.
Lombok should be 1.18.1+ (https://github.com/rzwitserloot/lombok/issues/1782).
xercesImpl 2.12.0+

Multiple SLF4J in tests

In functionalTest, compatTest:

org.fidata.gradle.GroovyProjectPluginSpecification STANDARD_ERROR
    SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:/C:/Users/Basil/.gradle/caches/4.9/generated-gradle-jars/gradle-api-4.9.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:/C:/Users/Basil/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-simple/1.7.25/8dacf9514f0c707cbbcdd6fd699e8940d42fb54e/slf4j-simple-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:/C:/Users/Basil/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-slf4j-impl/2.10.0/8e4e0a30736175e31c7f714d95032c1734cfbdea/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual binding is of type [org.gradle.internal.logging.slf4j.OutputEventListenerBackedLoggerContext]

Improve tests

  • Specification -> Spec
  • labels — on the same line
  • use closures in data tables
  • use GradleRunner instead of compatTest whenever appropriate
  • compatTest - ugly tests (task to print list of tasks…)
  • task -> taskName
  • testProjectDir vs project
  • FIDATA/common#6
  • Make sure that offline mode is respected in tests
  • Cut out test fixtures in separate artifact / project to use them in other projects too

Add VisTEG report on Jenkins

                dir('build/reports/png/assemble') {
                  exec 'dot -Tpng ../visteg.dot -o ./visteg.dot.png'
                }
                publishHTML(target: [
                  reportName: 'VisTEG : assemble',
                  reportDir: 'build/reports/png/assemble',
                  reportFiles: 'visteg.dot.png',
                  allowMissing: true,
                  keepAll: true,
                  alwaysLinkToLastBuild: false /* TODO: determine if we are on develop HEAD */
                ])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.