ЁЯПл The SchoolтА║ЁЯУо CI/CDтА║ЁЯз╣ рдзрдбрд╛ 12 тАФ Pipeline hygiene & рд╣рд╕реНрддрд╛рдВрддрд░: mailroom рдЪреЗ рдирд┐рдпрдордкреБрд╕реНрддрдХ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯз╣ рдзрдбрд╛ 12 тАФ Pipeline hygiene & рд╣рд╕реНрддрд╛рдВрддрд░: mailroom рдЪреЗ рдирд┐рдпрдордкреБрд╕реНрддрдХ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 12 тАФ рд╢реЗрд╡рдЯрдЪрд╛ рдзрдбрд╛! ┬╖ рдорд╛рдЧреАрд▓: lesson-11-four-dialects

ЁЯФЧ рдкреБрдвреЗ: ArgoCD рд╢рд╛рд│реЗрдЪрд╛ рдзрдбрд╛ 01 рдиреЗрдордХрд╛ рдЗрдереЗ рд╣рд╛ рдзрдбрд╛ рд╕рдВрдкрддреЛ рддрд┐рдереВрди рд╕реБрд░реВ рд╣реЛрддреЛ.


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рд╕рдЧрд│реЗ 12 рдзрдбреЗ тАФ рд╕рдВрдкреВрд░реНрдг рдХреЛрд░реНрд╕. рд╢реЗрд╡рдЯ рдореНрд╣рдгрдЬреЗ mailroom рдЪреНрдпрд╛ рднрд┐рдВрддреАрд╡рд░рдЪреЗ poster: рдирд╡рд▓рд╛рдИ рдУрд╕рд░рд▓реНрдпрд╛рдирдВрддрд░рд╣реА courier рд╡рд┐рд╢реНрд╡рд╛рд╕рд╛рд░реНрд╣ рдареЗрд╡рдгрд╛рд▒реНрдпрд╛ рд╕рд╡рдпреА, рдПрдХ рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рдЧреБрдгрдлрд▓рдХ, рд╣рд╛ рд╕рдВрдкреВрд░реНрдг рдХреЛрд░реНрд╕ рд╕реЛрдбрд╡реВ рд╢рдХрдд рдирд╛рд╣реА рдЕрд╢реА рдПрдХ рд╕рдорд╕реНрдпрд╛, рдЖрдгрд┐ рддреБрдордЪреА рдкрджрд╡реА рдкрд░реАрдХреНрд╖рд╛. рдЦрд▒реНрдпрд╛ files: рд╕рдЧрд│реНрдпрд╛рдЪ тАФ рдЖрдзреАрдкрд╛рд╕реВрди рдЕрд╕рд▓реЗрд▓реНрдпрд╛ hygiene рдЪреНрдпрд╛ рдУрд│реА рдЦрд╛рд▓реА рджрд╛рдЦрд╡рд▓реНрдпрд╛ рдЖрд╣реЗрдд.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

