git_source(:<source_name>) do |repo_name|
if system('ssh -T git@github.com 2>/dev/null')
"git@github.com:<user>/#{repo_name}.git"
else
"https://github.com/<user>/#{repo_name}.git"
end
end
Dynamically select SSH or HTTPS in Gemfile git_source
If valid key added to ssh-agent
, use SSH for custom Gemfile git_source
, else fallback to HTTPS
Setting custom gemfiles
Custom private .git
repositories can be set in the Gemfile to be install using SSH using the following syntax:
git_source(:<source_name>) { |repo_name| "git@github.com:<user>/#{repo_name}.git" }
gem '<gem-name>', <source_name>: '<repo-name>', tag: 'v1.1.0' # custom private gem
See the bundler docs for more info.
Working with Docker
When building container images with private gems, at some point in the build credentials must be added to the container in order to authenticate with the gemfile source and download the gem. On local machines credentials are commonly SSH keys, however, SSH key expiry tends to be hard to manage and they are not in a very convenient form to inject as a build arg, sometimes leading to active SSH keys being left as artefacts in container images.
One convenient way to avoid this is by using a GitHub token build arg in a builder stage and exporting to the the BUNDLE_GITHUB__COM
environment variable. The builder stage is used to install the gems and they are then copied in the main container image, leaving behind any sensitive artefacts and build args in the builder stage which is not uploaded.
To use a GitHub to access a private gem repository, the source link must be in the HTTPS form, for example:
git_source(:<source_name>) { |repo_name| "https://github.com/<user>/#{repo_name}.git" }
However, an issue with having the source fixed to HTTPS is that on local machines either the BUNDLE_GITHUB__COM
environment will require setting (accessible to all) or the GitHub token will require entering on each bundle install
. Neither of which are ideal.
Use the git_source snippet to dynamically check if suitable SSH keys are added on a local machine and select authentication method respectively.