Brightspot Gradle Plugins

A set of Gradle plugins to manage building Brightspot projects.

Requires Gradle 8.4 or higher. Requires Java 11 or higher to build, but can build Java 8 classes if desired; see below for configuring the project’s Java version.

Table of contents
  1. Brightspot Gradle Plugins
    1. Typical usage
      1. Setup
      2. Parameters
        1. buildNumber
        2. codePath
        3. Gradle build cache
        4. release
    2. Additional configuration
      1. Bundle
      2. Version catalog
      3. General settings
      4. Javadoc annotations
      5. Publishing
      6. Shared Tests
      7. SonarQube
      8. Viewgen
      9. WAR file
    3. Frequently asked questions
    4. Custom usage

Typical usage

Setup

settings.gradle

pluginManagement {
    repositories {
        gradlePluginPortal() {
            content {
                excludeGroupByRegex 'com\\.brightspot($|\\..+)'
                excludeGroupByRegex 'com\\.psddev($|\\..+)'
            }
        }
        maven {
            url 'https://artifactory.psdops.com/public'
        }
    }
}

plugins {
    id 'com.brightspot.gradle' version '3.3.0'
}

dependencyResolutionManagement {
    versionCatalogs {
        brightspotLibs {
            library('brightspot', 'com.psddev:brightspot-bom:4.8.1')
            library('brightspotDependencies', 'com.psddev:brightspot-dependencies:4.8.1')

            library('brightspotGo', 'com.brightspot.go:bom:1.7.0')
            library('brightspotGoDependencies', 'com.brightspot.go:go-dependencies:1.7.0')

            library('brightspotSharedTests' , 'com.brightspot.shared-tests:bom:1.4.0')

            library('componentLib', 'com.psddev.component-lib:bom:4.5.33')
            library('componentLibDependencies', 'com.psddev.component-lib:cl-dependencies:4.5.33')

            library('brightspotMigration', 'com.psddev.migration:bom:4.8.1')
            library('brightspotMigrationDependencies', 'com.psddev.migration:dependencies:4.8.1')
        }
    }
}

brightspot {
    projectGroup = 'com.project-group'

    versions {
        java = 11
    }
}

core/build.gradle

plugins {
    id 'com.brightspot.java-core'
}

dependencies {
    sharedTest 'com.brightspot.shared-tests:pack-standard-backend-unit-tests'
}

frontend/build.gradle

plugins {
    id 'com.brightspot.viewgen'
}

All bundle build.gradle files (typically under frontend/bundles/)

plugins {
    id 'com.brightspot.bundle'
}

bundle {
    yarnBuildCommand = 'build'
    styleguideOutputDir = 'styleguide'
    zipOutputPath = 'theme.zip'

    // for CdnCssTest
    cdnCssFiles = [
        'styles/default/All.min.css'
    ]
}

node {
    version = '18.17.1'
    yarnVersion = '1.22.19'
    download = true
}

dependencies {
    sharedTest 'com.brightspot.shared-tests:pack-standard-frontend-unit-tests'
}

web/build.gradle (or site/build.gradle)

plugins {
    id 'com.brightspot.war'
}

dependencies {

    // for expansion into the WAR file
    compileOnly 'com.psddev:cms-tool-ui'

    // Tests
    sharedTest 'com.brightspot.go:lib-util-gradle-dynamic-test'
    sharedTest 'com.brightspot.shared-tests:pack-standard-backend-integration-tests'
}

Parameters

buildNumber

This is output in the generated build.properties and is for informational purposes. Set as a command-line argument; if not given, defaults to local.

./gradlew -PbuildNumber=123 build

codePath

This is used to generate code paths in the generated build.properties file and is required for reloader support in local development. Typically, it is set in the gradle.properties file; typical value is /code. If not given, defaults to the project’s root directory.

gradle.properties

systemProp.codePath=/code

Gradle build cache

To enable writing to the remote build cache, set the following environment variables:

  • GRADLE_CACHE_USERNAME
  • GRADLE_CACHE_PASSWORD

These should only be set on the CI server, as it is generally unsafe for local development builds to write to a shared cache.

To disable local cache for a single run, pass -DdisableLocalCache:

./gradlew -DdisableLocalCache build

To disable remote cache for a single run, pass -DdisableRemoteCache:

./gradlew -DdisableRemoteCache build

Note that this overrides the remoteCacheEnabled setting in gradleCache extension.

release

This is used to mark the build as producing a release. It sets the release version for the project and may trigger release-specific behavior, such as changing the Maven repository for publishing artifacts. Set as a command-line argument; if not given, the version defaults to the project version configured in settings.gradle.

./gradlew -Prelease=1.0.0 build

Additional configuration

Bundle

The following settings are available in all bundle build.gradle files (typically under frontend/bundles/) - i.e. any build.gradle file with the com.brightspot.bundle plugin applied.

yarnBuildCommand

Yarn command to build the bundle, from "scripts" in package.json; required, typically should be 'build'.

bundle {
    yarnBuildCommand = 'build'
}

styleguideOutputDir

Output directory for the bundle styleguide directory, relative to the subproject’s build directory. Required, typically should be 'styleguide'. This value probably comes from an argument of the build command in "scripts" in package.json.

bundle {
    styleguideOutputDir = 'styleguide'
}

zipOutputPath

Output path for the bundle zip, relative to the subproject’s build directory. Required, typically should be 'theme.zip'. This value probably comes from an argument of the build command in "scripts" in package.json.

bundle {
    zipOutputPath = 'theme.zip'
}

cdnCssFiles

Specifies CSS files to test with CdnCssTest. Paths are relative to the root of the generated zip file. This value will be set as the theme.*.cdnCssFiles build system property, which is read by CdnCssTest.

bundle {
    cdnCssFiles = [
        'path/to/All.min.css',
        'path/to/another/File.css'
    ]
}

testMode

Mode for ThemeCompatibilityTest. Possible values are 'disable', 'error', and 'warn'; defaults to 'error'. This value will be set as the theme.*.compatibilityTestMode build system property, which is read by ThemeCompatibilityTest.

bundle {
    testMode = 'warn'
}

compatibilityTestExcludedPaths

Excludes specific JSON files from ThemeCompatibilityTest. Paths are relative to the root of the generated zip file. This value will be set as the theme.*.compatibilityExcludedPaths build system property, which is read by ThemeCompatibilityTest.

Note that all files not explicitly included in the Styleguide navigation are excluded automatically.

bundle {
    compatibilityTestExcludedPaths = [
        'path/to/some/ignored/file.json'
    ]
}

Root styleguide dependency

Pointer to the root styleguide, used by ThemeCompatibilityTest. Defaults to the unique Gradle subproject with the plugin com.brightspot.viewgen; if the default value doesn’t work, you probably have an error in your Gradle setup.

dependencies {
    rootStyleguide project(path: ':frontend', configuration: 'rootStyleguideDir')
}

Version catalog

You must set your Brightspot dependencies in the version catalog named brightspotLibs, but other dependencies could go in a separate catalog if necessary or preferred. The following aliases are used:

brightspot and brightspotDependencies: these determine your Brightspot version by configuring the main Brightspot BOM (com.psddev:brightspot-bom) as well as the Brightspot dependencies BOM (com.psddev:brightspot-dependencies). Their versions must match exactly.

brightspotGo and brightspotGoDependencies: these determine your Brightspot Go version by configuring the main Brightspot Go BOM (com.brightspot.go:bom) as well as the Brightspot Go dependencies BOM (com.brightspot.go:go-dependencies). Their versions must match exactly. Configure these only if you are using Brightspot Go com.brightspot.go:lib-* dependencies.

brightspotSharedTests: this configures the Brightspot Shared Tests BOM (com.brightspot.shared-tests:bom).

componentLib and componentLibDependencies: these determine your Component Lib version by configuring the main Component Lib BOM (com.psddev.component-lib:bom) as well as the Component Lib dependencies BOM (com.psddev.component-lib:cl-dependencies). Their versions must match exactly. Configure these only if you are using Component Lib com.psddev.component-lib:* dependencies.

brightspotMigration and brightspotMigrationDependencies: these determine your Brighspot Migration version by configuring the main Brightspot Migration BOM (com.psddev.migration:bom) as well as the Brightspot Migration dependencies BOM (com.psddev.migration:dependencies). Their versions must match exactly. Configure these only if you are using Brightspot Migration.

You can set up Dependabot to automatically create PRs to upgrade any dependencies you declare in the version catalogs in dependencyResolutionManagement.

