Projects

Standardizing application delivery with GitLab CI

Shared pipeline templates that gave every service the same build, scan and deploy path, so delivery stopped depending on who wrote the pipeline.

Role
Designed the template library and led adoption across teams
Stack
GitLab CI, Docker, Kubernetes, Trivy, Bash

Problem

Each repository carried its own hand-written pipeline. Builds, image tags, scanning and deployments behaved differently per project, and fixing one pipeline fixed only that one.

Constraints

  • Teams had to keep shipping while pipelines were migrated; no freeze window.
  • Existing projects used different languages, base images and branching habits.
  • Security scanning had to be added without making pipelines slow enough that people bypassed them.

Decisions

Versioned, includable pipeline templates instead of copy-paste examples
A fix or new security stage lands in every project by bumping one version, and teams can pin while they test.
Build once, promote the same image through environments
What was tested is exactly what runs in production; environments differ by configuration, not by rebuild.
Scanning stages that report first and block later
Teams saw findings before enforcement, which kept trust in the pipeline while the backlog was cleared.

Architecture

  1. Source

    Merge request opens; protected branches and required approvals gate main.

    • GitLab
  2. Build

    Shared template builds a container image with a reproducible tag derived from the commit.

    • GitLab CI
    • Docker
  3. Verify

    Unit tests, linting, dependency and image scanning run from the same template stages.

    • Trivy
    • SAST
  4. Publish

    Image pushed once to the registry; later stages reference it by digest.

    • Container registry
  5. Deploy

    Environment-specific configuration applied; production requires a manual, audited approval.

    • GitLab environments
    • Kubernetes
Sanitized delivery flow. Stage names reflect the pattern, not a specific organization's environment.

Build notes

Implementation

The template library started with the stages every service already needed: build, test, publish. Each stage was a separate, includable file with documented inputs, so a project could adopt the build stage without committing to the full flow on day one.

Image tags were derived from the commit SHA and promoted by digest. That removed a whole category of “it worked in staging” problems where two environments silently ran different builds.

Security stages were introduced in report-only mode first. Findings appeared in merge requests, teams triaged them, and enforcement was switched on per stage once the noise was understood.

Challenges

The hardest part was not technical. Some projects had pipelines with years of special cases. Rather than forcing them into the template, the template exposed a small number of extension points and the remaining special cases were documented as known exceptions with an owner.

Outcome

Pipelines became predictable and reviewable in one place. New services start from a working pipeline, and security checks run everywhere by default rather than by request.

What I learned

Pipeline templates are a product. Versioning, changelogs and a migration path mattered as much as the YAML.