How to fetch a private dependency on GitHub Actions?

I use GitHub Actions to run tests every time I commit.
I have an application that uses a private repo on GitHub as a dependency.

My mix.exs file looks like this:

{:private_dependency, git: "git@github.com:ORGANIZATION/private_dependency.git"}, ref: "sha_of_working_commit_on_my_private_dependency_repo"}

However, GitHub Actions fails to fetch this particular dependency:

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
** (Mix) Command "git --git-dir=.git fetch --force --quiet --progress" failed
##[error]Process completed with exit code 1.

How to fetch a private dependency on GitHub Actions?

1 Like

Add a private SSH key to the action that has read only access to the private repository.

1 Like

How though?

I’ve been looking for how to add an SSH key to GitHub Actions, stumbled onto this blogpost which refers to this action.

  • I created a SSH key with the following command: ssh-keygen -t ed25519 -a 100 -f /path/to/file
  • copied the whole private key file to both to the repository where I run the action from and to the private repository that I use as a dependency under the secret configuration of each repository on GitHub
  • copied the whole public key file to the deploy_key configuration of the repository where I ran GitHub Actions
  • then I updated my GitHub Actions configurations with the webfactory/ssh-agent action.

However, I still get the following error message:

fatal: could not read Username for 'https://github.com': No such device or address
** (Mix) Command "git --git-dir=.git fetch --force --quiet --progress" failed
##[error]Process completed with exit code 1.

I have no clue how to do this in GHA, but for GitLab CI I usually have the private key as a variable, which I put into an ssh-agent session.

Roughly:

eval $(ssh-agent -s) # start the agents session
echo "$SSH_PRIVATE_KEY" | ssh-add - # load the key in the agent

I’m not sure though how exactly GHA and secrets work, therefore you might need to adjust this to GHA.

The public part of that key has to be added to that private repository. Usually it is added as a read only deploy key.

In Github Actions you may want to set the GITHUB_TOKEN variable in the step where you pull the repos:

- name: SomeStep
    run: git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic@github.com/".insteadOf "https://github.com/" && YOUR_COMMAND
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

You will need to generate a token with valid claims for this private repo and include it in your repo’s secrets. Notice how git is being configured to always include your token in the URL (https://${GITHUB_TOKEN}:x-oauth-basic@github.com) instead of just calling https://github.com/. Hopefully this configuration will suffice, but you’ll have to test it out.

Read more on the token here: https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token.

3 Likes

I finally got it working.

In my mix.exs file, I fetched the private dependency with SSH. Then I updated my workflow definition file with the webfactory/ssh-agent action; followed the steps in the README and added a deploy_key to the private dependency that GHA was trying to fetch.

More here: https://github.com/webfactory/ssh-agent/issues/31#issuecomment-647991948

1 Like

Ah nice, good to know there’s more than one way to fetch private repos in GA.

I would probably still opt for the token way, no need to maintain deployment keys in the projects, just the secrets.