Courier robot рдЪрд╛рд▓рддреЛ. рдЖрддрд╛ рд╢рд╛рд│рд╛ рдирд┐рдпрдордкреБрд╕реНрддрдХ poster ЁЯз╣ рд▓рд┐рд╣рд┐рддреЗ, рдореНрд╣рдгрдЬреЗ рддреЛ рдкреБрдврдЪреНрдпрд╛ рд╡рд░реНрд╖реАрд╣реА рдЪрд╛рд▓рдд рд░рд╛рд╣реАрд▓, рдЬреЗрд╡реНрд╣рд╛ рддреЛ рдХреЛрдгреА set up рдХреЗрд▓рд╛ рддреЗ рдХреЛрдгрд╛рд▓рд╛рдЪ рдЖрдард╡рдгрд╛рд░ рдирд╛рд╣реА:

  1. рдлрдХреНрдд рдордВрдЧрд│рд╡рд╛рд░реА fail рд╣реЛрдгрд╛рд░реА test рд╣реА test рдирд╛рд╣реА ЁЯО▓ тАФ рддреА рд╡реЗрдЧрд│реА рдХрд╛рдврд╛, рджреБрд░реБрд╕реНрдд рдХрд░рд╛, рдкрд╛рд╕ рд╣реЛрдИрдкрд░реНрдпрдВрдд рдлрдХреНрдд retry рдХрд░реВ рдирдХрд╛. Retries рд╕рдбрдгреЗ рд▓рдкрд╡рддрд╛рдд.
  2. рддреБрдореНрд╣реА рдиреЗрдордХреА рдХреЛрдгрддреА tools рдХрд╛рдорд╛рд╡рд░ рдареЗрд╡рд▓реА рддреЗ рдЬрд╛рдгреВрди рдШреНрдпрд╛ ЁЯУМ тАФ actions, orbs рдЖрдгрд┐ base images рдПрдХрд╛ fingerprint рд╡рд░ pin рдХрд░рд╛ (commit SHA рдХрд┐рдВрд╡рд╛ image digest), рдореНрд╣рдгрдЬреЗ "v4" рддреБрдордЪреНрдпрд╛ рдирдХрд│рдд рдЧреБрдкрдЪреВрдк рдмрджрд▓реВ рд╢рдХрдгрд╛рд░ рдирд╛рд╣реА.
  3. Robot рд▓рд╛ рдЪрд╛рд▓рдгрд╛рд░реА рд╕рд░реНрд╡рд╛рдд рдЫреЛрдЯреА key рджреНрдпрд╛ ЁЯкк тАФ рдкреНрд░рддреНрдпреЗрдХ workflow рдЖрдгрд┐ job рд╕рд╛рдареА permissions:, рдЖрдгрд┐ master keys рдирд╛рд╣реАрдд (рдзрдбрд╛ 06).
  4. рдореБрдЦреНрдп рдлрд▓рдХрд╛рд▓рд╛ рдХреБрд▓реВрдк рд▓рд╛рд╡рд╛ ЁЯФТ тАФ рд╣рд┐рд░рд╡рд╛ check рдЖрдгрд┐ review рд╢рд┐рд╡рд╛рдп main рд╡рд░ рдХрд╛рд╣реАрд╣реА рдЙрддрд░рдд рдирд╛рд╣реА; pushes рдЙрддрд░рдгреНрдпрд╛рдЖрдзреА secrets рд╕рд╛рдареА scan рдХрд░рд╛.
  5. рдкрд╛рд╡рддреНрдпрд╛ рдареЗрд╡рд╛ ЁЯз╛ тАФ lockfile рд╕рд╛рдВрдЧрддреЗ рдЖрдд рдХрд╛рдп рдЧреЗрд▓реЗ; build provenance рд╕рд╛рдВрдЧрддреЗ рддреЗ рдХреЛрдгреА build рдХреЗрд▓реЗ, рдХреЛрдгрддреНрдпрд╛ commit рд╡рд░реВрди, рдХреЛрдгрддреНрдпрд╛ pipeline рдиреЗ.
  6. рдШрдбреНрдпрд╛рд│ рд▓рд╛рд╡рд╛ тП▒я╕П тАФ рдЕрдбрдХрд▓реЗрд▓рд╛ job fail рдЭрд╛рд▓рд╛ рдкрд╛рд╣рд┐рдЬреЗ; рдирд╡рд╛ push рдЬреБрдирд╛ run рд░рджреНрдж рдХрд░рд╛рдпрд▓рд╛ рд╣рд╡рд╛.

