If you are a lib maintainer GitHub actions makes your life easier. In this article I will write about my current useful workflows: checks, release, publish to npm, husky commit hooks, and changelog generation.
Checks
Check every commit: run test, (you can add lint check, etc)
name: checks
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 16
- run: npm ci
- run: npm run test
Publish workflow:
Publish the library to npmjs when the release is created or you can trigger it manually
name: Publish Package to npmjs
on:
release:
types: [created]
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v3
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run npmjs-publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Requires an NPM_TOKEN.
It runs the package.json publish script: generate indexes, build the project, copy the *.json *.md files (package.json, readme, changelog...), and publish the build folder
"npmjs-publish": "rm -rf ./build && npm run generate-index && npm run build && cp *.json ./build && cp *.md ./build && npm publish ./build",
"generate-index": "cti clean ./lib && cti create ./lib"
For the index generation I use the "create-ts-index" npm package, it give you a nice cli "cti".
Release workflow:
Create new version (update package.json version), tag, create changelog, put the changelog to the release notes - based on conventional commits
name: Releases
on:
workflow_dispatch:
jobs:
changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: conventional Changelog Action
id: changelog
uses: TriPSs/conventional-changelog-action@v3.7.1
with:
github-token: ${{ secrets.MY_GITHUB_TOKEN }}
version-file: './package.json,./package-lock.json'
- name: create release
uses: actions/create-release@v1
if: ${{ steps.changelog.outputs.skipped == 'false' }}
env:
GITHUB_TOKEN: ${{ secrets.MY_GITHUB_TOKEN }}
with:
tag_name: ${{ steps.changelog.outputs.tag }}
release_name: ${{ steps.changelog.outputs.tag }}
body: ${{ steps.changelog.outputs.clean_changelog }}
The GITHUB_TOKEN is a special access token that you can use to authenticate on behalf of GitHub Actions. GitHub automatically creates a GITHUB_TOKEN secret for you to use in your workflow, and you can use it to authenticate in a workflow run.
In my case, I thought it will make sense to use it but If I use it the publish workflow will not run
"When you use the repository's GITHUB_TOKEN to perform tasks on behalf of the GitHub Actions app, events triggered by the GITHUB_TOKEN will not create a new workflow run. This prevents you from accidentally creating recursive workflow runs."
So I ended up creating a personal token MY_GITHUB_TOKEN
Enforce conventional commits:
The changelog is generated from conventional commits (Releases workflow) so useful to check the commit message before created. You can use Husky pre-commit hooks for this.
Husky setup:
npm install husky --save-dev
npm set-script prepare "husky install"
npm run prepare
Add the pre-commit commit mesage checker:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
If the commit message is not conventional it will not allow to commit it.
Maybe someone forgets to run a test before committing the changes the "check" workflow will fail but we can catch this locally when someone makes a commit:
pre-commit npm test
npx husky add .husky/pre-commit "npm test"
eg.
git commit -m "Keep calm and commit"
npm test
will run
Currently, I using these in this repo: https://github.com/OpenZer0/type-chef-di
There are maybe better solutions because I'm not an expert, If you can improve something please leave a comment.
Thank you for reading, I hope this was helpful 😊