com.github.bordertech.common:qa-parent

Quality assurance configuration for BorderTech java projects. Note that projects inheriting from this POM also inherit the release configuration from bordertech-parent.


License
MIT

Documentation

java-common

Status

Build Status Quality Gate Status Reliability Rating Codacy Badge Maven Central

Content

What is java-common

Reusable build configuration and parent pom modules for BorderTech open source projects.

Why use java-common

  • Simplifies the steps to release your project to Maven Central
  • Enforce quality assurance and security checks on your project code

Getting started

java-common provides two parent pom modules:

Projects should generally use qa-parent as their parent POM:

<project>
  ....
  <parent>
    <groupId>com.github.bordertech.common</groupId>
    <artifactId>qa-parent</artifactId>
    <version>1.0.20</version>
  </parent>
  ....
</project>

By default qa checks do not run, you must enable them on a per-module basis or in your project parent pom:

<property>
  <bt.qa.skip>false</bt.qa.skip>
</property>

The qa-parent default is to fail the build if QA violations are found. This can be overridden by setting the following property:

<property>
  <bt.qa.fail>false</bt.qa.fail>
</property>

Use the following to run the qa-parent verification:

mvn verify

Releasing

If using maven release ensure the necessary POM sections are overriden - these are marked in the bordertech-parent pom, for example:

<!--
  Descendants SHOULD override the url.
-->
<url>https://github.com/bordertech/java-common/</url>

Once you have configured your project and environment you can release to Maven Central.

The golden rule for releasing is ALWAYS do the release on a separate branch (it makes backing out much easier when problems arise).

Full documentation is available in the wiki under Releasing.

Features

bordertech-parent

This is the top-level pom.xml file.

It configures the maven release plugin for projects to release to Maven Central.

Note that java projects should generally not consume this directly but instead should use qa-parent as a parent POM instead.

qa-parent

The qa-parent runs quality assurance checks on your java code using tools such as:

The qa-parent also runs:

The qa-parent inherits all of the release functionality from bordertech-parent.

quick-build profile

The qa-parent provides a profile quick-build that for convenience skips all tests and QA. This is very useful when developing a project and a quick build of the project is required.

display-versions profile

The qa-parent provides a profile display-versions that uses the Version checker plugin to report project dependencies that have new versions.

Refer to Version checker plugin for all override details.

build-tools

This is primarily a shared resources module used by qa-parent and potentially other BorderTech maven modules.

Configuration

bordertech-parent config

Refer to bordertech-parent's pom.xml for all project properties.

Projects must ensure the necessary POM sections are overriden - these are marked in the bordertech-parent pom, for example:

<!--
  Descendants SHOULD override the url.
-->
<url>https://github.com/bordertech/java-common/</url>

qa-parent config

Refer to qa-parent's pom.xml for all project properties.

Refer to the plugin sections below for basic override details:

Enable Quality Checks

By default qa checks (i.e. Checkstyle, PMD, Spotbugs, OWASP, Convergence Check) do not run, you must enable them on a per-module basis or the project parent pom:

<property>
  <bt.qa.skip>false</bt.qa.skip>
</property>

Failing Build with QA Violations

The qa-parent default is to fail the build if QA violations are found. This can be overridden by setting the following property:

<property>
  <bt.qa.fail>false</bt.qa.fail>
</property>

Generated Sources

By default, qa-parent configures the code analysis plugins to ignore generated source code and only analyse the project's main source directory.

The following properties are set in qa-parent for Checkstyle and PMD:

<property>
  <bt.checkstyle.src>${project.build.sourceDirectory}</bt.checkstyle.src>
  <bt.pmd.src>${project.build.sourceDirectory}</bt.pmd.src>
</property>

Spotbugs is different from Checkstyle and PMD as it requires an exclude filter to be configured to ignore generated files.

The following properties are set in qa-parent for Spotbugs:

<property>
  <!-- Exclude files in the generated-sources directory -->
  <spotbugs.excludeFilterFile>bordertech/bt-spotbugs-exclude-generated-files.xml</spotbugs.excludeFilterFile>
  <!-- Need to add sources for source tag in exclude and include filters to work -->
 <spotbugs.addSourceDirs>true</spotbugs.addSourceDirs>
</property>

Checkstyle

Refer to Checkstyle plugin for all override details.

Skip Checkstyle
<property>
  <checkstyle.skip>true</checkstyle.skip>
</property>
Change or Add Checkstyle Rules

The checkstyle config defaults to bordertech/bt-checkstyle.xml. This config is based on sun-checks.xml provided by checkstyle.

To add or change a checkstyle rule you are required to create your own config.xml file and set the checkstyle.config.location property.

<property>
  <checkstyle.config.location>${basedir}/my-checkstyle-config.xml</checkstyle.config.location>
</property>
Ignore Checkstyle Rule

Create a suppression file add set the checkstyle.suppressions.location property.

<property>
  <checkstyle.suppressions.location>${basedir}/my-suppression.xml</checkstyle.suppressions.location>
</property>

Example suppression file:-