рдЖрдгрд┐ рдПрдХ рдЧреБрдгрдлрд▓рдХ ЁЯУК рдЬреЛ рджрд┐рдЦрд╛рдК рдЖрдХрдбрд╛ рдирд╛рд╣реА: рддреБрдореНрд╣реА рдХрд┐рддреА рд╡реЗрд│рд╛ deliver рдХрд░рддрд╛, рдПрдЦрд╛рджрд╛ рдмрджрд▓ рдХрд┐рддреА рд╡реЗрд│ рд╡рд╛рдЯ рдкрд╛рд╣рддреЛ, delivery рдХрд┐рддреА рд╡реЗрд│рд╛ рдХрд╛рд╣реАрддрд░реА рдореЛрдбрддреЗ, рддреБрдореНрд╣реА рддреЗ рдХрд┐рддреА рдкрдЯрдХрди рджреБрд░реБрд╕реНрдд рдХрд░рддрд╛. рдкреНрд░рд╛рдорд╛рдгрд┐рдХрдкрдгреЗ рдореЛрдЬрд▓реЗрд▓реЗ рдЪрд╛рд░ рдЖрдХрдбреЗ рдХреЛрдгрддреНрдпрд╛рд╣реА dashboard рдкреЗрдХреНрд╖рд╛ рд╕рд░рд╕.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart TB
    flaky["ЁЯО▓ flaky tests<br/>quarantine тЖТ fix"]
    pin["ЁЯУМ pin actions, orbs, images<br/>SHA or digest"]
    perm["ЁЯкк least privilege<br/>permissions: per job"]
    lock["ЁЯФТ protect main<br/>required checks + review"]
    prov["ЁЯз╛ lockfiles + provenance<br/>SLSA, attestations"]
    clock["тП▒я╕П timeout-minutes<br/>concurrency"]
    dora["ЁЯУК DORA: frequency ┬╖ lead time<br/>failure rate ┬╖ restore time"]
    argo["ЁЯдЦ ArgoCD school<br/>drift, self-heal, git as truth"]
    flaky -->|"1"| dora
    pin -->|"2"| dora
    perm -->|"3"| dora
    lock -->|"4"| dora
    prov -->|"5"| dora
    clock -->|"6"| dora
    dora -.->|"7 what push cannot fix"| argo

тЭУ рдХрд╛рдп

ЁЯза рдЧреБрдгрдлрд▓рдХ тАФ DORA рдЪреЗ рдЪрд╛рд░ metrics

metric рд╡рд┐рдЪрд╛рд░рддреЛ рдпрд╛ рдХреЛрд░реНрд╕рдордзрд▓рд╛ рдЙрдкрд╛рдп
deployment frequency рд╡реНрд╣реЕрди рдХрд┐рддреА рд╡реЗрд│рд╛ production рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрддреЗ? рдЫреЛрдЯреЗ рдмрджрд▓, рдХрдВрдЯрд╛рд│рд╡рд╛рдгреА pipeline
lead time for changes commit тЖТ production рдордзреНрдпреЗ рдЪрд╛рд▓реВ: рдХрд┐рддреА рд╡реЗрд│? рд╡реЗрдЧрд╡рд╛рди CI (L04), рдЖрдкреЛрдЖрдк deploy (L10)
change failure rate рдХрд┐рддреА рдЯрдХреНрдХреЗ deliveries рдирд╛ fix рдХрд┐рдВрд╡рд╛ rollback рд▓рд╛рдЧрддреЛ? BOX рд╡рд░ tests (L07), рдЖрдзреА staging (L08), probes (L09)
time to restore service рдмрд┐рдШрдбрд▓реЗ рддрд░ рдкреБрдиреНрд╣рд╛ рдЪрд╛рд▓реВ рд╡реНрд╣рд╛рдпрд▓рд╛ рдХрд┐рддреА рд╡реЗрд│? рдХрд╛рд▓рдЪрд╛ tag рдкреБрдиреНрд╣рд╛ deploy рдХрд░рд╛ (L09)

рдЗрдереЗ рдЬрд╛рдгреВрдирдмреБрдЬреВрди рдХреЛрдгрддреЗрд╣реА рд▓рдХреНрд╖реНрдп-рдЖрдХрдбреЗ рдирд╛рд╣реАрдд: рдЪрд╛рдВрдЧрд▓реЗ рдХрд╢рд╛рд▓рд╛ рдореНрд╣рдгрд╛рдпрдЪреЗ рддреЗ team рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЗ, рдЖрдгрд┐ рдкреНрд░рдХрд╛рд╢рд┐рдд рд╕рдВрд╢реЛрдзрди рджрд░рд╡рд░реНрд╖реА рдмрджрд▓рдгрд╛рд▒реНрдпрд╛ рд╢реНрд░реЗрдгреА рд╕рд╛рдВрдЧрддреЗ. рддреБрдордЪреЗ рд╕реНрд╡рддрдГрдЪреЗ рдЪрд╛рд░ рдореЛрдЬрд╛ рдЖрдгрд┐ рдХрд▓ рдкрд╛рд╣рд╛.

ЁЯдФ рдХрд╛

