Why one integrated system
A requirement from a Hyundai or Tata stakeholder review becomes a work item, branches link to it, the PR references it, the pipeline run traces to it, and the release notes generate from it. That traceability is not bureaucracy — when an auditor or an OEM asks “when did this behavior change and why,” the answer takes minutes. Fragmented toolchains make that question a forensic project.
Pipeline patterns that held up
- YAML everything: pipelines live in the repo, reviewed like code; classic UI pipelines are unauditable snowflakes.
- Templates: one shared build/scan/test/publish template across 10+ services — fix a vulnerability scan once, every service inherits it.
- Environments with approvals: production deploys gate on a human for the billing path, auto-deploy for stateless services with instant rollback.
- Artifacts feeds: internal NuGet packages for shared protocol models (OCPI DTOs, OCPP messages) — versioned contracts, not copy-pasted classes.
Boards without theater
- Epics map to platform capabilities (roaming, smart charging, telemetry), features to protocol modules — the backlog mirrors the architecture.
- User stories carry acceptance criteria written with stakeholders during grooming, not reverse-engineered at demo time.
- Sprint queries and dashboards replace status meetings; the burndown is honest or it is useless.
- Velocity is a planning input, never a performance metric — the moment it becomes a target, it stops being true.
Worked example: the shared pipeline template
Every service repo’s pipeline is ten lines extending one reviewed template — fix the scan step once, every service inherits it:
# azure-pipelines.yml (per service)
trigger: { branches: { include: [main] } }
extends:
template: templates/dotnet-service.yml@pipeline-templates
parameters:
serviceName: sessions-api
runContractTests: true
productionApproval: true # billing-path services gate on a human
# templates/dotnet-service.yml (shared, versioned)
stages:
- stage: Build
jobs:
- job: build
steps:
- script: dotnet test --logger trx
- task: dependency-check@6 # CVE scan blocks on high severity
- script: docker build -t $(registry)/${{ parameters.serviceName }}:$(Build.BuildNumber) .
- stage: Production
${{ if eq(parameters.productionApproval, true) }}:
jobs: [{ deployment: deploy, environment: prod-gated }]
FAQ
For enterprise platform teams needing integrated backlog + pipelines + artifacts + granular approvals, Azure DevOps remains stronger. For open-source or lightweight repos, GitHub Actions. Many of my teams run both — Boards + GitHub is a common hybrid.
Commit to production under 30 minutes including tests and scans. Longer than that and engineers batch changes, and batched changes are where incidents hide.
Shared cadence, separate boards per service area, one cross-team sync anchored on dependencies — and every dependency tracked as a linked work item, not a promise in a meeting.