This is a work in progress page, hopefully that will be built as we progress with the projects. For now, holds some scraps of information.

Anything noted here with respect to Git repositories applies to project repositories, not *.github.io site repositories or other script/ancillary repositories.

Git Repository Layout

The projects are laid out as a single Git repository with Maven multi-module project layout. All SCM (Git) and Build (Maven) operations are executed at the parent project directory.

Branches & (protected) branches

A full branching strategy / plan is in the works, for now these are some ideas. Basic ideas include:

  • All development happens on public feature or bugfix branches
  • Use local branches and squash commits to public branches
  • Release trains run on their own branches.

master

This is a protected branch; so direct commits to this branch are not possible, neither is it possible to merge anything to this branch directly without certain checks, currently:

  • Clean merge (without conflicts)
  • Travis CI build pass on the other branch (or pull request)
  • AppVeyor build pass on the other branch (or pull request) (if the project uses AppVeyor)

NOTE/TODO: We still have to clarify how the interaction between master and release branches will work.

gh-pages

This is of course the special GitHub pages orphan branch from which we serve this website. All the content of this branch is generated by maven. If static files like CNAME are required; they should be placed in the src/site/resources folder of the regular branch from which the site is generated.

TODO: On Site Generation

  • Automate site generation / deployment
  • Think about what to do if we want to support multi-version sites (major versions).
  • Think about how to handle .* files (like .gitignore); these do not get copied over by the site plugin.