General settings

The following are additional settings configurable in settings.gradle.

projectGroup

Group used for generated artifacts; required.

brightspot {
    projectGroup = 'com.project-name'
}

dependencyConstraints

This is the preferred way to enforce a specific version for a dependency, as enforced BOMs will probably override other ways of specifying constraints.

brightspot {
    dependencyConstraints = [
        'com.some-group:some-artifact-in-use': '1.2.3',
    ]
}

dependencySubstitutions

Augment, override, or remove default dependency substitutions.

brightspot {
    dependencySubstitutions = [
        // add additional substitution
        // or override default
        'com.some-group:some-artifact': 'com.some-preferred-group:some-preferred-artifact:1.0.0',

        // remove default substitution (or previous substitution above)
        'com.some-group:some-other-artifact': ''
    ]
}

dependencyExclusions

Exclude dependencies from the build.

brightspot {
    dependencyExclusions = [
        'com.some-group:some-unwanted-artifact',
    ]
}

classEnhancers

Specify custom ClassEnhancers to use; defaults to ['com.psddev.dari.db.LazyLoadEnhancer', 'com.psddev.dari.db.QueryCommentEnhancer']. If you are running Brightspot 4.7.3 or higher, you can add 'com.psddev.dari.util.JavadocEnhancer'.

brightspot {
    classEnhancers = [
        'com.psddev.dari.db.LazyLoadEnhancer',
        'com.psddev.dari.db.QueryCommentEnhancer',
        'com.psddev.dari.util.JavadocEnhancer'
    ]
}

Gradle cache configuration

Caching using both local cache and Brightspot’s Gradle cache server is configured by default. Be advised that you still have to explicitly enable build cache with either the --build-cache command-line argument, the org.gradle.caching Gradle property, or some other means.

You can override the defaults in settings.gradle:

url: url of remote cache to use; defaults to 'https://cache.gradle.psdops.com/cache/'.

brightspot {
    gradleCache {
        url = 'https://example.com/cache/'
    }
}

remoteCacheEnabled: whether the remote cache should be used; defaults to true. When false, only the local cache will be used, if build cache is enabled. This is overridden by the -DdisableRemoteCache command-line argument.

brightspot {
    gradleCache {
        remoteCacheEnabled = false
    }
}

Version specification

enforcePlatform: whether to use enforcedPlatform or platform to apply the BOM versions specified in the brightspotLibs version catalog; defaults to true (i.e. use enforcedPlatform). Libraries will need to set this to false, but regular projects can use the default.

brightspot {
    versions {
        enforcePlatform = false
    }
}

java: version of Java used for compiling classes, and the Java version those classes will be compatible with; required.

brightspot {
    versions {
        java = 8
    }
}

project: version applied to project artifacts; defaults to '1.0.0-SNAPSHOT'.

brightspot {
    versions {
        project = '2.0.0-SNAPSHOT'
    }
}

basePrefix: prefix applied to non-BOM subproject versions; defaults to unset - only library projects with a BOM should set this.

brightspot {
    versions {
        basePrefix = '2.0'
    }
}

Javadoc annotations

Requires Brightspot 4.7.3+ and Gradle plugins 3.2.1+

core/build.gradle, web/build.gradle, and similar - i.e. build.gradle for any subproject which builds Java source files.

dependencies {
    annotationProcessor 'com.psddev:javadoc-annotationprocessor'
}

frontend/build.gradle

dependencies {
    annotationProcessor 'com.psddev:javadoc-annotationprocessor'
}

// this is optional; it will run whatever classEnhancers are configured in settings.gradle otherwise
brightspot {
    classEnhancers = [
        'com.psddev.dari.util.JavadocEnhancer'
    ]
}

settings.gradle

brightspot {
    classEnhancers = [
        'com.psddev.dari.db.LazyLoadEnhancer',
        'com.psddev.dari.db.QueryCommentEnhancer',
        'com.psddev.dari.util.JavadocEnhancer'
    ]
}

Publishing

For subprojects that use BOM versioning, the calculated Git hash version can be incremented like so:

gitHashVersion {
    commitCountOffset = 1
}

This is needed when a subproject’s location is moved within its Git repo, which will reset its commit count.

Shared Tests

