diff --git a/Templates/Common-Backend-Scripts/README.md b/Templates/Common-Backend-Scripts/README.md index a029a43d..734c4d80 100644 --- a/Templates/Common-Backend-Scripts/README.md +++ b/Templates/Common-Backend-Scripts/README.md @@ -133,7 +133,8 @@ Artifact Name | Description | Script details ---------- | -----| ----------------------------------------------------- [gitClone.sh](gitClone.sh) | Pipeline Shell Script to perform Git Clone to z/OS UNIX System Services | [script details](README.md#41---gitclonesh) [dbbBuild.sh](dbbBuild.sh) | Pipeline Shell Script to invoke the Dependency Based Build framework [zAppBuild](https://github.com/IBM/dbb-zappbuild) | [script details](#dbbbuildsh-for-zappbuild-frameworkh) -[zBuilder.sh](zBuilder.sh) | Pipeline Shell script to invoke the zBuilder framework [zBuilder](https://www.ibm.com/docs/en/dbb/3.0?topic=building-zos-applications-zbuilder) | [script details](#zbuildersh-for-dbb-zbuilder) +[zBuilder.sh](zBuilder.sh) | Pipeline Shell Script to invoke the zBuilder framework [zBuilder](https://www.ibm.com/docs/en/dbb/3.0?topic=building-zos-applications-zbuilder) | [script details](#zbuildersh-for-dbb-zbuilder) +[computeReleaseVersion.sh](computeReleaseVersion.sh) | Pipeline Shell Script to compute the next release version based on the baseline version information stored in the application's [baselineReference.config](samples/baselineReference.config) file. | [script details](#computeReleaseVersionsh) [packageBuildOutputs.sh](packageBuildOutputs.sh) | Pipeline Shell Script to create a Package using the [PackageBuildOutputs groovy script](https://github.com/IBM/dbb/tree/main/Pipeline/PackageBuildOutputs) | [script details](#packagebuildoutputssh) [ucdPackage.sh](ucdPackaging.sh) | Pipeline Shell Script to publish to UCD Code Station binary repository using the [CreateUCDComponentVersion groovy script](https://github.com/IBM/dbb/tree/main/Pipeline/CreateUCDComponentVersion) | [script details](#ucdpackagingsh) [wazideploy-generate.sh](wazideploy-generate.sh) | Pipeline Shell Script to generate a Deployment Plan to be used with Wazi Deploy | [script details](#wazideploy-generatesh) @@ -492,6 +493,84 @@ The [dbbzBuilderUtils](utilities/dbbzBuilderUtils.sh) script is a core utility s Depending on the Deployment Manager tool you are using, you can choose from either creating a package with the [PackageBuildOutputs](#packagebuildoutputssh) script that can be used with IBM Wazi Deploy, or the [UCD packaging](#ucdpackagingsh) script that creates the UCD shiplist and UCD component version. +### computeReleaseVersion.sh + +This script is to compute the version for the next release based on the information of baseline version stored in the [baseineReference.config](samples/baselineReference.config) file. The computation of the release version follows the versioning described in [IBM recommended Git branching model for mainframe developer](https://ibm.github.io/z-devops-acceleration-program/docs/branching/git-branching-model-for-mainframe-dev). It follows the Systematic Versioning as MAJOR.MINOR.PATCH number. The number of the coresponding part is increased based on the type of release. + +The computed release version is used as part of the archive name to be uploaded or downloaded from the artifact repository. The release version is an input for [packageBuildOutputs.sh](#packagebuildoutputssh) and [wazideploy-generate.sh](#wazideploy-generatesh). + +#### Invocation + +The `computeReleaseVersion.sh` script can be invoked as follows: + +``` +computeReleaseVersion.sh -w MortApp/main/build-1 -a MortgageApplication -b main -r minor +``` + +CLI parameter | Description +---------- | ---------------------------------------------------------------------------------------- +-w `` | **Workspace directory**, an absolute or relative path that represents unique directory for this pipeline definition, that needs to be consistent through multiple steps. +-a `` | **Application name** to be built. +-b `` | **Git branch** that is built. +-r `` | **Release Type** to indicate the type of changes to be relased. + +#### Output + +The section below contains the output that is produced by the `computeReleaseVersion.sh` script. + +
+ Script Output + +``` ++ computeReleaseVersion.sh -w /var/jenkins/workspace/tgageApplication-Pipelines2_main -a MortgageApplication -b main -r major +[Pipeline] echo +computeReleaseVersion.sh: [INFO] Release Version Wrapper. Version=1.10 +computeReleaseVersion.sh: [INFO] Reading pipeline configuration file: /var/jenkins/dbb/Templates/Common-Backend-Scripts/pipelineBackend.config +computeReleaseVersion.sh: [INFO] Validating Options +computeReleaseVersion.sh: [INFO] Application Directory: /var/jenkins/workspace/tgageApplication-Pipelines2_main/MortgageApplication +computeReleaseVersion.sh: [INFO] Detected the application respository (MortgageApplication) within the git repository layout structure. +computeReleaseVersion.sh: [INFO] Assuming this as the new application location. +computeReleaseVersion.sh: [INFO] ************************************************************** +computeReleaseVersion.sh: [INFO] ** Started Next Release Computation on HOST/USER: z/OS ZT01 05.00 02 8561/ +computeReleaseVersion.sh: [INFO] ** Workspace: /var/jenkins/workspace/tgageApplication-Pipelines2_main/MortgageApplication +computeReleaseVersion.sh: [INFO] ** Application: MortgageApplication +computeReleaseVersion.sh: [INFO] ** Branch: main +computeReleaseVersion.sh: [INFO] ** Release Type: major +computeReleaseVersion.sh: [INFO] ** Baselinereference file: /var/jenkins/workspace/tgageApplication-Pipelines2_main/MortgageApplication/application-conf/baselineReference.config +computeReleaseVersion.sh: [INFO] ************************************************************** + +computeReleaseVersion.sh: [INFO] Baseline reference: refs/tags/rel-1.6.0 +computeReleaseVersion.sh: [INFO] Compute the next release version complete. The next release version: rel-2.0.0. rc=0 + +``` + +
+ +#### Extract the next release version + +To obtain the release version from the `computeReleaseVersion.sh` script's output log, utilize string manipulation commands within your pipeline orchestrator to search for the pattern `version: .*rc=0` pattern and extract the version number form the search result. + +
+ Example snippet to extract the version number + +``` +regexPattern = "version: .*rc=0" +pattern = java.util.regex.Pattern.compile(regexPattern) +//logContent is the output from invoking the computeReleaseVersion.sh script +def pMatcher = pattern.matcher(logContent) +if (pMatcher.find()) { + def version = "${pMatcher.group()}" + if (version){ + releaseVersion = version.substring(9,version.length()-6) + } +} else { + println("[INFO]: Failed to search for ${regexPattern}") +} + +``` + +
+ ### packageBuildOutputs.sh This script is to execute the `PackageBuildOutputs.groovy` that packages up the build outputs and optionally uploads it to an artifact repository to publish the artifacts created by a DBB build in the pipeline. @@ -512,7 +591,8 @@ For release builds (that use the `pipelineType=release`), the archive is uploade `release//-`: * **release** is defined for release builds. -* **reference** is the release name: for instance, `rel-1.2.3` (provided through the mandatory `-r` argument). +* **reference** is the release name: for instance, `rel-1.2.3` (provided through the mandatory `-r` argument). The release name can be automatically computed using the [computeReleaseVersion.sh](#computereleaseversionsh) script. + The archive's file name is computed using the application's name, the release name (`-r` argument) and a unique build identifier (`-i` argument). This parameter is typically the pipeline build number that is passed by the pipeline orchestrator. If a build identifier is not provided, the current timestamp is used. @@ -629,8 +709,6 @@ rc=0 - - ### ucdPackaging.sh This script is to execute the `dbb-ucd-packaging.groovy` that invokes the Urban Code Deploy (UCD) buztool utility, to publish the artifacts created by the DBB Build from a pipeline. @@ -727,7 +805,7 @@ CLI parameter | Description -- | - when retrieving the tar file from Artifact repo the below options are mandatory - -b ``| Name of the **git branch** turning into a segment of the directory path for the location within the artifact repository. -p `` | **Pipeline Type** to indicate a `build` pipeline (build only with test/debug options) or a `release` pipeline (build for optimized load modules for release candidates). --R `` | **Release identifier** to indicate the next planned release name. This is a computed value based on the pipeline templates. +-R `` | **Release identifier** to indicate the next planned release name. This is a computed value based on the pipeline templates. It can be automatically computed using the [computeReleaseVersion.sh](#computereleaseversionsh) script. -I `` | **Build identifier** a unique value to identify the tar file. This is a computed value provided by the pipeline templates. Typically the build number of the pipeline run. -c `` | Absolute path to the Wazi Deploy **Configuration File** that contains information to connect to the artifact repository. See [IBM Wazi Deploy documentation](https://www.ibm.com/docs/en/developer-for-zos/17.0?topic=files-configuration-file) diff --git a/Templates/Common-Backend-Scripts/computeReleaseVersion.sh b/Templates/Common-Backend-Scripts/computeReleaseVersion.sh new file mode 100755 index 00000000..91bef450 --- /dev/null +++ b/Templates/Common-Backend-Scripts/computeReleaseVersion.sh @@ -0,0 +1,377 @@ +#!/bin/env bash +# +#=================================================================================== +# NAME: computeReleaseVersion.sh +# +# DESCRIPTION: The purpose of this script is to perform computation of the version +# for the next release. +# +# SYNTAX: See Help() section below for usage +# +# RETURNS: +# +# rc - Return Code +# +# RETURN CODES: +# +# 0 - Successful +# 4 - Warning message(s) issued. See Console messages +# 8 - Error encountered. See Console messages +# +# NOTE(S): +# +# 1. Review and update the Customization Section to reference the +# central configuration file pipelineBackend.config +# +# 2. The naming convention of the release version is 'rel-x.y.z' +# when: x increased for a major release +# y increased for a minor release +# z increased for a patch release +# +#=================================================================================== +Help() { + echo $PGM" - Invoke Release Version Computation ("$PGMVERS") " + echo " " + echo "DESCRIPTION: The purpose of this script is to execute the " + echo "computeReleaseVersion scripts to compute the version " + echo "of the next release. " + echo " " + echo "Syntax: " + echo " " + echo " "$PGM" [Options] " + echo " " + echo "Options: " + echo " " + echo " Mandatory parameters " + echo " " + echo " -w - Directory Path to a unique " + echo " working directory " + echo " Either an absolute path " + echo " or relative path. " + echo " If a relative path is provided, " + echo " buildRootDir and the workspace " + echo " path are combined " + echo " Default=None, Required. " + echo " " + echo " Ex: MortgageApplication/main/build-1 " + echo " " + echo " -a - Application name " + echo " Used to compute " + echo " Artifact repository name. " + echo " " + echo " Ex: MortgageApplication " + echo " " + echo " -b - Name of the git branch. " + echo " " + echo " Ex: main " + echo " " + echo " -r - Type of the release " + echo " to calculate the version. " + echo " Accepted values: " + echo " - Major " + echo " - Minor (Default) " + echo " - Patch " + echo " " + exit 0 +} + +# Customization +# Central configuration file leveraged by the backend scripts +SCRIPT_HOME="`dirname "$0"`" +pipelineConfiguration="${SCRIPT_HOME}/pipelineBackend.config" +# Customization - End + +# internal veriables +PGM=$(basename "$0") +PGMVERS="1.10" +USER=$USER +SYS=$(uname -Ia) + +rc=0 +ERRMSG="" + +# Initialized option variables passed to this script +Workspace="" +App="" +Branch="" +ReleaseType="" +HELP=$1 + +# Local Variables +# TLD: Always a good idea to initialize any local varables +AppDir="" # Derived Application Directory +Type="" # Derived Build Type +baselineRef="" # baselineReference that is to be computed +mainBranchSegment="" +secondBranchSegment="" +thirdBranchSegment="" +baselineReferenceFile="" +newVersion="" +releaseVersion="" + +if [ "$HELP" = "?" ]; then + Help +fi + +# Validate Shell environment +currentShell=$(ps -p $$ | grep bash) +if [ -z "${currentShell}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] The scripts are designed to run in bash. You are running a different shell. rc=${rc}. \n. $(ps -p $$)." + echo $ERRMSG +fi +# + +if [ $rc -eq 0 ]; then + echo $PGM": [INFO] Release Version Wrapper. Version=${PGMVERS}" +fi + + +if [ $rc -eq 0 ]; then +# Read and import pipeline configuration + if [ ! -f "${pipelineConfiguration}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] Pipeline Configuration File (${pipelineConfiguration}) was not found. rc="$rc + echo $ERRMSG + else + echo $PGM": [INFO] Reading pipeline configuration file: ${pipelineConfiguration}" + source $pipelineConfiguration + fi +# + +# Get Options + if [ $rc -eq 0 ]; then + while getopts "h:w:a:b:r:" opt; do + case $opt in + h) + Help + ;; + w) + argument="$OPTARG" + nextchar="$(expr substr $argument 1 1)" + if [ -z "$argument" ] || [ "$nextchar" = "-" ]; then + rc=4 + ERRMSG=$PGM": [WARNING] Build Workspace Folder Name is required. rc="$rc + echo $ERRMSG + break + fi + Workspace="$argument" + ;; + a) + argument="$OPTARG" + nextchar="$(expr substr $argument 1 1)" + if [ -z "$argument" ] || [ "$nextchar" = "-" ]; then + rc=4 + ERRMSG=$PGM": [WARNING] Application Folder Name is required. rc="$rc + echo $ERRMSG + break + fi + App="$argument" + ;; + b) + argument="$OPTARG" + nextchar="$(expr substr $argument 1 1)" + if [ -z "$argument" ] || [ "$nextchar" = "-" ]; then + rc=4 + ERRMSG=$PGM": [WARNING] Branch Name is required. rc="$rc + echo $ERRMSG + break + fi + Branch="$argument" + ;; + r) + # release type + argument="$OPTARG" + nextchar="$(expr substr $argument 1 1)" + if [ -z "$argument" ] || [ "$nextchar" = "-" ]; then + rc=4 + INFO=$PGM": [WARNING] Release type is required (-r). rc="$rc + echo $INFO + break + fi + ReleaseType="$argument" + ;; + \?) + Help + rc=1 + break + ;; + :) + rc=4 + ERRMSG=$PGM": [WARNING] Option -$OPTARG requires an argument. rc="$rc + echo $ERRMSG + break + ;; + esac + done + fi +fi +# + +# Validate Options +validateOptions() { + + echo $PGM": [INFO] Validating Options" + if [ -z "${Workspace}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] Unique Workspace parameter (-w) is required. rc="$rc + echo $ERRMSG + else + + if [ ! -d "$(getWorkDirectory)" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] Workspace Directory ($(getWorkDirectory)) was not found. rc="$rc + echo $ERRMSG + fi + fi + + if [ -z "${App}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] Application parameter (-a) is required. rc="$rc + echo $ERRMSG + else + + AppDir=$(getApplicationDir) + echo $PGM": [INFO] Application Directory: ${AppDir}" + + # Check if application directory contains + if [ -d "${AppDir}" ]; then + echo $PGM": [INFO] Detected the application respository (${App}) within the git repository layout structure." + echo $PGM": [INFO] Assuming this as the new application location." + AppDir="${AppDir}" + nestedApplicationFolder="true" + + # Locate the baseline reference file based on the baselineReferenceLocation config in pipelineBackend.config + baselineReferenceFile="${AppDir}/$baselineReferenceLocation" + if [ ! -f "${baselineReferenceFile}" ]; then + echo [ERROR] Applications baseline reference configuration file ${baselineReferenceFile} was not found. + exit 1 + fi + + fi + + if [ ! -d "${AppDir}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] Application Directory (${AppDir}) was not found. rc="$rc + echo $ERRMSG + fi + fi + + if [ -z "${Branch}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] Branch Name parameter (-b) is required. rc="$rc + echo $ERRMSG + fi + + if [ -z "${ReleaseType}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] Release Type parameter (-r) is required. Valid release types are 'major', 'minor' or 'patch'. rc="$rc + echo $ERRMSG + fi + +} +# + +# Get baseline reference version from current branch +getBaselineReference() { + + baselineRef="" + + case $(echo $mainBranchSegment | tr '[:lower:]' '[:upper:]') in + "RELEASE" | "EPIC") + baselineRef=$(cat "${baselineReferenceFile}" | grep "^${mainBranchSegment}/${secondBranchSegment}" | awk -F "=" ' { print $2 }') + ;; + "MAIN") + baselineRef=$(cat "${baselineReferenceFile}" | grep "^${mainBranchSegment}" | awk -F "=" ' { print $2 }') + ;; + "FEATURE") + rc=4 + ERRMSG=$PGM": [ERROR] Branch name ${Branch} is a feature branch and does not need to compute the baseline reference. rc="$rc + echo $ERRMSG + ;; + *) + rc=8 + ERRMSG=$PGM": [ERROR] Branch name ${Branch} does not follow the recommended naming conventions to compute the baseline reference. Received '${mainBranchSegment}' which does not fall into the conventions of release, epic or main. rc="$rc + echo $ERRMSG + ;; + esac + + if [ $rc -eq 0 ]; then + if [ -z "${baselineRef}" ]; then + rc=8 + ERRMSG=$PGM": [ERROR] No baseline ref was found for branch name ${Branch} in ${baselineReferenceFile}. rc="$rc + echo $ERRMSG + fi + fi + + ##DEBUG ## echo -e "baselineRef \t: ${baselineRef}" ## DEBUG +} + +computeNextReleaseVersion() { + # Compute the name of the next release based on the releaseType + case $(echo $ReleaseType | tr '[:upper:]' '[:lower:]') in + "patch") + export newVersion=`echo ${baselineRef} | sed 's/^["refs\/tags\/rel-]*//g' | sed 's/-[a-zA-Z0-9]*//g' | awk -F. -v OFS=. '{$3 += 1 ; print}'` + rc=0 + ;; + "minor") + export newVersion=`echo ${baselineRef} | sed 's/^["refs\/tags\/rel-]*//g' | sed 's/-[a-zA-Z0-9]*//g' | awk -F. -v OFS=. '{$2 += 1 ; $3 = 0; print}'` + rc=0 + ;; + "major") + export newVersion=`echo ${baselineRef} | sed 's/^["refs\/tags\/rel-]*//g' | sed 's/-[a-zA-Z0-9]*//g' | awk -F. -v OFS=. '{$1 += 1 ; $2 = 0; $3 = 0; print}'` + rc=0 + ;; + *) + rc=8 + ERRMSG=$PGM": [ERROR] No valid release type found. Valid release types are 'major', 'minor' or 'patch'. rc="$rc + echo $ERRMSG + ;; + esac + +} + +# Call validate Options +if [ $rc -eq 0 ]; then + validateOptions +fi + +# +# Ready to go +if [ $rc -eq 0 ]; then + echo $PGM": [INFO] **************************************************************" + echo $PGM": [INFO] ** Started Next Release Computation on HOST/USER: ${SYS}/${USER}" + echo $PGM": [INFO] ** Workspace:" $(getWorkDirectory) + echo $PGM": [INFO] ** Application:" ${App} + echo $PGM": [INFO] ** Branch:" ${Branch} + echo $PGM": [INFO] ** Release Type:" ${ReleaseType} + echo $PGM": [INFO] ** Baselinereference file:" ${baselineReferenceFile} + echo $PGM": [INFO] **************************************************************" + echo "" + +# Extract the current branch from GitLab environment + export mainBranchSegment=`echo ${Branch} | awk -F "/" '{ print $1 }'` + export secondBranchSegment=`echo ${Branch} | awk -F "/" '{ print $2 }'` + export thirdBranchSegment=`echo ${Branch} | awk -F "/" '{ print $3 }'` + # echo $PGM": [DEBUG] Branch segments: ${mainBranchSegment}, ${secondBranchSegment}, ${thirdBranchSegment}" + +# Find base line version of the current branch from the baseLineReferenceFile + getBaselineReference + if [ $rc -eq 0 ]; then + ERRMSG=$PGM": [INFO] Baseline reference: ${baselineRef}" + echo $ERRMSG + + computeNextReleaseVersion + + if [ $rc -eq 0 ]; then + export releaseVersion="rel-"${newVersion} + ERRMSG=$PGM": [INFO] Compute the next release version complete. The next release version: ${releaseVersion}. rc="$rc + echo $ERRMSG + else + ERRMSG=$PGM": [ERROR] Compute the next release version failed. Check console for details. rc="$rc + echo $ERRMSG + fi + fi +fi + +exit $rc \ No newline at end of file