release/* branches

  • Branch Off From: master if on the same Major version; or the highest release/* branch of the same Major version.
  • Merge Back Into: master only if on the same Major version.
  • Lifetime: Stays forever
  • Protected: Yes (basic). May not need to require Status Checks.

This is a branch from which release are created. The branch is created when we are about ready to create a new Minor release. Only a very few changes (like version update, site update, blocker fixes) are expected on this branch between the time the branch is created and the first release in that Major/Minor series is created. The release is of course tagged (and the tag should be cryptographically signed, see -s or -u <key> flags).

After the release is completed, the content should be merged back into master, unless master has moved on to the next Major. If master has moved on, selective / appropriate fixes need to be cherry picked into a feature / bug fix branch and merged into master and any other appropriate release/* branch.

If a Patch release is required on that Major/Minor, changes can be made on the branch or on a feature/* or bugfix/* branch; release created and tagged. After the release the changes are to be merged back to master (using the same rules as above) and any other release/* branch in the higher Minor branches in the same or higher Major versions.

release/-alpha.x and release/-beta.x branches

For releases with major or multiple features we may want intermediate alpha or public testing beta release. To create these releases, release/*-alpha.x and release/*-beta.x branches may be created.

These branches are very similar to the release/* branches, except:

  • The releases created from the branch are not feature complete, hence multiple merges happen to the branch from master (feature/*masterthis branch; bugfix/*release/*masterthis branch; etc.) or feature/* branches.
  • There are usually no Patch releases from these branches as any changes/fixes are simply rolled into the next alhpa or beta release.

feature/* and bugfix/* branches

  • Branch Off From: master or release/*
  • Merge Back Into: master or release/* where branched from; or multiple. No FF
  • Lifetime: Time to develop the feature, may involve one or more merges back into the source.
  • Protected: Temporary (no status checks) to avoid data loss.

This is a branch to develop a single (or multiple related) feature(s) or bug fix(es); and once everything is done the contents are merged back into where we started from or into multiple branches. Once all done, feel free to delete the branch.

Note: Since this branch is expected to be deleted at some point, make sure the merge from this branch to master or one or more release/* branches is done without a Fast Forward (git merge --no-ff).

Git Settings

The following minimal settings are required, in global, system or local configs:

  • user.name
  • user.email

The following are recommended (change values per your preference):

  • core.editor=vi
  • core.repositoryformatversion=0
  • core.filemode=true
  • core.logallrefupdates=true
  • push.default=simple

The following is required / will be added if using the Travis CI client

  • travis.slug=deventropy/<project-github-name>

Storing credentials in GNOME Keyring

Git comes with support to store credentials securely in gnome keyring, but that code is not compiled. On Ubuntu at least, do the following:

sudo apt-get install libgnome-keyring-dev
cd /usr/share/doc/git/contrib/credential/gnome-keyring
sudo make
git config --global credential.helper /usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring

Credit: James Ward on Stackoverflow

Git Hooks (local)

Utility Git Hooks

pre-push

Prevent pushing local development branches to GitHub

If you work with local development branches and have a template for naming those branches (I use the 00_wip/ prefix); the following Git Hook can be used to prevent pushing the development branches to the remote (like GitHub).

Steps:

  1. Copy the contents of the script to a file $GIT_DIR/hooks/pre-push
  2. Change the script to be executable (chmod +x)

Git Shorthands

  • Backup Repository: git bundle create <backup_folder>/junit-helper-<timestamp>.git --all
  • Show older commits: git log --pretty=format:"%h %cn" or git log --pretty=fuller
  • Squash last n commits: git rebase -i HEAD~2
  • Merging a branch (non-fast forward): git checkout <destin> && git merge --no-ff <branch-to-merge>
  • Remove a public branch: git branch -d <branch-to-delete> && git push origin --delete <branchName> OR git push origin :<branchName>
  • Merging a pull request cheat sheet: https://gist.github.com/bindul/0f82097018946a4f3028
  • Show Remotes: git remote -v
  • Change Remote: git remote set-url <remote-name> <remote-url>
  • Create an orphan branch: git checkout --orphan <branch_name>
    • The orphan branch needs some content added and committed / pushed before it is useful

Version Numbers

The projects aim to adhere to Semantic Versioning 2.0.0 Guidelines; with the following exceptions/ notes:

  • Patch Version, as defined by Semver (Z (x.y.Z | x > 0)) is omitted if it is 0.
  • Pre-release versions (also tracked as Milestones in the issue management) use the -alpha.n and -beta.n identifiers in the pre-release-candidate stages; and -rc.n identifiers for release candidates, when required.
    • -alpha.n indicate feature incomplete releases
    • -beta.n indicate feature complete; public testing versions.

Code Guidelines

Some basic coding guidelines (for Java and XML files):

All source files in the project should have the following copyright and license statement within the appropriate file types comment section.

Copyright <year> Development Entropy (deventropy.org) Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Travis Setup

The projects use an almost generic Travis Setup, but we said almost. So, the exceptions are:

Using JFrog OSS Snapshot Repository

We use JFrog OSS Artifactory Instance as our Maven repository, so for builds relying on snapshots of other Deventropy parents, we are out of luck on default Travis CI settings, as it only checks Central, Sonatype OSS, Apache and Codehaus (does not exist any more) repositories. The build fails with errors such as:

[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]   
[ERROR]   The project org.deventropy.junit-helper:junit-helper:0.1-SNAPSHOT (/home/travis/build/deventropy/junit-helper/pom.xml) has 1 error
[ERROR]     Non-resolvable parent POM: Could not transfer artifact org.deventropy.parent:deventropy-parent:pom:1.0-SNAPSHOT from/to

To get around the problem, Google was to our aid and with ideas from a Coderwall blog on Deploying maven artifacts from Travis, we proceeded as follows:

  1. Set up a branch travis on the parent project.
  2. On that branch create a Maven Settings File with:
    • An active profile, and the profile has all the repositories and plugin repositories we want to check.
  3. Define a remote repository with the settings variable as DENT_TRAVIS_MVN_SETTINGS_REPO (either in the Travis CI settings UI or as a Global Environment variable in .travis.yml).
  4. Update .travis.yml of the project to have a before_install step, which essentially checks out the travis branch mentioned above into a directory under target
    • before_install: "git clone -b travis ${DENT_TRAVIS_MVN_SETTINGS_REPO} target/travis"
  5. Explicitly set the install and script entries in .travis.yml to use the explicit settings file:
    • "mvn <whatever...> -B --settings target/travis/travis-mvn-settings.xml"

Build Matrix

We use a simple build matrix with JDKs:

  • Oracle JDK 7 (oraclejdk7)
  • Oracle JDK 8 (oraclejdk8)

There is a mechanism to use JDK 9 EA versions in Travis, but we have not felt the need to use it yet.

Travis Cache

To speed up build (and savis the nice folks at Travis some network bandwidth), we cache our local Maven repository ($HOME/.m2/repository). However, without the just built artifacts, so there is a before_cache stage to remove files from our group ID: rm -rf $HOME/.m2/repository/org/deventropy/<group-id>.

AppVeyor Build

Though we would love to stick with just Travis, there are still people using Windows, haha. Number of projects use AppVeyor’s free service for open source projects for continuous integration builds on the Windows environment.

AppVeyor does not have direct support for Maven or Java builds, so a custom appveyor.yml is required to build Java projects on Windows on AppVeyor. The config file for deventropy-parent could serve as a template for other Deventropy projects. See the file at deventropy/deventropy-parent/appveyor.yml.

The following links are reference when we need to alter something:

Coverity Status

The projects use Coverity for static code analysis. Coverity does have support for integrating with Travis CI, but they limit the number of builds that can be submitted for analysis; so for the moment scans are completed locally and uploaded to the site (could script it later; but not done yet).

To run / upload a coverity scan, download and install the Coverity Scan Build Tool: Java and checkout the branch on which the scan is to be run, then run the following on the command line:

$ mvn clean
$ cov-build --dir cov-int mvn -DskipTests=true compile
$ # Make sure you see the following \
	Compilation units (85%) are ready for analysis
	The cov-build utility completed successfully
$ tar czvf <artifactId>.tgz cov-int

Upload the <artifactId>.tgz script created above to the Coverity project page. The <artifactId>.tgz and cov-int file / folder can be removed next.

Coveralls Setup

The project is set up to upload Jacoco code coverage reports to coveralls.io using the org.eluder.coveralls:coveralls-maven-plugin plugin. This plugin uses a repository token to gain access to the project. This token is not part of the POM file and is kept as an environment variable to be picked up by the plugin using:

<plugin>
	<groupId>org.eluder.coveralls</groupId>
	<artifactId>coveralls-maven-plugin</artifactId>
	<configuration>
		<repoToken>${env.COVERALLS_REPO_KEY}</repoToken>
	</configuration>
</plugin>

The actual property key used (instead of COVERALLS_REPO_KEY) can be found in each Top Level Project’s pom.xml.

Running Coveralls from Travis

The .travis.yml file has the key encrypted and stored as a global variable:

env:
    global:
        # SHARED_UTILS_COVERALLS_REPO_KEY=<secret...>
        - secure: "gbK0c3IbHze8..."

The key property is encrypted using the Travis client in the checked out git working directory:

travis encrypt SHARED_UTILS_COVERALLS_REPO_KEY=<secret...>

In the .travis.yml, the actual upload requires the jacoco report to be generated (as it creates the xml file used by the plugin to upload the coverage report) and the report is uploaded on successful builds:

after_success:
    # Coverage report to coveralls.io (but not for pull requests)
    - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && mvn clean test jacoco:report coveralls:report'

Running Coveralls locally

The Travis CI environment already has this value as an encrypted global variable (in .travis.yml); but if you need to run the coveralls report (and upload results) locally, do the following:

# Set the repository key environment variable (will not work as -DCOVERALLS_REPO_KEY=)
$ export COVERALLS_REPO_KEY=<key_from_coveralls.io>
$ mvn clean test jacoco:report coveralls:report

The actual property key used (instead of COVERALLS_REPO_KEY) can be found in each Top Level Project’s pom.xml.

Codacy Static Code Analysis

Some Deventropy projects use Codacy’s free service for open source projects for static code analysis. The link above will take you to the team page for all Deventropy projects (the link may not work unless you are logged into Codacy; each Top Level Project’s badge links to the project’s Codacy dashboard directly). The tool uses Git commits on GitHub for static code analysis and no additional steps are required for commits/builds.

The tool also supports adding test coverage information; that needs to be done from a build, either locally or from our CI builds at Travis CI. Codacy has has an API Integration point to send coverage information to be integrated into the code analysis information. They also provide a tool to upload coverage information from some standard code coverage tools.

Codacy Maven plugin

The project used to use the Codacy Coverage Reporter, which uses JPM to install and maintain dependencies. We ran into a few challenges and issues with this approach: First, the tool is not aware of Maven multi-module project setup; so required an extra line in the .travis.yml file for each module Second, the short link to the JPM installer broke, and is a long changing link now

The project uses the Codacy Maven Plugin to upload the coverage reports to Codacy for analysis. The plugin is primarily configured in the org.deventropy.parent:deventropy-parent (version 1.0-beta.1 or higher), as:

<!-- Upload code coverage reports to codacy.com -->
<plugin>
	<groupId>com.gavinmogan</groupId>
	<artifactId>codacy-maven-plugin</artifactId>
	<version>1.0.3</version>
	<configuration>
		<apiToken>${env.CODACY_API_TOKEN}</apiToken>
		<projectToken>${env.CODACY_PROJECT_TOKEN}</projectToken>
		<language>Java</language>
		<coverageReportFile>${project.build.directory}/site/jacoco/jacoco.xml</coverageReportFile>
		<failOnMissingReportFile>false</failOnMissingReportFile>
		<prefix>${codacy.project.prefix}</prefix>
	</configuration>
</plugin>

Unlike the Codacy Coverage Reporter, the plugin requires not only the project specific API token (usualy configured as an environment variable CODACY_PROJECT_TOKEN), but also an API token from someone with access to the projects at Codacy (configured as an environment variable CODACY_API_TOKEN).

The plug-in has been configured to use the following input / config at each project and module:

Parameter Summary Configured value / reference Project Specific Configuration Required
API Token The upload API Token Env variable CODACY_API_TOKEN Set in the build environment or can be overridden using -DapiToken= CLI override
Project Token The project Token Env variable CODACY_PROJECT_TOKEN Set in the build environment or can be overridden using -DprojectToken= CLI override
Language Code Language Java No
Coverage File Either a Jacoco or Cobertura file ${project.build.directory}/site/jacoco/jacoco.xml None, unless the project is configured to write JaCoCo report from the jacoco:report execution somewhere else
Prefix Prefix for multi-module projects Property ${codacy.project.prefix} Should be set at the leaf projects to point to the Java source folder relative to the Git repository root

Running Codacy coverage locally

Codacy tries to tie the uploaded coverage information to a commit, so if you are running this locally against a commit that has not been pushed upstream, the uploaded coverage information will most likely just be ignored.

Obtain the API and Project tokens and export them as CODACY_API_TOKEN and CODACY_PROJECT_TOKEN respectively. If not, both of these have to be added to the Maven runtime as -DapiToken= and -DprojectToken= respectively.

Then make sure Maven is executed to the test phase with the jacoco:report plugin; then execute the codacy:coverage plugin. Note, it is possible to execute all the Maven goals in a single executable

$ export CODACY_API_TOKEN=<secret...>
$ export CODACY_PROJECT_TOKEN=<secret...>
$ mvn clean test jacoco:report codacy:coverage

OR

$ mvn -DapiToken=<secret...> -DprojectToken=<secret...> clean test jacoco:report codacy:coverage

Uploading coverage from Travis

The Travis build config, .travis.yml is configured to generate and upload the coverage information for each build automatically.

The CODACY_API_TOKEN and CODACY_PROJECT_TOKEN is encrupted using the Travis command line client in the project Git checkout working directory:

$ travis encrypt CODACY_API_TOKEN=<secret...>
$ travis encrypt CODACY_PROJECT_TOKEN=<secret...>

Note: At this point, there is no way to obtain a API token for Codacy for a GitHub org, so all uploads run on an API token from Bindul’s account.

And add it to the .travis.yml:

env:
    global:
    	# CODACY_API_TOKEN=<secret...>
        - secure: "uhVAyeF..."
        # CODACY_PROJECT_TOKEN=<secret...>
        - secure: "gbK0c3IbHze8..."

And the actual script is run in the after_success step. The setup below shares the Jacoco report generation step between Coveralls and Codacy. If the project does not use Coveralls, skip the coveralls:report step:

after_success:
    # Coverage report to coveralls.io and codacy.com (but not for pull requests)
    - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && mvn clean test jacoco:report coveralls:report codacy:coverage'

VersionEye Setup

Deventropy project’s use VersionEye’s free service for Open Source projects to track dependency and plug-in versions and licenses.

The projects are setup to upload version updates from builds on the master branch on Travis CI through the VersionEye Maven Plug-in. This plugin uses a repository token to gain access to the project. This token is not part of the POM file and is kept as an environment variable to be picked up by the plugin using:

<plugin>
	<groupId>com.versioneye</groupId>
	<artifactId>versioneye-maven-plugin</artifactId>
	<version>3.9.0</version>
	<configuration>
		<apiKey>${env.VERSIONEYE_REPO_KEY}</apiKey>
		<nameStrategy>name</nameStrategy>
		<organisation>deventropy</organisation>
		<team>Owners</team>
	</configuration>
</plugin>

VersionEye Nesting

VersionEye projects are set up using a nested modules; the versioneye-maven-plugin has the capability to create projects directly on versioneye.com; however we have not identified a mechanism to add modules created later on. Besides, the plugin also has issues managing the Project Ids (see VersionEye Maven Plugin Issue #48).

So, projects should be created on the versioneye.com web interface parsing the GitHub repository and the correct pom.xml. Once sub modules are created, they get created as individual projects; which need to be moved to the correct parent using the Settings tab and Move project under option.

TODO: Figure out how to name the sub-projects once they are parsed from GitHub in the Summary sub tabs.

Project ID

The versioneye-maven-plugin requires each project’s project_id to be available (including modules). These can be set up in the pom.xml using the projectId configuration parameter; however to avoid repeating the plugin configuration in each project, it is maintained in a src/qa/resources/versioneye.properties file using the property key project_id. Note, these are unique for each parent POM and child project.

Running VersionEye from Travis

The .travis.yml file has the key encrypted and stored as a global variable:

env:
    global:
        # VERSIONEYE_REPO_KEY=<secret...>
        - secure: "iIe2cpGaG..."

The key property is encrypted using the Travis client in the checked out git working directory:

travis encrypt VERSIONEYE_REPO_KEY=<secret...>

In the .travis.yml, the actual upload happens if the build is on the master branch for a non pull request build; and if the build succeeds.

after_success:
    # Update dependencies in VersionEye
    - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ] && mvn com.versioneye:versioneye-maven-plugin:update'

Running Coveralls locally

If you need to update dependency and plug-in information to VersionEye locally, do the following:

# Set the API key environment variable (will not work as -DVERSIONEYE_REPO_KEY=)
$ export VERSIONEYE_REPO_KEY=<API_key_from_versioneye.com>
$ mvn com.versioneye:versioneye-maven-plugin:update

Eclipse Setup

Additional Eclipse setup steps:

Code Template

Set up Java > Code Style > Code Templates > Comments > Files to have the following:

/* 
 * Copyright ${year} Development Entropy (deventropy.org) Contributors
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Checkstyle Plug-in

If you have the checkstyle plug-in installed set it up to have an additional Global Configuration to point to the Checkstyle configuration XML file:

  • Either, as a Remote configuration file pointing to the URL in Code Guidelines above
  • Or, if you have the deventropy-parent or deventropy-cq-config project checked out; as a Project Relative configuration.

In both cases, define the checkstyle.header.file under Additional Properties to point to the license-header.txt file in the same location.

Build / Maven Setup

Maven Settings

T.B.D.

Code Signing Settings

T.B.D.

GPG Signing Settings

T.B.D.

Maven shortcuts

T.B.D.

Site Generation

  • To delete stage folder and stage site: OD=<site-stage-directory> && rm -rf $OD/* && mvn clean verify site:site site:stage -DstagingDirectory=$OD
    • The site staging is being replaced with the mvn-site-stage.sh script.
  • To clean up the checked out gh-pages repository: ls | grep -v '.project' | grep -v '.nojekyll' | grep -v '.git' | grep -v '.gitignore' | xargs rm -r
  • Copy the staged site there; then do a commit and push.

Issue Management

Though not as good as a JIRA instance, we have GitHub issues to work with. Since we are using the same issue system for all the modules, here are a few guidelines:

  • Try and have properly labeled component:* issues to know where an issue belongs.
  • For anything that will be fixed, have a proper milestone label.
  • For any commit to a public branch, that is related to an open issue, make sure to refer the issue in the commit message.

Back to top

Version: 1.0-SNAPSHOT. Last Published: 19 Dec 2016.

Reflow Maven skin by Andrius Velykis.