These settings are available in any build.gradle with the com.brightspot.shared-tests plugin applied.

classesDirs

Location of subproject-specific compiled classes to execute shared tests against; defaults to classesDirs of the main source set output, or, if EnhanceClassesPlugin is applied, to the enhanced-classes directory. Paths need to be relative to the subproject directory for cacheability.

sharedTests {
    classesDirs = [
        project.getProjectDir().toPath().relativize(project.getBuildDir().resolve('classes').resolve('java').resolve('main'))
    ]
}

allClassesDirs

Locations of compiled classes for the entire Gradle project. Pulls from the projectJars configuration, which defaults to all dependency JARs of the current subproject which are part of the broader Gradle project.

SonarQube

settings.gradle

plugins {
    id 'com.brightspot.sonar' version '3.3.0'
}

Be sure the version exactly matches your main Gradle plugins version (i.e. whatever you have configured for com.brightspot.gradle).

Manual configuration

If you prefer, you can manually apply SonarQube plugins to individual subprojects.

core/build.gradle and similar:

plugins {
    id 'com.brightspot.sonar-java'
}

All bundle build.gradle files:

plugins {
    id 'com.brightspot.sonar-frontend'
}

Root build.gradle file (create if it doesn’t exist):

plugins {
    id 'org.sonarqube' version '5.1.0.4882'
}

Viewgen

frontend/build.gradle

styleguideDir

Location of the root styleguide directory, relative to the subproject directory; defaults to 'styleguide'.

viewgen {
    styleguideDir = '../styleguide'
}

WAR file

web/build.gradle (or site/build.gradle)

Note the war { } block MUST go after the brightspotWar { } block in the site/build.gradle or web/build.gradle file.

applyDefaultExclusions

Whether to exclude the default set of JAR files from the WAR file; defaults to true. If false, you are responsible for excluding everything that is provided by Tomcat.

brightspotWar {
    applyDefaultExclusions = false
}

Projects running on Brightspot Cloud can almost certainly accept the default exclusions. Non-Cloud projects should not exclude slf4j-api.

For reference, these are the default exclusions:

war {
    rootSpec.exclude '**/javax.el-api'
    rootSpec.exclude '**/javax.servlet-api-*.jar'
    rootSpec.exclude '**/javax.servlet.jsp-api-*.jar'
    rootSpec.exclude '**/mysql-connector-java-*.jar'
    rootSpec.exclude '**/slf4j-api-*.jar'
    rootSpec.exclude '**/slf4j-jdk14-*.jar'
}

WAR file name

For regular builds, the WAR file name doesn’t include the version, to simplify configuration of the local Docker Compose setup. For release builds, the WAR file name includes the release version, which makes tracking build artifacts easier.

Frequently asked questions

How do I add mavenLocal()?

Create the build.gradle file in the project root (if it doesn’t exist) and add the following:

subprojects {
    repositories {
        mavenLocal()
    }
}

Note that adding Maven local can interfere with caching so is only recommended as a temporary configuration while testing something. See Gradle’s documentation for more details.

How do I add a custom repository?

Create the build.gradle file in the project root (if it doesn’t exist) and add the following:

subprojects {
    repositories {
        maven {
            url = 'https://example.com'

            // only if required
            credentials {
                // these must be set as GitHub repo secrets
                // and then loaded as environment variables in the GitHub Actions workflow
                username = System.getenv('SOME_REPO_USERNAME')
                password = System.getenv('SOME_REPO_PASSWORD')
            }
        }
    }
}

How do I enforce an additional BOM?

Create the build.gradle file in the project root (if it doesn’t exist) and add the following:

subprojects {
    apply plugin: 'java'

    dependencies {
        implementation enforcedPlatform("com.example:bom:1.0.0")
    }
}

How do I fix this error?

Expected configuration ':web:compileClasspath' files to contain exactly one file, however, it contains no files.

This means you are missing the com.psddev:cms-tool-ui dependency in site/build.gradle or web/build.gradle. Add the following to that file:

dependencies {
    // for expansion into the WAR file
    compileOnly 'com.psddev:cms-tool-ui'
}

Custom usage

All functionality is broken down in to discrete plugins which you can use individually if the standard plugins mentioned above are not appropriate for your project’s needs. See the javadocs on each plugin for details on what it does and how to configure it.