Say there are various snippets of code that you’ve built up over some time that could be useful in multiple projects. You COULD copy and paste this code between the projects, but if you find a bug, that means you have to go into each and fix the bug. A better approach would be to create a package that can be shared across multiple projects. That’s exactly what you’ll learn how to do in this article.

To demonstrate this, I’m going to create a simple npm package that exports a command that combines a name with Hello, so the result of passing in my name would output Hello Brian!

Here’s the code.

const sayHello = function (name) {
  console.log("Hello " + name + "!")
}

module.exports = {
  sayHello
}

You’ll also need to add the following to package.json. Notice what’s called the scope at the end of the URL. For your project, replace this with your GitHub username.

"publishConfig": {
  "registry":"https://npm.pkg.github.com/@YOUR_USERNAME"
},

Create an empty repository to hold your package. When you do, make sure you tick the Private radio.

https://cdn.brianmorrison.me/media/2020/2d856f63-0031-4232-8ff1-970d7a92376a

After you’ve pushed the code to your repo, go into Actions and click "set up a workflow yourself →"

https://cdn.brianmorrison.me/media/2020/b43da98e-b637-4843-8e74-5fc50ddd485d

name: Node.js Package

on:
  push:
    branches:
      - master

jobs:
  publish-gpr:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: 12
          registry-url: https://npm.pkg.github.com/
          scope: '@YOUR_USERNAME'
      - run: npm install
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}

Once done, click Start commit, then Commit new file.

https://cdn.brianmorrison.me/media/2020/bccdaa74-a28c-4598-a0be-7e287067e5d9

Now head back into Actions and you should see your project building. Once its done and you receive the following, you should be ready to use your package in another project.

https://cdn.brianmorrison.me/media/2020/a011169d-c372-4172-afaa-c53ea19ea419

You can also see the package details by going back to the repository home and clicking on the package on the right sidebar.

https://cdn.brianmorrison.me/media/2020/276c63b7-36cd-4e3f-9d6b-241e296a0fa8

Adding to a Project

Adding to a project is pretty simple. The only thing you’ll need to is add a file to the root of your project called .npmrc with some info telling your local npm where to look for packages for your scope. Before you do, you’ll need to generate a personal access token (or PAT) from GitHub that is used to authenticate with private package feeds.

To get your PAT, click on your profile image on the upper right of GitHub and select Settings. Then go to Developer Settings, Personal Access Tokens, and Generate New.

https://cdn.brianmorrison.me/media/2020/0f415295-0406-4251-88e9-1eb305e4bb27
https://cdn.brianmorrison.me/media/2020/7125b821-a837-489f-88d7-6acb4f1d1a7c
https://cdn.brianmorrison.me/media/2020/1f8a1f2f-01fc-4f03-b0ac-53ca21c0fa38

In the next window, give your token a name and select the read:pacakges scope. Make sure not to check any other boxes as this might give the token too much access to your account. Scroll to the bottom and click Generate Token.

https://cdn.brianmorrison.me/media/2020/219a0dab-6ed6-4ed1-b036-d1d4df6fbdd7

Once you create the token, you’ll be put back into the previous view with the PAT listed. You MUST copy it now as you can’t get it again.

https://cdn.brianmorrison.me/media/2020/fb4b01c8-856e-4881-a4af-4457362335c1

Tokens should be treated as passwords. Never share them with anyone you don’t trust. Furthermore, in the following section, I’ll be adding the token directly into the repo. This is generally bad practice and a build variable should be used instead (more here). I’m doing this as a demonstration.

Now lets get that .npmrc file setup. Create the file in the project you want to use your new package with and add the following content to it. Replace the scope with your username, and the token with your token.

@YOUR_USERNAME:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=YOUR_TOKEN

Now you can install the package just like you would any other NPM package. Replace the scope & project name with whatever yours is.

npm install @learning-brianmmdev/github-actions-packages

In the project, I created a small file just to test the exported function from the package like so.

let demoPackage = require('@learning-brianmmdev/github-actions-packages')

demoPackage.sayHello('Brian')

And here is the output of testing this.

https://cdn.brianmorrison.me/media/2020/909adce7-ad6c-4a92-8c6a-55f82d399d0b

Congratulations! You now have your very own private package that can be reused across projects you build.