Skip to content

npiper/npiper-parent-org

Repository files navigation

Parent Organisation pom for neilpiper.me

Version

0.3

How to use the Parent POM?

Pre-Requisites

  • AWS Storage Repo S3 for Repository

  • AWS CLI installed locally

  • Java/Maven installed

  • github account - OAuth token (to commit/push mvn site pages)

AWS Setup for S3 Repository

An S3 bucket (public access) has been created called solveapuzzle-repo, to avoid the need to keep AWS-credentials in github a role is created that can get an OpenIDConnect credential via a Github trusted authentication. The role has minimal permissions to only be able to interact with the S3 bucket.

roles

Create the AWS Role from CLI

Role to be created

arn:aws:iam::{account-id}:role/npiper-githubactions-role

Running the AWS CLI

Create an AWS session aws configure , the script needs parameters for the GitHubOrg and the RepositoryName to associate the role to.

Parameters:
  GitHubOrg = npiper
  RepositoryName = npiper-parent-org


aws cloudformation create-stack --stack-name teststack --template-body file://$(pwd)/cloudformation/role-cloudformation.yaml --parameters ParameterKey=GitHubOrg,ParameterValue=npiper ParameterKey=RepositoryName,ParameterValue=npiper-parent-org --capabilities CAPABILITY_NAMED_IAM

Parent POM - Release process

Tagging, Site documentation generation and deployment to the S3 Maven repository MUST only ever be done from the build server.

This is currently using Github Actions off the master branch.

Build metadata: * Github Actions build number * Git commit ID - short Ref

Project tags and the site documentation 'About' page give traceability of which CI tag and build the semantic version was built against.

[Semantic Version]_[BuildNumber].[gitCommitId]

Use semantic versioning in your POM file to consider a release candidate of the change you are intending to make, and the CI server to guide the succesful build candidate to take forward.

Why: You know the change you are after,.. it might take a few builds and tests to get it so the code traceability is always built in.

The .github/workflows/build_master.yml build file should be structured to only permit these actions to happen on the build server.

A maven <profile> is used so it is not possible to do this locally (unless you need to debug.)

mvn site deploy scm:tag -Drevision=${TRAVIS_BUILD_NUMBER}.$(git rev-parse --short HEAD) -Dusername=${GIT_USER_NAME} -Dpassword=${GITPW}

Using the npiper-parent-org and setting up a CI-CD repo

Use the shell script gitsetup.sh to create a project and appropriate branches for typical development.

- develop : development branch - trunk based development
- gh-pages : Github pages - a maven  and reports site will be deployed using a plugin
- master : semantic versioning and deployments run through this branch

Inheritance model

The npiper-parent-org provides placeholder information that can be re-used in sub-poms in the Github organisation, that allows the same features and conventions for deployment, publishing, CI/CD, rules (Maven Enforcer) and site generation to be consistently applied.

The ${project.name} variable is used in this POM’s settings that allows may common values to be re-used.

Inheritance example

Encrypt keys into Github Actions

The following encrypted variables are used on a succesful build and mvn deploy to the Release repository.

  • Git Tag and push site doco to gh-pages branch, push tag to master

[lock] GHBUILDEMAIL
[lock] GHOAUTH_SECRET_TOKEN
[lock] GHUBUILDSER

TO DO: How to do this via curl, secrets must be encrypted/encoded before posting

List secrets

curl -H "Accept: application/vnd.github+json" -H "Authorization: Bearer {PW Tokent}}" https://api.github.com/repos/npiper/npiper-parent-org/actions/secrets

Conventions to follow

Repository is in Github, as the site pages go to Github pages, and use Github actions for CI-CD. This should be effectively free for most developers.

project.name = Align to GIT repository name

Use git issue tracking (default) When using site put published version into github pages as path ${project.name} Repository is the Amazon S3 solveapuzzle-repo for Deployment, retrieving any 'neipiper.me' dependencies.

Choose the right Parent Version for inheritance (Ranges)

Release versions can be browsed using the 'tags' tags

The parent versions can be browsed at: https://s3-ap-southeast-2.amazonaws.com/solveapuzzle-repo

Release Naming Convention: MAJOR.MINOR.PATCH _BUILD.COMMIT*

Release management and supported version changes should only be done off the master branch.

The following parent example inherits the highest version under ⇐ v1.0.0.

  <parent>
    <groupId>neilpiper.me</groupId>
    <artifactId>parent.org</artifactId>
    <version>(,1.0]</version>
  </parent>

How this works?…​ Maven Version Range References

Set your project name

A lot of the project inherits location and github projects

  <name>hello-world</name>

Set / Override the Github Organisation

The default Github Organisation for this POM is npiper.

It is possible to overwrite the Organisation by setting this property in the Child POM.

<githubOrg>solveapuzzle-dev</githubOrg>

Add Repository , overwrite SCM URL in child

There’s a need to redefine the <scm> tag in each child.

This is to workaround to an inconsistency in Maven that child projects scm tag, appends parent’s pom name in pom.xml

	<scm>
		<url>https://github.com/${githubOrg}/[repo-name]</url>
		<developerConnection>scm:git:https://github.com/${githubOrg}/[repo-name].git</developerConnection>
	</scm>

About the POM for npiper-parent-org

Build Extension: Configuration to use an S3 Repository

To add the capability of using an S3 Bucket as a repository, 2 extensions are added

com.github.seahen:maven-s3-wagon - enables communication between Maven and Amazon S3

org.apache.maven.wagon:wagon-webdav-jackrabbit - enables communication to WebDav servers.

