Hook
Want your code to automatically run tests, build an image and safely land in production without you clicking anything? CI/CD pipelines are your robot assistant.
Problem / Context
Without automation every push requires manual test runs, builds and deployments. This slows development, introduces human error and raises the risk of production incidents.
Why it matters
An automated pipeline speeds up time‑to‑market, improves reliability (reducing human mistakes) and adds transparency – logs and statuses are always visible.
How to do it
1. Choose a tool
- GitHub Actions – built into GitHub, easy to configure with
.github/workflows/*.yml. - GitLab CI – similar approach, uses a
.gitlab-ci.ymlfile. - Jenkins – self‑hosted server, suitable for complex environments.
2. Create a simple pipeline (GitHub Actions example)
name: CI/CD Pipeline
on:
push:
branches: [ main ]
jobs:
test-build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build Docker image
run: |
docker build -t myapp:${{ github.sha }} .
- name: Push image to registry
run: |
echo ${{ secrets.REGISTRY_TOKEN }} | docker login -u ${{ secrets.REGISTRY_USER }} --password-stdin
docker push myapp:${{ github.sha }}
- name: Deploy to staging
run: |
ssh ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} "docker pull myapp:${{ github.sha }} && docker compose up -d"
3. Testing and validation
- Make sure every step exits with code 0.
- Add an artifact uploader (
actions/upload-artifact) for test logs.
4. Isolation
- Run each job in a Docker container or VM (GitHub provides
ubuntu‑latest). - Avoid sharing global state between steps.
5. Automatic rollback
- Add a separate job
rollbackwith the conditionif: failure(); - In that job run a script that reverts to the previous stable version (
kubectl rollout undo).
Anti‑patterns
- No tests – pipeline passes but the code breaks in production.
- Hard‑coded secrets in the yaml file (use GitHub Secrets or a vault).
- Running on every commit without filtering (use
paths/branches). - Long monolithic jobs – makes debugging hard; split into atomic steps.
- Do not use
latesttag for Docker images – pin specific versions to avoid unexpected changes.
Conclusion / Action plan
- Pick a CI tool and add a basic workflow file.
- Add steps for testing, building and deploying.
- Store secrets securely via GitHub Secrets or Vault.
- Implement a rollback job for failure scenarios.
- Monitor pipeline status in the UI and continuously improve it.
- Regularly review and update the workflow to keep it aligned with new requirements.