Project · Platform engineering · August 2026
GitLab CI/CD Standardisation
A PowerShell-led programme to audit, sandbox, verify and safely standardise CI/CD across a mixed GitLab repository estate.
This project began with one failed semantic-release job and expanded into a repeatable multi-repository workflow. The objective was not simply to patch a broken pipeline. It was to understand configuration drift, validate changes without production side effects and move repositories towards reusable, versioned GitLab CI/CD components.
Internal repository names, hostnames, package registries and credential identifiers have been removed from this public write-up.
At a glance
- 37 projects inventoried across the GitLab group.
- 18 root CI/CD configurations collected and classified.
- 9 repositories found with the same unpinned release-tooling failure mode.
- 16 repositories copied into an isolated verification group.
- 10 verified changes proposed back through merge requests.
- 1 repository initially using the target shared-component model.
The problem
A release job installed its tooling dynamically against an old Node.js runtime. New plugin versions were accepted by npm with an engine warning and then failed at execution time. The same pattern had been copied into several repositories and into a project template, so the immediate defect was also an estate-wide maintenance problem.
The audit exposed wider drift:
- multiple Python and Node.js runtime generations;
- pinned, unpinned and locally patched release dependencies;
- different publishing mechanisms and semantic-release configurations;
- legacy and modern pipeline rule styles;
- scheduled jobs with production side effects;
- active package repositories with no visible root pipeline;
- very limited adoption of the existing reusable CI/CD component.
What I built
1. Targeted estate audit
A PowerShell collector enumerated projects and subgroups through the GitLab API. It fetched only the files needed to understand CI/CD and packaging behaviour, then produced a consistent project inventory and risk classification.
2. Manifest-driven sandbox
A migration manifest recorded source and sandbox projects, commits, pipeline identifiers, verification outcomes and backport state. Git repositories were mirrored into a separate group with CI disabled by default, protected branches recreated and only explicitly approved variables copied.
3. Safety controls
The workflow used default-deny variable handling, did not copy pipeline schedules, excluded high-risk maintenance repositories and asserted that no target project could mirror changes back to the source estate. Scripts also refused production namespaces and source default branches where a sandbox destination was required.
4. Pipeline verification and evidence capture
Changes ran through real GitLab pipelines in the isolated group. The watcher recorded more than a green or red status: it classified the semantic-release outcome and downloaded failed and release-job traces for later review.
5. Verified backport workflow
A dry-run-first script compared the verified sandbox files with the live source branch, rejected sandbox-only content and allowed only the intended CI/CD files. Successful changes were proposed through source branches and ordinary merge requests rather than written directly to default branches.
Automation created
The working toolkit included scripts for:
- group-wide CI configuration discovery;
- sandbox manifest and subgroup creation;
- repository mirroring and protected-branch recreation;
- safe CI/CD variable transfer;
- sandbox safety assertions;
- controlled CI enablement;
- deterministic pipeline updates;
- pipeline execution and trace collection;
- verified backport merge requests;
- backport status and failure reporting.
Architecture
GitLab source group
|
v
Read-only CI/CD audit
|
v
Migration manifest
|
v
Isolated sandbox group
- mirrored refs and tags
- CI disabled initially
- approved variables only
- no schedules
|
v
Pipeline verification
- status and semantic verdict
- failed and release traces
|
v
Live-source comparison
|
v
Narrow merge request backport
|
v
Normal repository review and merge controlsKey design decisions
Preserve Git history
Release tooling derives decisions from branches, tags and commit history. Repository copies therefore used mirror semantics rather than a shallow default-branch clone.
Treat variables as typed configuration
Variable metadata such as type, protection, masking, raw expansion and environment scope was preserved. Secret values were not written into the migration manifest or normal logs.
Never recreate schedules automatically
Schedules can represent operational workloads rather than test triggers. They were omitted from the sandbox and had to be assessed separately.
Verify against the live source
The original audit was a snapshot, not a permanent authority. Before a backport, the script fetched the current source files and stopped when repository owners had changed them after sandbox creation.
Separate immediate remediation from the target model
The immediate horizon pinned compatible release dependencies. The next horizon migrates coherent repository classes to versioned CI/CD components. The final horizon adds policy, ownership and upgrade monitoring to prevent renewed drift.
Outcomes
- The original release failure was reproduced and corrected safely.
- Repeated failure patterns became measurable rather than anecdotal.
- Production repositories remained read-only throughout verification.
- Every proposed backport had a pipeline, commit and trace evidence chain.
- The project produced a reusable migration method rather than a one-off bulk edit.
- The audit established a prioritised route towards versioned shared components.
Lessons learned
- A copied pipeline is a dependency that cannot be patched centrally.
- A dormant repository can still contain the next active failure.
- A green pipeline is not enough when release semantics matter.
- Scanner findings and estate inventories need freshness checks.
- Idempotent automation must persist state after every external write.
- Small PowerShell control-flow mistakes can invalidate a bulk workflow.
- The safest multi-repository automation proposes changes; it does not merge them.
Technical articles
- How I standardised CI/CD across 37 GitLab repositories
- Auditing GitLab CI/CD drift across a group with PowerShell
- Building a safe GitLab CI sandbox for multi-repository changes
- From copy-pasted pipelines to versioned GitLab CI/CD components
- Automating verified backports across multiple GitLab repositories