In order to make this work, you need to meet a few requirements:
- A GitHub account
- A Travis CI account (connect with GitHub)
- A NPM account
- Your repository needs to be set to public (only needed if you have the free plan on Travis CI)
Once you have met the requirements, you can start configuring things.
First, go to NPM and create a new token:
Make sure it’s an
Automation token, so that 2FA is not asked (used for CI/CD purposes).
Copy the contents of the token (this will only be showed ONCE, so make sure to copy it now) and go to your Travis CI dashboard.
On your Travis dashboard, go to the repository you want to configure, and click on
More Options > Settings
Environment Variables , create two variables:
NPM_TOKEN> the token you copied from NPM
NPM_EMAIL> the email address from your NPM account (not sure if this needs to be the actual address you used, but I haven’t tested using a different one)
Setting up the jobs
The next step is to configure the jobs you want Travis to run on the builds. For the purpose of this post, we’re making three jobs:
- Test > Runs
- Version > Runs
npm versionto create a new version of the package
- Release > Runs
npm publishto release the new package to NPM
A note on the
This job will create a new version of your package automatically and push the new tag to GitHub. You can skip this if you want to do it manually. It depends on how your workflow is setup.
These jobs will be configured on a
.travis.yml file on the root of your project:
Let’s go through each part of the file.
The first part is only describing which type of project this is and the tools to use. Since this is a Node project, we set up the
node_js property, and here we have it configured to use version
12.14 . If you want to read more about the available properties on this file, go to the official documentation for Travis.
The first job we’re configuring is called
Test. This is automatically run on a Travis build, but I like having things explicit in code, so that it’s easier to understand what’s going on at each stage.
The second job is
Version , and this is optional as it will automatically version your package and push a new tag to GitHub. If you want to tag your package manually on your workflow, skip this step.
Note that for this script to work, you need a GitHub deploy key, so that Travis can push the tags to your repository.
Note: You can add the
openssl script to your
before_install if you want it to run before every stage, or you can add it as part of the
Version stage as I did on my
The final job is
Release , which will publish our NPM package accordingly.
Release stage is set to only run if a tag is present, and the commit message matches the RegEx
/^Version /. Notice the use of
$NPM_TOKEN , those are the variables we set on the first steps of this post.
Note that we didn’t specify for it to run on branch
master , that’s because pushing the tags to the repo creates a separate build with a commit detached from any branches. That’s why we check for the tag presence and the commit name (should match what we specified on the
And lastly, make sure
skip_cleanup is set to
true and you have
before_deploy: “npm run build" , otherwise your
dist folder will not be sent to NPM.
So with this setup, this is the workflow you can expect:
- Checkout a new branch from
master, work on it and push to remote
- Create a PR pointing to
master. This will trigger the
teststage, because it runs on every commit
- After PR is merged,
versionwill be triggered, which will version the package and push a new commit to
masterwith the commit message
Version x.x.x(where x will be replaced with your actual version numbers)
- The new commit will trigger
release, which will publish the package to NPM
One thing to note is that
Version only runs on commits that do not match the RegEx
/^Version / . Meaning any commit that matches
Version ... will be skipped. This is so that we don’t create an infinite loop where we publish a commit to
Version, and that in turn triggers
Version again and again.
This allows for you to create a new
patch version on every PR. Of course, this means that
minor versions need to be created manually. In our case, that wasn’t necessary, as every new version we release is a
You could configure your steps in a way that it assumes which new version you want based on the commit message for example, or you can set up a
release branch that will trigger the release everytime a tagged commit is sent to it. You should adapt this method to your workflow, to meet your demands.
Thank you for reading! See you on the next one!