Pipeline рдореНрд╣рдгрдЬреЗ рджреАрд░реНрдШрдХрд╛рд│ рдЪрд╛рд▓рдгрд╛рд░реЗ software рдЬреНрдпрд╛рд╡рд░ рдЗрддрд░ рд▓реЛрдХ рдбреЛрд│реЗ рдЭрд╛рдХреВрди рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡рддрд╛рдд. Pin рди рдХреЗрд▓реЗрд▓реА action, рд╕рдЧрд│реЗ рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ рдЪрд╛рд▓рд╡рддрд╛рдд рдЕрд╢реА flaky test, рдХрдзреАрдЪ рди рд╡рд╛рдкрд░рд▓реЗрд▓рд╛ write access рдЕрд╕рд▓реЗрд▓рд╛ token тАФ рдкреНрд░рддреНрдпреЗрдХ рдкрд╣рд┐рд▓реНрдпрд╛ рджрд┐рд╡рд╢реА рдареАрдХ рдЕрд╕рддреЗ рдЖрдгрд┐ рдЪрд╛рд░рд╢реЗрд╡реНрдпрд╛ рджрд┐рд╡рд╢реА рд╢рд╛рдВрдд рдзреЛрдХрд╛ рдмрдирддреЗ. Docker рд╢рд╛рд│реЗрдЪрд╛ L08 image tags рд╕рд╛рдареА рд╣рд╛рдЪ рдпреБрдХреНрддрд┐рд╡рд╛рдж рдХрд░рддреЛ, рдЖрдгрд┐ AWS рд╢рд╛рд│реЗрдЪрд╛ L06 IAM рд╕рд╛рдареА.

рдирд┐рдпрдордкреБрд╕реНрддрдХ рдХрд╛рдп рджреБрд░реБрд╕реНрдд рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА. рд╡реНрд╣реЕрди рдирд┐рдШреВрди рдЧреЗрд▓реНрдпрд╛рд╡рд░ рдпрд╛ рдХреЛрд░реНрд╕рдордзрд▓реЗ рдХрд╛рд╣реАрд╣реА рдлрд▓рдХрд╛рд╡рд░ рд▓рдХреНрд╖ рдареЗрд╡рдд рдирд╛рд╣реА. рд╣рд╛рддрд╛рдиреЗ рдХреЗрд▓реЗрд▓реЗ kubectl edit, рдШрд╛рдИрдд рдХреЗрд▓реЗрд▓реЗ rollout undo, рднрд▓реНрдпрд╛ рд╣реЗрддреВрдиреЗ рдПрдЦрд╛рджреНрдпрд╛ рд╢рд┐рдХреНрд╖рд┐рдХреЗрдиреЗ scale рдХреЗрд▓реЗрд▓рд╛ Deployment тАФ pipeline рдЪрд╛ рд╢реЗрд╡рдЯрдЪрд╛ run рддрд░реАрд╣реА тЬЕ рдореНрд╣рдгрддреЛ. рддреНрдпрд╛ рдлрдЯреАрд▓рд╛ рдПрдХ рдирд╛рд╡ рдЖрд╣реЗ, drift, рдЖрдгрд┐ рддрд┐рдЪрд╛ рдЙрдкрд╛рдп mailroom рдордзреНрдпреЗ рдирд╡реНрд╣реЗ рддрд░ cluster рдЪреНрдпрд╛ рдЖрдд рд░рд╛рд╣рддреЛ. рддреАрдЪ ArgoCD рд╢рд╛рд│рд╛: L04 рдлрдЯреА рдореЛрдЬрддреЛ, L05 git рд▓рд╛ рд╕рддреНрдпрд╛рдЪрд╛ рдПрдХрдореЗрд╡ рд╕реНрд░реЛрдд рдЖрдгрд┐ pull рдХрд░реВрди рд╕реНрд╡рддрдГрд▓рд╛ рджреБрд░реБрд╕реНрдд рдХрд░рдгрд╛рд░рд╛ agent рдпрд╛рдВрдЪреА рдУрд│рдЦ рдХрд░реВрди рджреЗрддреЛ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

Poster рд╡рд░ рдЖрдзреАрдЪ тАФ ci.yml:

permissions:
  contents: read            # lesson 06: the job's own token gets the least it needs

concurrency:                # a newer push cancels the older run of the same branch
  group: ci-${{ github.ref }}
  cancel-in-progress: true