<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.0//EN" "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
<suppressions>
  <!-- Ignores for all files -->
  <suppress checks="NPathComplexity" files="."/>
</suppressions>

PMD and CPD

Refer to PMD plugin for all override details.

Skip PMD and CPD
<property>
  <pmd.skip>true</pmd.skip>
  <cpd.skip>true</cpd.skip>
</property>
Change PMD Rule Set

The default rule set is bordertech/bt-pmd-rules.xml.

You can override the default by creating your own custom rule set and set the bt.pmd.rules.file property.

<property>
  <bt.pmd.rules.file>${basedir}/my-rules.xml</bt.pmd.rules.file>
</property>
Add extra PMD Rule set

An extra rule set can be added via the plugin rulesets configuration.

<plugin>
  ...
  <configuration>
    <rulesets>
      <ruleset>${bt.pmd.rules.file}</ruleset>
      <ruleset>${basedir}/my-rules.xml</ruleset>
    </rulesets>
  </configuration>
  ...
</plugin>
Ignore PMD Rule

Create an excludes file that lists classes and rules to be excluded from failures and set the pmd.excludeFromFailureFile property.

<property>
  <pmd.excludeFromFailureFile>${basedir}/my-pmd-excludes.properties</pmd.excludeFromFailureFile>
</property>

Example properties file:

com.my.example.MyClass=LoggerIsNotStaticFinal

Spotbugs

Refer to spotbugs plugin or doco for all override details.

Skip spotbugs
<property>
  <spotbugs.skip>true</spotbugs.skip>
</property>
Ignore Spotbugs Rule

Create a filter file and set spotbugs.excludeFilterFile property.

<property>
  <!-- List of exclude filter files -->
  <spotbugs.excludeFilterFile>${basedir}/my-spotbugs-exclude-file.xml</spotbugs.excludeFilterFile>
</property>

Example filter file:-

<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
  <!-- False Positive on Loading Property Filenames -->
  <Match>
    <Bug pattern="PATH_TRAVERSAL_IN" />
  </Match>
</FindBugsFilter>

When adding a custom exclude filter and the module still needs to ignore generated source, then merge the excludes used in the default filter bt-spotbugs-exclude-generated-files:

<FindBugsFilter>
  <!-- Exclude files in the generated-sources directory. For the source tag to work with the full path of the source files the addSourceDirs property on the plugin must be set to true. -->
  <Match>
    <Source name="~.*generated-sources.*" />
  </Match>
</FindBugsFilter>

OWASP

Refer to OWASP plugin for all override details.

Skip OWASP
<property>
  <dependency-check.skip>true</dependency-check.skip>
</property>
Ignore OWASP Rule

Create a suppression file add set the suppressionFiles property.

<property>
  <suppressionFiles>${basedir}/my-owasp-suppressions.xml</suppressionFiles>
</property>

Example suppression file content:

<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
  <suppress>
    <notes>
      <![CDATA[
          Example to suppress a specific CVE.
      ]]>
    </notes>
    <cve>CVE-2019-12814</cve>
  </suppress>
</suppressions>
Using OWASP behind a Proxy

If you are behind a Proxy then the OWASP plugin needs to be told which proxy to use. You can set the mavenSettingsProxyId property in your settings.xml to the appropriate PROXY-ID (which is usually defined in the same settings.xml).

<properties>
  <mavenSettingsProxyId>MY-PROXY-ID</mavenSettingsProxyId>
</properties>

Updating the OWASP vulnerability database can also be blocked by the PROXY blocking HTTP HEAD requests. To work around this you will need a command line option: -Ddownloader.quick.query.timestamp=false

Enforcer Plugin

Refer to enforcer plugin for all override details.

Skip enforcer convergence check
<property>
  <bt.convergence.check.skip>true</bt.convergence.check.skip>
</property>
Report issues but dont fail
<property>
  <bt.convergence.check.fail>false</bt.convergence.check.fail>
</property>

JaCoCo

Refer to JaCoCo plugin for all override details.

Skip JaCoCo
<property>
  <jacoco.skip>true</jacoco.skip>
</property>

Surefire

Refer to Surefire plugin for all override details.

Skip Surefire
<property>
  <skipTests>true</skipTests>
</property>

Build tools module for override artefacts

If your project has multiple modules and you want to provide the same override/exclude files for all the submodules, then a good solution is to use a build-tools module similar to java-common/build-tools.

Once you have created a build-tools submodule, define the plugins you want to override in the project parent pom with the custom build-tools module as a dependency.

<!-- Example of adding a custom build-tools module to spotbugs -->
<plugin>
  <groupId>com.github.spotbugs</groupId>
  <artifactId>spotbugs-maven-plugin</artifactId>
  <dependencies>
    <!-- My project build-tools module. -->
    <dependency>
      <groupId>com.my.project</groupId>
      <artifactId>build-tools</artifactId>
      <version>1.0.0-SNAPSHOT</version>
    </dependency>
  </dependencies>
</plugin>

Contributing

Refer to these guidelines for Workflow and Releasing.