CI/CD Basics
Continuous integration (CI) means merging changes often and having a server automatically build and test every change. Continuous delivery and deployment (CD) extend that by automating the release of passing builds to environments.
What happens when you push a commit
A pipeline is a defined series of automated steps, triggered by an event such as a push or a pull request. A typical CI run:
- Checks out the code at that commit onto a clean machine.
- Restores dependencies.
- Builds the project.
- Runs automated tests (see Unit Testing and Integration Testing).
- Runs other checks such as linting, formatting or a dependency scan (see Dependency Risks).
- Reports pass or fail, usually on the pull request, and may store the build as an artifact.
If a step fails, the pipeline stops and the change should not be merged.
CI, delivery and deployment
- Continuous integration: build and test every change, merged to the main line often.
- Continuous delivery: every passing build is ready to release, and a person decides when to deploy it.
- Continuous deployment: every passing build is deployed to production automatically.
“CD” is used for either of the last two, so check what a team means by it.
Pipelines as code
Most tools (GitHub Actions, Azure Pipelines, GitLab CI and others) define pipelines in a file in the repository, usually YAML. The pipeline is versioned and reviewed like any other code. The file is where you find which commands run and in what order.
Using a pipeline day to day
- Run the same build and test commands locally before pushing.
- Read the failing step’s log first; the cause is usually near the first error (see Log Analysis).
- Keep the pipeline fast. Fix or remove flaky tests instead of re-running until green.
- Pass secrets through the tool’s secret store, never in the pipeline file (see Secrets Management).
- Pipelines usually deploy through environments, with a manual approval before production in many teams.
Try it
Open a repository you work on and find its pipeline definition file. Write down the trigger, each step, and what would make it fail. Then break something on a branch on purpose, for example a failing test, push it and watch the pipeline report it.
Common mistakes
- Re-running a flaky test until it passes instead of fixing it.
- Putting secrets in the pipeline file instead of the secret store.
- Pushing without running the same build and tests locally first.
- Reading the end of a long log instead of the first error.
Check yourself
- What is the difference between continuous delivery and continuous deployment?
- Where do you find which commands a pipeline runs?
- Where in a failing log should you start reading?