added files

This commit is contained in:
Your Name
2026-08-26 02:02:24 +05:30
parent 58ee8a276a
commit 3419cfba0c
200 changed files with 22132 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
package com.meesho.utilities
def create() {
withCredentials([file(credentialsId: 'ssh-private-key', variable: 'FILE')]) {
sh """
cat ${FILE} > ./id_github_jenkins
chmod 600 ./id_github_jenkins
# Ensure .ssh directory has correct permissions
chmod 700 /root/.ssh
# Fix SSH config file permissions if it exists
if [ -f /root/.ssh/config ]; then
chmod 600 /root/.ssh/config
chown root:root /root/.ssh/config
fi
# Fix existing SSH private key permissions if it exists
if [ -f /root/.ssh/id_rsa ]; then
chmod 600 /root/.ssh/id_rsa
chown root:root /root/.ssh/id_rsa
fi
# Fix any other SSH key files that might exist
find /root/.ssh -type f -name "id_*" -exec chmod 600 {} \\; 2>/dev/null || true
"""
}
}
@@ -0,0 +1,125 @@
/*
Purpose: Utility function to return BU and their respective teams
Author: Avinash kumar Lodhi
*/
package com.meesho.utilities
def validate(String bu, String team) {
def bu_team_map = ['supply':['supplier-ads', 'supplier-ads-frontend', 'experience', 'fulfilment', 'fulfilment-frontend','financial-services', 'cataloging', 'cataloging-frontend', 'payout', 'payout-frontend', 'supplier-acquisition-activation', 'supplier-service', 'returns', 'supply-shared', 'display-ads', 'offers','transact', 'supplier-live-commerce'],
'demand':['comms-platform', 'live-commerce', 'shopping-platform', 'product-feed', 'search', 'product-meta', 'user-growth', 'web', 'transact', 'communications', 'discovery-platform', 'offers', 'android-platform', 'ios', 'demand-shared', 'discovery-ranking'],
'farmiso':['farmiso'],
'admin':['devops'],
'central':['shared', 'devops', 'psec', 'dbe'],
'dataengg':['data-platform', 'dataengg-shared', 'data-intelligence', 'data-platform-consumption', 'data-platform-ingestion', 'data-platform-nrt', 'data-platform-prism-frmw', 'data-platform-experimentation'],
'datascience':['data-science', 'ml-platform', 'for-you', 'recommendation', 'catalog-listing-page', 'search', 'advertisement', 'explore', 'pricing', 'product-match', 'catalog-taxonomy', 'brand-infringment', 'fds', 'return-reimbursements', 'fullfilment', 'ugc-moderation-analysis', 'home-page', 'core', 'usergrowth', 'demand-forecast', 'catalog-qc'],
'mcache':['mcache', 'mcache-shared', 'supplier-service'],
'infra':['devops', 'dbe']
]
if (bu == null || team == null) {
return null
}
return bu_team_map[bu].contains(team)
}
def get_initials(String targetMap, String targetString) {
def bu_initials = ['supply':'supl',
'demand':'dmnd',
'farmiso':'farm',
'admin':'admn',
'central':'cntr',
'dataengg':'deng',
'datascience':'dsci',
'mcache':'mche',
'infra':'infr'
]
def team_initials = ['supplier-ads':'ads',
'comms-platform': 'cplat',
'supplier-ads-frontend':'fads',
'experience':'xp',
'fulfilment':'fnf',
'fulfilment-frontend':'ffnf',
'financial-services':'fsvc',
'cataloging':'ctlng',
'cataloging-frontend':'fctlg',
'payout':'pay',
'payout-frontend':'fpay',
'supplier-acquisition-activation':'saa',
'supplier-service':'ssvc',
'seller-services': 'sis',
'live-commerce':'lcom',
'shopping-platform':'splat',
'product-feed':'pfeed',
'search':'srch',
'product-meta':'pmeta',
'user-growth':'grwth',
'web':'web',
'transact':'trnst',
'communications':'comms',
'discovery-platform':'dplat',
'farmiso':'farm',
'devops':'devop',
'offers':'offer',
'returns':'retrn',
'android-platform':'andrd',
'ios':'ios',
'shared':'xcntr',
'supply-shared':'xsupl',
'demand-shared':'xdmnd',
'data-platform':'dp',
'data-science':'ds',
'ml-platform':'ml',
'dataengg-shared':'xdeng',
'datascience-shared':'xdsci',
'data-intelligence':'di',
'recommendation':'rcmnd',
'catalog-listing-page':'ctllp',
'advertisement':'adv',
'explore':'explr',
'pricing':'price',
'product-match':'patch',
'catalog-taxonomy':'ctltx',
'brand-infringment':'brndi',
'fds':'fds',
'return-reimbursements':'retrr',
'fullfilment':'flfmt',
'ugc-moderation-analysis':'umdra',
'home-page':'hpage',
'usergrowth':'ugrwt',
'demand-forecast':'dmndf',
'catalog-qc':'ctlqc',
'data-platform-consumption':'dpcon',
'data-platform-ingestion':'dping',
'data-platform-nrt':'dpnrt',
'data-platform-prism-frmw':'dpprf',
'data-platform-experimentation':'dpexp',
'display-ads':'dplay',
'discovery-ranking':'drank',
'mcache':'mche',
'mcache-shared':'xmche',
'supplier-live-commerce':'slcom',
'trust-and-safety': 'tns',
'valmo': 'vlm',
'psec':'psec',
'dbe':'dbe',
'dev-productivity':'devprd']
if (targetString == null) {
return null
}
switch (targetMap) {
case 'bu_initials':
return bu_initials[targetString]
case 'team_initials':
return team_initials[targetString]
default:
return 'Undefined option'
}
}
def get_team_initials(String team) {
return get_initials('team_initials', team)
}
def get_bu_initials(String bu) {
return get_initials('bu_initials', bu)
}
@@ -0,0 +1,391 @@
package com.meesho.utilities
def getWhitelistedRepos(fileName){
dir('whitelist'){
git(
url: "https://github.com/Meesho/whitelists.git",
branch: "main",
credentialsId: 'cicd-github-app',
)}
def yaml = readYaml file: "whitelist/${fileName}.yaml"
return yaml.get("repos", []) as Set
}
def getWhitelistedDeployable(fileName, keyName){
dir('whitelist'){
git(
url: "https://github.com/Meesho/whitelists.git",
branch: "main",
credentialsId: 'cicd-github-app',
)}
def yaml = readYaml file: "whitelist/${fileName}.yaml"
return yaml.get(keyName, []) as Set
}
/*
* return `true` if we should not proceed
*/
def isMultizoneEnabled( String deployable){
def WHITELIST = getWhitelistedDeployable("multizone-enabled-repos" , "multizone_enabled_deployables")
if (WHITELIST.contains(deployable)) {
return true
}
return false
}
/*
* return `true` if we should not proceed
*/
def skipSonarCheckForbidden(Map config, Map environment_map) {
def branch = env.BRANCH_NAME
def environment = environment_map.getOrDefault(branch, "int")
def WHITELIST = getWhitelistedRepos("skip-sonar-whitelist")
// returns 'true' if we aren't skipping sonar
// or if we're allowed to skip sonar
def build_version = config['dockerBuildVersion']
def repo_name = config['repo_name']
// if not a maven build OR if it a hotfix we exit early and dont care what skip_sonar is
if (WHITELIST.contains(repo_name)|| !(build_version.contains("maven")) || environment != "prd" || branch.contains("hotfix")){
return false;
}
return config['skip_sonar'];
}
def skipSonarCheckForGo(Map config) {
def branch = env.BRANCH_NAME
def WHITELIST = getWhitelistedRepos("skip-sonar-whitelist")
def build_version = config['dockerBuildVersion']
def repo_name = config['repo_name']
echo "env.INFRA_ENV: ${env.INFRA_ENV}"
if (WHITELIST.contains(repo_name)|| branch.contains("hotfix")|| env.INFRA_ENV == "toolchain"){
return true;
}
return false;
}
/*
* return `true` if we should not proceed
*/
def appConfigDisabledForbidden(boolean appConfigEnabled, String repo_name, String environment, String build_version){
def branch = env.CHANGE_TARGET
def WHITELIST = getWhitelistedRepos("app-config-disabled")
if (WHITELIST.contains(repo_name) || environment!="stg"){
return false
}
if (!(build_version.contains("maven") || build_version.contains("gradle"))){
return false
}
return !appConfigEnabled
}
/*
* return `true` if we should not proceed
*/
def allowedNonDevelopPrDeploymentToIntRepos( String repo_name){
def WHITELIST = getWhitelistedRepos("allowedNonDevelopPrDeploymentToInt")
if (WHITELIST.contains(repo_name)) {
return true
}
return false
}
/*
* return `true` if we should not proceed
*/
def ValidateCacConfigForRepo(boolean ValidateConfig, String repo_name ){
def branch = env.CHANGE_TARGET
def WHITELIST = getWhitelistedRepos("ValidateCacConfig")
if (WHITELIST.contains(repo_name)) {
return true
}
return ValidateConfig
}
def getToolchainEnv() {
def paramsAction = currentBuild.rawBuild.getAction(hudson.model.ParametersAction.class)
if (paramsAction) {
echo "paramsAction: ${paramsAction}"
def p = paramsAction.getParameter("TOOLCHAIN_ENV")
echo "p: ${p}"
if (p) {
return p.getValue()?.toString()
}
}
return null
}
def run(Map config) {
def branch_name = env.BRANCH_NAME
if (env.INFRA_ENV == 'toolchain' && (config.build_tool?.startsWith('node-') || config.dockerBuildVersion?.startsWith('node-'))) {
branch_name = 'develop' // develop maps to stg in the environment_map
def tcEnv = getToolchainEnv()
env.TOOLCHAIN_ENV = tcEnv
log.info("Successfully extracted TOOLCHAIN_ENV from trigger cause: ${env.TOOLCHAIN_ENV}")
}
def environment_map = ['master':'prd', 'main':'prd', 'develop':'stg', 'gcp-main':'prd', 'farmiso-main':'prd', 'gcp-master':'prd', 'gcp-dev':'stg']
env.skip_user_input = config.skip_user_input ?: false
// don't allow skip_sonar
if (skipSonarCheckForbidden(config, environment_map)){
throw new Exception("Not allowed to skip sonar (skip_sonar in config.yaml)")
}
if (env.CHANGE_ID) {
branch_name = env.CHANGE_TARGET
environment_map = ['master':'int', 'main':'int', 'gcp-main':'int', 'farmiso-main':'int', 'gcp-master':'int', 'develop':'ftr', 'gcp-dev':'ftr']
}
environment_map[branch_name] = environment_map[branch_name] ?: 'ftr'
if (config.containsKey('branch_params')) {
Map branch_config = config['branch_params'].collectEntries { key, value -> branch_name.matches(key) ? value : [ : ] }
config.remove('branch_params')
config.putAll(branch_config)
}
if (config.containsKey('environment')) {
Map envrionment_config = config['environment'].collectEntries { key, value -> environment_map[branch_name].matches(key) ? value : [ : ] }
config.remove('environment')
config.putAll(envrionment_config)
}
env.GITHUB_CRED = 'svc-devops-meesho'
env.cicd_environment = environment_map[branch_name]
env.helm_repo_name = 'devops-helm-charts'
env.argo_repo_name = 'devops-argo-config'
echo "Branch Name - ${branch_name} and Environment - ${env.cicd_environment}"
if (env.CLOUD_PROVIDER == 'AWS') {
def prodAccountID = '847438129436'
def prodRegion = 'ap-southeast-1'
def prodObjBucket = 'meesho-prod-artifacts'
def devAccountID = '766380763301'
def devObjBucket = 'meesho-stg-artifacts'
def devRegion = 'ap-south-1'
def accountDetails = [
'prd': [
'accountID': prodAccountID,
'region': prodRegion,
'objBucket': prodObjBucket
],
'int': [
'accountID': prodAccountID,
'region': prodRegion,
'objBucket': prodObjBucket
],
'stg': [
'accountID': devAccountID,
'region': devRegion,
'objBucket': devObjBucket
],
'ftr': [
'accountID': devAccountID,
'region': devRegion,
'objBucket': devObjBucket
]
]
env.accountID = accountDetails[env.cicd_environment]['accountID']
env.region = accountDetails[env.cicd_environment]['region']
env.registry = "${env.accountID}.dkr.ecr.${env.region}.amazonaws.com"
env.buildRegistry = env.registry
env.helmChartsPath = 'charts'
env.defaultHelmChartVersion = '1.0.10'
env.objBucket = accountDetails[env.cicd_environment]['objBucket']
env.skip_notify = false
echo "${env.accountID}.dkr.ecr.${env.region}.amazonaws.com"
}
else if (env.CLOUD_PROVIDER == 'GCP') {
def prodVaultURL = 'https://vault-prd.meeshogcp.in'
def prodVaultToken = 'vault-prd-token'
def prodSonarURL = 'https://sonarqube-prd.meeshogcp.in'
def prodSonarToken = 'sonar-token-prod'
def prodSonarEnv = 'sonarqube-test'
def prodGoProxyUrl = 'https://athens-prd.meeshogcp.in'
def prdDockerHost = 'dind-prd-svc'
def preProdDockerHost = 'dind-int-svc'
def prodGCPProject = "meesho-${config.bu}-prd-0622"
def preprodGCPProject = "meesho-shared-int-0525"
def devVaultURL = 'https://vault-dev.meeshogcp.in'
def devVaultToken = 'vault-dev-token'
def devSonarURL = "https://sonarqube-${config.bu}-dev.meeshogcp.in"
def devSonarToken = "sonar-token-${config.bu}-dev"
def devSonarEnv = "sonar-${config.bu}-dev"
def devGoProxyUrl = 'https://athens-dev.meeshogcp.in'
def devGCPProject = "meesho-${config.bu}-dev-0622"
def devDockerHost = 'dind-dev-new-svc.jenkins-new.svc.cluster.local'
def toolchainDockerHost = 'toolchain-dind-dev-svc.jenkins-toolchain.svc.cluster.local'
def accountDetails = [
'prd': [
'vaultURL': prodVaultURL,
'vaultToken': prodVaultToken,
'sonarURL': prodSonarURL,
'sonarToken': prodSonarToken,
'GCPProject': prodGCPProject,
'sonarEnv': prodSonarEnv,
'GCPLBProject': prodGCPProject,
'goProxyUrl': prodGoProxyUrl,
'dockerHost': prdDockerHost
],
'int': [
'vaultURL': prodVaultURL,
'vaultToken': prodVaultToken,
'sonarURL': prodSonarURL,
'sonarToken': prodSonarToken,
'GCPProject': preprodGCPProject,
'sonarEnv': prodSonarEnv,
'GCPLBProject': prodGCPProject,
'goProxyUrl': prodGoProxyUrl,
'dockerHost': preProdDockerHost
],
'stg': [
'vaultURL': devVaultURL,
'vaultToken': devVaultToken,
'sonarURL': devSonarURL,
'sonarToken': devSonarToken,
'GCPProject': devGCPProject,
'sonarEnv': devSonarEnv,
'GCPLBProject': devGCPProject,
'goProxyUrl': devGoProxyUrl,
'dockerHost': devDockerHost
],
'ftr': [
'vaultURL': devVaultURL,
'vaultToken': devVaultToken,
'sonarURL': devSonarURL,
'sonarToken': devSonarToken,
'GCPProject': devGCPProject,
'sonarEnv': devSonarEnv,
'GCPLBProject': devGCPProject,
'goProxyUrl': devGoProxyUrl,
'dockerHost': devDockerHost ]
]
env.GCPProject = accountDetails[env.cicd_environment]['GCPProject']
env.GCPLBProject = accountDetails[env.cicd_environment]['GCPLBProject']
env.registry = 'asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622'
if (env.INFRA_ENV == 'toolchain') {
env.registry = 'asia-southeast1-docker.pkg.dev/meesho-central-dev-0622/toolchain'
}
env.buildRegistry = 'asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin'
env.helmChartsPath = env.cicd_environment == 'prd' ? 'values_v3' : 'values_v2'
env.defaultHelmChartVersion = '2.0.0'
env.objBucket = "gcs-infr-dvps-meesho-artifacts-${env.cicd_environment}"
env.vaultURL = accountDetails[env.cicd_environment]['vaultURL']
env.vaultToken = accountDetails[env.cicd_environment]['vaultToken']
env.sonarURL = accountDetails[env.cicd_environment]['sonarURL']
env.sonarToken = accountDetails[env.cicd_environment]['sonarToken']
env.sonarEnv = accountDetails[env.cicd_environment]['sonarEnv']
env.goProxyUrl = accountDetails[env.cicd_environment]['goProxyUrl']
env.skip_notify = true
env.DOCKER_HOST = accountDetails[env.cicd_environment]['dockerHost']
if (env.INFRA_ENV == 'toolchain') {
env.DOCKER_HOST = toolchainDockerHost
}
}
echo "Bucket and Image Repo Details - ${env.registry} ${env.buildRegistry} ${env.objBucket}"
echo "Docker Host - ${env.DOCKER_HOST}"
}
def perDeploymentVars(Map value_binding) {
env.BU = value_binding.bu
echo "${env.BU}"
if (env.CLOUD_PROVIDER == 'AWS') {
def inClusterName = 'https://kubernetes.default.svc'
def prodArgoURL = 'prod-ops-argocd.meesho.com'
def devArgoURL = 'stg-dev-argocd.meeshotest.in'
def prodK8sCluster = [
'supply': 'https://211689C65F4496AAA76FE19B29E24B6E.yl4.ap-southeast-1.eks.amazonaws.com',
'demand': 'https://9059D138B6277A0EA592BA7F4B680CEC.gr7.ap-southeast-1.eks.amazonaws.com',
'dataengg': 'https://806ADE97231CA65D2A0FFB780352630D.yl4.ap-southeast-1.eks.amazonaws.com',
'datascience': 'https://E34D119516F751AFD1A61043B0514726.yl4.ap-southeast-1.eks.amazonaws.com',
'central': 'https://C95FCEDF7CEE890F531E1D0488BEC6C3.gr7.ap-southeast-1.eks.amazonaws.com',
'mcache': 'https://2FFADF214AD8BE58769C5F2797987E50.gr7.ap-southeast-1.eks.amazonaws.com'
]
def devK8sCluster = [
'supply': inClusterName,
'demand': inClusterName,
'dataengg': inClusterName,
'datascience': inClusterName,
'central': inClusterName,
'mcache': inClusterName
]
def accountDetails = [
'prd': [
'argoURL': prodArgoURL,
'argoIncubator': 'prod-app-of-apps',
'serverMap': prodK8sCluster
],
'int': [
'argoURL': prodArgoURL,
'argoIncubator': 'int-app-of-app',
'serverMap': prodK8sCluster
],
'stg': [
'argoURL': devArgoURL,
'argoIncubator': 'app-of-apps',
'serverMap': devK8sCluster
],
'ftr': [
'argoURL': devArgoURL,
'argoIncubator': 'ftr-app-of-apps',
'serverMap': devK8sCluster
]
]
env.clusterName = accountDetails[env.cicd_environment]['serverMap'][env.BU]
env.argoAppsPath = 'applications'
env.argoURL = accountDetails[env.cicd_environment]['argoURL']
env.argoCreds = 'argocd-jenkins'
env.argoIncubator = accountDetails[env.cicd_environment]['argoIncubator']
env.argoAppNS = 'argocd'
}
else if (env.CLOUD_PROVIDER == 'GCP') {
def prodArgoURL = "argocd-${env.BU}-prd.meeshogcp.in"
def prodArgoCreds = "argocd-${env.BU}-prd-creds"
def preprodArgoURL = "argocd-shared-int.meeshogcp.in"
def preprodArgoCreds = "argocd-shared-int-creds"
def devArgoURL = 'argocd-dev.meeshogcp.in'
def devArgoCreds = 'argocd-dev-creds'
def accountDetails = [
'prd': [
'argoURL': prodArgoURL,
'argoCreds': prodArgoCreds,
'argoAppNS': "argocd-${env.BU}-prd",
'clusterName': "k8s-${env.BU}-prd-ase1"
],
'int': [
'argoURL': preprodArgoURL,
'argoCreds': preprodArgoCreds,
'argoAppNS': "argocd-shared-int",
'clusterName': "k8s-shared-int-ase1"
],
'stg': [
'argoURL': devArgoURL,
'argoCreds': devArgoCreds,
'argoAppNS': "argocd-dev",
'clusterName': "k8s-${env.BU}-stg-ase1"
],
'ftr': [
'argoURL': devArgoURL,
'argoCreds': devArgoCreds,
'argoAppNS': "argocd-dev",
'clusterName': "k8s-${env.BU}-stg-ase1"
]
]
env.clusterName = accountDetails[env.cicd_environment]['clusterName']
if (env.cicd_environment == 'int') {
env.argoAppsPath = "applications_v2/k8s-${env.BU}-int-ase1"
} else {
env.argoAppsPath = "applications_v2/${env.clusterName}"
}
env.argoURL = accountDetails[env.cicd_environment]['argoURL']
env.argoCreds = accountDetails[env.cicd_environment]['argoCreds']
env.argoAppNS = accountDetails[env.cicd_environment]['argoAppNS']
env.argoIncubator = "incubator-apps-k8s-${env.BU}-${env.cicd_environment}-ase1"
}
echo "${env.clusterName} ${env.argoURL} ${env.argoIncubator}"
}
@@ -0,0 +1,51 @@
package com.meesho.utilities
def run(Map binding, String text) {
return _construct(binding, text)
}
def renderTemplate(Map binding, String templateFile, String fileName) {
def template = libraryResource 'com/meesho/' + templateFile
// Generic add_file support (language-agnostic): user repos declare files to bake
// into the image under `add_file` in config.yaml -- either a single {path, target}
// mapping or a list of them. renderTemplate always runs inside dir(repo_name), so
// config.yaml resolves to the repo's config. The Dockerfile templates COPY each entry
// into the image. Set for every render so the `add_files.each { ... }` guard never
// hits a missing binding var. This is the one language-agnostic convention for
// mounting extra files (e.g. the ab-client SDK's configs/abacus_experiments.yml ->
// /opt/config/abacus_experiments.yml).
binding['add_files'] = resolveAddFiles()
def renderedTemplate = run(binding, template.toString())
writeFile file:fileName, text: renderedTemplate
}
// resolveAddFiles reads config.yaml (if present) and normalises the optional `add_file`
// list into a list of [path, target] maps. `add_file` is a list of {path, target}
// entries; each entry's target defaults to /opt/target when omitted; entries without a
// path are skipped. A non-list add_file is ignored.
def resolveAddFiles() {
if (!fileExists('config.yaml')) {
return []
}
def cfg = readYaml file: 'config.yaml'
def entries = cfg?.add_file
if (!(entries instanceof List)) {
return []
}
def result = []
entries.each { entry ->
if (entry?.path) {
result.add([path: entry.path, target: entry.target ?: '/opt/target'])
}
}
return result
}
@NonCPS
def _construct(Map binding, String text) {
binding = new HashMap(binding)
def engine = new groovy.text.SimpleTemplateEngine()
def template = engine.createTemplate(text).make(binding)
engine = null
return template.toString()
}
@@ -0,0 +1,52 @@
package com.meesho.utilities
def retryDockerPush(String cmd) {
int maxAttempts = 5
int attempt = 1
while (attempt <= maxAttempts) {
try {
sh cmd
break
} catch (err) {
if (attempt == maxAttempts) {
error("Command failed after ${maxAttempts} attempts: ${err}")
}
echo "Command failed, retrying... (${attempt}/${maxAttempts})"
sleep 3
attempt++
}
}
}
def imageExists(String registry, String repoName, String tag) {
int maxAttempts = 5
int attempt = 1
while (attempt <= maxAttempts) {
try {
if (env.CLOUD_PROVIDER == 'GCP') {
def result = sh(
script: "gcloud container images list-tags ${registry}/${repoName} --filter='tags:${tag}' --format='get(tags)'",
returnStdout: true
).trim()
return result != ""
}
else if (env.CLOUD_PROVIDER == 'AWS') {
echo "AWS not supported."
return false
}
} catch (Exception e) {
echo "Attempt ${attempt}/${maxAttempts} failed: Error checking image existence: ${e.toString()}"
if (attempt == maxAttempts) {
echo "Max attempts reached. Assuming image does not exist or service is down."
return false
}
echo "Retrying in 5 seconds..."
sleep 5
attempt++
}
}
return false
}
@@ -0,0 +1,61 @@
package com.meesho.utilities
def getCommitid(String repo_name) {
dir(repo_name) {
def gitCmd = env.INFRA_ENV == 'toolchain' ? 'git -c safe.directory="$(pwd)"' : 'git'
def commitID = sh(returnStdout: true, script: "${gitCmd} log -1 --format=%h").trim()
env.commit_id = sh(returnStdout: true, script: "${gitCmd} log -1 --format=%H").trim()
return commitID
}
}
def getVersion(String repo_name) {
dir(repo_name) {
if (fileExists('pom.xml')) {
return sh(returnStdout: true, script: 'xq -r .project.version pom.xml').trim()
}
else if (fileExists('package.json')) {
return sh(returnStdout: true, script: 'jq -r .version package.json').trim()
}
else {
return '1.0'
}
}
}
def getModules(String repo_name) {
dir(repo_name) {
if (fileExists('pom.xml')) {
modules = sh(returnStdout: true, script: 'xq -r .project.modules.module[] pom.xml 2>/dev/null || xq -r .project.modules.module pom.xml 2>/dev/null || echo empty').trim()
if (modules == 'empty' || modules == 'null') {
return null
}
modules = modules.split('\n') as List
return modules
}
else {
return null
}
}
}
def getTag(String repo_name) {
def version = getVersion(repo_name)
def commitID = getCommitid(repo_name)
def date = new Date()
def timesha = date.getTime()
def tag = "v${version}-${commitID}-${timesha}"
if (env.INFRA_ENV == 'toolchain') {
tag = "v${version}-${commitID}"
}
return tag
}
def getTagShort(String repo_name) {
def version = getVersion(repo_name)
def commitID = getCommitid(repo_name)
def tagShort = "v${version}-${commitID}"
return tagShort
}
@@ -0,0 +1,16 @@
package com.meesho.utilities
def getParam(String wd, String fileName = 'config.yaml') {
dir(wd) {
def config = readYaml file: fileName
return config
}
}
//read as string
def getParamAsString(String wd, String fileName = 'config.yaml') {
dir(wd) {
// Read the entire file content as a string
def yamlContent = readFile(file: fileName)
return yamlContent
}
}
+342
View File
@@ -0,0 +1,342 @@
package com.meesho.utilities
def clone(String path, String repo_name, String branch_name) {
log.info("Cloning repo - ${repo_name}, branch - ${branch_name} in path - ${path}")
dir(path) {
try {
sh "rm -rf ${repo_name}"
}
catch (Exception e) {
log.info('Repo not present, proceeding to clone the repo.')
}
try {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
if (branch_name) {
sh "git clone -b ${branch_name} https://github.com/Meesho/${repo_name}.git"
}
else {
sh "git clone https://github.com/Meesho/${repo_name}.git"
}
}
}
catch (Exception e) {
env.msg += "\n\nFAILED -\n ```Unable to clone repo - ${repo_name}, branch - ${branch_name} in path - ${path}.\n Full Erroror Details - ${e}```"
env.error_msg_to_db += "Unable to Clone Repo ${repo_name};"
log.error("${env.msg}")
throw e
}
}
}
def branchCheckOut(String path, String branch_name) {
log.info("Checking out to branch - ${branch_name} in path - ${path}")
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
sh 'git fetch'
try {
sh "git checkout ${branch_name}"
sh 'git pull --ff-only'
}
catch (Exception e) {
log.info('Creating new branch')
sh "git checkout -b ${branch_name}"
}
sh 'git branch'
}
}
}
def add(String path, String git_add_file) {
log.info("Adding files - ${git_add_file} to git, in path - ${path}")
try {
dir(path) {
sh "git add ${git_add_file}"
}
}
catch (Exception e) {
env.msg += "\n\nFAILED -\n ```Unable to add files - ${git_add_file} to git, in path - ${path}.\n Full Erroror Details - ${e}```"
env.error_msg_to_db += 'Unable to Add Files;'
log.error("${env.msg}")
throw e
}
}
def createTag(path, git_tag, tag_message) {
log.info("Creating tag - ${git_tag} in git, in path - ${path}")
try {
dir(path) {
sh "git tag ${git_tag} -m '${tag_message}'"
}
}
catch (Exception e) {
env.msg += "\n\nFAILED -\n ```Unable to create tag - ${git_tag} in git, in path - ${path}.\n Full Erroror Details - ${e}```"
env.error_msg_to_db += "Unable to Create Tag ${git_tag};"
log.error("${env.msg}")
throw e
}
}
def codeCommit(String path, String branch_name, String commit_message) {
log.info("Commiting code with message - ${commit_message} in git, in path - ${path}")
def global_arg = '--global'
def gitName = 'svc-devops-meesho'
def gitEmail = 'devops@meesho.com'
def gitEnv = [
"GIT_AUTHOR_NAME=${gitName}",
"GIT_AUTHOR_EMAIL=${gitEmail}",
"GIT_COMMITTER_NAME=${gitName}",
"GIT_COMMITTER_EMAIL=${gitEmail}",
]
dir(path) {
withEnv(gitEnv) {
if (sh(returnStatus: true, script: "git diff-index --quiet ${branch_name} 2>/dev/null")) {
try {
sh "git commit -m '${commit_message}'"
return 0
}
catch (Exception e) {
env.msg += "\n\nFAILED -\n ```Unable to commit code with message - ${commit_message} to git in path - ${path}.\n Full Erroror Details - ${e}```"
env.error_msg_to_db += 'Unable to Commit;'
log.error("${env.msg}")
return 1
}
}
else {
log.info("No changes were made in branch - ${branch_name}")
return 1
// log.error("${env.msg}")
}
}
}
}
def codePush(String path, String branch_name) {
log.info("Pushing code in branch - ${branch_name} in path - ${path}")
try {
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
try {
sh "git push -f --set-upstream origin ${branch_name}"
}
catch (Exception e) {
sh 'git pull --ff-only'
sh 'git push -f'
}
}
}
}
catch (Exception e) {
env.msg += "\n\nFAILED -\n ```Unable to push code in branch - ${branch_name} in path - ${path}.\n Full Erroror Details - ${e}```"
env.error_msg_to_db += "Unable to push code in branch - ${branch_name};"
log.error("${env.msg}")
throw e
}
}
def tagPush(String path) {
log.info("Pushing tag in path - ${path}")
try {
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
sh 'git push --tags'
}
}
}
catch (Exception e) {
env.msg += "\n\nFAILED -\n ```Unable to push tag from path - ${path}.\n Full Erroror Details - ${e}```"
env.error_msg_to_db += 'Unable to Push tag;'
log.error("${env.msg}")
throw e
}
}
def createPR(String app_name, String repo_name, String base_branch, String target_branch, String pr_message) {
log.info("Creating PR with message - ${pr_message} in Github for repo ${repo_name}")
def body = "{\"title\":\"${app_name} ${base_branch} Onboarding\",\"body\":\"${pr_message}\",\"head\":\"${target_branch}\",\"base\":\"${base_branch}\"}"
def pr_num = 'empty'
try {
withCredentials([usernamePassword(credentialsId: "${env.GITHUB_CRED}", usernameVariable:'user', passwordVariable: 'token')]) {
create_pr = httpRequest httpMode: 'POST',
customHeaders: [
[name: 'Accept', value: 'application/vnd.github+json'],
[maskValue: true, name: 'Authorization', value: 'Bearer ' + token]
],
requestBody: body,
url: "https://api.github.com/repos/Meesho/${repo_name}/pulls",
validResponseCodes: '201',
timeout: 10
def create_pr_json = readJSON(text: create_pr.content)
try {
error_filter = create_pr_json.errors.message[0]
}
catch (Exception e) {
error_filter = 'empty'
}
if ( error_filter.contains('No commits between') ) {
log.info("No changes were made in branch - ${target_branch}. Skipping - PR Creation...\n${create_pr_json}")
}
else if ( error_filter.contains('A pull request already exists') ) {
log.info(error_filter)
}
else {
pr_num = create_pr_json.number
pr_url = create_pr_json.url
log.info("PR Number - ${pr_num} and URL - ${pr_url}")
}
return pr_num.toString()
}
}
catch (Exception e) {
env.msg = "\n\nFAILED -\n Unable to create PR with message - ${pr_message}.\n Full Error Details - ${e}"
def error_code = "${e}".split('Status code')[1]
error_code = error_code.toString()
error_code = error_code.split(' ')
error_code = error_code[1]
env.error_part_msg_to_db = "Unable to Create PR for base branch - ${base_branch}, target branch - ${target_branch}, Repo Name - ${repo_name}. Failed with status code ${error_code};" //Akshay has asked to remove it
log.error("${env.msg}")
throw e
}
}
def mergePR(String repo_name, String pr_num, String target_branch) {
log.info("Merging PR ${pr_num} in repo - ${repo_name}")
if ( "${pr_num}" == 'empty' || pr_num == null) {
log.info("No changes were made in branch - ${target_branch}. Skipping - PR Merge...")
}
else {
try {
withCredentials([usernamePassword(credentialsId: "${env.GITHUB_CRED}", usernameVariable:'user', passwordVariable: 'token')]) {
merge_pr = httpRequest httpMode: 'PUT',
customHeaders: [
[name: 'Accept', value: 'application/vnd.github+json'],
[maskValue: true, name: 'Authorization', value: 'Bearer ' + token]
],
url: "https://api.github.com/repos/Meesho/${repo_name}/pulls/${pr_num}/merge",
validResponseCodes: '200',
timeout: 10
def merge_pr_json = readJSON(text: merge_pr.content)
if ( merge_pr_json.message.contains('not mergeable') ) {
env.msg += "\n\nFAILED -\n Unable to merge PR - ${pr_num}. PR URL - https://github.com/Meesho/${repo_name}/pulls/${pr_num}. ${merge_pr_json.message}"
log.error("${env.msg}")
error("${env.msg}")
}
else {
log.info("PR Merge was SUCCESSFUL. Message - ${merge_pr_json.message}")
}
}
}
catch (Exception e) {
env.msg = "\n\nFAILED -\n Unable to merge PR - ${pr_num} \n Full Error Details - ${e}"
def error_code = "${e}".split('Status code')[1]
error_code = error_code.toString()
error_code = error_code.split(' ')
error_code = error_code[1]
env.error_part_msg_to_db = "Unable to Merge PR - ${pr_num}, Repo Name - ${repo_name} status code ${error_code};" //Akshay has asked to remove it
log.error("${env.msg}")
throw e
}
}
}
def deleteBranch(String path, String base_branch, String target_branch) {
log.info("Deleting branch - ${target_branch}")
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
sh 'git fetch'
try {
sh "git checkout ${base_branch}"
sh "git branch -d ${target_branch}"
sh "git push -d origin ${target_branch}"
}
catch (Exception e) {
env.msg = "\n\nFAILED -\n Unable to delete branch - ${target_branch}.\n Full Error Details - ${e}"
env.error_msg_to_db = "Unable to Delete Branch ${target_branch};"
log.error("${env.msg}")
throw e
}
sh 'git branch'
}
}
}
def preDeleteBranch(String path, String base_branch, String target_branch) {
log.info("Pre Deleting branch - ${target_branch}")
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
try {
sh 'git fetch'
sh "git checkout ${base_branch}"
sh "git push -d origin ${target_branch}"
}
catch (Exception e) {
echo "Pre Delete Branch - Unable to delete branch ${target_branch}"
}
sh 'git branch'
}
}
}
def fetchDiffFilesForPullRequest(String path , String target_branch){
log.info("check diff from target branch - ${target_branch}")
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
try {
sh "git fetch origin ${target_branch}:${target_branch}"
sh "git branch"
def changedFiles = sh(script: "git diff --name-only HEAD ${target_branch}", returnStdout: true).trim()
echo "${changedFiles}"
return changedFiles
}
catch (Exception e) {
echo "failed to get the diff files from ${target_branch}"
}
}
}
}
def fetchDiffFilesForPushRequest(String path ){
log.info("check diff of current and previous commit for ${path}")
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
try {
sh "git fetch origin"
// Get the latest commit hash and the previous commit hash
def currentCommit = sh(script: "git rev-parse HEAD", returnStdout: true).trim()
def previousCommit = sh(script: "git rev-parse HEAD~1", returnStdout: true).trim()
// Capture the list of changed files in a Groovy variable
def changedFiles = sh(script: "git diff --name-only ${previousCommit} ${currentCommit}", returnStdout: true).trim()
return changedFiles
}
catch (Exception e) {
echo "failed to get the diff files for ${path}"
}
}
}
}
def fetchLatestCommitId(String path, String branch) {
log.info("Checking the latest commit for branch '${branch}' in path '${path}'")
dir(path) {
withCredentials([gitUsernamePassword(credentialsId: "${env.GITHUB_CRED}", gitToolName: 'git-tool')]) {
try {
// Fetch the latest changes for the specific branch
sh "git fetch origin ${branch}:${branch}"
// Check out the specified branch
sh "git checkout ${branch}"
// Get the latest commit hash for the branch
def currentCommit = sh(script: "git rev-parse ${branch}", returnStdout: true).trim()
return currentCommit
} catch (Exception e) {
echo "Failed to get the latest commit for branch '${branch}' in path '${path}': ${e.message}"
return null
}
}
}
}
@@ -0,0 +1,141 @@
package com.meesho.utilities
def run(String memory_request, String cpu_request, String priority_v2) {
echo 'Code to select node pool based on environment'
switch (env.cicd_environment) {
case 'prd':
echo 'Code to select node pool based on memory and cpu request in prd'
def mem_req_part = memory_request
def cpu_req_part = cpu_request
def priority = priority_v2
echo "mem_req_part is ${mem_req_part}"
echo "cpu_req_part is ${cpu_req_part}"
if ( mem_req_part.contains('M') ) {
mem_req = mem_req_part.replaceAll('Mi', '')
mem_req = mem_req.replaceAll('M', '')
try {
mem_req = mem_req.toDouble()
}
catch (NumberFormatException e) {
mem_req = mem_req.toDouble()
//mem_req = mem_req.toInteger()
}
}
else if ( mem_req_part.contains('G') ) {
mem_req = mem_req_part.replaceAll('Gi', '')
mem_req = mem_req.replaceAll('G', '')
try {
mem_req = mem_req.toDouble() * 1024
}
catch (NumberFormatException e) {
mem_req = mem_req.toDouble() * 1024
//mem_req = mem_req.toInteger()
}
}
echo "memory_request is ${memory_request} ${mem_req}"
if ( cpu_req_part.contains('m') ) {
cpu_req = cpu_req_part.replaceAll('m', '')
try {
cpu_req = cpu_req.toDouble()
}
catch (NumberFormatException e) {
cpu_req = cpu_req.toDouble()
//cpu_req = cpu_req.toInteger()
}
}
else {
try {
cpu_req = cpu_req_part.toDouble() * 1000
}
catch (NumberFormatException e) {
cpu_req = cpu_req_part.toDouble() * 1000
//cpu_req = cpu_req.toInteger()
}
}
echo "cpu_request is ${cpu_request} ${cpu_req}"
def ratio = (mem_req / cpu_req).toDouble()
if ( cpu_req > mem_req ) {
ratio = 2
}
//ratio = ratio.toInteger()
echo "Ratio - ${ratio}"
if(priority.equalsIgnoreCase('cp1')||priority.equalsIgnoreCase('cp2')||priority.equalsIgnoreCase('cp3')||priority.equalsIgnoreCase('up1')||priority.equalsIgnoreCase('up2')||priority.equalsIgnoreCase('up3')||priority.equalsIgnoreCase('sp1')||priority.equalsIgnoreCase('sp2')||priority.equalsIgnoreCase('sp3')){
low_priority="lite"
if ( ratio >= 2.5 ) {
ratiovalue = "tetra"
}
else {
ratiovalue = "duo"
}
if ( cpu_req >=2200 ) {
nodename = "sumo"
}
else{
nodename= "mega"
}
nodeSelectorvalue = "${nodename}${ratiovalue}${low_priority}"
println nodeSelectorvalue
break
}
else{
if ( ratio > 5.5 ) {
ratiovalue = 'octa'
}
else if ( ratio >= 2.5 ) {
ratiovalue = 'tetra'
}
else {
ratiovalue = 'duo'
}
if ( cpu_req >= 2200) {
nodevalue = 'sumo'
}
else if ( cpu_req < 2200 && cpu_req >= 1000) {
nodevalue = 'mega'
}
else {
nodevalue = 'compact'
}
switch ( env.BU?.toLowerCase() ) {
case 'supply':
if (nodevalue == 'sumo' && (ratiovalue == 'hexa' || ratiovalue == 'octa')){
ratiovalue = 'tetra'
}
else if (nodevalue == 'mega' && (ratiovalue == 'quad' || ratiovalue == 'octa')){
ratiovalue = 'tetra'
}
else if (nodevalue == 'compact' && ratiovalue == 'trio'){
ratiovalue = 'tetra'
}
break
case 'demand':
if (nodevalue == 'mega' && ratiovalue == 'quad'){
ratiovalue = 'tetra'
}
else if (nodevalue == 'compact' && (ratiovalue == 'octa' || ratiovalue == 'trio')){
ratiovalue = 'tetra'
}
break
}
nodeSelectorvalue = "${nodevalue}${ratiovalue}"
break
}
case 'int':
echo 'Shared node pool for int/pre-prod'
nodeSelectorvalue = "preprod-cost-optimized"
break
case ['dev', 'ftr', 'stg']:
echo 'Shared node pool for dev and ftr'
nodeSelectorvalue = "${env.BU}-shared"
break
default:
log.error('Unable to fetch environment')
}
return nodeSelectorvalue
}