This lab will guide you through building a "BASIC" continuous delivery pipeline using Jenkins and Pivotal Cloud Foundry.
-
FORK (using the GitHub UI) and clone the [citytest repo](https://github.com/hinyinlam-pivotal/citytest):
$ git clone https://github.com/<YOUR_GIT_USERNAME>/citytest $ cd citytest
-
Navigate back to Jenkins Home (The URL will be provided)
-
Login with your Pivotal CloudFoundry account. (Will be provided)
-
Click New Job, give it the name citytest-<your_name>-build and select ``Build a free-style software project.'' Then click OK. Replace in the script below <your_name> with your name without space!
-
Under Source Code Management, select Git, and supply your repository URL (e.g.
https://github.com/<YOUR_GIT_USERNAME>/citytest
). -
Under Build Triggers, select Poll SCM and provide the string * * * * *.
-
Under Build, add a Invoke Gradle Script build step.
Select: Use Gradle Wrapper Select: Make gradlew executable Select: From Root Build Script Dir Build Step Description:: build environment agnostic artifact Switches:: -Pbuildversion=$BUILD_NUMBER Tasks:: clean assemble
-
Under "Post-build Actions" Click: "Add post-build action"
-
Click "Add build step" under the "Build" section of the page
-
Select "[ArtifactDeployer] - Deploy the artifacts from build workspace to remote locations"
-
Artifacts to deploy: build/libs/*.jar
-
Remote File Location: /artifacts/<your_name>
-
-
Save the config and try running the build by clicking ``Build Now''. Ensure that you see the artifact in Artifactory.
-
Navigate back to Jenkins Home (The URL will be provided)
-
Login with your PCF account.
-
Click New Job, give it the name citytest-<your_name>-deploy and select ``Build a free-style software project.'' Then click OK.
-
Check This build is parameterized.
-
Click Add Parameter and choose Extensible Choice. Make sure to click on the arrow pointing down to allow multiple lines
- Name
-
BUILD_VERSION
- Description
-
The citytest build to promote.
- Choice Provider
-
System Groovy Choice Parameter
- Groovy System Script
-
//Change the parameter of <your_name> below, otherwise the script won't work! import jenkins.model.* import hudson.model.* def getAllBuildNumbers(Job job) { def buildNumbers = [] (job.getBuilds()).each { build -> buildNumbers.add(build.getDisplayName().substring(1)) } return buildNumbers } def buildJob = Jenkins.instance.getItemByFullName('citytest-<your_name>-build'); return getAllBuildNumbers(buildJob)
-
Under Build, add a Execute Shell build step. Remember to replace in the script below <your_name> with your name without space and also any other parameters!
- Command
-
#!/bin/bash -x #Please fill in details settings below or otherwise it won't work! PCF_USERNAME=<YOUR_PCF_USERNAME_HERE> PCF_PASSWORD=<YOUR_PCF_PASSWORD_HERE> PCF_ORGANIZATION=<YOUR_PCF_ORGANIZATION_HERE> PCF_SPACE=<YOUR_PCF_SPACE_HERE> YOUR_NAME=<YOUR_NAME_HERE> PCF_API_ENDPOINT=https://api.run.pivotal.io PCF_APP_DOMAIN=cfapps.io APP_ARTIFACT_PATH=/artifacts/$YOUR_NAME/build/libs f --version cf login -a ${PCF_API_ENDPOINT} -u ${PCF_USERNAME} -p ${PCF_PASSWORD} -o ${PCF_ORGANIZATION} -s ${PCF_SPACE} DEPLOYED_VERSION_CMD=$(CF_COLOR=false cf apps | grep "cities-${YOUR_NAME}-" | cut -d" " -f1) DEPLOYED_VERSION=$DEPLOYED_VERSION_CMD ROUTE_VERSION=$(echo "${BUILD_VERSION}" | cut -d"." -f1-3 | tr '.' '-') echo "Deployed Version: $DEPLOYED_VERSION" echo "Route Version: $ROUTE_VERSION" cf push "cities-${YOUR_NAME}-$BUILD_VERSION" -i 1 -m 512M -n "cities-${YOUR_NAME}-$ROUTE_VERSION" -d ${PCF_APP_DOMAIN} -p ${APP_ARTIFACT_PATH}/citytest-${BUILD_VERSION}.jar --no-manifest echo "Is ${APP_ARTIFACT_PATH}/citytest-${BUILD_VERSION}.jar exists?" pwd ls -l ${APP_ARTIFACT_PATH}/citytest-${BUILD_VERSION}.jar cf map-route "cities-${YOUR_NAME}-${BUILD_VERSION}" ${PCF_APP_DOMAIN} -n cities-${YOUR_NAME} cf scale cities-${YOUR_NAME}-${BUILD_VERSION} -i 2 if [ ! -z "$DEPLOYED_VERSION" -a "$DEPLOYED_VERSION" != " " -a "$DEPLOYED_VERSION" != "cities-${YOUR_NAME}-${BUILD_VERSION}" ]; then echo "Performing zero-downtime cutover to $BUILD_VERSION" while read line do if [ ! -z "$line" -a "$line" != " " -a "$line" != "cities-${YOUR_NAME}-${BUILD_VERSION}" ]; then echo "Scaling down, unmapping and removing $line" cf scale "$line" -i 1 cf unmap-route "$line" ${PCF_APP_DOMAIN} -n cities-${YOUR_NAME} cf delete "$line" -f else echo "Skipping $line" fi done <<< "$DEPLOYED_VERSION" fi
-
Save the config and try running the build by clicking ``Build With Parameters''. Select the build you created in the previous step from the drop list. You should see the build deploy to Cloud Foundry.
-
Return to the citytest-<your_name>-build project and click Configure.
-
Under Post Build Actions add a post-build action, selecting Trigger parameterized build on other projects.
- Projects to build
-
citytest-<your_name>-deploy
- Predefined parameters
-
BUILD_VERSION=$BUILD_NUMBER
-
Save the config and try running the build by clicking ``Build Now''. You should see both builds executed coupled with a zero-downtime deploy of the app to Cloud Foundry.
-
In your local clone of the citytest project, open src/main/java/org/example/cities/VersionController.java in an editor.
-
Change the version number in the string.
-
Execute git commit -am "change version number".
-
Execute git push origin master.
-
You should see both builds executed coupled with a zero-downtime deploy of the app to Cloud Foundry!
-
Congrats! You’ve reached the end of the lab.