You know that feeling when you're already planning a big trip, and then your old car starts making a *new* worrying noise? That was us last week. We'd been slowly building out GitLab CI pipelines for six months, phasing out our old Jenkins monolith. Then that CVE list dropped for the Script Security plugin. Our security team's Slack channel lit up like a Christmas tree. 😅
It wasn't that we were *unprepared*—our Jenkins instance was locked down and we were already 70% migrated. But that alert was the final "nope, we're done" moment. Management signed off on the overtime, and we went into a two-week "great migration" sprint. The real pain wasn't the pipeline logic translation; it was the little things. Like migrating decades of Jenkins secrets to GitLab's Vault integration without anything leaking. Here's a snippet of the hacky script we used to sanity-check our variable translation, running in a throwaway container:
```bash
# This wasn't the migration script, just a checker
for OLD_JOB in $(jq '.[].name' jenkins_jobs.json); do
echo "Checking vars for $OLD_JOB..."
# Compare against our new .gitlab-ci.yml mappings
grep -q "$OLD_JOB" ./mapping.log || echo "MISSING: $OLD_JOB"
done
```
The biggest win? Moving from a "groovy script as a pipeline" mindset to a declarative `.gitlab-ci.yml` file checked into the repo. No more plugin dependency hell. The final push took about 14 days with a team of three, but the last 20% of jobs (the weird, snowflake ones) were 80% of the work. Anyone else finally make the leap because of a security scare? How did your "last mile" go?
-- Dad
it worked on my machine
Oh man, that script security plugin CVE was a real wake-up call. We did a similar migration last year, and you're right - the secrets migration is the silent killer. We ended up writing a small Go service that acted as a temporary proxy, fetching from the old Jenkins credential store and injecting into GitLab's CI variables API during pipeline runs. Ran it for a month in parallel to catch any mismatches.
Did you run into any issues with the different pipeline trigger models? That was our other gotcha - moving from Jenkins' event-driven jobs to GitLab's commit-based triggers broke a few of our older deployment workflows.
Latency is the enemy, but consistency is the goal.
>moving from Jenkins' event-driven jobs to GitLab's commit-based triggers
That's not a bug, it's forcing you to fix a design flaw. If your deployment workflow depends on a Jenkins event and not a commit/tag, it was too detached from your actual code state.
Writing a proxy service for secrets is overkill. Just script a one-time export/import and be done. Running a parallel service for a month adds complexity you don't need.
We moved and deleted the old Jenkins instance the same day. No proxies, no fallbacks. It forces the team to adapt.
Simplicity is the ultimate sophistication
That's a bold approach, but it assumes your entire team has the same risk tolerance. Deleting the old system same-day works if you have 100% confidence in your new pipelines, which our security team didn't after a big platform switch.
Our parallel proxy run wasn't about the team adapting, it was about verifying the secrets mapping was correct before burning the bridge. The last thing you want is a production outage because a service account token got misformatted in a scripted export. Sometimes a little complexity upfront saves a bigger headache later.
I do agree on the trigger model point, though. Being forced to tie deployments to a commit state was a net positive, even if it was painful to refactor those old workflows.