Jenkins and submodules
Welcome
That will be a short post, rather full of my pain and frustration. Fortunately with happy-end and topic for a small article.
Problem
GitHub has some problems with service accounts for CI/CD usage. At least in Free Plan. You can’t share deployment keys like for example in GitLab. I can understand that in the context of security, but If you have 4,5, or 15 repositories, you need to manage the same numbers of ssh key pairs. That is annoying, but I used to it. The problem comes when you need use sumbodules in CICD pipelines with Jenkins. Let’s say Jenkins also has probem with submodules. In general if you’re using multibranch situation is documented:
checkout([
$class: 'GitSCM',
branches: scm.branches,
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
extensions: scm.extensions,
extensions: [
[$class: 'RelativeTargetDirectory', relativeTargetDir: 'dir'],
[
$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: true,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: false
]
],
userRemoteConfigs: scm.userRemoteConfigs
])
But when you’re using regular pipeline, you can’t just use userRemoteConfigs. The solution was simple, after regular checkout add small sh step:
sh("""
cd /dir && git submodule update --init --recursive
""")
Also what is important out Jenkins need to have the right configuration of ~/.ssh/config
with IdentityFile set to correct private key. But it’s ok.
Then…
But how to deal with the second private module? it’s not so trivial. Git doesn’t work as regular ssh - not checks id_rsa in order. Git check the first one and throw an error… The most popular solution is:
- change the hostname of GitHub, then checkout with this new hostname
Sure it’s great when you’re a developer, but when it’s come to CI it’s… eh don’t do that. Your developers will hate you.
Solution
Maybe it’s not the best solution ever, not sooo smart and beautiful, but at least it works.
Implementation
First - add new id_rsa to your .ssh/
directory - location could be different, but professionals have standards.
And then comes bash
sh("""
cd /dir
git submodule update --init external/module_a
export GIT_SSH_COMMAND="/usr/bin/ssh -i /root/.ssh/id_rsa_b"
git submodule update --init external/module_b
git submodule update --init --recursive
unset GIT_SSH_COMMAND
""")
And that’s it. Simple, readable, and working.
Summary
What I can add? Submodules are hard, Github is hard, Jenkins is awesome but hard. Life is hard… In general, IT is hard but is so much fun. I can’t imagine better work, even If someone adds a new submodule to the stable branch, and destroy your great Friday’s evening. Take care then and maybe drop me some message, now I feel like nobody read this…