markdown guide
 

CI == Automating the running of code, tests, and or builds on a separate machine

( ๐€,โœ…,๐Ÿ”จ) ๐Ÿ”œ๐Ÿ’ป๐Ÿ”œ๐Ÿ‘Œ๐Ÿพ

Good CI will prevent ๐Ÿ‘‡๐Ÿฝ

Jackie

CD == Automating the deployment of code to a server

๐€ ๐Ÿ”œ๐Ÿ’ป

Good CD will prevent ๐Ÿ‘‡๐Ÿฝ

Nope

It's important to note that Continuous Delivery and Continuous Deployment are not the same thing. The two get conflated and sometimes used wrong interchangeably. Continuous Deployment specifically means deploying straight to production.

When CI/CD is put into practice it creates automation. When automation works as it is intended, it's magical.

 

Basically it is a way to ensure every deployment you do is not breaking. So let's say you are actively developing a website ( can be any piece of software, not just a website ) and before publishing it you might want to run some checks and do other related things - which you can automate rather than doing manually. That's where CI comes. And not just that, it runs the tests for you, you can configure notifications ( through web hooks ) so you can verify everything before publishing it on production and other things depending on what you're working with.

EDIT: Another example might be a library - where you can check if all test cases are passing so that you can be sure no other functionalities are breaking due to a certain change, schedule version release / publishing, version bumping, changelog generation etc.

 
 

You should also consider gitlabs ci/cd tools, which are kinda free. They also play well with github.
The biggest advantage, in my use-case vs. circle & travis, you get way better access controls.
Especially when using it with github / mirror repo.

 

I've only worked with two - Travis CI and Circle CI. I like travis more but yeah Circle CI is great too. For me, Circle CI was easier to adopt and get started with but can't say for sure if it would be the same for everyone!

 

It really depends on what you need -- for a modern-ish web app, with code hosted on GitHub, CircleCI, Travis, and Jenkins will likely all do the job. They're all fairly easy to set up (probably -- I've only set up CircleCI and Travis). So if you're likely to be outside of the free offerings, I'd check the pricing before anything else.

I believe GitLab and BitBucket have their own built-in CI solutions.

At my last gig we eventually switched to BuildKite because their pricing was better for the number of parallel jobs we wanted (basically unbounded). It's a good product, and getting rid of the build queue was awesome. Also, we were able to get parallelism within builds by splitting groups of tests into separate runs.

