Software Engineering

    Enterprise DevOps and CI/CD: GitHub Actions, GitLab, Monorepo and Deployment Pattern Guide

    Seven practical decisions for production-grade enterprise CI/CD: pipeline architecture (GitHub Actions vs GitLab CI vs Jenkins), monorepo vs polyrepo, deploy strategies (blue-green, canary, rolling), secret + artifact management, KVKK-compliant pipeline logs. Lessons from Turkish B2B projects. An eCloud Tech engineering note.

    Published: May 26, 202613 min read
    devopsci-cdgithub-actionsgitlab

    Enterprise software has transformed in deploy velocity over the past five years. Banks that used to ship 4 releases a year now ship 2 a week; e-commerce SaaS, 5-10 a day; modern startups, 50+. Behind this leap is CI/CD modernisation — from manual build/test/deploy to automated pipelines, from monolithic repos to monorepos, from ssh-deploy to GitOps + container orchestration. In Türkiye this shift is about 3 years behind; regulated sectors (banking, insurance, telco) sit in the Jenkins era, while e-commerce, B2B SaaS and AI startups are moving fast to GitHub Actions/GitLab CI. KVKK compliance, BDDK Information Systems Regulation, ISO 27001 audits — all expect provable discipline from a modern CI/CD pipeline.

    Within our DevOps + CI/CD engineering and cloud migration services we have delivered 16 enterprise CI/CD modernisation projects over the past 24 months — in finance, e-commerce, healthcare, logistics and SaaS. We operate our own AIGENCY platform on a GitHub Actions + Turborepo + GitOps architecture. In this article we walk through seven practical decisions for enterprise DevOps + CI/CD modernisation in order: pipeline platform choice, repo strategy (monorepo vs polyrepo), build optimisation, test automation, deployment patterns, secret + secret management, KVKK-compliant observability.

    1. Pipeline platform — GitHub Actions, GitLab CI, Jenkins decision matrix

    Figure 1 — Pipeline platform — GitHub Actions, GitLab CI, Jenkins decision matrixFigure 1 — Pipeline platform — GitHub Actions, GitLab CI, Jenkins decision matrix

    CI/CD platform choice is a skeletal decision — it shapes team workflow, cost structure and operational load for 5+ years.

    GitHub Actions:

    • Pro: zero-config integration with GitHub repo, marketplace of 15,000+ actions, simple YAML, included in GitHub's enterprise pricing. Native OIDC (trust with cloud-provider IAM).
    • Con: heterogeneous action ecosystem (each vendor sets its own quality, no security review), self-hosted runner setup (for KVKK) is extra effort.
    • Best fit: organisations living on GitHub, modern green-field projects, small-to-mid teams.

    GitLab CI/CD:

    • Pro: fully integrated with GitLab (issue, merge request, CI, registry, monitoring on one platform), self-hosted Community Edition is free, self-hosted runners by default.
    • Con: less widespread than GitHub, vendor lock-in (if you migrate to GitLab, git history + issues + PRs move).
    • Best fit: enterprise projects with self-hosted compliance needs, KVKK-critical sectors, those who want a single all-in-one platform.

    Jenkins:

    • Pro: 20 years of maturity, 1,800+ plugins, fully self-hosted, the "Swiss army knife" of build automation.
    • Con: Groovy DSL rather than YAML (extra learning), plugin-compatibility issues, Jenkins-master as a single point of failure, modern security practices (OIDC, dynamic secrets) require extra plugins.
    • Best fit: legacy Java/Maven projects, organisations with sunk Jenkins investment, on-prem requirements.

    CircleCI / Buildkite / Drone CI / Travis CI: niche; uncommon in Türkiye, rare in enterprise projects.

    Decision matrix:

    CriterionGitHub ActionsGitLab CI/CDJenkins
    Setup time<1 week1-2 weeks3-6 weeks
    Monthly cost (mid-size team)USD 200-1,500USD 0-1,000 (self-hosted free)Infrastructure only (~USD 200-1,000)
    Self-hosted runnerPossible, manualNativeNative
    OIDC + cloud IAMNativeNativePlugin
    Plugin / action ecosystemVery broadBroadBroadest but older
    KVKK self-hostedSelf-hosted runnerFull GitLab self-hostedFull self-hosted
    Modern UXExcellentGoodOld (Blue Ocean improves it)

    Practical recommendation: new project + on GitHub → Actions; on-prem/KVKK-critical → GitLab self-hosted; with existing Jenkins, plan a 6-12 month migration, don't migrate immediately.

    2. Repo strategy — monorepo vs polyrepo

    Figure 2 — Repo strategy — monorepo vs polyrepoFigure 2 — Repo strategy — monorepo vs polyrepo

    Repo strategy affects even organisational structure (Conway's law: software mirrors the organisation). The wrong choice produces a refactoring project in 1-2 years.

    Monorepo (single repo, multiple packages):

    • Tooling: Nx (TypeScript + Node heavy), Turborepo (Vercel, modern + fast), Bazel (Google, polyglot + huge scale), pnpm workspaces (simple + lightweight), Lerna (legacy).
    • Pro: atomic cross-package commits (UI + API + types in one PR), shared dep management (no version mismatch), refactor across the whole codebase, zero-friction code sharing (utils, types, UI library).
    • Con: CI complexity (build only affected packages — affected algorithm), repo size (need shallow clone), git operations slow down (large repo).
    • Sweet spot: TypeScript/JS heavy, shared UI/types, 1-3 teams, 5-15 packages.

    Polyrepo (every service/package in its own repo):

    • Pro: independent deploy cycles, team autonomy (each team owns its repo rules), small repo (fast clone), narrow blast radius (a bug in one service doesn't touch others).
    • Con: cross-repo change is hard (PR coordination), code duplication (utils copied to every repo), version mismatch (a shared SDK on 2 different versions in prod).
    • Sweet spot: independent microservices, polyglot (Go + Python + Node together), 10+ teams.

    Hybrid (middle ground):

    • Frontend + shared packages as one monorepo, backend microservices in separate repos.
    • The most common enterprise pattern; least compromise.

    Decision matrix:

    FactorMonorepoPolyrepo
    Team count1-55+
    Package count5-3030+ or 1-3
    Language diversity1-23+
    Cross-package change frequencyHighLow
    Deploy independenceLow (usually whole app together)High (each service independent)
    RefactoringVery easyHard

    Practical recommendation: PoC + early MVP = monorepo (speed + consistency); as organisation + service count grow drift selectively to polyrepo. Conservative: respect Conway's law — draw package boundaries to match organisational shape.

    3. Build optimisation — only affected packages

    A pipeline's single biggest performance lever is incremental build. Naive monorepo builds rebuild all 15 packages on every PR (12 min); smart incremental builds only the affected 2-3 (90 seconds).

    Build cache pattern:

    1. Local cache (developer machine): Turborepo, Nx, Bazel hash-based local cache. Second build in seconds.
    2. Remote cache (CI ↔ developer shared): Turborepo Remote Cache, Nx Cloud, Bazel Build Cache. Developer 1's build output is reused by CI and Developer 2. Hashed input → output mapping, S3/Redis backing.
    3. Docker layer cache: BuildKit --cache-to type=registry keeps the docker build cache in the image registry. Cache hits even when CI runners are ephemeral.

    Affected algorithm:

    • git diff origin/main...HEAD → changed files.
    • From the dependency graph, derive "affected packages" (transitive).
    • Only those are built + tested.
    • Nx nx affected --target=build, Turborepo turbo run build --filter=...[origin/main], Bazel native.

    Pipeline performance pattern:

    [git push]
        ↓
    [Lint + typecheck affected only] — 60-120s
        ↓
    [Unit test affected only] — 90-300s
        ↓ (parallel)
    [Build affected only] — 90-300s
    [Integration test critical paths] — 5-15min
        ↓
    [Deploy staging] — 60-120s
        ↓ (manual approval)
    [Deploy production] — 60-180s
    

    Unoptimised naive pipeline is 25-45 min; optimised is 5-10 min. A 3-5× improvement in developer productivity.

    Practical targets:

    • PR pipeline: <10 min (developer flow preserved)
    • Main-branch full build: <20 min
    • Production deploy: <5 min (CI end + actual deploy)

    Sustaining these targets requires CI-infrastructure investment + ongoing tuning. CI minute cost matters — a monthly USD 50K-200K GitHub Actions/GitLab CI bill is common in mid-to-large teams; with optimisation it drops 50-70%.

    4. Test automation — the trust spine of the pipeline

    Test pyramid (Mike Cohn): 70% unit + 20% integration + 10% e2e. The confidence CI provides depends on the existence + quality of each layer.

    Unit test:

    • Speed: <50ms/test, parallel execution.
    • Coverage target: 70-85% (sector-dependent). Higher targets have diminishing returns.
    • Tooling: Jest, Vitest (modern Node), pytest, Go test, JUnit.
    • In CI: on every PR, on the affected-package basis.

    Integration test:

    • Real HTTP/gRPC between services, real DB (test container), real queue.
    • Speed: 1-30s/test, sequential or constrained parallel.
    • Target: critical flows (auth, payment, core CRUD).
    • Tooling: Testcontainers (Docker-based throwaway env), Playwright (API + UI), Pact (contract testing).

    End-to-end (e2e) test:

    • Browser automation (Playwright, Cypress), full deployed app environment.
    • Speed: 10-60s/test, parallel + flaky risk.
    • Target: 10-50 critical user journeys (login → main task → logout).
    • Cadence: 5-10 critical tests in PR; full suite nightly.

    Flaky test management:

    • A flaky test in CI = lost trust + alert fatigue.
    • Detection: same test passes 2 out of 3 runs = flaky.
    • Quarantine: flaky tests are pulled from the main suite, run in a separate job, fixed in a weekend sprint.
    • Zero tolerance: leaving flaky tests in place corrodes pipeline quality.

    Security testing in CI:

    • SAST: Semgrep, Snyk Code, GitHub CodeQL (every PR).
    • SCA (dependency vulnerability): Dependabot, Renovate + Snyk/Trivy (every PR).
    • DAST: OWASP ZAP, Burp Suite (after staging deploy).
    • Container scan: Trivy, Grype (after Docker build).
    • IaC scan: Checkov, tfsec (on Terraform PRs).

    Pipeline test coverage matrix:

    StageTests
    PR openLint + typecheck + unit + SAST + dependency scan
    PR merge to main+ integration + container scan + e2e smoke
    Staging deploy+ full e2e + DAST + performance test
    Production deploy+ post-deploy smoke + monitoring sync

    5. Deployment patterns — rolling, blue-green, canary

    The deploy pattern is chosen by risk tolerance + sector + budget.

    Rolling deployment:

    • Restart N instances in 2-N steps (e.g. 10 instances → roll 2 at a time, 5 steps).
    • Kubernetes default (RollingUpdate strategy).
    • Pro: zero extra infra, simple, auto in most PaaS.
    • Con: rollback is slow (reverse rollout), old + new live simultaneously → DB schema breaking changes are problematic.
    • Sweet spot: stateless services, small-to-mid teams, SMBs.

    Blue-green deployment:

    • Two full parallel environments: blue (current prod) + green (new). Switch via DNS/LB.
    • Zero-downtime, instant rollback (flip DNS back).
    • Pro: production-identical testing (test green prod-fashion), second-level rollback on incident.
    • Con: 2× infra cost, single DB (can't parallelise — schema migration must be backwards-compatible).
    • Sweet spot: B2B SaaS, regulated sectors, financial transactions.

    Canary deployment:

    • New version traffic split: 1% → 5% → 25% → 50% → 100%. At every step a metric (error rate, latency, business KPI) is monitored.
    • Automatic rollback: if error rate exceeds threshold, fall back to old.
    • Pro: validation on real production traffic, safest, "free" if you already have A/B testing.
    • Con: feature-flag system required (LaunchDarkly, Unleash, custom), observability must be mature, complex.
    • Sweet spot: high-volume consumer (e-commerce, social), millions of users.

    Modern hybrid: Argo Rollouts, Flagger, Spinnaker — Kubernetes-native canary + blue-green orchestration. Combine with a service mesh (Istio, Linkerd) for traffic splitting + observability integration.

    GitOps (Argo CD, Flux):

    • Deploy state is declarative in a Git repo (Helm charts, Kustomize manifests).
    • Production = projection of Git. No manual kubectl apply.
    • Automatic drift detection + reconciliation (if cluster differs from Git, cluster is corrected).
    • Audit trail: who deployed what when → Git commit history.
    • Ideal from a KVKK + compliance perspective: change evidence is immutable.

    Practical decision matrix:

    Sector / ScenarioRecommended
    SMB web/app, <50K usersRolling
    Mid-size B2B SaaS, 50K-500KBlue-green
    E-commerce, finance, >500KCanary + GitOps
    Banking coreBlue-green + canary hybrid + extensive manual approval
    Microservice mesh, >20 servicesGitOps + Argo Rollouts

    6. Secret + artifact management — the pipeline's security gate

    A CI/CD pipeline is the central point for credentials (DB password, cloud IAM key, API token, SSL cert). Wrong management = breach source.

    Secret management pattern stack:

    [Developer]
        ↓ (commit code, NO secrets in repo)
    [Git repo] — .gitignore .env, pre-commit secret scan (git-secrets, truffleHog)
        ↓
    [CI runner]
        ↓ (fetch at runtime)
    [Secret store: Vault / Secrets Manager / Key Vault]
        ↓ (short-lived token via OIDC)
    [Application]
    

    Layer 1 — Repo discipline:

    • .env in .gitignore, git secrets --register-aws global hook.
    • Pre-commit: husky + lint-staged + secret pattern scan.
    • Repo history scan (BFG, git-filter-repo) — if secrets leaked in the past, rotate.

    Layer 2 — CI native secret store:

    • GitHub Actions: Settings → Secrets and variables → Actions. Masked output, environment-scoped, branch-protected.
    • GitLab: Settings → CI/CD → Variables. Protected, masked, expand variables.
    • Jenkins: Credentials Plugin + folder-level scoping.
    • Every access is logged.

    Layer 3 — External secret manager:

    • HashiCorp Vault: self-hosted, most widely adopted in enterprises, dynamic secret generation (DB credential is created when pipeline calls + 1-hour TTL).
    • AWS Secrets Manager / Azure Key Vault / GCP Secret Manager: cloud-native, vendor lock-in.
    • Doppler, 1Password Secrets Automation: modern SaaS alternative.
    • Vault is mandatory for KVKK-critical organisations (data residency + audit log + access control matrix).

    Layer 4 — OIDC trust (short-lived credentials):

    • GitHub Actions ↔ AWS IAM Role: GitHub identity token → AWS STS AssumeRole → 15-min temporary credentials.
    • Static IAM access keys become unnecessary — the chance of a credential leak goes to zero.
    • Setup: GitHub Actions workflow + AWS IAM OIDC provider + Role trust policy.

    Layer 5 — Audit + rotation:

    • Every secret access is logged (CloudTrail, Vault audit log, GitLab audit events).
    • 90-day automated rotation policy.
    • Unused secrets are revoked after 30 days.
    • Quarterly access review (who still needs which secret).

    Artifact management:

    • Docker image: GitHub Container Registry (ghcr.io), Docker Hub, AWS ECR, Harbor (self-hosted).
    • Build artifact (jar, npm pkg): GitHub Packages, JFrog Artifactory, Nexus (self-hosted).
    • Retention policy: prod tags forever, PR builds 30 days, scheduled prune.
    • Signing: Sigstore Cosign, Notary v2 — supply-chain integrity (did this image really come from our CI?).

    Our SOC operations article details how CI/CD pipeline logs integrate into the SOC SIEM.

    7. KVKK-compliant observability + audit

    CI/CD pipelines do not seem to process personal data, but indirectly they do: developer identity (commit author), deploy decision (who approved), test data in pipeline logs (mock customer email), production access (debug session). KVKK + ISO 27001 audits require written discipline.

    Seven disciplines:

    1. Immutable pipeline run logs: GitHub Actions / GitLab CI run history (default 90 days, 400 days on enterprise). 12 months + retention policy in writing for KVKK audit.

    2. Developer identity (commit) policy: verified commits (GPG/SSH signed) mandatory, no anonymous commits. Evidence: who wrote what, who merged.

    3. Approval gates auditable: 2 reviewers required for production deploy (GitHub branch protection rule); each approval logs who + when + commit SHA.

    4. Test data sanitisation: no real customer email/national ID/IBAN in test fixtures. Faker library + synthetic data. No PII should appear in CI logs.

    5. Production debug log access: pipeline-to-prod debug session limited (break-glass procedure), each access logged + post-hoc justification.

    6. Secret access audit: which pipeline run called which secret → Vault audit log + correlation by pipeline run ID.

    7. Compliance reporting: monthly report — number of deploys, rollbacks, hotfixes, incidents. Goes into KVKK risk assessment.

    Observability stack:

    • Pipeline metrics: DORA metrics (deploy frequency, lead time, change failure rate, MTTR) — state-of-the-art DevOps KPIs. Trackers: LinearB, Sleuth, DX Engineering Effectiveness.
    • Build performance: cache hit rate, average pipeline duration, queue time, runner utilisation.
    • Cost tracking: GitHub Actions usage report, GitLab CI minute analytics, cloud-runner spot pricing.
    • Failure analytics: flaky test detection, distinguishing infrastructure failure from code failure.

    DORA metrics targets (DORA Elite tier):

    • Deploy frequency: 1+ per day
    • Lead time for changes: <1 hour (commit → prod)
    • Change failure rate: <15%
    • MTTR (failed change recovery): <1 hour

    Reaching these targets takes years; the enterprise average (Medium tier): 1-7 deploys per week, <1-day lead time, 15-30% failure rate, <1-day MTTR.

    Practical summary — starting checklist

    The correct order for your first production CI/CD modernisation project:

    1. Platform: GitHub repo → Actions; on-prem/KVKK → GitLab self-hosted; legacy → plan a Jenkins migration.
    2. Repo strategy: 1-3 teams + JS/TS = monorepo (Turborepo/Nx); 5+ teams + polyglot = polyrepo; hybrid is the most common.
    3. Build optimisation: affected algorithm + remote cache + Docker layer cache. PR pipeline target <10 min.
    4. Test pyramid: 70% unit + 20% integration + 10% e2e; zero tolerance for flaky; SAST + SCA + DAST + IaC scan in CI.
    5. Deployment pattern: SMB rolling; mid-size B2B blue-green; high-volume canary; GitOps (Argo CD) ideal for compliance.
    6. Secret management: Vault or cloud manager + OIDC short-lived credentials + audit + 90-day rotation.
    7. Artifact management: image registry + signing (Cosign) + retention policy.
    8. KVKK observability: pipeline log 12-month retention, verified commits, audited approval gates, test data sanitisation.
    9. DORA metrics: deploy frequency / lead time / failure rate / MTTR — monthly dashboard.
    10. Continuous improvement: quarterly platform retro, CI cost optimisation, security training, runbook updates.

    This list is the minimum discipline. On top come sector-specific additions (deploy controls for PSD2 payment services, FDA validation pipeline for medical devices, change-management evidence for ISO 27001). The value of CI/CD is not in being live but in weekly measurable improvement of DORA metrics — the numerical trend curve for deploy velocity + confidence + recoverability.

    Our team in Şanlıurfa Karaköprü has delivered CI/CD modernisation projects in finance, e-commerce, healthcare and logistics through DevOps + CI/CD engineering and cloud migration, and operates our own AIGENCY platform on GitHub Actions + Turborepo + GitOps. For an enterprise CI/CD modernisation pilot, a DORA-metric audit of your existing pipeline, or monorepo/polyrepo decision advisory, you can reach us through the contact form — the first assessment call is free of charge.


    eCloud Tech — A team based in Şanlıurfa, Türkiye, working on enterprise software, AI, blockchain and cybersecurity. Building Tomorrow.

    Frequently Asked Questions

    The decision rests on three variables. (1) Repo hosting: CI naturally lives where your code lives — on GitHub → GitHub Actions (annual plan from USD 21/user, 50K Actions minutes included), on GitLab → GitLab CI/CD (integrated, self-hosted runner is free). This alignment is the right answer in ~80% of cases. (2) Self-hosted compliance need: if a KVKK-critical organisation requires the runner on Türkiye soil, self-hosted GitLab or Jenkins dominate. Even on cloud CI, self-hosted runners are possible. (3) Legacy + Java/Maven-heavy: the mature Jenkins ecosystem (1,800+ plugins) still dominates. Picking Jenkins on a modern green-field project produces technical debt in 6-12 months. CircleCI is popular in mid-to-large SaaS companies but uncommon in Türkiye. Practical advice: if you're on GitHub, use Actions; if you need on-prem/self-hosted, GitLab self-hosted; in a modernisation project the Jenkins → Actions/GitLab migration pattern is standard.

    Monorepo (single repo, multiple packages — Nx, Turborepo, Bazel, pnpm workspaces): atomic cross-package commits, shared dependency management, easy code sharing, refactoring across the whole codebase in one PR. Drawbacks: CI complexity (build only affected packages — incremental), repo size grows over time (Google's monorepo is in TBs). Sweet spot: TypeScript/JS-heavy team, shared UI/types/utils, 3-15 packages. Polyrepo (every service in its own repo): independent deployment, team autonomy, small + fast repo clones, narrow blast radius. Drawbacks: cross-repo change is hard (PR coordination), code duplication (utils copied everywhere), version mismatch. Sweet spot: independent microservices, polyglot (Go + Python + Node together), 10+ teams. Practical rule: 1-3 teams + 5+ packages = monorepo; 5+ teams + independent services = polyrepo. Our AIGENCY platform uses a monorepo (Turborepo); the eCloud Tech website is a single repo (vite-react-ssg).

    Three core patterns. Rolling (renew instances in order): the default, transition from old to new version in 2-N steps. Kubernetes default, the default in most PaaS. Pro: no extra infra; con: rollback is slow, old + new run concurrently (DB schema changes are hard). Blue-green (two parallel full environments, switch over): zero-downtime, instant rollback (reverse DNS/LB switch), production-identical test env. Cons: 2× infra cost, DB is the single source of truth (can't parallelise). Sweet spot: B2B SaaS, regulated sectors (banking, healthcare). Canary (new version takes 1%, 5%, 25%, 100% of traffic): validated on real production traffic, metric-based automated rollback, the safest. Cons: feature flags + observability required, complex. Sweet spot: high-volume consumer apps, when you already have A/B testing. Practical for Türkiye: SMB → rolling; mid-size B2B → blue-green; high-volume (1%+ of market) → canary.

    A five-layer pattern is standard. (1) No secrets in git.env in .gitignore, pre-commit hook with git-secrets or truffleHog blocking commits. (2) CI native secret store: GitHub Actions Secrets, GitLab CI/CD Variables (masked + protected), Jenkins Credentials Plugin. Single admin RBAC control, audit log. (3) External secret manager: HashiCorp Vault (self-hosted), AWS Secrets Manager, Azure Key Vault, GCP Secret Manager. Pipeline fetches at runtime + 15-min TTL token. In KVKK-critical organisations Vault is mandatory; cloud-vendor managers need an EU region + DPA. (4) Short-lived credentials: OIDC trust (GitHub Actions ↔ AWS IAM Role) ends static credentials; every pipeline run gets a fresh token. (5) Audit + rotation: every secret access is logged, rotate every 90 days (automated), revoke unused secrets after 30 days. Our AIGENCY infra uses Vault + GitHub OIDC; not a single API key has been entered into production by hand.

    Three scales. (1) Basic (1-3 services, 5-15 devs, existing Jenkins → GitHub Actions migration + basic pipeline + Docker build + auto-deploy staging): 6-10 weeks, 200-400 engineer-hours, TRY 700K-1.5M + ongoing CI-minute licence (annual TRY 20K-100K). (2) Mid-size (5-15 services, 15-40 devs, monorepo refactor + Turborepo/Nx + blue-green deploy + secret management + observability integration): 16-24 weeks, 900-1,800 engineer-hours, TRY 3M-7M. (3) Enterprise (20+ services, 40+ devs, multi-env + canary + Terraform IaC + compliance pipeline + KVKK audit log + GitOps): 6-14 months, 2,500-6,000 engineer-hours, TRY 7M-22M + continuous platform team (3-6 DevOps + SRE). 40-50% of cost is personnel; licences + infra 25-35%; training 10-15%. Important ROI data: a correct CI/CD modernisation reduces bug ratios by 40-60%, increases deploy frequency 10-50×, shortens MTTR (incident → resolution) 5-10×. First-year investment, second-year net ROI.

    Related articles