Sometimes in website and backend projects we found common components (React, utils, validations, etc) and, if we follow the DRY concept, we should find a way to create a private package and install it in every project that needs it.
We're going to review how to build and publish JavaScript packages using GitHub and npm.
The GitHub solution
GitHub provides the GitHub Package Registry to publish private npm packages. We can also use it for Docker images and libraries for other languages like Ruby, but we're going to focus on the npm solution.
The publish configuration
You should add the publishConfig
section in the package.json
file to publish to the GitHub registry.
"publishConfig": {
"registry": "https://npm.pkg.github.com"
}
The workflow
This workflow will publish a package to the GitHub Registry every time we create a release in the GitHub repository:
name: Publish
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
- run: npm install
- run: npm run build
- run: |
echo @lexacode:https://npm.pkg.github.com/ > build/.npmrc
echo '//npm.pkg.github.com/:_authToken=${NPM_TOKEN}' >> build/.npmrc
- run: npm publish
working-directory: ./build
env:
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
The permissions
modifies the default permissions granted to the GITHUB_TOKEN
.
This workflow creates a .npmrc
file inside the build/
directory before publishing the package to the registry.
echo @lexacode:registry=https://npm.pkg.github.com/ > build/.npmrc
echo '//npm.pkg.github.com/:_authToken=${NPM_TOKEN}' >> build/.npmrc
🧠Remember that your organization name, e.g. lexacode
, should be in kebab-case
, no uppercase allowed.
Then, you should add the GITHUB_TOKEN
as an environment variable for the npm publish
command.
- run: npm publish
working-directory: ./build
env:
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Installing the GitHub package
To install the GitHub package locally you should create a PAT (Personal Access Token) in the GitHub web. Make sure you selected the read:packages
permission. Then, add the token to your environment:
export NPM_TOKEN=<YOUR_GITHUB_TOKEN>
Create the following .npmrc
file in the project:
@lexacode:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
Now, you can run the npm install
:
npm install @lexacode/package-example
In GitHub Actions
To use your package in GitHub actions you should use a code like the following:
build:
permissions:
contents: read
packages: read
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
- run: npm ci
env:
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
👉 You need the explicit packages: read
permission.
Packages cross organizations
If you want to use a package from another organization using the GitHub Package Registry, you should set your PAT as a secret in the repository. Edit the YAML file using the new secret instead:
- run: npm ci
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
💡 The custom permissions
section is not required for this scenario.
Conclusion
You can publish private packages and use it everywhere you want via the GitHub Package Registry.
I left you a full repository with a TypeScript package, already published using the CI action. 🙌
Example npm package
This repository is a template for create TypeScript packages compatible with ES modules and CommonJS.
Top comments (1)
Helpful