Using SSH to push changes to external repository

This post is a quick follow-up that aims to enhance the previous "How to automatically push every change to an external repository" post by using the SSH protocol to push changes to external repository.

Project Updates

Since the publication of the previous post, the reference implementation project that has been actively updated, including valuable contributions from the community (special thanks to Aly ). The new features include:

  • Centralized configuration using ~/.gitremote

  • Support for GitLab

  • Token based authentication

  • Ignore pattern via configuration

  • Support to create and push changes to GitHub Organizations

  • Support to create and push changes to GitLab Groups/Subgroups

  • SSH protocol

Please check the updated README for detailed information on how to use it with your Business Central.

Using SSH

The Secure Shell (SSH) Protocol is a protocol for secure remote login and other secure network services over an insecure network.

To use the SSH protocol, you need to have it correctly set up in the Business Central hosted operation system that, by default, stores the SSH keys in the user’s ~/.ssh directory. Before starting Business Central, try to first use the SSH config by cloning and pushing changes to your external git infrastructure like GitHub - this makes sure that not only your SSH is configured correctly but also that your external git infrastructure is appropriately registered in the know_hosts SSH config file.

Now that you have the SSH properly configured, all you need is to enable the SSH protocol in the reference implementation project by adding the following line to the ~/.gitremote config:

useSSH=true

As of today, there is a caveat to using this configuration. If you want that the githook code automatically creates the repository in your external git infrastructure, you still need to provide the user and password. This additional credential is needed because to create a repository a user/pass (or token) are required for an API call.

If you don’t provide the user/[pass|token] information, the reference implementation project will not create repositories and will run in push mode only where all your changes will be pushed only for repositories that were imported (that had to be imported using the SSH protocol in order to preserve the original origin information of the repository).

For those that could be curious what is like the setup to push changes using the SSH protocol, here is the code block that does that in the reference implementation project:

//common push configuration
final PushCommand pushCommand = git.push() (1)
        .setRefSpecs(new RefSpec(ref + ":" + ref))
        .setRemote(remoteURL);
//check if ssh should used
if (properties.getUseSSH()) {  (2)
    // setup of ssh transport config
    pushCommand.setTransportConfigCallback(transport -> { (3)
        final SshTransport sshTransport = (SshTransport) transport;
        sshTransport.setSshSessionFactory(new JschConfigSessionFactory() {
            @Override
            protected void configure(OpenSshConfig.Host host, Session session) {
            }
        });
    });
} else {
    // if not ssh, it requires credentials
    pushCommand.setCredentialsProvider(integration.getCredentialsProvider()); (4)
}

// push changes to the remote repository
pushCommand.call(); (5)
  1. This is the common configuration part for the jgit push command. Notice that we’ll split the PushCommand builder as we have a different config for ssh and user/pass.

  2. Check if the Git hook has the SSH protocol enabled (defined by the properties config defined above)

  3. Setup the SSH protocol, but note that this is the protocol setup, not credentials (as the SSH protocol itself use a secure connection using the public key stored). JGit uses the Jsch library, and here we’re just using the default configuration. It would be possible to customize the public key file location and other configs.

  4. If not SSH, we use our regular user/pass (or token) credentials.

  5. Finally we execute the push command.

Business Central Enhancement

In the current state of Business Central, you cannot start a new project pointing to an external repository to have the content stored. As of today, the only way to use an external repository inside Business Central is importing a repository that already contains a project structure on it.

I just created this jira, so that you can follow the progress of this proposed enhancement.

Wrapping up

In this post, we learned how to use the SSH protocol with the reference implementation project, including the trade-offs associated with it. If you want to know more about Business Central and git, please check other posts of the series.

rhba business-central git hook external integration push ssh