-->
This is more like a note to self than a blog post, but I’m sure it’ll help someone out there. So, I was working on this sweet little JS Library boilerplate called Crust and I wanted to create a release on GitHub whenever I push a git tag as well as build and publish the package to NPM. Here’s how I got it done.
Firstly, I created a workflow file in .github/workflows
and named it release.yml
. Then, I added the following code to it.
name: Crusty
on:
push:
tags:
- "*"
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
registry-url: https://registry.npmjs.org/
- uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Crust@v${{ github.ref }}
draft: false
prerelease: false
publish-to-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
registry-url: https://registry.npmjs.org/
# Install deps
- run: npm i
# Prepare release
- run: npm run release.prepare
# Publish to NPM
- run: npm run release.publish
env:
# This is the NPM token used to publish the package to NPM, you only need this if you've enabled publishing with access tokens. Read more about this [here](https://docs.npmjs.com/about-access-tokens). Once you have the token in NPM, you'll have to add it as a secret in the GitHub repository. Read more about GitHub secrets [here](https://docs.github.com/en/actions/reference/encrypted-secrets).
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
Let’s setup some meta data first. The following line is the name of the workflow, you can name it whatever you want, but a convention is to name it after the repository prefixed with the name of the event that triggers the workflow. In this case, the event is a release event, so I named it Release crust
.
name: Release crust
Onwards, we need to specify when to trigger a workflow. The following line watches for a new git tag to be pushed and then triggers the workflow. You can read more about it here. The *
means that it’ll trigger on any tag push. Say you wanna trigger the workflow only on a tag push that starts with v
, you can replace the *
with v*
.
on:
push:
tags:
- "*"
You can also trigger a workflow on a pull request, a push to a branch, or just about anything. You can read more about it here.
Next, we need to specify the jobs that we want to run when the workflow is triggered. In this case, we want to create a release on GitHub and publish the package to NPM. So, we’ll create two jobs.
jobs:
create-release:
publish-to-npm:
This is the first job that creates a release on GitHub.
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
registry-url: https://registry.npmjs.org/
- uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: crust@v${{ github.ref }}
draft: false
prerelease: false
Most of this is just what the docs say, the only thing you need to care about is the release_name
. The release_name
is the name of the release that’ll be created on GitHub, a convention is to name it as repository@version
. In our case, the tag that triggered the workflow is the version, so we’ll use that, prefixed with a v
just to make it look smexy. Note that the variable github.ref
contains the tag that triggered the workflow, you can use it wherever you need the tag.
This is the second job that builds and publishes the package to NPM.
publish-to-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
registry-url: https://registry.npmjs.org/
# Install deps
- run: npm i
# Prepare release
- run: npm run release.prepare
# Publish to NPM
- run: npm run release.publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
Most of this, as expected, is boilerplate I copied from the docs, take care about the. The node-version
is the version of Node.js you want to use to run the job, this depends on which version you used for your app, crust used Node 18 at the time it was created so 18 is the specified version. The steps prefixed with run
are the actual commands you need to install the dependencies, build the package, and publish it to NPM. The env
section is where you specify the environment variables you need to run the commands. If you need secret env variables, keep on reading.
When you publish to NPM from a CI/CD pipeline, you’ll need to specify a NODE_AUTH_TOKEN
. This is just basic authentication stuff, see the links below if you wanna go in depth. Here’s what you need to do to get it working.
Access Tokens
.Create New Token
.classic token
, granular tokens are for more advanced stuff.Automation
option from the 3, this allows you to use your token in CI/CD pipelines, and click Generate Token
.Settings
and then Secrets
and then Actions
from the left sidebar.New repository secret
.NODE_AUTH_TOKEN
is a good choice, then paste the token you copied from NPM in the Value
field. Click Add secret
and you’re done.NODE_AUTH_TOKEN
. If you named it something else, change it accordingly.And that’s about it, you’re done. Now, whenever you push a tag to your repository, the workflow will trigger and create a release on GitHub and publish the package to NPM.
Yeah, I know, I love you too ❤. Until next time, keep solving problems, keep getting better, and keep moving forward.
I used Astro to put this site together and added a bit of an interstellar vibe. Styling is done with Tailwind, and it's running on Cloudflare. Oh, and all the text is in Bricolage Grotesque font for that extra touch.