It's not as turnkey; with BuildKite you're responsible for your own container infrastructure, but I mention it in case there are folks who don't mind self-hosting builds and who haven't heard of them yet. (From what I can tell their pricing is better than e.g. AppVeyor's self-hosted offering, depending on team size.)

Also, just realized TeamCity offers unlimited builds, too. I would imagine they're in parallel. Might also be worth checking out for those who need to scale up.

Buildkite is a god-send. The reliability that comes with running an internal CI client almost made me cry tears of joy.

 

I like CircleCI over TravisCI. We use HerokuCI at work which is fine, bit obviously tied to Heroku.

 

Depending on your tech stack, I can also recommend Appveyor.

 

CI:

It's the practice of continuously integrating your changes into the main branch, therefore branching is incompatible with CI.

Why is it useful? Well, the most expensive part of developing software is maintaining the code and the longer it is maintained the more complex it is, making the integration of new changes, bugfixes or features, more costly in terms of time and rollbacks. That is why everyone pushes their changes when they are little things using techniques like branch by abstraction or feature toggles thus making the integration way more progressive and cheaper.

Usually, you have a build server, like Jenkins or Travis, that runs the tests and executes a tool like SonarQube to ensure standards instead of PRs.

CD:

This means to deploy any new green build automatically to production. Your build process has executed the tests, linters and everything and it is green? then the final step instead of some person greenlighting the deploy is just rolling out into production the artefact resulting from the build process.

 

"branching is incompatible with CI". This is not entirely true. It is still best practice to branch for features, hotfixes, etc. However you are correct in that CI is difficult execute with long-lived branches. As the name continual integration implies changes are continually integrated into a target branch. But it is not, in and of itself, incompatible with branching.

 

Well, in my opinion, it is totally incompatible with branching because it ceases to be continuous even if it is for a couple of hours. You can call it very often integration but not continuous if you do branches.

 

Tests: Help have less ๐Ÿ› and, when you get good at it, write more clear code.

CI: Let ๐Ÿค– run your tests every time you change your code and shout if you broke anything. At the end of a CI pipeline comes out something that you can deploy.

CD: Let ๐Ÿค– deploy a new version of your app every time all tests are โœ… so you can focus on what matters.

Come for the automation to save time and avoid mistakes, stay for improved productivity. Shipping with confidence โ†’ shipping more often โ†’ happier users and you. โค๏ธ

P.S. If you're looking for a free service, Semaphore can help. ๐Ÿ˜‰

 

Continuous integration is usually but not necessarily automated (I've used Jenkins or Gitlab to automate) and in essence is the integration of the master code into your changes (not the other way around) at a high frequency, which usually is on every commit in Gitlab or can be time or commit quantity based in Jenkins. This high frequency continuous integration of the master branch into your code tests that when your code is integrated into master then master will still compile and pass any unit and / or integration tests depending on your CI tool setup.
Continuous deployment is then the follow on factor of CI, if all is good and master is still compiling and passing tests to show it is performing as expected then the new version of master with your changes integrated can be deployed to allow your customers (whether that just be other Devs on your team or actual customers) such that any bugs are fixed for them, or requested features are provided. Agile sprints essentially provide a continuous (usually 2 weekly) deployment.

 

is the integration of the master code into your changes (not the other way around) at a high frequency

That's interesting. Your comment led me to look up the origins of the term. It seems like Booch and the other XPers specifically advocate merging working copies into the main line daily, but I agree that it's more useful to just make sure that working copies remain in a state where they're ready to be -- so, given distributed version control, to have master merged in often.

I'm sure the hardcore agilists would say that you shouldn't end up with something that's not ready to merge in the first place, since you're fully TDD / YAGNI / etc., but IME there may be good reasons to wait until something's fully baked (schema changes come to mind).

FWIW my preferred thing is for PRs to be small, but self-contained -- i.e. as simple as possible but no simpler.

 

I agree. I simply meant you want to ensure the integration of your code and master will not cause master to faulter so safer to merge out to you than in to master until stability is confirmed

 

I always explain it at work like this:

Continuous Integration (CI)/Continuous Delivery (CD) is like baking cookies.

When creating a cookie you build a recipe and go through the process of taste testing the recipe to ensure the cookie you want to cook is just right, not too much butter, salt wasn't used instead of sugar, that kind of thing.

Likewise, with code we run CI to build and test our code making sure it tastes like an API, an app or library to ensure it returns to the user a sugary tasty response that delights, not leaking any data or bugs that tastes salty or buggy...

Once you know you have a beautiful recipe that won't fail to delight, you get into the process of creating it for everyone with a cookie factory. So you get to work baking the cookies from the recipe you've tested, package them and deliver them for customers to enjoy.

With CD, we have a factory (Drone, TravisCI e.t.c.) configured to build our 'code recipe', which may or may not grab some extra ingredients (dependencies), proceeds to mix (compile) and cook (link) the cookies. Once we have a finished cookie, it can get to work packaging them (docker, exe, dmg e.t.c) and deploy/deliver them (docker registry, kubernetes e.t..c) for customers to enjoy.

 

In software, people work with code. Normally, in a case when more than one person is working on a piece of software, that means more than one person is changing the code.

This presents a few problems:

  • How do you make sure that a developer's change works with the code that's already there?
  • How do you make sure that after developer 1 changes code, developer 2's code won't break?
  • How do you make sure that when both developer 1 and 2's changes are made, the system overall will work correctly?

In historical times, developers would keep copies of their code that diverged and would have to have big meetings to manually change the files and make sure that changes didn't diverge too far from one another. Normally, they had, and this would be very painful; developers would have to sit together for a long time. This is a form of a feedback loop.

So, we started to shorten the feedback loop. We started to prefer smaller changes, and making them more often, so that those meetings were less painful. We started to prefer integrating small changes continually. This is sometimes known as trunk-based development. Rather than creating a branch of code that diverged from the main bit of code for many months, we start making our changes in smaller increments off of the main branch (sometimes called "main", "master", or "trunk").

But there was still another question: Even though the code looked good to the devs, how could we be sure it would always compile and work correctly? That it could always be deployed? This is where build scripts and continuous integration (CI) servers come into play. A CI server knows how to run the same build script on any branch of the code, and it therefore can tell us if anything breaks.

A CI server usually contains several quality gateways, such as:

  • Does the code compile?
  • Do the tests associated with the code run successfully?
  • Can I package this code for deployment?
  • Can I deploy it to a environment successfully?

These are steps we build up over time.

When combined with the right source control systems for check-in and check out, we can shorten the feedback loop even more. Rather than telling us that something is broken after we merge it, many CI systems can tell us if something will break when we're about to merge it. This way, we keep our builds "green" (successful) and ensure that a minor change isn't going to introduce a problem. git is a source control system whose idea of a "pull request" sets this up for success. Someone creates a request to pull code in on the project, and a CI server can see what the result will look like after that code is merged. It can then run all of its build process & tests on that tool.

Continuous deployment takes that one step farther. Once we have good quality gateways in place, we have a high degree of confidence that code will work. Continuous Deployment says "well, if the CI server feels good about it and we've deployed to various environments and run tests, let's push this code out to production". This system of automated delivery is very powerful, because in many cases it enables teams to deliver more quickly -- but also to recover from problems more quickly. It also forces teams to build up tests and better automated processes in important areas to alleviate any concerns about going to production. Building up to continuous delivery has a lot of efficiencies as well. Imagine if instead of filing a bug report, you could sit down together, write a test to prove the bug exists, fix the bug, watch all the tests pass, and then send that code write to production? A lot of intermediate steps -- massive bug reports, time spend discussing prioritization, etc. -- can be saved when this level of collaboration and safety is enabled.

I'd love to hear your questions if I can clarify this more!

 

I made a YouTube video on my channel a couple years ago for this purpose. It doesnโ€™t get into CI much but I did my best to explain Continuous Delivery as a /principle/ so you donโ€™t get hung up on tools or processes.

Iโ€™ve been implementing CD as a consultant for 8 years, so while Iโ€™d never consider myself an expert (see Jez Humble), I hope I can offer you some value from my experience. YMMV.

I really hope it helps someone!

Continuous Delivery: Are You Missing The Big Picture?

youtu.be/TioLSzFw7Yo

 

Like you're 5...

Imagine your building a Lego house ๐Ÿ  ๐Ÿ”จ with a bunch of your friends. Each of you is building a different part of the house.

Every time one of you adds its part to the existing base of the house, your teacher (CI) comes in and shakes the house to make sure nothing breaks and everything is well put together.

If every thing is OK (CI passes) she builds a replica of the house on the playground for all the other kids to play with. (CD)

Then one of the kids breaks the house and they come crying for you to fix it! ๐Ÿ˜ญ

 
 

A basic local workflow looks like this:

  1. Write code
  2. Compile it
  3. Run tests
  4. Publish app/lib

In a modern context, CI/CD is a set of tools that let you automate steps 2 through 4, on a remote virtualized environment with a predictable configuration, whenever you commit to a repository or on other events.

This is good because this allows us to have a stable, fast and automated workflow with significantly smaller chance of human error.

 

Continuously integration: Doing whatever is required before making your codebase ready to deploy. For example: we build and test (optional) any angular application to generate a build file. Everything must be in automated fashion

Continuous deployment: putting it to server in automatic fashion

 

In an example of a computer game (for a 5 yr old)
CI would be every time a new part (feature) is created checking and adding it to the game.
CD would be the part that every time a feature is added it would be the current version that is available.

 

CI refers to merging code continuously, and CD refers to deploying the app continuously. Doing both is increasingly common for SaaS apps. The tooling around this stuff is good now, but that wasn't always the case.

Regarding CI: I used subversion before I used git, and while it was just for personal stuff, I can't imagine that branching & merging with the frequency that's normal for git would have been pretty.

Regarding CD: if building the app takes a lot of manual work (as opposed to checking that the tests passed and hitting a button), it's hard to do it continuously. For hosted apps, we now have good tools for automating server provisioning (ansible, chef, etc.), and the hardware can be done in a virtualized way thanks to the PaaS providers. And tools like terraform let you automate it.

Some places still do "named" releases -- i.e. new code get written, then there's a feature freeze, the focus switches to quality control, and eventually a new version is cut. For certain products, like an OS, that's probably a better model. (In general, software that's installed by the end user follows a traditional release cycle, but there are exceptions, like Arch Linux's rolling releases.)

Some hosted apps still release that way. I imagine that one factor that might keep you on that model is if your app is itself a platform. When you're providing an API to your customers, they need a clear way of tracking changes and targeting a specific version. (Which is not to say that providing a versioned API forces you into a particular release style, or that app releases always line up with the API versions, or that such apps always do monolithic releases, etc., etc.)

Anyway, my point is that you can still automate merging and building when doing less frequent releases, but continuously releasing requires automation, and that is where CI/CD comes in. Note that the automation isn't an either/or thing. For example, deploying from a "special" machine is less automated than deploying from a server that can be rebuilt at any time from an image or script, but you can still deploy continuously, provided that the machine doesn't go down.

 
 

Sometimes people pay me money to make them a present they can use on their computerโ€”like a video game.

First I write the instructions on how to make the present. Then I put them into a C/CD machine.

The machine builds my present. It tests it to make sure there were no goobers, boogers, or ear wax in my instructions. And if everything's ok it packages up my preset and sends it to a magical land made of clouds called Microsoft Azure. Then all of my friends can open my present and play with it on their computers.

 

I hope, my friends like the present.โค๐Ÿ––๐Ÿ‘๐Ÿ™„

 

Continuous Cleaning

Every time you leave a toy out, mommy picks it up and puts it away.

 
 

My take: Everything that is today necessary to transform lines of code into a production app / service.

 

CI is like going to Target and getting your hands on an amazing LEGO Technic set. My favorite is the Bugatti Chiron LEGO Technic.

But I am 5 and at Target that is $349...

CD is convincing your parents you are ready for Technic, having your friends and family help you assemble this complicated Technic, dreading to take back the Technic because a piece rolled under your bed, finishing the Technic, playing with the Bugatti and posting on InstaGram for all to see.

Classic DEV Post from May 24

Follow Friday: What DEV member would you recommend following?

Ali Rizvi profile image
MERN Stack Developer, with the passion to develop apps that can make this world better. "Whenever I get bored, I call API's"

Don't ghost on us โค๏ธ

Join dev.to