<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Harsh Zalavadiya</title>
    <description>The latest articles on Forem by Harsh Zalavadiya (@harshzalavadiya).</description>
    <link>https://forem.com/harshzalavadiya</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F148592%2F0f26ef07-581d-4d93-a8c7-3990cb2c4280.jpeg</url>
      <title>Forem: Harsh Zalavadiya</title>
      <link>https://forem.com/harshzalavadiya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/harshzalavadiya"/>
    <language>en</language>
    <item>
      <title>Automating package publishing to NPM</title>
      <dc:creator>Harsh Zalavadiya</dc:creator>
      <pubDate>Fri, 14 Aug 2020 11:01:44 +0000</pubDate>
      <link>https://forem.com/harshzalavadiya/automating-package-publishing-to-npm-5fng</link>
      <guid>https://forem.com/harshzalavadiya/automating-package-publishing-to-npm-5fng</guid>
      <description>&lt;p&gt;It's easy to publish a package to NPM directly by running &lt;code&gt;npm publish&lt;/code&gt; however in real-world scenario you might want to automate this so you don't have to worry about maintaining NPM access for everyone especially in a corporate environment&lt;/p&gt;

&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You create a release on GitHub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt; will trigger a build&lt;/li&gt;
&lt;li&gt;package will be published if the build is successful&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So to automate this in a more secure and automated manner you can follow below steps&lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Maintainer Must-Haves&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Prepare your code
&lt;/h4&gt;

&lt;p&gt;The first step is to push your code to GitHub repository if not already&lt;/p&gt;

&lt;p&gt;In this demo, I'm going to use &lt;a href="https://github.com/harshzalavadiya/random-fastfood"&gt;this repository&lt;/a&gt; that has a very tiny package that will return random fast food name when called&lt;/p&gt;

&lt;h4&gt;
  
  
  2. generating and setting up auth token
&lt;/h4&gt;

&lt;p&gt;Since we can't directly login to NPM registry when performing automated release we have to generate an auth token to do that follow below steps&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X5ulD-AA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k73nerl8vhtq5k8iddar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X5ulD-AA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k73nerl8vhtq5k8iddar.png" alt="Generating NPM Auth token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6MlerYE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ie9htc28fq1v52j1gc6e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6MlerYE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ie9htc28fq1v52j1gc6e.jpg" alt="Create New Token Button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3m7kOah0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ht9ok5txu6vnl6dlwkae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3m7kOah0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ht9ok5txu6vnl6dlwkae.png" alt="Copy newly created token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now once we have a token ready we can create a secret in GitHub repository so  action can access this token securely&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4j-qW_cK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5p2tuwaae06eaen3u4np.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4j-qW_cK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5p2tuwaae06eaen3u4np.png" alt="Going to New Secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;after clicking on &lt;em&gt;New Secret&lt;/em&gt; you can create a secret like below this will be available to build system on build time&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FESs3yCz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lv4lpapvpb5mvq4y9lf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FESs3yCz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lv4lpapvpb5mvq4y9lf8.png" alt="Adding a new secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Creating a build configuration file
&lt;/h4&gt;

&lt;p&gt;To tell GitHub actions GitHub repository has a special folder called &lt;code&gt;.github/workflows&lt;/code&gt; on repository root where GitHub will look for build instructions so we will create a file called &lt;code&gt;main.yml&lt;/code&gt; with below-given contents&lt;/p&gt;

&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Begin CI...&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use cached node_modules&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/cache@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node_modules&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nodeModules-${{ hashFiles('**/yarn.lock') }}&lt;/span&gt;
          &lt;span class="na"&gt;restore-keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;nodeModules-&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn install --frozen-lockfile&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;CI&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn build&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;CI&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;startsWith(github.ref, 'refs/tags/')&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" &amp;gt; ~/.npmrc &amp;amp;&amp;amp; npm publish --access public&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;NPM_AUTH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NPM_AUTH_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;once you commit this file in your GitHub repository it will run a build each time you push your code. once you do this you should be able to see little orange dot to your commit indicating Actions is running your build ✨&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Uv-3u8k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qdte6bciv3zui9kjv6pz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Uv-3u8k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qdte6bciv3zui9kjv6pz.png" alt="Actions building orange dot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;once finished it will show green checkmark indicating that build was a success like below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L08ODpbP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/801stbixdxxk41bk99ni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L08ODpbP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/801stbixdxxk41bk99ni.png" alt="Successful Build"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;but we don't want to publish to happen every time we commit, the above workflow is designed to not to perform publish unless you create a release&lt;/p&gt;

&lt;p&gt;So now to publish package we are going to create a release on GitHub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--60ypiGB5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z6whe7euyut2amx26459.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--60ypiGB5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z6whe7euyut2amx26459.png" alt="Click on publish release"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JpteOU6c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cf2b26neczzucn5t0p31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JpteOU6c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cf2b26neczzucn5t0p31.png" alt="Creating a release"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;once done GitHub Actions will trigger a new build and if workflow is successful then you should be able to see package published to NPM Registry&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0vprNZv5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a460v99ieg5sk505rmvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0vprNZv5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a460v99ieg5sk505rmvv.png" alt="Published package"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎉 Congratulations, you have successfully automated your NPM package publishing 🎊&lt;/p&gt;
&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/harshzalavadiya"&gt;
        harshzalavadiya
      &lt;/a&gt; / &lt;a href="https://github.com/harshzalavadiya/random-fastfood"&gt;
        random-fastfood
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A tiny package demonstrating automated NPM package publishing using GitHub Actions
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Real react package using this workflow
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/harshzalavadiya"&gt;
        harshzalavadiya
      &lt;/a&gt; / &lt;a href="https://github.com/harshzalavadiya/react-multi-select-component"&gt;
        react-multi-select-component
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Lightweight (~4KB gzipped) multiple selection dropdown component
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;This is my first post on DEV, so suggestions are always welcome 😁&lt;/p&gt;

&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@pinjasaur?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Paul Esch-Laurent&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/javascript?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>actionshackathon</category>
      <category>github</category>
      <category>actions</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
