CI/CD as code 

at drivetime

A look into how and why we do builds at DriveTime

using DSL plugin and a custom build framework

What is CI/CD?

Summary:
  1. Code goes into SCM
  2. ??? 
  3. Applications run in prod

Specifics:
  • Builds
  • Tests (Unit, Integration, e2e)
  • Reporting
  • Deployments
  • Preferably all automated (tiny robots)

Problems associated 
with CI/CD

  • Things that should be easy are hard
  • No consistencies
  • No disaster recovery
  • No way to rollback
  • No way to share work
  • No way to test work
  • No way to migrate
  • Nice-to-have's are rarely done

CI/CD as code fixes all this


  • Things that should be easy are hard
Changing from tfs to github can be 1 line of code

  • No consistencies,  No way to share work
Reusable base classes, interfaces, methods and frameworks solve this

  • No disaster recovery,  No way to rollback
SCM does this for free!

CI/CD as code fixes all this


  • No way to test work
We unit test code all the time

  • No way to migrate
Migrating code can be done quickly: abstractions, testing, and code re-use enables this 

  • Nice-to-have's are rarely done
Do it once in a method or base class and
now everyone can use it regardless of how difficult it once was

How do you get CI/CD as code?

First a little bit about how Jenkins works

Next, Jenkins DSL plugin!  It's all groovy, man

How does the DSL plugin work?


Jenkins job: Seed build

Comes from the DSL plugin, it runs groovy code that creates:
  • Folders
  • Views
  • Jobs
  • Other seed builds

It can be confusing


Groovy code runs from your seed job

That code creates jobs by generating XML

There isn't any code running when your builds run

Misc things that DSL does

From your seed build

From your generated build

It's very flexible

R E B E L B O Y E

Additional flexibility


You can ignore, disable or delete removed items
and we typically disable

This doesn't look very reusable

job("Your folder/example build name") {
    scm {
        git {
            remote {
                github repo
                refspec '+refs/pull/*:refs/remotes/origin/pr/*'
           }
           branch '${sha1}'
    } }
    triggers {
        githubPullRequest {
            admin 'sheehan'
            triggerPhrase 'OK to test'
            onlyTriggerPhrase true
    } }
    steps {
        grails {
            useWrapper true
            targets(['test-app', 'war'])
} } }
That's because it's not

This is all code, we can do whatever we want

new SeedBuildDefinition(
	jobName: 'OnlineAutoSales Seed',  
	scmConnector: new GitHubConnector(repoName: 'Builds.OnlineAutoSales'),
	groovyFileToRun: 'jobs.groovy'
),
new SeedBuildDefinition(
	jobName: 'DevOps Seed',  
	scmConnector: new GitHubConnector(repoName: 'Builds.DevOps'),
	groovyFileToRun: 'devops_seed.groovy'
),
new SeedBuildDefinition(
	jobName: 'BPM Seed',  
	scmConnector: new GitHubConnector(repoName: 'Builds.BPM'),
	groovyFileToRun: 'jobs.groovy'
)

Different ways of doing stuff

Generic
new NpmPackagePublisher(
	jobName: 'UX/UI.Components',  
	descriptionText: readFileFromWorkspace('dt-components/description.html'),
	scmConnector: new GitHubConnector(
              repoName: 'Ui.Components', 
              buildPullRequests: true),
	failedBuildEmailAddresses: AllYourEmailsInAVariable,
	azurePublishProfiles: Arrays.asList(
               'dt-components/drivetime-components-dev.PublishSettings')
),
Specific
new FinancingBuild(
         jobName: rootLocation + '/Financing/Financing-Main'
)

Some additional generic stuff






How you can get started

  1. Watch a couple of videos if you want (33m and 34m)
  2. Read the documentation
  3. Create your own seed in the root seed
  4. Create your own job from your seed
  5. If it's generic, move it up to the root

Anything else I should know?


Yeah... we're doing this a little POC'y

But it will get better with time!

And we'll add tests!

Thanks for coming!!

Made with Slides.com