diff --git a/scripts/pipelines/azure-devops/pipeline_generator.sh b/scripts/pipelines/azure-devops/pipeline_generator.sh index f5ed33453..41b0cece3 100644 --- a/scripts/pipelines/azure-devops/pipeline_generator.sh +++ b/scripts/pipelines/azure-devops/pipeline_generator.sh @@ -60,6 +60,17 @@ function obtainHangarPath { hangarPath=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && cd ../../.. && pwd ) } +function addAdditionalArtifact { + # Check if an extra artifact to store is supplied. + if test ! -z "$artifactPath" + then + # Add the extra step to the YAML. + cat "${hangarPath}/${commonTemplatesPath}/store-extra-path.yml" >> "${localDirectory}/${pipelinePath}/${yamlFile}" + else + echo "The '-a' flag has not been set, skipping the step to add additional artifact." + fi +} + function createPipeline { echo -e "${green}Generating the pipeline from the YAML template..." echo -ne ${white} @@ -156,6 +167,8 @@ createNewBranch copyYAMLFile +addAdditionalArtifact + copyCommonScript type copyScript &> /dev/null && copyScript diff --git a/scripts/pipelines/common/pipeline_generator.lib b/scripts/pipelines/common/pipeline_generator.lib index 698f09346..5eb49ef01 100644 --- a/scripts/pipelines/common/pipeline_generator.lib +++ b/scripts/pipelines/common/pipeline_generator.lib @@ -59,7 +59,7 @@ function help { echo " --s3-bucket [Required] Name of the S3 bucket where the Terraform state of the cluster will be stored." echo " --s3-key-path [Required] Path within the S3 bucket where the Terraform state of the cluster will be stored." echo " --aws-access-key [Required, on first run] AWS account access key ID." - echo " --aws-secret-access-key [Required, on first run] AWS account secret access key." + echo " --aws-secret-access-key [Required, on first run] AWS account secret access key." echo " --aws-region [Required, on first run] AWS region for provisioning resources." echo " --rancher Install Rancher to manage the cluster." @@ -142,6 +142,9 @@ function checkInstallations { elif ([ "$provider" == "azure-devops" ] && ! [ -x "$(command -v az)" ]); then echo -e "${red}Error: Azure CLI is not installed." >&2 exit 127 + elif ([ "$provider" == "gitlab" ] && ! [ -x "$(command -v glab)" ]); then + echo -e "${red}Error: Azure CLI is not installed." >&2 + exit 127 fi # Check if Python is installed @@ -223,4 +226,4 @@ function setTargetDirectory { quarkus*) targetDirectory="./target/" ;; *) echo -e "${red}Error: Specified language '${language}' is not supported." >&2; exit 1 esac -} +} \ No newline at end of file diff --git a/scripts/pipelines/github/pipeline_generator.sh b/scripts/pipelines/github/pipeline_generator.sh index 556f6f248..eb1fcb02f 100644 --- a/scripts/pipelines/github/pipeline_generator.sh +++ b/scripts/pipelines/github/pipeline_generator.sh @@ -54,6 +54,19 @@ function obtainHangarPath { hangarPath=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && cd ../../.. && pwd ) } +function addAdditionalArtifact { + # Check if an extra artifact to store is supplied. + if test ! -z "$artifactPath" + then + # Add the extra step to the YAML. + storeExtraPathContent="\n - name: Publish Additional Output Artifact\n uses: actions\/upload-artifact@v3\n with:\n name: additional-pipeline-output\n path: \"\${{ env.artifactPath }}\"" + sed -i "s/# mark to insert step for additonal artifact #/$storeExtraPathContent\n/" "${localDirectory}/${pipelinePath}/${yamlFile}" + else + echo "The '-a' flag has not been set, skipping the step to add additional artifact." + sed -i '/# mark to insert step for additonal artifact #/d' "${localDirectory}/${pipelinePath}/${yamlFile}" + fi +} + # Function that adds the variables to be used in the pipeline. function addCommonPipelineVariables { if test -z "${artifactPath}" @@ -141,6 +154,8 @@ type addPipelineVariables &> /dev/null && addPipelineVariables copyYAMLFile +addAdditionalArtifact + copyCommonScript type copyScript &> /dev/null && copyScript @@ -152,6 +167,4 @@ commitCommonFiles type commitFiles &> /dev/null && commitFiles -# createPipeline - createPR diff --git a/scripts/pipelines/gitlab/pipeline_generator.sh b/scripts/pipelines/gitlab/pipeline_generator.sh new file mode 100644 index 000000000..3f04b4d29 --- /dev/null +++ b/scripts/pipelines/gitlab/pipeline_generator.sh @@ -0,0 +1,180 @@ +#!/bin/bash +set -e +FLAGS=$(getopt -a --options c:n:d:a:b:l:i:u:p:hw --long "config-file:,pipeline-name:,local-directory:,artifact-path:,target-branch:,language:,build-pipeline-name:,sonar-url:,sonar-token:,image-name:,registry-user:,registry-password:,resource-group:,storage-account:,storage-container:,cluster-name:,s3-bucket:,s3-key-path:,quality-pipeline-name:,dockerfile:,test-pipeline-name:,aws-access-key:,aws-secret-access-key:,aws-region:,help" -- "$@") + +eval set -- "$FLAGS" +while true; do + case "$1" in + -c | --config-file) configFile=$2; shift 2;; + -n | --pipeline-name) export pipelineName=$2; shift 2;; + -d | --local-directory) localDirectory=$2; shift 2;; + -a | --artifact-path) artifactPath=$2; shift 2;; + -b | --target-branch) targetBranch=$2; shift 2;; + -l | --language) language=$2; shift 2;; + --build-pipeline-name) export buildPipelineName=$2; shift 2;; + --sonar-url) sonarUrl=$2; shift 2;; + --sonar-token) sonarToken=$2; shift 2;; + -i | --image-name) imageName=$2; shift 2;; + -u | --registry-user) dockerUser=$2; shift 2;; + -p | --registry-password) dockerPassword=$2; shift 2;; + --resource-group) resourceGroupName=$2; shift 2;; + --storage-account) storageAccountName=$2; shift 2;; + --storage-container) storageContainerName=$2; shift 2;; + --cluster-name) clusterName=$2; shift 2;; + --s3-bucket) s3Bucket=$2; shift 2;; + --s3-key-path) s3KeyPath=$2; shift 2;; + --quality-pipeline-name) export qualityPipelineName=$2; shift 2;; + --test-pipeline-name) export testPipelineName=$2; shift 2;; + --dockerfile) dockerFile=$2; shift 2;; + --aws-access-key) awsAccessKey="$2"; shift 2;; + --aws-secret-access-key) awsSecretAccessKey="$2"; shift 2;; + --aws-region) awsRegion="$2"; shift 2;; + -h | --help) help="true"; shift 1;; + -w) webBrowser="true"; shift 1;; + --) shift; break;; + esac +done + +# Colours for the messages. +white='\e[1;37m' +green='\e[1;32m' +red='\e[0;31m' + +# Common var +commonTemplatesPath="scripts/pipelines/gitlab/templates/common" # Path for common files of the pipelines +pipelinePath=".pipelines" # Path to the pipelines. +scriptFilePath=".pipelines/scripts" # Path to the scripts. +gitlabCiFile=".gitlab-ci.yml" +export provider="gitlab" + +function obtainHangarPath { + + # This line goes to the script directory independent of wherever the user is and then jumps 3 directories back to get the path + hangarPath=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && cd ../../.. && pwd ) +} + +function addAdditionalArtifact { + # Check if an extra artifact to store is supplied. + if test ! -z "$artifactPath" + then + # Add the extra step to the YAML. + grep " artifacts:" "${localDirectory}/${pipelinePath}/${yamlFile}" > /dev/null && storeExtraPathContent=" - \"$artifactPath\"" + grep " artifacts:" "${localDirectory}/${pipelinePath}/${yamlFile}" > /dev/null || storeExtraPathContent="\n artifacts:\n paths:\n - \"$artifactPath\"" + sed -i "s/# mark to insert step for additonal artifact #/$storeExtraPathContent\n/" "${localDirectory}/${pipelinePath}/${yamlFile}" + else + echo "The '-a' flag has not been set, skipping the step to add additional artifact." + sed -i '/# mark to insert step for additonal artifact #/d' "${localDirectory}/${pipelinePath}/${yamlFile}" + fi +} + +# Function that adds the variables to be used in the pipeline. +function addCommonPipelineVariables { + if test -z "${artifactPath}" + then + echo "Skipping creation of the variable artifactPath as the flag has not been used." + # Delete the commentary to set the artifactPath input/var + sed -i '/# mark to insert additional artifact env var #/d' "${localDirectory}/${pipelinePath}/${yamlFile}" + else + # add the input for the additional artifact + grep "variables:" "${localDirectory}/${pipelinePath}/${yamlFile}" > /dev/null && textArtifactPathVar=" artifactPath: ${artifactPath//\//\\/}" + grep "variables:" "${localDirectory}/${pipelinePath}/${yamlFile}" > /dev/null || textArtifactPathVar="variables:\n artifactPath: \"${artifactPath//\//\\/}\"" + sed -i "s/# mark to insert additional artifact env var #/$textArtifactPathVar/" "${localDirectory}/${pipelinePath}/${yamlFile}" + fi +} + +function addCiFile { + echo -e "${green}Copying and commiting the gitlab ci file." + echo -ne ${white} + + cp "${hangarPath}/${commonTemplatesPath}/${gitlabCiFile}" "${localDirectory}/${gitlabCiFile}" + testCommit=$(git status) + if echo "$testCommit" | grep "nothing to commit, working tree clean" > /dev/null + then + echo "gilab-ci file already present with same content, nothing to commit." + else + git add "${gitlabCiFile}" -f + git commit -m "adding gitlab-ci.yml" + git push + fi +} + +function createPR { + # Check if a target branch is supplied. + if test -z "$targetBranch" + then + # No branch specified in the parameters, no Pull Request is created, the code will be stored in the current branch. + echo -e "${green}No branch specified to do the Pull Request, changes left in the ${sourceBranch} branch." + exit + else + echo -e "${green}Creating a Pull Request..." + echo -ne "${white}" + repoURL=$(git config --get remote.origin.url) + repoNameWithGit="${repoURL/https:\/\/gitlab.com\/}" + repoName="${repoNameWithGit/.git}" + # Create the Pull Request to merge into the specified branch. + #debug + echo "glab mr create -b \"$targetBranch\" -d \"merge request $sourceBranch\" -s \"$sourceBranch\" -H \"${repoName}\" -t \"merge $sourceBranch\"" + pr=$(glab mr create -b "$targetBranch" -d "merge request $sourceBranch" -s "$sourceBranch" -H "${repoName}" -t "merge $sourceBranch") + + # trying to merge + if glab mr merge -s $(basename "$pr") -y + then + # Pull Request merged successfully. + echo -e "${green}Pull Request merged into $targetBranch branch successfully." + exit + else + # Check if the -w flag is activated. + if [[ "$webBrowser" == "true" ]] + then + # -w flag is activated and a page with the corresponding Pull Request is opened in the web browser. + echo -e "${green}Pull Request successfully created." + echo -e "${green}Opening the Pull Request on the web browser..." + python -m webbrowser "$pr" + exit + else + # -w flag is not activated and the URL to the Pull Request is shown in the console. + echo -e "${green}Pull Request successfully created." + echo -e "${green}To review the Pull Request and accept it, click on the following link:" + echo "${pr}" + exit + fi + fi + fi +} + + +obtainHangarPath + +# Load common functions +. "$hangarPath/scripts/pipelines/common/pipeline_generator.lib" + +if [[ "$help" == "true" ]]; then help; fi + +ensurePathFormat + +importConfigFile + +checkInstallations + +createNewBranch + +type addPipelineVariables &> /dev/null && addPipelineVariables + +copyYAMLFile + +addAdditionalArtifact + +copyCommonScript + +type copyScript &> /dev/null && copyScript + +# This function does not exists for the github pipeline generator at this moment, but I let the line with 'type' to keep the same structure as the others pipeline generator +type addCommonPipelineVariables &> /dev/null && addCommonPipelineVariables + +commitCommonFiles + +type commitFiles &> /dev/null && commitFiles + +addCiFile + +createPR diff --git a/scripts/pipelines/gitlab/templates/common/.gitlab-ci.yml b/scripts/pipelines/gitlab/templates/common/.gitlab-ci.yml new file mode 100644 index 000000000..34904840a --- /dev/null +++ b/scripts/pipelines/gitlab/templates/common/.gitlab-ci.yml @@ -0,0 +1,12 @@ +include: + - '.pipelines/*.yml' + +stages: + - build + - test + - quality + - package + +default: + image: maven:3-jdk-11 + tags: ['docker_ruby'] \ No newline at end of file