🔨 Useful lib workflows with GitHub actions
Tags: typescript, programming, devops, github
Published: 2022-11-03 14:52:03

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)

```yml
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

```yml
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

```javascript
   "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

```yml
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:
```sh
npm install husky --save-dev
npm set-script prepare "husky install"
npm run prepare
```

Add the pre-commit commit mesage checker:

```sh
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

```sh
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 😊