diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..26d47a0 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,115 @@ +def APPS = [] +pipeline { + // If you are running jenkins in a container use "agent { docker { image 'docker:18.09.0-git' }}" + agent { + kubernetes { + label 'docker' + defaultContainer 'jnlp' + yaml """ +apiVersion: v1 +kind: Pod +metadata: + labels: + app: jenkins-docker +spec: + containers: + - name: docker + image: docker:18.09.0-git + command: + - cat + tty: true + volumeMounts: + - mountPath: /var/run/docker.sock + name: docker-sock + volumes: + - name: docker-sock + hostPath: + path: /var/run/docker.sock +""" + } + } + + environment { + GITHUB_HOOK_SECRET = "github-webhook-token-app-mono" + //DOCKERHUB = credentials('dockerhub-credentials') + DOCKERHUB_USR = "" + DOCKERHUB_PSW = "" + } + + stages { + stage('configure webook') { + steps { + script { + setupWebhook() + } + } + } + + stage('Find app name to build') { + steps { + script { + if (REF != "") { + VALUESFILE = sh(returnStdout: true, script:'git show --name-only --pretty=""') + LIST = VALUESFILE.split('\n') + def MAP = [:] + for(String file in LIST) { + MAP.put(file.split('/')[0], "build"); + } + APPS = MAP.keySet() + echo "${APPS}" + } + } + echo "Changes in:${VALUESFILE}" + echo "application to build:${APPS}" + } + } + + stage('Build and push docker image') { + steps { + container('docker') { + script { + sh 'docker login -u $DOCKERHUB_USR -p $DOCKERHUB_PSW' + for(String app in APPS) { + TO_BUILD = sh ( + script: "ls ${app}/Dockerfile", + returnStatus: true + ) + if (TO_BUILD == 0) { + env.APP = app + env.GIT_SHA = sh(returnStdout: true, script: "git rev-parse --short HEAD") + sh '''docker build -t infracloud/app-mono-${APP}:${GIT_SHA} ./${APP}/ + docker push infracloud/app-mono-${APP}:${GIT_SHA} + docker rmi infracloud/app-mono-${APP}:${GIT_SHA} + ''' + } + } + sh 'docker logout' + } + } + } + } + } + post { + cleanup { + deleteDir() + } + } +} + +def setupWebhook() { + properties([ + pipelineTriggers([ + [$class: 'GenericTrigger', + genericVariables: [ + [key: 'REF', value: '$.ref'], + ], + causeString: 'Triggered on github push', + token: env.GITHUB_HOOK_SECRET, + printContributedVariables: true, + printPostContent: true, + regexpFilterText: '$REF', + regexpFilterExpression: 'refs/heads/master' + ] + ]) + ]) +} diff --git a/README.md b/README.md index 185004c..73dac51 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,14 @@ -This sample app demonstrates the use of Shippable CI/CD with a mono repo -approach, i.e. code for all services managed within a single repository. It -features top-level folders for services grouped by language with shared -components within each language-specific folder. +# Monorepo - Kubernetes + + +This is a working example of using Monorepo and deploying to Kubernetes using Helm. For details check the post: http://www.infracloud.io/monorepo-ci-cd-helm-kubernetes + +There are 5 repositories involved: + +- [Application Source Code - this repo](https://github.com/infracloudio/app-mono) +- [Helm charts for applications](https://github.com/infracloudio/app-mono-helmcharts) +- [Helm values/state for applicatiopns](https://github.com/infracloudio/app-mono-helmstate) +- [Orchestrator job](https://github.com/infracloudio/app-mono-orchestrator) +- [Jenkins Setup for end to end example](https://github.com/infracloudio/app-mono-jenkins-setup) + +For details on setup [check the repo](https://github.com/infracloudio/app-mono-jenkins-setup) diff --git a/api/Dockerfile b/api/Dockerfile index d4af4e4..7e8dec2 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,3 +1,4 @@ +# docker build -t infracloud/app-mono-api . FROM drydock/u14nod:prod # this folder must be created in the base images diff --git a/api/README.md b/api/README.md index fa1852f..c090d12 100644 --- a/api/README.md +++ b/api/README.md @@ -1,4 +1,4 @@ -# API microservice readme. +# API microservice README. API micro service written in Node.js.. diff --git a/www/Dockerfile b/www/Dockerfile index 20a9e81..2f2219c 100644 --- a/www/Dockerfile +++ b/www/Dockerfile @@ -1,3 +1,4 @@ +#docker build -t infracloud/app-mono-www . FROM drydock/u14nod:prod # this folder must be created in the base images diff --git a/www/_global/package-service.sh b/www/_global/package-service.sh new file mode 100755 index 0000000..2d55bf0 --- /dev/null +++ b/www/_global/package-service.sh @@ -0,0 +1,34 @@ +install_node_modules() { + npm install +} + +execute_tests_and_code_coverage() { + if [ -f ./Gruntfile.js ]; then + grunt --force + ./node_modules/.bin/istanbul cover grunt --force --dir $SHIPPABLE_BUILD_DIR/shippable/codecoverage + ./node_modules/.bin/istanbul report cobertura --dir $SHIPPABLE_BUILD_DIR/shippable/codecoverage/ + fi +} + +tag_and_push_image() { + ACCOUNT_NAME='679404489841.dkr.ecr.us-east-1.amazonaws.com' + + echo "building image $1" + sudo docker build -t $ACCOUNT_NAME/$1:$BRANCH.$SHIPPABLE_BUILD_NUMBER . + echo "pushing image $1" + sudo docker push $ACCOUNT_NAME/$1:$BRANCH.$SHIPPABLE_BUILD_NUMBER + + # We trigger the manifest and subsequently the deploy jobs downstream by posting a new version to the image resource. + # Since the image resource is an INPUT to the manifest job, the manifest job will get scheduled to run after these steps. + echo "posting the version of the image resource for $1" + shipctl put_resource_state $1"_img" "SHIPPABLE_BUILD_NUMBER" $SHIPPABLE_BUILD_NUMBER + shipctl put_resource_state $1"_img" "versionName" $BRANCH.$SHIPPABLE_BUILD_NUMBER +} + +main() { + install_node_modules + execute_tests_and_code_coverage + tag_and_push_image "$@" +} + +main "$@" diff --git a/www/_global/placeholder.js b/www/_global/placeholder.js new file mode 100644 index 0000000..bf7e563 --- /dev/null +++ b/www/_global/placeholder.js @@ -0,0 +1,4 @@ +'use strict'; + +var placeholder = false; +var test = true;