Jenkinsfile рдШрдбреНрдпрд╛рд│ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдкрджреНрдзрддреАрдиреЗ рд▓рд┐рд╣рд┐рддреЛ:

  options { timestamps(); disableConcurrentBuilds() }
      options { timeout(time: 2, unit: 'DAYS') }

Poster рд╡рд░ рдЕрдЬреВрди рдирд╛рд╣реА тАФ files рд╡рд╛рдЪрд╛рдпрд▓рд╛ рд╕реЛрдкреНрдпрд╛ рд░рд╛рд╣рд╛рд╡реНрдпрд╛рдд рдореНрд╣рдгреВрди рд╣рд╛ рдХреЛрд░реНрд╕ @v4 major tags рдареЗрд╡рддреЛ; production repo pin рдХрд░рддреЗ рдЖрдгрд┐ pins рдкреБрдвреЗ рд╕рд░рдХрд╡рдгреНрдпрд╛рдЪреЗ рдХрд╛рдо bot рд▓рд╛ рджреЗрддреЗ:

# illustrative тАФ pinned and time-boxed
jobs:
  test:
    timeout-minutes: 10                                   # a hung job fails instead of waiting for hours
    steps:
      - uses: actions/checkout@<full-40-char-sha>         # v4.x тАФ Dependabot/Renovate bump the pin
# illustrative тАФ the same idea for an image, an orb, and a provenance statement
FROM node:22-alpine@sha256:<digest>
orbs: { aws-cli: circleci/aws-cli@5.1.<patch> }           # full x.y.z, not a floating 5.1
- uses: actions/attest-build-provenance@<pinned>          # after the image push; needs attestations: write

Branch protection рдЖрдгрд┐ secret scanning рд╣реЗ repository settings рдЖрд╣реЗрдд, files рдирд╛рд╣реАрдд: рддреБрдордЪреНрдпрд╛ fork рдордзреНрдпреЗ, Settings тЖТ Branches (рдХрд┐рдВрд╡рд╛ Rules) main рд╕рд╛рдареА рдЕрд╕рд╛ рдирд┐рдпрдо рдЬреЛрдбрддреЗ рдЬреЛ pull request рдЖрдгрд┐ test (node 20|22|24) checks рдЖрд╡рд╢реНрдпрдХ рдХрд░рддреЛ; Settings тЖТ Code security secret scanning рдЖрдгрд┐ push protection рдЪрд╛рд▓реВ рдХрд░рддреЗ. Menu рдЪреА рдирд╛рд╡реЗ рдмрджрд▓рддрд╛рдд; рдХрд▓реНрдкрдирд╛ рдмрджрд▓рдд рдирд╛рд╣реА.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

