Github package registry from A to Z (nodejs)

Github package registry from A to Z (nodejs)

Throughout this post, you will learn how to

  • Publish a package to the GitHub registry
  • Delete a package from Github registry (for public and private packages)
  • Install a package from Github registry

Github registry does support Javascript (npm, yarn), Ruby (gem), Java (mvn, gradle), docker, .NET (dotnet). In this post, everything will be about Javascript (yarn or npm) only.


Credential preparation

Goto to your GitHub profile (Settings entry at the menu) -> Developer settings -> Personal access tokens -> Generate new token.

Naming your token for future reference, and select the following scopes for the token

  • repo: Full control of private repositories
  • write:packages: Upload packages to Github package registry
  • read:packages: Download packages from GitHub package registry

Click "Generate token", copy the generated token, and store it in a secreted location. In the rest of this post, <TOKEN> will be referred to as this token.


Publish a package

Step 1: Configure package.json

Go to your project, add the following entry to package.json

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

Naming your package (via the "name" entry in package.json) in the following format @<username>/<package-name>, where <username> is your Github username, <package-name> is the package name.

Note that the package name my-package should be the same as your repository name.

Why do I say "should" instead of "must"? It is possible to make the package name different from the repository name. Github even allows you to publish a package name without the existence of the corresponding repository. However, the behavior, in this case, is uncontrollable and I believe this is a bug. So I recommend creating the repository and match it with the package name.

Step 2: configure credentials

Yarn 1:

Method 1 (not work anymore): global npm config with username/password:

Run npm login --registry=https://npm.pkg.github.com, use your Github username as username and the generated <TOKEN> as the password to log in.

This method may not work, as Github might already deprecate this legacy token type. The following error will occur.

npm ERR! code E403
npm ERR! 403 403 Forbidden - PUT https://npm.pkg.github.com/-/user/org.couchdb.user:tranvansang - Permission denied
npm ERR! 403 In most cases, you or one of your dependencies are requesting
npm ERR! 403 a package version that is forbidden by your security policy, or
npm ERR! 403 on a server you do not have access to.

npm ERR! A complete log of this run can be found in:
Method 2: global config with token

In .npmrc (this file can be placed in your home $HOME or project directory), add //npm.pkg.github.com/:_authToken=<TOKEN> where <TOKEN> is generated in the credential preparation step.

Note: .npmrc can use environment variable, you can use

//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

and pass the token via environment variable GITHUB_TOKEN.

GITHUB_TOKEN=<TOKEN> yarn publish

Yarn 2

Method 1: use environment variable

Set the environment variable YARN_NPM_AUTH_TOKEN as the token.

 YARN_NPM_AUTH_TOKEN=<TOKEN> yarn npm publish

Method 2: use config file

In .yarnrc.yml (this file can be placed in your home $HOME or project directory), add

npmRegistries:
  "https://npm.pkg.github.com":
    npmAlwaysAuth: true
    npmAuthToken: <TOKEN>

Step 3: Publish

Publish the package with yarn publish (for yarn v2: yarn npm publish).

Question: Will my package be public or private?

Answer: if the associated repository is private (public), the package is private (public).


Delete a package

For private packages

Method 1: via the web.

Go to the repository page, click "package", select the npm package. On the right side, open the "Edit package" menu. Select "Manage versions".

Iterate through all versions and delete them by clicking on the "Delete" button.

Method 2: via CLI.

The package can be manipulated from CLI via graphql API.

curl -sL -X POST https://api.github.com/graphql \
-H "Authorization: bearer <TOKEN>" \
-d '{"query":"query{repository(owner:\"<username>\",name:\"<package-name>\"){registryPackages(first:10){nodes{packageType,registryPackageType,name,nameWithOwner,id,versions(first:10){nodes{id,version}}}}}}"}'
{"data":{"repository":{"registryPackages":{"nodes":[]}}}} | jq .

Copy the version id, and substitute <version-id> in the following command.

curl -X POST \
-H "Accept: application/vnd.github.package-deletes-preview+json" \
-H "Authorization: bearer <TOKEN>" \
-d '{"query":"mutation { deletePackageVersion(input:{packageVersionId:\"<version-id>\"}) { success }}"}' \
https://api.github.com/graphql

For public packages

Convert the package to private, delete the package with the above steps, convert the package back to public.

If the repository is deleted, the associated package also will be gone.


How to use the package

Yarn 1

In .yarnrc (this file can be placed in your $HOME or project directory), add the following content

"@<username>:registry" "https://npm.pkg.github.com/"
"@<username>:npmAuthToken" "<TOKEN>"

Or, equivalently, running

yarn config set -H npmScopes.<username>.npmRegistryServer "https://npm.pkg.github.com/"
yarn config set -H npmScopes.<username>.npmAuthToken "<TOKEN>"

Where <username>  is your github username.

Yarn 2

In .yarnrc.yml (in $HOME or project directory), add

npmScopes:
  <username>:
    npmAlwaysAuth: true
    npmRegistryServer: "https://npm.pkg.github.com"
    npmAuthToken: "<TOKEN>"

Now, you can add your package with yarn add @<username>/<package-name>. All package under @<username> scope will be downloaded from Github registry npm.pkg.github.com.

Buy Me A Coffee