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
.