# 1) how pinned are we? list the floating references in the four dialects
grep -nE "uses: .*@v[0-9]" .github/workflows/*.yml                  # major tags тАФ readable, not pinned
grep -nE "image: cimg|aws-cli@|^FROM " .circleci/config.yml app/Dockerfile   # image tags and an orb, no digest

# 2) resolve one digest so you know what a pin looks like (needs Docker)
docker pull node:22-alpine >/dev/null && docker inspect --format '{{index .RepoDigests 0}}' node:22-alpine

# 3) the flaky-test drill: run the suite 10 times; one тЭМ means quarantine + fix, not retry
for i in $(seq 1 10); do (cd app && node --test >/dev/null 2>&1) && printf тЬЕ || printf тЭМ; done; echo

# 4) a rough deployment-frequency baseline from your fork's run history
gh run list --workflow=ship.yml --limit=20 --json conclusion,createdAt,updatedAt

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯОУ рдкрджрд╡реА рдкрд░реАрдХреНрд╖рд╛ тАФ рд╣реЗ рд╕рдордЬрд╛рд╡рддрд╛ рдпреЗрддреЗ рдХрд╛?

рдПрдХ developer pull request рдЙрдШрдбрддреЗ. CI Node 20, 22 рдЖрдгрд┐ 24 рд╡рд░ tests рдЪрд╛рд▓рд╡рддреЗ рдЖрдгрд┐ JUnit report upload рдХрд░рддреЗ. main рдордзреНрдпреЗ merge рдЭрд╛рд▓реНрдпрд╛рд╡рд░ pipeline рдПрдХ image build рдХрд░рддреЗ, container рдЪреА smoke-test рдХрд░рддреЗ, рдкреВрд░реНрдг commit SHA рдЪрд╛ tag рд▓рд╛рд╡реВрди рддреА ECR рд▓рд╛ push рдХрд░рддреЗ, staging рд▓рд╛ deploy рдХрд░рддреЗ, rollout рдЪреА рд╡рд╛рдЯ рдкрд╛рд╣рддреЗ, рдЖрдгрд┐ reviewer production approve рдХрд░реЗрдкрд░реНрдпрдВрдд рдерд╛рдВрдмрддреЗ.

  1. рдкрд╣рд┐рд▓рд╛ run рдХреЛрдгрддреНрдпрд╛ event рдиреЗ рд╕реБрд░реВ рдЭрд╛рд▓рд╛, рдЖрдгрд┐ рджреБрд╕рд░рд╛ рдХреЛрдгрддреНрдпрд╛?
  2. Cache step hit рдЖрд╣реЗ рдХреА miss рд╣реЗ рдХрд╛рдп рдард░рд╡рддреЗ?
  3. Build job рдЖрдгрд┐ push job рдпрд╛рдВрдЪреНрдпрд╛рдордзреНрдпреЗ рдХрд╛рдп рдкреНрд░рд╡рд╛рд╕ рдХрд░рддреЗ, рдЖрдгрд┐ рддреЛ cache рдХрд╛ рдирд╛рд╣реА?
  4. рд╕рд╛рдард╡рд▓реЗрд▓реНрдпрд╛ key рд╢рд┐рд╡рд╛рдп push job рд▓рд╛ AWS credentials рдХрд╕реЗ рдорд┐рд│рддрд╛рдд?
  5. Image tag рдХрд╛рдп рдЖрд╣реЗ, рдЖрдгрд┐ latest рдРрд╡рдЬреА рддреЛрдЪ рдХрд╛?
  6. APP_VERSION рд▓рд╛ рдХрд╛рдп value рджрд┐рд▓реА рдЬрд╛рддреЗ, рдЖрдгрд┐ рддреА рдкрд░рдд рдХреБрдареЗ рд╡рд╛рдЪрддрд╛ рдпреЗрддреЗ?
  7. рдХреЛрдгрддреА рдУрд│, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд рдХреЛрдгрддреЗ repository setting, production рд▓рд╛ approval gate рдмрдирд╡рддреЗ?
  8. рдирд╡рд╛ pod рддреБрдЯрд▓реЗрд▓рд╛ рдЕрд╕реЗрд▓ рддрд░ rolling update рдХрд╢рд╛рдореБрд│реЗ рдерд╛рдВрдмрддреЛ?
  9. Rollback рдЪреЗ рджреЛрди рдорд╛рд░реНрдЧ рдХреЛрдгрддреЗ, рдЖрдгрд┐ рдЖрдзреА рдХреЛрдгрддрд╛ рд╡рд╛рдкрд░рд╛рд╡рд╛?
  10. рдпрд╢рд╕реНрд╡реА production job рдирдВрддрд░ рдПрдХрд╛ рддрд╛рд╕рд╛рдиреЗ pipeline рд▓рд╛ cluster рдмрджреНрджрд▓ рдХрд╛рдп рдорд╛рд╣реАрдд рдЕрд╕рддреЗ?

рдкреНрд░рддреНрдпреЗрдХ рдЙрддреНрддрд░ рдПрдХрд╛ рд╡рд╛рдХреНрдпрд╛рдд рдЖрд▓реЗ, рддрд░ рддреБрдордЪреА рд╣реА рд╢рд╛рд│рд╛ рдкреВрд░реНрдг рдЭрд╛рд▓реА.

ЁЯОУ рдорд╛рд▓рд┐рдХрд╛ тАФ рддреБрдореНрд╣реА рдЖрддрд╛ рдХреБрдареЗ рдЖрд╣рд╛рдд

рддреБрдореНрд╣реА Ops track рдЪрд╛ рдерд╛рдВрдмрд╛ 3я╕ПтГг рдкреВрд░реНрдг рдХреЗрд▓рд╛ рдЖрд╣реЗ. рдПрдХ рдерд╛рдВрдмрд╛ рдЙрд░рд▓рд╛ рдЖрд╣реЗ:

рддрдкрд╛рд╕рд╛. Copy рдХрд░рд╛. рдкреЛрд╣реЛрдЪрд╡рд╛. рдордЧ git рд▓рд╛ рддреЗ рддрд╕реЗрдЪ рдареЗрд╡реВ рджреНрдпрд╛. ЁЯУоЁЯЪЪЁЯдЦ

git checkout main

ЁЯз╣ Lesson 12 тАФ Pipeline hygiene & the handoff: the mailroom rulebook

ЁЯУН You are here: Lesson 12 of 12 тАФ the final lesson! ┬╖ Previous: lesson-11-four-dialects

ЁЯФЧ Next: the ArgoCD school's lesson 01 starts exactly where this one ends.


ЁЯУж What's in this branch

All 12 lessons тАФ the complete course. The finale is the poster on the mailroom wall: the habits that keep the courier trustworthy after the novelty wears off, an honest scoreboard, the one problem this whole course cannot solve, and your graduation test. Real files: all of them тАФ the hygiene lines already present are called out below.

ЁЯзТ Explain like I'm 5

The courier robot works. Now the school writes the rulebook poster ЁЯз╣ so it keeps working next year, when nobody remembers who set it up:

  1. A test that fails only on Tuesdays is not a test ЁЯО▓ тАФ quarantine it, fix it, do not just retry until it passes. Retries hide rot.
  2. Know exactly which tools you hired ЁЯУМ тАФ pin actions, orbs and base images to a fingerprint (a commit SHA or an image digest), so "v4" cannot quietly change under you.
  3. Give the robot the smallest key that works ЁЯкк тАФ permissions: per workflow and job, and no master keys (lesson 06).
  4. Lock the main board ЁЯФТ тАФ nothing lands on main without a green check and a review; scan pushes for secrets before they land.
  5. Keep receipts ЁЯз╛ тАФ a lockfile says what went in; build provenance says who built it, from which commit, with which pipeline.
  6. Set a clock тП▒я╕П тАФ a job that hangs should fail; a newer push should cancel the older run.

And one scoreboard ЁЯУК that is not a vanity metric: how often you deliver, how long a change waits, how often a delivery breaks something, how fast you fix it. Four numbers, honestly measured, beat any dashboard.

ЁЯЧ║я╕П Diagram

flowchart TB
    flaky["ЁЯО▓ flaky tests<br/>quarantine тЖТ fix"]
    pin["ЁЯУМ pin actions, orbs, images<br/>SHA or digest"]
    perm["ЁЯкк least privilege<br/>permissions: per job"]
    lock["ЁЯФТ protect main<br/>required checks + review"]
    prov["ЁЯз╛ lockfiles + provenance<br/>SLSA, attestations"]
    clock["тП▒я╕П timeout-minutes<br/>concurrency"]
    dora["ЁЯУК DORA: frequency ┬╖ lead time<br/>failure rate ┬╖ restore time"]
    argo["ЁЯдЦ ArgoCD school<br/>drift, self-heal, git as truth"]
    flaky -->|"1"| dora
    pin -->|"2"| dora
    perm -->|"3"| dora
    lock -->|"4"| dora
    prov -->|"5"| dora
    clock -->|"6"| dora
    dora -.->|"7 what push cannot fix"| argo

тЭУ What

ЁЯза The scoreboard тАФ DORA's four metrics

metric asks this course's lever
deployment frequency how often does the van reach production? small changes, a boring pipeline
lead time for changes commit тЖТ running in production: how long? fast CI (L04), automated deploy (L10)
change failure rate what share of deliveries need a fix or a rollback? tests on the BOX (L07), staging first (L08), probes (L09)
time to restore service when it breaks, how long until it works again? redeploy yesterday's tag (L09)

No target numbers here on purpose: what counts as good depends on the team, and the published research reports ranges that shift from year to year. Measure your own four and watch the trend.

ЁЯдФ Why

A pipeline is long-lived software that other people trust blindly. An unpinned action, a flaky test everyone re-runs, a token with write access it never uses тАФ each is fine on day one and a quiet liability on day four hundred. The Docker school's L08 makes the same argument for image tags, and the AWS school's L06 for IAM.

What the rulebook cannot fix. After the van drives away, nothing in this course watches the board. A kubectl edit by hand, a rollout undo in a hurry, a Deployment scaled by a well-meaning teacher тАФ the pipeline's last run still says тЬЕ. That gap has a name, drift, and its fix lives inside the cluster rather than in the mailroom. That is the ArgoCD school: L04 counts the gaps, L05 introduces git as the single source of truth and an agent that pulls and self-heals.

ЁЯФз How (in this repo)

Already on the poster тАФ ci.yml:

permissions:
  contents: read            # lesson 06: the job's own token gets the least it needs

concurrency:                # a newer push cancels the older run of the same branch
  group: ci-${{ github.ref }}
  cancel-in-progress: true

The Jenkinsfile spells the clock its own way:

  options { timestamps(); disableConcurrentBuilds() }
      options { timeout(time: 2, unit: 'DAYS') }

Not yet on the poster тАФ this course keeps @v4 major tags so the files stay readable; a production repo pins and lets a bot bump the pins:

# illustrative тАФ pinned and time-boxed
jobs:
  test:
    timeout-minutes: 10                                   # a hung job fails instead of waiting for hours
    steps:
      - uses: actions/checkout@<full-40-char-sha>         # v4.x тАФ Dependabot/Renovate bump the pin
# illustrative тАФ the same idea for an image, an orb, and a provenance statement
FROM node:22-alpine@sha256:<digest>
orbs: { aws-cli: circleci/aws-cli@5.1.<patch> }           # full x.y.z, not a floating 5.1
- uses: actions/attest-build-provenance@<pinned>          # after the image push; needs attestations: write

Branch protection and secret scanning are repository settings, not files: in your fork, Settings тЖТ Branches (or Rules) adds a rule for main that requires a pull request and the test (node 20|22|24) checks; Settings тЖТ Code security turns on secret scanning and push protection. Menu names move; the idea does not.

ЁЯзк Try it

# 1) how pinned are we? list the floating references in the four dialects
grep -nE "uses: .*@v[0-9]" .github/workflows/*.yml                  # major tags тАФ readable, not pinned
grep -nE "image: cimg|aws-cli@|^FROM " .circleci/config.yml app/Dockerfile   # image tags and an orb, no digest

# 2) resolve one digest so you know what a pin looks like (needs Docker)
docker pull node:22-alpine >/dev/null && docker inspect --format '{{index .RepoDigests 0}}' node:22-alpine

# 3) the flaky-test drill: run the suite 10 times; one тЭМ means quarantine + fix, not retry
for i in $(seq 1 10); do (cd app && node --test >/dev/null 2>&1) && printf тЬЕ || printf тЭМ; done; echo

# 4) a rough deployment-frequency baseline from your fork's run history
gh run list --workflow=ship.yml --limit=20 --json conclusion,createdAt,updatedAt

тЪая╕П Common mistakes

ЁЯОУ Graduation test тАФ can you explain this?

A developer opens a pull request. CI runs the tests on Node 20, 22 and 24 and uploads a JUnit report. After the merge to main, the pipeline builds an image, smoke-tests the container, pushes it to ECR tagged with the full commit SHA, deploys it to staging, waits for the rollout, and holds until a reviewer approves production.

  1. Which event started the first run, and which the second?
  2. What decides whether the cache step is a hit or a miss?
  3. What travels between the build job and the push job, and why is it not a cache?
  4. How does the push job get AWS credentials without a stored key?
  5. What is the image tag, and why that and not latest?
  6. What is APP_VERSION set to, and where can you read it back?
  7. Which line, plus which repository setting, turns production into an approval gate?
  8. What makes the rolling update pause if the new pod is broken?
  9. What are the two ways to roll back, and which one should you reach for first?
  10. After a successful production job, what does the pipeline know about the cluster an hour later?

If every answer comes out in one sentence, you are done with this school.

ЁЯОУ The series тАФ where you are now

You have finished stop 3я╕ПтГг of the Ops track. One stop remains:

Check it. Copy it. Deliver it. Then let git keep it that way. ЁЯУоЁЯЪЪЁЯдЦ

git checkout main
тЖР Previousfour dialectsFinished! Take the quiz тЖТcheck what stuck

This page is the lesson's README from the lesson-12-pipeline-hygiene branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.