header image

Code Snippets

Dynamically select SSH or HTTPS in Gemfile git_source

| Last updated:
git_source(:<source_name>) do |repo_name| 
  if system('ssh -T git@github.com 2>/dev/null')

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.