diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000..95d23868e0 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,153 @@ +pipeline { + agent any + tools { + dockerTool 'docker' + } + environment { + IMAGENAME = 'blockscout-v2' // Set the image name as an environment variable + } + parameters { + choice(name: 'BUILD_TYPE', choices: ['patch', 'minor', 'major'], description: 'Select version to build in develop') + choice(name: 'NET', choices: ['stagenet', 'testnet', 'mainnet'], description: 'Select net type to build') + choice(name: 'CLOUD', choices: ['AZURE', 'GCP', 'AWS'], description: 'Select cloud operator to push docker image') + } + stages { + stage('GCP Release') { + when { + expression { return params.CLOUD == 'GCP' } + } + environment { + INCREMENT_TYPE = "${params.BUILD_TYPE}" + TAG = "${params.NET}" + GCR = "asia-south1-docker.pkg.dev/prod-dojima/${params.NET}" + } + steps { + script { + withCredentials([sshUserPrivateKey(credentialsId: 'dojimanetwork', keyFileVariable: 'SSH_KEY'), + string(credentialsId: 'gcloud-access-token', variable: 'GCLOUD_ACCESS_TOKEN'), + string(credentialsId: 'ci-registry-user', variable: 'CI_REGISTRY_USER'), + string(credentialsId: 'ci-registry', variable: 'CI_REGISTRY'), + string(credentialsId: 'ci-pat', variable: 'CR_PAT')]) { + // Set the SSH key for authentication + withEnv(["GIT_SSH_COMMAND=ssh -o StrictHostKeyChecking=no -i ${env.SSH_KEY}"]) { + echo "Selected action: $INCREMENT_TYPE, $TAG, $GCR" + sh 'gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin --password-stdin https://$GCR' + sh 'make release' + } + } + } + } + } + + stage('AZURE Release') { + when { + expression { return params.CLOUD == 'AZURE' } + } + environment { + INCREMENT_TYPE = "${params.BUILD_TYPE}" + } + steps { + script { + withCredentials([sshUserPrivateKey(credentialsId: 'dojimanetwork', keyFileVariable: 'SSH_KEY'), + string(credentialsId: 'azure-stagenet-cr-token', variable: 'AZURE_STAGENET_ACCESS_TOKEN'), + string(credentialsId: 'azure-mainnet-cr-token', variable: 'AZURE_MAINNET_ACCESS_TOKEN'), + string(credentialsId: 'azure-testnet-cr-token', variable: 'AZURE_TESTNET_ACCESS_TOKEN'), + string(credentialsId: 'ci-registry-user', variable: 'CI_REGISTRY_USER'), + string(credentialsId: 'ci-registry', variable: 'CI_REGISTRY'), + string(credentialsId: 'ci-pat', variable: 'CR_PAT'), + string(credentialsId: 'DOCKER_HUB_CREDENTIALS_ID', variable: 'DOCKER_PASSWORD')]) { + // Set the SSH key for authentication + withEnv(["GIT_SSH_COMMAND=ssh -o StrictHostKeyChecking=no -i ${env.SSH_KEY}"]) { + // Declaring env var here gives flexibility to modify within the scope + env.AZURE = "${params.NET}.azurecr.io" + def _azure = "${params.NET}.azurecr.io" + def _net = "${params.NET}" + env.TAG = "${params.NET}" + if (params.NET == "stagenet") { + sh 'echo $AZURE_STAGENET_ACCESS_TOKEN | docker login -u stagenet --password-stdin $AZURE' + } else if (params.NET == "mainnet") { + sh 'echo $AZURE_MAINNET_ACCESS_TOKEN | docker login -u mainnet --password-stdin $AZURE' + } else if (params.NET == "testnet") { + _azure = "${params.NET}1.azurecr.io" + sh """ + echo $AZURE_TESTNET_ACCESS_TOKEN | docker login -u testnet1 --password-stdin $_azure + """ + } + + // Overriding env var + env.AZURE = _azure + sh "/usr/bin/make azure-release AZURE=${env.AZURE} INCREMENT_TYPE=${params.BUILD_TYPE}" + + // Capture environment variables from Makefile after release + def buildInfo = sh(script: "make print-vars INCREMENT_TYPE=${params.BUILD_TYPE}", returnStdout: true).trim().split('\n') + def envVars = [:] + buildInfo.each { + def (key, value) = it.split('=') + envVars[key.trim()] = value.trim() + } + + // Assign values to Jenkins environment variables + env.GITREF = envVars['GITREF'] + env.VERSION = envVars['VERSION'] + + // Verify the captured environment variables + echo "Captured GITREF: ${env.GITREF}" + echo "Captured VERSION: ${env.VERSION}" + + def imageDigest = sh( + script: "docker inspect --format='{{index .RepoDigests 0}}' ${env.AZURE}/${IMAGENAME}:${GITREF}_${VERSION} | awk -F'@' '{print \$2}'", + returnStdout: true + ).trim() + + echo "Image Digest: ${imageDigest}" + + if (params.NET == 'mainnet') { + withCredentials([string(credentialsId: 'Gitops_PAT', variable: 'GIT_TOKEN')]) { + sh """ + cd ${WORKSPACE} + git clone https://${GIT_TOKEN}@github.com/dojimanetwork/helm_charts.git -b azure_master + cd helm_charts + sed -i "/^ frontend:/,/^ frontend:/s|^\\(\\s*tag:\\).*|\\1 ${GITREF}_${VERSION}|" dependency_charts/blockscout-v2-frontend/values.yaml + sed -i "/^ frontend:/,/^ frontend:/s|^\\(\\s*hash:\\).*|\\1 \"${imageDigest}\"|" dependency_charts/blockscout-v2-frontend/values.yaml + git add . + git commit -m "Update mainnet_hash with image digest ${imageDigest}" + git push origin azure_master + cd ${WORKSPACE} && rm -r helm_charts + """ + } + } else if (params.NET == "testnet") { + withCredentials([string(credentialsId: 'Gitops_PAT', variable: 'GIT_TOKEN')]) { + sh """ + cd ${WORKSPACE} + git clone https://${GIT_TOKEN}@github.com/dojimanetwork/helm_charts.git -b azure_develop + cd helm_charts + sed -i "/^ frontend:/,/^ frontend:/s|^\\(\\s*tag:\\).*|\\1 ${GITREF}_${VERSION}|" dependency_charts/blockscout-v2-frontend/values.yaml + sed -i "/^ frontend:/,/^ frontend:/s|^\\(\\s*hash:\\).*|\\1 \"${imageDigest}\"|" dependency_charts/blockscout-v2-frontend/values.yaml + git add . + git commit -m "Update testnet_hash with image digest ${imageDigest}" + git push origin azure_develop + cd ${WORKSPACE} && rm -r helm_charts + """ + } + } else if (params.NET == "stagenet") { + withCredentials([string(credentialsId: 'Gitops_PAT', variable: 'GIT_TOKEN')]) { + sh """ + cd ${WORKSPACE} + git clone https://${GIT_TOKEN}@github.com/dojimanetwork/helm_charts.git -b azure_stagenet + cd helm_charts + sed -i "/^ frontend:/,/^ frontend:/s|^\\(\\s*tag:\\).*|\\1 ${GITREF}_${VERSION}|" dependency_charts/blockscout-v2-frontend/values.yaml + sed -i "/^ frontend:/,/^ frontend:/s|^\\(\\s*hash:\\).*|\\1 \"${imageDigest}\"|" dependency_charts/blockscout-v2-frontend/values.yaml + git add . + git commit -m "Update stagenet_hash with image digest ${imageDigest}" + git push origin azure_stagenet + cd ${WORKSPACE} && rm -r helm_charts + """ + } + } + } + } + } + } + } + } +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..466168d106 --- /dev/null +++ b/Makefile @@ -0,0 +1,59 @@ +BRANCH?=$(shell git rev-parse --abbrev-ref HEAD | sed -e 's/develop/testnet/g;s/stage/stagenet/g;s/prod/mainnet/g') +GITREF=$(shell git rev-parse --short HEAD) +BUILDTAG?=$(shell git rev-parse --abbrev-ref HEAD | sed -e 's/prod/mainnet/g;s/develop/testnet/g;s/testnet-multichain/testnet/g;s/stage/stagenet/g') +# pull branch name from CI, if available +ifdef CI_COMMIT_BRANCH + BRANCH=$(shell echo ${CI_COMMIT_BRANCH} | sed 's/master/mocknet/g') + BUILDTAG=$(shell echo ${CI_COMMIT_BRANCH} | sed -e 's/master/mocknet/g;s/develop/mocknet/g;s/testnet-multichain/testnet/g;s/stage/stagenet/g') +endif +VERSION=$(shell bash ./get_next_git_tag.sh ${INCREMENT_TYPE}) +TAG=$(shell date +%Y-%m-%d) +DATE=$(shell date +%Y-%m-%d) + + +# ------------------------------- GitLab ------------------------------- # +git-pull: ## Git pull repository + @git clean -idf + @git pull origin $(shell git rev-parse --abbrev-ref HEAD) + +docker-login: + docker login -u ${CI_REGISTRY_USER} -p ${CR_PAT} ${CI_REGISTRY} + +url-check: + @if [ -z "${GCR}" ]; then\ + echo "add gcr env variable";\ + exit 1;\ + fi + +azure-check: + @if [ -z "${AZURE}"]; then\ + echo "add azure env variable";\ + exit 1;\ + fi + +azure-build: azure-check + DOCKER_BUILDKIT=1 docker build -f ./Dockerfile --build-arg CI_PAT=${CI_PAT} -t ${AZURE}/${IMAGENAME}:${GITREF}_${VERSION} --build-arg TAG=${TAG} . + +azure-push: + docker push ${AZURE}/${IMAGENAME}:${GITREF}_${VERSION} + +docker-push: + docker push ${GCR}/${IMAGENAME}:${GITREF}_${VERSION} + +docker-build: + DOCKER_BUILDKIT=1 docker build -f ./Dockerfile --build-arg CI_PAT=${CI_PAT} -t ${GCR}/${IMAGENAME}:${GITREF}_${VERSION} --build-arg TAG=${TAG} . + +push-tag: + bash ./push_tag.sh ${VERSION} + +release: docker-build docker-push push-tag + +azure-release: azure-build azure-push + +push-only-image: docker-build docker-push + +print-vars: + @echo "GITREF=$(GITREF)" + @echo "VERSION=$(VERSION)" + +# ------------------------------------------------------------------ # diff --git a/get_next_git_tag.sh b/get_next_git_tag.sh new file mode 100644 index 0000000000..d30c57cc0f --- /dev/null +++ b/get_next_git_tag.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +INCREMENT_TYPE=$1 + +# Fetch tags from the remote repository +git fetch --tags + +# Get the latest tag +latest_tag=$(git describe --tags --abbrev=0) + +# Split the version into major, minor, and patch parts +IFS='.' read -r -a parts <<< "$latest_tag" +major=${parts[0]} +minor=${parts[1]} +patch=${parts[2]} + +# Increment the version based on the provided type +case "$INCREMENT_TYPE" in + major) + ((major++)) + minor=0 + patch=0 + ;; + minor) + ((minor++)) + patch=0 + ;; + patch) + ((patch++)) + ;; + *) + echo "Invalid increment type. Use 'major', 'minor', or 'patch'." + exit 1 + ;; +esac + +new_tag="$major.$minor.$patch" + +echo $new_tag