simbathesailor.DEV

Github private packages and docker

library
reactjs
github packages
Docker

November 18, 2020

Photo by https://unsplash.com/@element5digital

Photo from https://unsplash.com/@element5digital

Github packages have been around for a while now. As a developer we spend so much time on github either for our office work or for opensource projects.

Couple of months back , our team rolled out a design system, which have a library component also. The library has to be hosted somewhere so that , we can consume it in various projects.

The installation should be very similar to how we do it today mostly with frontend projects using npm install / yarn

We were already having teams licence for organization. we were having all our codebase available on github already. Github packages seemed very legit as an option for private package hosting. We are anyways getting it with the existing licence.


In this article, I am going to explain how we can publish and consume Github packages (private/public) and also what changes needs to be done in Dockerfile to get the installs working for docker builds


Let’s see how we can get it done.

PACKAGE CREATION

Note: If you have js based packages ready , Please dive directly into next section: which is Publish packages

You can create packages in javascript ecosystem using webpack, rollup or grunt/gulp e.t.c .

We used TSDX which is an excellent library creation helper. I also used lerna Lerna for versioining of packages, allthough we will not talk about lerna here.

Let’s create a simple packages which will just give us some random numbers between any two numbers. The example is kept trivial to keep the attention into the most important aspect of this article which are Github Packages

Run

npx tsdx create randomnumberlib

Pick name of your choice for this library, I have chosen randomnumberlib name. We are going to use https:npm.pkg.github.com(This is packages namespace for npm with github packages) as the registry for this package. Other languages have their own registeries.

Read more here : Github Packages with npm & Supported github packages client and namespaces

The tsdx command will create a folder , just navigate to the folder in terminal and add your library code. I have added the following code in

src/index.ts

  let times = 0

  export const random = (min: number, max: number): number => {
    if ('development' === process.env.NODE_ENV) {
      console.log(`boop ${++times}`);
    }
    
    return Math.ceil(Math.random() * (max - min) + min)
  };

My function does nothing more than returning a random number between min and max.

PUBLISH PACKAGE

If you have the package already or you have created a package using the steps in above section, let’s dive into how to publish the package.

As it is a github package make sure the package name is in this format @[username]/[packagename]. In my case it is @simbathesailor/randomnumberlib

simbathesailor is mygithub username and randomnumberlib is the library name

if your package is under any organization, then the above format will become @[organizationnameseenongithub]/[packagename]. I think most of you reading will have this scenario.

The name attribute in the package.json can be changed to the required package name.

so my package.json will look something like this:

...
"name": "@[organizationnameseenongithub]/[packagename]"
...

For this example , mine package.json looks like this:

"name": "@simbathesailor/randomnumberlib"

First step is to generate a personal access token from https://github.com/settings/tokens.

  1. Generate the one with read and write packages permission. Copy the token and keep it handy as it is going to be needed soon.

Token Permission snaphsot

  1. Run the following command to login to registry.
 npm login  --registry=https://npm.pkg.github.com

It will prompt for username. Put you github username

Next, it will ask for password: Paste the token generated in step 1.

Next , enter your email attached to your github account against which you want to publish the package.

If every thing works, you should see the message stating that you have successfully logged in.

  1. Next step : Just run publish command for you library. Run npm publish.

This npm publish will trigger a fresh build(due to prepare npm hook in tsdx, can be different for you) and then will try to publish the package.

By now, you should see the github repository listing package on right handside, somewhat similar to the below snapshot.

Github page with github package

Consuming Package [PRIVATE]

  1. Create a .npmrc file at the level parallel to your package.json file of your project.
  2. Add following content to the .npmrc file.
@[USERNAME]:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=[YOURTOKEN]

Replace USERNAME and YOURTOKEN with the orgname/username and github token(with read packages right) respectively.

If you don’t want to add this file at repository level. You can also keep the same in ~/.npmrc.

  1. Add .npmrc in .gitignore. Because we definitely don’t want to commit token to github.

You can create a .npmrc at ~/.npmrc and put the same content there. That should also work.

  1. Then just do the normal package install by running below command

There is one more way of doing it.

npm install

If every steps worked fine above, the install would have happened successfully.

And That’s it voila,🎆 you have published and consumed a private package. In my opinion, now with github packages it is very easy to publish and consume private packages as the packages stays near to your code.

To consume a public github package, you can just get rid of follwing line from .npmrc, because now you should bnot be needing any authentication

//npm.pkg.github.com/:_authToken=[YOURTOKEN]

In most of the cases, organizations are using Github plans which automatically allows github packages.

Docker Install

Add the following content to your docker file. Not all the parts are relevant,but the part where I am adding github token can be noticed bit more carefully.

ARG GENERATE_SOURCEMAP
ARG GITHUB_TOKEN
FROM node:12.10 as BUILD
ARG GENERATE_SOURCEMAP
ARG GITHUB_TOKEN

ENV GENERATE_SOURCEMAP $GENERATE_SOURCEMAP
ENV GITHUB_TOKEN $GITHUB_TOKEN
WORKDIR /usr/src/app
COPY package.json .

# Notice part below this line
# This is needed for installing private github packages
RUN echo //npm.pkg.github.com/:_authToken=$GITHUB_TOKEN >> ~/.npmrc
RUN echo @[USERNAME]:registry=https://npm.pkg.github.com/ >> ~/.npmrc
RUN yarn install
# Removing the github token from npmrc file in below line
RUN echo > ~/.npmrc
# Notice part above this line
ADD . /usr/src/app

RUN yarn run build
FROM node:12-alpine3.9
COPY --from=BUILD /usr/src/app .
EXPOSE 8001
CMD ["node", "start.js"]

Replace USERNAME with the your package username/organization.

There are some issue with how the scoped packages are handled via .npmrc. You cannot tell npm to download the packages from different registry at package level. Currently it is at scope level. Below is the ticket that I filed https://github.com/npm/cli/issues/2307

Finally I am going to provide the link where i am consuming the private package. I have added a sample npmrc file also for the reference.

Consumer Example

That’s all . Best of luck !!

Join the discussion