<build>
		<!-- Extension : s3 wagon for repo -->
		<extensions>
			<extension>
				<groupId>com.github.seahen</groupId>
				<artifactId>maven-s3-wagon</artifactId>
				<version>${mavenS3WagonVersion}</version>
			</extension>

			<extension>
				<groupId>org.apache.maven.wagon</groupId>
				<artifactId>wagon-webdav-jackrabbit</artifactId>
				<version>${wagon-webdav-jackrabbitVersion}</version>
			</extension>
		</extensions>

        ...
</build>

Build Plugin: Enforcer for Build Rules

Use the Enforcer plugin to verify that a minimum Maven version that allows for parent / child version ranges, v3.6+.

Build Pluigin: Deploy, off in local mode, on in CI/CD Profile

The deploy plugin is primarily used during the deploy phase, to add your artifact(s) to a remote repository for sharing with other developers and projects.

Deploys as they are configured to deploy to S3 Repo are off locally, but turned to true in the CI/CD profile so that only a CI/CD driven build will do the process of updating the maven site documentation, tagging the codebase and deploying to the S3 bucket.

				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-deploy-plugin</artifactId>

Plugins Inherited: pluginManagement

Section is intended to configure project builds that inherit from this one

Child projects are set to use the reporting plugin: maven-project-info-reports

Project Information summary

One of the main purposes of the org parent POM is to pre-load inherited Organisation values for documentation and maintenance, used in reporting / site goals.

Using some property values these can be automatically changed in each child project by using common maven values such as ${project.name} when convention is followed.

<name/>
<description/>
<url/>
<inceptionYear/>
<licenses/>
<developers/>
<organization/>

Project Environment (Build/Deploy/Repo settings)

The following elements are set in this Parent Org POM to mainly allow inheritance, because of one known issue the SCM element needs to be re-defined in each Child repository.

Using some property values these can be automatically changed in each child project by using common maven values such as ${project.name} when convention is followed.

<issueManagement/>
<ciManagement/>
<scm/>
<repositories/>
<distributionManagement/>

Profile (CI)

The CI/CD profile looks for the Github build environment variable CI to be active.

site-maven-plugin
maven-deploy-plugin (skip = false)

Profile : PluginManagement (Inheritance)

com.github.github:site-maven-plugin
maven-deploy-plugin
maven-scm-plugin

Site Plugin: Github pages Homepage for Maven Site documentation

The pom file sets up for use the plugin com.github.github:site-maven-plugin

This plugin can be used to deploy a created Maven site to a gh-pages branch so that it can be served statically as a GitHub Project Page.

	<distributionManagement>

		<!-- Where the site pages go -->
		<site>
			<id>gh-pages</id>
			<name></name>
			<url>https://${githubOrg}.github.io/${project.name}/</url>
		</site>
	</distributionManagement>
https://${githubOrg}.github.io/${project.name}/

Next Steps

  • ❏ Automate / guidance for encrypting Github secrets using script or command line (per new repo, in setup script)

  • ❏ Setup script creates required brances and workflows, sample Github actions template

  • ❏ Steps / Github actions to create the AWS CloudFormation Stack

  • ❏ Remove references to travisCI build config

Child project full example

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>


	<!-- Template Project file for my projects - based on https://maven.apache.org/pom.html -->

	<artifactId>child.pom</artifactId>
	<!-- Default starting version is 0-SNAPSHOT -->
	<version>0.1.0_${revision}</version>
	<packaging>pom</packaging>

	<parent>
		<groupId>neilpiper.me</groupId>
		<artifactId>parent.org</artifactId>
        <version>(,1.0]</version>
	</parent>


	<name>child-pom</name>

	<properties>
		<!-- Sane default when no revision property is passed in from the commandline -->
		<revision>0-SNAPSHOT</revision>
		...
	</properties>

	<!-- BUILD SETTINGS -->

	<dependencies>
       ...
	</dependencies>

	<build>
	   <plugins>
	   </plugins>
   </build>



   <!-- Workaround scm inheritance bug in Maven for parent/child -->
   <scm>
		<url>https://github.com/npiper/child-pom</url>
		<connection>scm:git:git://github.com/npiper/child-pom.git</connection>
		<developerConnection>scm:git:https://github.com/npiper/child-pom.git</developerConnection>
	</scm>

</project>

Debugging locally

When refactoring or when you need to test, - try to this as a rolling patch or minor revision that you throw away.

e.g.

0.1 Current--> 0.2 Test, throwaway --> 0.3  Next

Set up environment variables so you can behave like a build server:

export AWS_ACCESS_KEY_ID=[Your_AWS_Access_Key]
export AWS_SECRET_KEY=[Your_AWS_Secret_Key]
export GIT_USER_NAME=[Your Git User]
export GITPW=[Your GIT OAuth]
export BUILD_NUMBER=01TEST
export CI=true

TO DO: Show how using -D it is possible to potentially avoid the github pages publish, tag

Run the maven command from .github/workflow/build_master.yml to test a build and deploy process:

mvn site deploy scm:tag -Drevision=${BUILD_NUMBER}.$(git rev-parse --short HEAD) -Dusername=${GIT_USER_NAME} -Dpassword=${GITPW}

Writing Documentation

We are going after Github Flavoured Asciidoc with Plantuml, Kroki for diagrams.

Creating a Repo based on directory name

cd to your new directory, have to have your Github auth token set in Env variable GIT_PW

export dirName=$(realpath --relative-to=.. $(pwd))


curl -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token $GIT_PW" \
-d '{"name":"${dirName"}' https://api.github.com/user/repos
````