Getting Started with GPR

(Github Package Registry)

GitHub Packages

What's the difference with npm?

A new 🏑 home for your packages

with the same experience.

With a great difference:

But that makes them a little more difficult to work with...

Let's create one of our own!

Only stored in GPR (and private)

1. Creating the lib

export const getBlahMessage = () => ({ message: 'blah' })
// src/index.js

1. Creating the lib

Type definitions (TS/JSDocs) for EXTRA POINTS!

2. Installing tools

> npm init
> npm i -D rollup
> npm i -D @babel/core rollup-plugin-babel  
rollup-plugin-terser  rimraf 

3. Configuring Rollup

export default {
  input: 'src/index.js',
  output: {
    file: `dist/blah.mjs`,
    format: 'esm', 
    sourcemap: true,
  },
  plugins: [/*...*/]
}
// rollup.config.js

Outputs 1 file

3. Configuring Rollup

export default [
  {/* ... */},
  {/* ... */},
]
// rollup.config.js

Outputs 2 files

3. Configuring Rollup

import babel from 'rollup-plugin-babel'
import { terser } from 'rollup-plugin-terser'
import pkg from './package.json'

const terserOptions = {
  sourcemap: true,
  compress: true,
  mangle: true
}

const createConfig = ({ minify, format, ext = 'js' }) => ({
  input: 'src/index.js',
  output: {
    name: pkg.name,
    file: `dist/index${minify ? '.min' : ''}.${ext}`,
    format,
    sourcemap: true
  },
  plugins: [
    babel({ exclude: 'node_modules/**' }), ...(minify ? [terser(terserOptions)] : [])
  ]
})

export default [
  { minify: false, format: 'esm', ext: 'mjs' },
  { minify: true, format: 'esm', ext: 'mjs' },
  { minify: false, format: 'esm' },
  { minify: true, format: 'esm' }
].map(createConfig)

4. Let's create the bundle!

{
  ...
  "scripts": {
    ...
    "build": "rimraf dist && rollup -c"
  }
  ...
}
> npm run build
// pacakge.json

4. Let's create the bundle!

5. Configure package.json

{
  ...
  "files": [
    "dist"
  ],
    
  "main": "dist/index.js",
    
  "module": "dist/index.mjs"
  ...
}
// pacakge.json

Like .gitignore, but the opposite and for the "artifacts" exposed

πŸ‘‰πŸ½

🌟

6. Creating the repo

(A regular repository... As usual!)

> git init

6. Creating the repo

πŸ˜ŽπŸ‘‰πŸ½

6. Creating the repo

> git add .
> git commit -m "initial commit :rocket:" 
> git remote add origin git@...
> git push -u origin master

7. Make it installable

 {
+  "name": "@lovetoknow/npm-pkg-test",
+  "repository": "git://github.com/lovetoknow/npm-pkg-test.git",
+  "publishConfig": {
+    "registry": "https://npm.pkg.github.com/"
+  },
-  "private": true
 }

Β Edit package.json

*

* Name of the organization in github (in lowecase!)

7. Make it installable

registry=https://npm.pkg.github.com/lovetoknow

Β Add a .npmrc file

πŸ‘†πŸ½ Oh, must be lowercase!

8. Publish it!

8. Publish it!

But first, authenticate!

8. Publish it!

You have 2 options:

  1. adding a PAT (Personal Access Token) to the .npmrc file.
    Β 
  2. logging in via npm CLI

πŸ‘‰πŸ½

8. Publish it!

> npm publish

8. Publish it!

πŸ† Tip! Pre-publish hook

"prepublish": "npm run build"

Now, let's install it!

9. Installing the lib

> cd ..
> mkdir install-test
> npm init -y

We set up a test project

9. Installing the lib

> npm install @lovetoknow/npm-pkg-test  

9. Installing the lib

Why?

We forgot to tell npm to look for in GPR!

registry=https://npm.pkg.github.com/lovetoknow
// .npmrc

9. Installing the lib

> npm install @lovetoknow/npm-pkg-test  

10. Installing the lib on a CI env

The "robot" πŸ€– needs to be authenticated too.

- Via npm CLI

- Via .npmrc with a PAT

//npm.pkg.github.com/:_authToken=PERSONAL_ACCESS_TOKEN
// .npmrc

- Or...

10. Installing the lib on a CI env

Github actions!!

- GITHUB_TOKEN env var

- registry_url
...
      - uses: actions/setup-node@master
        with:
          registry-url: >
          	https://npm.pkg.github.com/
...
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: >
          	${{ secrets.GITHUB_TOKEN }}

Credit: Daniel Young

11. Updating our library

> git add .

> git commit -m 'change ...'

> git push

> npm version <major | minor | patch>

> npm publish

πŸ‘‰πŸ½

πŸ‘‰πŸ½

πŸ‘†πŸ½manually

11. Updating our library

npm versioning should follow semver

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards compatible manner, and
  3. PATCH version when you make backwards compatible bug fixes.

11. Updating our library

npm version

- Updates package.json and package-lock.json

- Creates git tags

- And a commit

11. Updating our library

Alternative workflow:

  • You add as many pushes to master as you want.
  • Once you consider the library should get those changes, you create a git tag
  • npm version manually
  • npm publish automatically on another github action.
name: Publish package
on:
  push:
    tags:
      - v.*
jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions/setup-node@master
        with:
          node-version: 12.x
          registry-url: >
          	https://npm.pkg.github.com/
      - run: npm install
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: >
          	${{ secrets.GITHUB_TOKEN }}

Credit: Daniel Young

12. npm audit

> npm audit

12. npm audit

> npm audit --registry https://registry.npmjs.org/

Credit: Carlo and Josh

13. Good practices

- Tests! (and using the dist files in your tests, not the src)

- npm hooks (pretest, prepublish)

- semver!

- Publishing a changelog file

Resources

Thank you

Thanks for your help!

Joshua Coady

Carlo D'Ambrosio

Daniel Young
Lluis de Lasaosa

Rakhi Neigi

Credits

Get Started with GPR (Github Package Registry)

By Paul Melero

Get Started with GPR (Github Package Registry)

Short intro to GPR (Github Package Registry) for private npm modules.

  • 49
Loading comments...

More from Paul Melero