Golo Roden
Golo Roden

Reputation: 150902

Install an npm module from a private GitHub repository using GitHub Actions

I am trying to run a build for a Node.js project using GitHub Actions. As part of the npm install, I need to install an npm module directly from a private GitHub repository (not from GPR!).

In the package.json I have:

"dependencies": {
  ...
  "my-module": "github:<org>/<my-module>#master",
  ...
},

However, when running npm install, I get:

npm ERR! [email protected]: Permission denied (publickey). npm ERR! fatal: Could not read from remote repository.

The repository is part of my own organization, and locally (i.e. from my machine) it works. How can I make this run?

I have already tried setting the NODE_AUTH_TOKEN environment variable, but it didn't make a difference. Although you find this suggestion quite often, it seems to only address GPR. What I would like to avoid is having to hardcode the token into the package.json file. Any thoughts on this?

Upvotes: 44

Views: 23546

Answers (5)

levmillr
levmillr

Reputation: 11

What worked for me. Create a npmrc file in root with the builtin GITHUB_TOKEN from secrets.

  - name: Create .npmrc
    run: echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc

I also needed to allow read access to the repository using the action from the private repository via Manage Actions access for the GITHUB_TOKEN to work. AFAIK the GITHUB_TOKEN is scoped to the current repository. Otherwise you can pass a PAT (Personal Access Token) with read packages permissions as an action secret as well.

I'd assume the same would need to be done if you use actions/setup-node@v3 to create the npmrc. Or if you pass it as an env var.

Access Example

Upvotes: 1

Dmytro
Dmytro

Reputation: 5701

A very straightforward solution that requires only read-only access to the repo. Uses GitHub's Deploy Keys and the following action https://github.com/webfactory/ssh-agent

1. Provide a private repo in package.json in the following format:

"dependencies": {
    "repo": "git+ssh://[email protected]:user/private_repo.git",
}

2. Generate a deploy key locally on your machine. Use empty passphrase

ssh-keygen -f my_key

3. Create a deploy key via GitHub UI (prefer read-only). Use contents of my_key.pub

Deploy keys

4. Create a GitHub Actions secret named REPO_SSH_KEY for the target repo via GitHub UI - the one that will be running GitHub Actions. Use contents of my_key – it is a private key

SSH secret

5. Update the GitHub Actions workflow file to look like this

# ...
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Add SSH key to chekout a private repo
        uses: webfactory/[email protected]
        with:
          ssh-private-key: ${{ secrets.REPO_SSH_KEY }}

      - name: Checkout code
        uses: actions/checkout@v2
      
      # ...
      # the rest of the steps, including npm install
      # that will successfully access the private repo

Upvotes: 14

peterevans
peterevans

Reputation: 42220

This is how I have managed to install dependencies from private GitHub repositories.

Dependencies in package.json can be added as follows. The github: prefix is optional. Specifying the #branch or #tag is also optional.

    "dependencies": {
        ...
        "myrepo": "username/myrepo#master",
        "myotherrepo": "github:username/myotherrepo"
    },

Here is an example workflow. PAT is a repo scoped Personal Access Token. It is important to disable persisted credentials on actions/checkout, otherwise they will override your PAT. Note that the git config change persists between steps so you only need to run it once per job.

      - uses: actions/checkout@v2
        with:
          persist-credentials: false
      - uses: actions/setup-node@v1
        with:
          node-version: 12.x
      - run: git config --global url."https://${{ secrets.PAT }}@github.com/".insteadOf ssh://[email protected]/
      - run: npm ci
      ...

Upvotes: 42

3rdeye7
3rdeye7

Reputation: 536

From the error and the way you've included the dependency (in package.json), it seems you are not passing authentication credentials (token, ssh.

Refer to this documentation for specifics on Git URLs as Dependencies

It can be done via https and oauth or ssh.

https and oauth: create an access token that has "repo" scope and then use this syntax:

"package-name": "git+https://<github_token>:[email protected]/<user>/<repo>.git"

or

ssh: Setup ssh and then use this syntax:

"package-name": "git+ssh://[email protected]:<user>/<repo>.git"
(note the use of colon instead of slash before user)

Upvotes: 1

Ziv Yatziv
Ziv Yatziv

Reputation: 153

You should edit your .npmrc file. You can also use npm config

npm config set @myco:registry http://reg.example.com

Please see the following thread for more information: Is there any way to configure multiple registries in a single npmrc file

Upvotes: -3

Related Questions