You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
πͺ¦ Alternative timeline: no CI. The bug ships on Monday. Customer reports /notes returning empty arrays on Wednesday. Postmortem on Friday
π Lesson: CI doesn't make engineers smarter. It makes the consequence of being wrong fast and cheap
π€ Think: The same human, the same commit. One world catches it in 90 seconds. The other catches it in 7 days. What changed?
π Slide 2 β π― Learning Outcomes
#
π Outcome
1
β Distinguish Continuous Integration, Delivery, and Deployment
2
β Describe a four-stage pipeline: trigger β build β test β publish
3
β Write a GitHub Actions workflow for a Go project
4
β Write the equivalent GitLab CI pipeline
5
β Use caching, matrix builds, and reusable workflows safely
6
β Identify common CI supply-chain risks (tj-actions, secret leaks)
π Slide 3 β πΊοΈ Lecture Overview
graph LR
A["π CI History<br/>Fowler 2006"] --> B["π― CI vs CD vs CD"]
B --> C["π οΈ Pipeline Shape"]
C --> D["π GitHub Actions"]
D --> E["π¦ GitLab CI"]
E --> F["π Secrets & OIDC"]
F --> G["π₯ Real Incidents"]
Loading
π Slides 1-5 β History and what CI/CD actually means
π Slides 6-11 β GitHub Actions in detail
π Slides 12-15 β GitLab CI in detail, and a comparison
Always points at current LTS; don't pin to this in 2026 if you need stability
Self-hosted
Your hardware
Persistent disks, GPUs, ARM β but you maintain them
β οΈPin runner versions (ubuntu-24.04, not ubuntu-latest) β GitHub's auto-upgrade has bitten everyone at least once.
π Slide 9 β π¦ GitLab CI Anatomy
# .gitlab-ci.ymlstages: [test, scan, publish]variables:
GO_VERSION: "1.24"test:
stage: testimage: golang:${GO_VERSION}-alpinescript:
- go vet ./...
- go test -race ./...scan:
stage: scanimage: aquasec/trivy:0.59.1script:
- trivy fs --severity HIGH,CRITICAL .
π§± One file: .gitlab-ci.yml at repo root
π¬ Stages run sequentially; jobs within a stage run in parallel
π³ Each job runs in a container image β no need for actions/setup-X
π Runners can be GitLab-hosted (saas-linux-*) or self-hosted
π Slide 10 β π vs π¦ GitLab CI vs GitHub Actions
Capability
GitHub Actions
GitLab CI
Config location
.github/workflows/*.yml
.gitlab-ci.yml (or includes)
Reuse
Composite + reusable workflows
extends: + include:
Secrets
Repo / Org / Env secrets
Project / Group / Instance vars
Cloud OIDC
β first-class
β first-class
Self-hosted runners
β
β
Free minutes
Yes, generous on public repos
Yes, similar tier
Manual approval
environments + reviewers
when: manual + protected env
π° Feature parity is high β concepts transfer in both directions
π« If you can't use GitHub (sanctions, banned account), the same ci.yml ports to .gitlab-ci.yml in an afternoon β Lab 3 Bonus asks you to do exactly this
π Slide 11 β π Matrix Builds: Same Test, Many Versions
jobs:
test:
runs-on: ${{ matrix.os }}strategy:
fail-fast: false # β run them all even if one failsmatrix:
os: [ubuntu-24.04, macos-14, windows-2022]go: ['1.23', '1.24']steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5with: { go-version: ${{ matrix.go }} }
- run: go test ./...
π§ͺ Same workflow, 6 combinations β 6 parallel jobs
π Catches "works on my machine" β and which machine
β οΈ Cost: 6Γ the runner minutes. Use it for projects, not for every PR
π Slide 12 β πΎ Caching: From 4 Minutes to 30 Seconds
- uses: actions/setup-go@v5with:
go-version: '1.24'cache: true # β caches $GOMODCACHE and $GOCACHE keyed by go.sum
πͺ€ Tags are mutable β anyone with push to the action's repo can move v4 to malicious code
π₯ In March 2025, the popular tj-actions/changed-files action was compromised; the attacker rewrote all tags to a malicious version, leaking secrets from thousands of public CI runs
π¬ "If you trust a tag, you trust its maintainer's GitHub account forever."
π Slide 17 β β‘ Build Speed Antipatterns
π₯ Antipattern
β Fix
One job that does build + test + scan + deploy
Split into stages; parallel where possible
No cache β re-download deps every run
Use setup-Xcache: true, or actions/cache@v4
Tests serial: 18-min run
go test -p N, pytest -n auto, matrix
Building Docker image without layer cache
docker buildx build --cache-from --cache-to
30-minute integration test as PR gate
Move to nightly; PR gate runs unit only
One mega-workflow, 90% no-op for most PRs
Path filters: on.push.paths: ['app/**']
π Slide 18 β π Real Story: A Build So Brittle It Quit
ποΈ 2014-2018 β many startups stand up Jenkins, then realize the team spends more time fixing the build server than writing code
πͺ¦ Jenkins on a single VM with no backups, plugins upgraded ad-hoc, secrets in environment variables, deploy scripts maintained by "the one engineer who knows it"
π₯ Single point of failure for every release. When Jenkins is down, the company can't ship
π Hosted CI (GitHub Actions, GitLab.com, CircleCI) eliminated the "CI as a service we host" problem for most teams from ~2020 onward
π€ But hosted CI has a new failure mode: a global outage means the whole industry stops shipping at once (GitHub Actions, October 2025)
π Slide 19 β π§ͺ Lab 3 Preview: CI for QuickNotes
You'll write ci.yml (and a .gitlab-ci.yml mirror for the Bonus):
jobs:
test:
runs-on: ubuntu-24.04steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5with: { go-version: '1.24', cache: true }
- run: go vet ./...
- run: go test -race -count=1 ./...lint:
runs-on: ubuntu-24.04steps:
- uses: actions/checkout@v4
- uses: golangci/golangci-lint-action@v6with: { version: 'v2.5.0' }
π’ PR-gated: every PR runs go vet, go test, golangci-lint
π« PR is auto-blocked if any fail (branch protection)
π¦ Bonus: same idea as .gitlab-ci.yml β for students using GitLab instead
π Slide 20 β π§ Key Takeaways
π― CI catches what humans miss β by making the consequence of a typo fast and cheap
π οΈ The four-stage pipeline shape β trigger β build β test β publish β is universal
π GitHub Actions and π¦ GitLab CI are conceptually equivalent β feature parity is high
πͺͺ OIDC kills the "long-lived cloud keys as secrets" antipattern
π‘οΈ Pin actions by SHA β tags move, and tj-actions/changed-files proved it
π¦ The same lab works on either platform β the discipline is what counts
π¬ "Continuous Integration doesn't get rid of bugs, but it does make them dramatically easier to find and remove." β Martin Fowler
π Slide 21 β π What's Next + π Resources
π Next lecture: OS & Networking β the substrate every container, every cloud, every deploy ultimately runs on
π§ͺ Lab 3: GitHub Actions for QuickNotes (Task 1+2). Bonus: GitLab CI mirror
𦫠golangci-lint β the Go linter you'll use in Lab 3
graph LR
P["π³ Week 2<br/>Git Internals"] --> Y["π You Are Here<br/>CI/CD"]
Y --> N["π» Week 4<br/>OS & Networking"]
N --> M["π¦ Week 5<br/>Virtualization"]
Loading
π― Remember: CI/CD is a culture, not a tool. The pipeline is just where the culture's discipline becomes executable.