First add a .gitignore
file at the root of your project
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
Create a .github/workflows/main.yml
file.
This is a configuration file for GitHub Actions, which is a continuous integration and continuous deployment (CI/CD) platform provided by GitHub. It defines a workflow that is triggered when code is pushed to the main branch of a repository. The workflow has two jobs, "build" and "publish", which respectively build the code and publish it as a Node.js package to GitHub's package registry. The workflow is designed to ensure that the code builds and passes tests before it is published, which helps ensure the quality of the published package.
name: Netspective Labs Commons
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
path: nodejs/universal
node-version: 16
- run: cd nodejs/universal && npm ci
- run: cd nodejs/universal && npm test
publish-universal:
needs: build
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
path: nodejs/universal
node-version: 16
registry-url: https://npm.pkg.github.com/
- run: cd nodejs/universal && echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc
- run: cd nodejs/universal && npm ci
- run: cd nodejs/universal && npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
publish-astro:
needs: build
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
path: nodejs/astro
node-version: 16
registry-url: https://npm.pkg.github.com/
- run: cd nodejs/astro && echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc
- run: cd nodejs/astro && npm ci
- run: cd nodejs/astro && npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
This workflow includes two additional jobs in addition to the build
job. These jobs are responsible for publishing the nodejs/universal
and nodejs/astro
packages, respectively. Let's start by looking at the job for the astro
package.
Inside the nodejs
directory, create a directory. This directory will contain the contents of the new package.
To get started, add the following files at the root of the new directory..
- package.json
{
"name": "@netspective-labs/package-name",
"version": "0.0.1",
"description": "Some brief description of the package",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"files": [
"dist/*",
"src/*",
"!src/**/*.spec.ts"
],
"repository": {
"type": "git",
"url": "git+https://github.com/netspective-labs/commons/package-name.git"
},
"keywords": [
"library",
"typescript"
],
"dependencies": {},
"devDependencies": {
"typescript": "^4.9.5"
},
"scripts": {
"cp-astro-components": "cp -r src/components dist", // Only for astro packages
"build": "rm -rf dist && mkdir dist && npm run cp-astro-components && tsc", // Remove the npm run cp-astro-components if the package do not have any astro components
"upgrade-major": "npm version major",
"upgrade-minor": "npm version minor",
"upgrade-patch": "npm version patch",
"test": "exit 0"
},
"author": "",
"license": "MIT"
}
After you added the package.json
, run
npm install
This will create the package-lock.json
file.
- tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"allowJs": true,
"esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "nodenext"
},
"include": ["./src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts", "**/*.spec.tsx", "**/*.test.tsx"]
}
- .npmrc
@OWNERORORG:registry=https://npm.pkg.github.com
Replace the OWNERORORG namespace with the owner of the repo or organization.
- .npmignore
# Ignore source files and development files
src/
*.ts
*.tsx
*.map
*.d.ts
*.spec.ts
*.spec.tsx
*.test.ts
*.test.tsx
jest.config.js
tsconfig.json
# Ignore version control files
.gitignore
.git/
*/.gitignore
# Ignore editor-specific files
.vscode/
.idea/
*.sublime-*
*.swp
.DS_Store
Now create a src
directory and inside of it you will start adding the files with the contents of your package.
In this example we will expose a sum function in a new sum.ts
file.
export function sum (a: number, b: number): number => a + b;
Lastly, we need to create the entrypoint for the package, that is the index.ts
. This file should be at the root of the src
directory, i.e. src/index.ts
. Here we will export all the functions, components, constants, etc. that we want to expose to our package consumers.
export { sum } from './sum.js';
If you are making a public repo this section won't be necessary.
We will need to be authenticated with a proper Github Personal Access Token (PAT) in order to be able to deploy. So create a PAT with all permissions, if you don't know how to here's a guide for you.
Once you have the PAT, we will need to add it to the secrets of the repo. Follow these steps to achieve this:
- Go to the repo in Github.
- Click on Settings.
- Click on Secrets and variables on the left sidebar.
- Click on Actions.
- New repository secret
The name should be
NPM_TOKEN
and the value would be the PAT you've created earlier.
The name of the secret should match the name of the property accessed by the secrets object in the .github/workflows/main.yml
file.
echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
In the root of the project that you wish to install a nodejs
package, add a .npmrc
file with this content
@OWNERORORG:registry=https://npm.pkg.github.com
Replace the OWNERORORG namespace with the owner of the repo or organization.
The purpose of this file is to configure the npm client to use GitHub's package registry as the default registry for installing and publishing packages. This is typically used to install or publish private packages hosted on GitHub's package registry.
Let's use as an example the astro package
that we've already created here.
The command to install the package may vary on the owner of the repo.
pnpm install @OWNERORORG/nlc-astro
Once again replace the OWNERORORG namespace with the owner of the repo or organization.
In order to deploy a new version of a package you would just need to upgrade the version of it by running one of these commands first at the root of the package. It's important that you follow the semantic versioning standards.
npm run upgrade-major
npm run upgrade-minor
npm run upgrade-patch
Then commit your work and push.
git push
This will trigger the Github Action and will deploy your package automatically. You can check the Actions tab in the repository and see the progress of the workflows if you want.