diff --git a/Jenkinsfile b/Jenkinsfile index 705416636..096153a3c 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,134 +1,71 @@ -properties([pipelineTriggers([githubPush()])]) +@Library('lib-jenkins-pipeline') _ -pipeline { - options { - disableConcurrentBuilds() - buildDiscarder(logRotator(numToKeepStr: '10')) - timeout(time: 30, unit: 'MINUTES') - } - agent { - kubernetes { - label 'worker-apibuilder' - inheritFrom 'kaniko-slim' - } - } - - environment { - ORG = 'flowcommerce' - } +// => Mandatory to use a definition before the node or Blue Ocean doesn't show the expected info +def newTagEveryRunMainBranch = "yes" // Force a new version and deploy clicking on Build Now in Jenkins +def sbtOnMain = "no" - stages { - stage('Checkout') { - steps { - checkoutWithTags scm - - script { - VERSION = new flowSemver().calculateSemver() //requires checkout - } +// we can remove the pod_template block if we end up having only one template +// in jenkins config +// +String podLabel = "Jenkinsfile-apibuilder" +podTemplate( + label: "${podLabel}", + inheritFrom : 'generic' +){ + node(podLabel) { + try { + checkoutWithTags scm + //Checkout the code from the repository + stage('Checkout') { + echo "Checking out branch: ${env.BRANCH_NAME}" + checkout scm } - } - stage('Commit SemVer tag') { - when { branch 'main' } - steps { - script { - new flowSemver().commitSemver(VERSION) - } + // => tagging function to identify what actions to take depending on the nature of the changes + stage ('tagging') { + semversion = taggingv2(newTagEveryMainRun: "${newTagEveryRunMainBranch}") + println(semversion) } - } - - stage('Build and push docker image release') { - when { branch 'main' } - parallel { - stage('API builder api') { - steps { - container('kaniko') { - script { - semver = VERSION.printable() - sh """ - /kaniko/executor -f `pwd`/api/Dockerfile -c `pwd` \ - --snapshot-mode=redo --use-new-run \ - --destination ${env.ORG}/apibuilder-api:$semver - """ - } - } - } - } + // => Running the actions for each component in parallel + checkoutWithTags scm - stage('API builder app') { - agent { - kubernetes { - label 'worker-apibuilder-app' - inheritFrom 'kaniko-slim' - } - } - steps { - container('kaniko') { - script { - semver = VERSION.printable() - - sh """ - /kaniko/executor -f `pwd`/app/Dockerfile -c `pwd` \ - --snapshot-mode=redo --use-new-run \ - --destination ${env.ORG}/apibuilder-app:$semver - """ - } - } - } - } - } - } - - stage('Display Helm Diff') { - when { - allOf { - not {branch 'main'} - changeRequest() - expression { - return changesCheck.hasChangesInDir('deploy') - } - } + String jsondata = ''' + [{"serviceName": "apibuilder-api", + "dockerImageName": "apibuilder-api", + "dockerFilePath" : "/api/Dockerfile"}, + {"serviceName": "apibuilder-app", + "dockerImageName": "apibuilder-app", + "dockerFilePath" : "/app/Dockerfile"}] + ''' + withCredentials([string(credentialsId: "jenkins-argocd-token", variable: 'ARGOCD_AUTH_TOKEN')]) { + mainJenkinsBuildArgo( + semversion: "${semversion}", + pgImage: "flowcommerce/bentest-postgresql:latest", + componentargs: "${jsondata}", + sbtOnMain: "${sbtOnMain}" + // => optional + //orgName: "flowvault" + // SBT test + //sbtCommand: 'sbt clean flowLint coverage test scalafmtSbtCheck scalafmtCheck doc', + //playCpuLimit: "2", + //playMemoryRequest: "4Gi", + //pgCpuLimit: "1", + //pgMemoryRequest: "2Gi", + //sbtTestInMain: "${sbtOnMain}" + ) } - steps { - script { - container('helm') { - if(changesCheck.hasChangesInDir('deploy/apibuilder-api')){ - new helmDiff().diff('apibuilder-api') - } - if(changesCheck.hasChangesInDir('deploy/apibuilder-app')){ - new helmDiff().diff('apibuilder-app') - } - } - } - } - } - stage('Deploy Helm chart') { - when { branch 'main' } - parallel { - - stage('deploy apibuilder-api') { - steps { - script { - container('helm') { - new helmCommonDeploy().deploy('apibuilder-api', 'apicollective', VERSION.printable(), 300) - } - } - } - } - - stage('deploy apibuilder-app') { - steps { - script { - container('helm') { - new helmCommonDeploy().deploy('apibuilder-app', 'apicollective', VERSION.printable(), 300) - } - } - } - } - } + } catch (Exception e) { + // In case of an error, mark the build as failure + currentBuild.result = 'FAILURE' + throw e + } finally { + // Always clean up workspace and notify if needed + cleanWs() + echo "Pipeline execution finished" } } } + diff --git a/Jenkinsfile.bak b/Jenkinsfile.bak new file mode 100755 index 000000000..705416636 --- /dev/null +++ b/Jenkinsfile.bak @@ -0,0 +1,134 @@ +properties([pipelineTriggers([githubPush()])]) + +pipeline { + options { + disableConcurrentBuilds() + buildDiscarder(logRotator(numToKeepStr: '10')) + timeout(time: 30, unit: 'MINUTES') + } + + agent { + kubernetes { + label 'worker-apibuilder' + inheritFrom 'kaniko-slim' + } + } + + environment { + ORG = 'flowcommerce' + } + + stages { + stage('Checkout') { + steps { + checkoutWithTags scm + + script { + VERSION = new flowSemver().calculateSemver() //requires checkout + } + } + } + + stage('Commit SemVer tag') { + when { branch 'main' } + steps { + script { + new flowSemver().commitSemver(VERSION) + } + } + } + + stage('Build and push docker image release') { + when { branch 'main' } + parallel { + stage('API builder api') { + steps { + container('kaniko') { + script { + semver = VERSION.printable() + + sh """ + /kaniko/executor -f `pwd`/api/Dockerfile -c `pwd` \ + --snapshot-mode=redo --use-new-run \ + --destination ${env.ORG}/apibuilder-api:$semver + """ + } + } + } + } + + stage('API builder app') { + agent { + kubernetes { + label 'worker-apibuilder-app' + inheritFrom 'kaniko-slim' + } + } + steps { + container('kaniko') { + script { + semver = VERSION.printable() + + sh """ + /kaniko/executor -f `pwd`/app/Dockerfile -c `pwd` \ + --snapshot-mode=redo --use-new-run \ + --destination ${env.ORG}/apibuilder-app:$semver + """ + } + } + } + } + } + } + + stage('Display Helm Diff') { + when { + allOf { + not {branch 'main'} + changeRequest() + expression { + return changesCheck.hasChangesInDir('deploy') + } + } + } + steps { + script { + container('helm') { + if(changesCheck.hasChangesInDir('deploy/apibuilder-api')){ + new helmDiff().diff('apibuilder-api') + } + if(changesCheck.hasChangesInDir('deploy/apibuilder-app')){ + new helmDiff().diff('apibuilder-app') + } + } + } + } + } + + stage('Deploy Helm chart') { + when { branch 'main' } + parallel { + + stage('deploy apibuilder-api') { + steps { + script { + container('helm') { + new helmCommonDeploy().deploy('apibuilder-api', 'apicollective', VERSION.printable(), 300) + } + } + } + } + + stage('deploy apibuilder-app') { + steps { + script { + container('helm') { + new helmCommonDeploy().deploy('apibuilder-app', 'apicollective', VERSION.printable(), 300) + } + } + } + } + } + } + } +} diff --git a/deploy/apibuilder-api/app.yaml b/deploy/apibuilder-api/app.yaml new file mode 100644 index 000000000..424dd02ba --- /dev/null +++ b/deploy/apibuilder-api/app.yaml @@ -0,0 +1,71 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: apibuilder-api + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: apicollective + server: 'https://kubernetes.default.svc' + ignoreDifferences: + - group: networking.istio.io + kind: VirtualService + jsonPointers: + - /spec/http/0 + - group: datadoghq.com + kind: DatadogMonitor + jqPathExpressions: + - .spec.tags + # Required if enable KEDA autoscaler to avoid conflicts between + # ArgoCD and HPA managing the number of replicas + - group: "apps" + kind: "Deployment" + jsonPointers: + - /spec/replicas + - group: argoproj.io + kind: Rollout + jsonPointers: + - /spec/replicas + # Ignore cluster IP changes + - group: "" + kind: Service + jsonPointers: + - /spec/clusterIP + #This is a common issue with Argo Rollouts and Istio DestinationRule resources. + #The rollouts-pod-template-hash label is automatically managed + #by the Argo Rollouts controller and gets added dynamically during rollout operations + - group: networking.istio.io + kind: DestinationRule + jqPathExpressions: + - .spec.subsets[].labels["rollouts-pod-template-hash"] + ################################### + sources: + - repoURL: 'git@github.com:flowcommerce/generic-charts.git' + path: charts/flow-generic + targetRevision: v2.0.0 + helm: + parameters: + - name: deployments.live.version + value: "0.16.59" + valueFiles: + - $values/deploy/apibuilder-api/values.yaml + - repoURL: 'git@github.com:apicollective/apibuilder.git' + targetRevision: main + ref: values + + project: production + + ## Keep it commenting out during the transition process to avoid auto + ## sync applying changes automatically until transition is completed. + syncPolicy: + syncOptions: + - RespectIgnoreDifferences=true + - CreateNamespace=false # Namespace exists + - ApplyOutOfSyncOnly=true # Only sync out-of-sync resources + - ServerSideApply=true # Use server-side apply + - PruneLast=true # Prune after successful sync + #automated: + # prune: true + # selfHeal: true diff --git a/deploy/apibuilder-app/app.yaml b/deploy/apibuilder-app/app.yaml new file mode 100644 index 000000000..24956235a --- /dev/null +++ b/deploy/apibuilder-app/app.yaml @@ -0,0 +1,71 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: apibuilder-app + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: apicollective + server: 'https://kubernetes.default.svc' + ignoreDifferences: + - group: networking.istio.io + kind: VirtualService + jsonPointers: + - /spec/http/0 + - group: datadoghq.com + kind: DatadogMonitor + jqPathExpressions: + - .spec.tags + # Required if enable KEDA autoscaler to avoid conflicts between + # ArgoCD and HPA managing the number of replicas + - group: "apps" + kind: "Deployment" + jsonPointers: + - /spec/replicas + - group: argoproj.io + kind: Rollout + jsonPointers: + - /spec/replicas + # Ignore cluster IP changes + - group: "" + kind: Service + jsonPointers: + - /spec/clusterIP + #This is a common issue with Argo Rollouts and Istio DestinationRule resources. + #The rollouts-pod-template-hash label is automatically managed + #by the Argo Rollouts controller and gets added dynamically during rollout operations + - group: networking.istio.io + kind: DestinationRule + jqPathExpressions: + - .spec.subsets[].labels["rollouts-pod-template-hash"] + ################################### + sources: + - repoURL: 'git@github.com:flowcommerce/generic-charts.git' + path: charts/flow-generic + targetRevision: v2.0.0 + helm: + parameters: + - name: deployments.live.version + value: "0.16.59" + valueFiles: + - $values/deploy/apibuilder-app/values.yaml + - repoURL: 'git@github.com:apicollective/apibuilder.git' + targetRevision: main + ref: values + + project: production + + ## Keep it commenting out during the transition process to avoid auto + ## sync applying changes automatically until transition is completed. + syncPolicy: + syncOptions: + - RespectIgnoreDifferences=true + - CreateNamespace=false # Namespace exists + - ApplyOutOfSyncOnly=true # Only sync out-of-sync resources + - ServerSideApply=true # Use server-side apply + - PruneLast=true # Prune after successful sync + #automated: + # prune: true + # selfHeal: true