Search Unity

Publish Unity package with NPMJS

Discussion in 'Package Manager' started by stanislav-osipov, May 3, 2020.

  1. stanislav-osipov

    stanislav-osipov

    Joined:
    May 30, 2012
    Posts:
    1,790
    Unity PackageManager is an awesome tool and it's a shame not to use it!

    This guide contains step by step instructions on how to create and publish a very own unity package using npmjs as the scope registry for your package. If you are looking for a sample rather then step by step instruction, check out how we did with few of our public packages:
    Why bother?
    Splitting up large codebases into separate independently versioned packages is extremely useful. Especially for the large project.
    • You can work on the isolation and test your package in the clean project rather then working in the main project all the time (could be a lifesaver if you have a very large Unity project).
    • Very clean dependencies.
    • Easy to share across your company projects or even share with the rest of the world :)
    Why NPMJS?
    • It can be consumed by the UPM(Unity Package Manager) system with no issue.
    • Even tho npm Registry is a public collection of packages of open-source code for Node.js it can be still used for the Unity package, it looks like more and more companies are choosing npm.
    • This is a well-known platform that already has lots of tools built for it.
    Another option to consider
    I would also recommend considering other options as the public registry for your package, like for example:
    • OpenUPM - Comunity based Open Source Unity Package Registry.
    • GitHub Packages - If you are using GitHub than it may appear like the best option. But there are some known issues with it:
      • The main limitation is discoverability. Even if your Github Packages registry-based scoped registry is correctly configured, packages won't show up in the Package Manager UI's All section. GitHub doesn't support any of the NPM search API endpoints (/-/all or /-/v1/search). You will have to resort to GitHub UI to search packages and manually add them to your project manifest.
      • Even if the GitHub Registry package is public, your users will need to provide authentication.
      • See the Using GitHub Packages Registry with Unity Package Manager forum post for more details.
    Let's assume you already have your package create, and you just want to make it available on npmjs. If you haven't made one, check your Creating custom packages Unity guide. Now let's get back to the publishing steps.
    1. Make an nmpjs account if you do not have one yet.
    2. Install NodeJS and npm, see the instructions here. If you are using brew as I am, it will be as easy as: brew install node
    3. Open console or terminal and type npm login.
    4. Change directory to your package location (this flexibility allows you to not keep your package in the repository root, or even have 1 repository for the multiple packages.)
    5. Type npm publish --access public
    6. All set your package is now available on npm.
    It's also recommended to add keys specific to npm into your package.json such as:
    • homepage
    • bugs
    • repository
    • license
    See the Foundation library package.json sample below:
    Code (CSharp):
    1. {
    2.   "name": "com.stansassets.foundation",
    3.   "displayName": "Stans Assets - Foundation Lib",
    4.   "version": "1.0.1",
    5.   "unity": "2019.3",
    6.   "description": "Foundation package is a collection of utility methods, design patterns, and extensions for Unity.",
    7.   "keywords": [
    8.         "pattern",
    9.         "utility",
    10.         "unity",
    11.         "stansassets"
    12.     ],
    13.   "homepage": "https://api.stansassets.com/",
    14.   "bugs": {
    15.     "url": "https://github.com/StansAssets/com.stansassets.foundation/issues"
    16.    },
    17.   "repository": {
    18.      "type": "git",
    19.      "url": "ssh://git@github.com:StansAssets/com.stansassets.foundation.git"
    20.   },
    21.   "license": "MIT",
    22.   "author": {
    23.          "name": "Stan's Assets",
    24.          "email": "stan@stansassets.com",
    25.          "url": "https://stansassets.com/"
    26.    }
    27. }
    Automatically Publish to npm using GitHub Actions
    I am as lazy as you are :) So if something can be automated it had to be done! If you are hosting your repository on GitHub you can automatically Publish to npm using GitHub Actions.

    Got to the Actions tab in your repository

    Pick set up a workflow yourself option.

    I was able to set up new publish action fairly quick thx to Sergio Xalambrí Guide. Check out his awesome guide for a more detailed description.

    The workflow script I used

    Code (CSharp):
    1. name: Publish to npm
    2.  
    3. # Controls when the action will run.
    4. # In this case, I'm saying on each release event when it's specifically a new release publish, the types: [published] is required here,
    5. # since releases could also be updated or deleted, we only want to publish to npm when a new release is created (published).
    6. on:
    7.   release:
    8.    types: [published]
    9.  
    10. jobs:
    11.   build:
    12.    runs-on: ubuntu-latest
    13.    steps:
    14.    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    15.    - uses: actions/checkout@v2
    16.    #Install Node.js, with the version 12 and using the registry URL of npm, this could be changed to a custom registry or the GitHub registry.
    17.    - uses: actions/setup-node@v1
    18.      with:
    19.        node-version: 12
    20.        registry-url: https://registry.npmjs.org/
    21.  
    22.    # Command to install the package dependencies
    23.    - run: yarn install
    24.    
    25.    # Publish to npm
    26.    - run: npm publish --access public
    27.      env:
    28.        NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

    Configure the NPM_TOKEN secret
    To configure the npm token secret
    • Go to https://github.com/$username/$repository/settings/secrets and click on Add a new secret.
    • Once you click that button GitHub will show you a form to write the name and the value of the secret.
    • In our case, we used NPM_TOKEN as name, for the value.
    • Now go to your npmjs.com account.
    • Go to https://www.npmjs.com/settings/$username/tokens to get a new token.
    • Click the Create New Token button, the token creation form will appear.
    • In this form check the first option, read and publish and click on Create Token, this way your token will have access to publish as you.
    • Now you will get back to the list of tokens with your new token created and displayed to you, copy it, and go back to GitHub and add it as value.
    Once you have done that you will be able to add the secret and use it in your GitHub Actions.

    Final Words
    I hope that was a helpful small article and we will be able to see a lot more awesome public open-source package for Unity!
     
    CodeSmile, Rowlan, ModLunar and 5 others like this.
  2. Favo-Yang

    Favo-Yang

    Joined:
    Apr 4, 2011
    Posts:
    464
    Great article. Just a tip that you can still get benefits from the openupm-cli even with the NPM registry.

    openupm --registry https://registry.npmjs.org add com.stansassets.foundation

    And if you manage your version using the Git tags, feel free to submit your package to the OpenUPM.
     
  3. stanislav-osipov

    stanislav-osipov

    Joined:
    May 30, 2012
    Posts:
    1,790
    Thanks for the tip @Favo-Yang and kudos for the OpenUPM.

    Also, I personally think since Unity does not have any default official public registry for the community packages I think then more registries you can utilize then better :)

    And it cost you literally nothing to register your package with OpenUPM since it already has Continuous Publishing based on Git tags.

    That's what I did for the foundation package and will do for a lot more open-source packages that will shortly be available.
     
  4. uno-sebastian

    uno-sebastian

    Joined:
    Mar 30, 2016
    Posts:
    1
    This is so amazing!!!! @lacost this is exactly the grace we need introduce into larger projects, if I have to send one more UnityPackage... Thank you for the sweet thread and the great read!
     
  5. stanislav-osipov

    stanislav-osipov

    Joined:
    May 30, 2012
    Posts:
    1,790
  6. svizcay

    svizcay

    Joined:
    Oct 26, 2015
    Posts:
    28
    That's great.

    One question: How can I add in the package.json file a dependency to another package published in npmjs?
    I read it has to be specified as
    Code (CSharp):
    1. "dependencies": {
    2.     "@scope/package_name": "^1.0.0"
    3.   }
    but in unity documentation said it doesn't support @Scope notation.
     
    calc1fer likes this.
  7. calc1fer

    calc1fer

    Joined:
    Oct 5, 2019
    Posts:
    62
    Very helpful. Thanks.
    But I don't know how to define dependencies in package.json.

    I tried upload my package onto npm but they told me they can't find the dependencies.

    Code (JavaScript):
    1.   "dependencies": {
    2.     "com.unity.shadergraph": "10.3.1"
    3.   },
    except this, amazing pipeline.
     
    havokentity likes this.