# Adding UPM Package

# UPM Package Criteria

OpenUPM requires the package repository fulfills below criteria

  • Valid UPM structure, contains at least the package.json file, can be placed at a sub-folder.
  • Open source license. It is recommended to choose one from the spdx license list.
  • Hosting on Github.
  • Git tags that are valid semver. i.e. v1.1.0, 1.1.0, 1.1.1-preview, v2.0.0-preview.1. Only valid tags are built. It is recommended to either use the GitHub release feature, or CI tools to create Git tags.

# Understanding Different Folder Structures of UPM Repositories

There're three typical folder structures of UPM repositories. OpenUPM build pipelines can handle all of them.

  • UPM package at the root path
  • UPM package at a sub-folder
  • UPM package at a sub-folder with UPM branch

# UPM Package at the Root Path

The package.json file is located at the root path of the master branch. It is the simplest case.

# UPM Package at a Sub-folder

The master branch is usually a Unity project (with Assets folder). The package.json file is located at a sub-folder, for example Assets/package-name or Packages/com.namespace.package-name. Git tags are based on the master branch. Build pipelines will detect the location of the package.json file, and handle it correctly.

# UPM Package at a Sub-folder with UPM Branch

The master branch is usually a Unity project (with Assets folder). The package.json file is located at a sub-folder, for example Assets/package-name or Packages/com.namespace.package-name. A upm branch is created from the package folder using the git subtree split/push command to make the package.json file placed at the root path. So the package can be installed by Unity Package Manager via Git URL. Git tags are based on the upm branch.

# Package YAML File

OpenUPM uses a YAML file to store the package information. Here's an example.

# package name
name: com.namespace.unitypackageexample
# package display name
displayName: Unity Package Example
# package description
description: An unity package example
# repository url
repoUrl: 'https://github.com/author/reponame'
# forked repository url
parentRepoUrl: null
# spdx license id
licenseSpdxId: MIT
# license name
licenseName: MIT License
# list of topic slugs
  - utilities
# Filter Git tags based on prefix. Used by monorepos to separate pacakges
gitTagPrefix: ''
# A regular expression to ignore Git tags
gitTagIgnore: '-master$'
# Minimal version to build
minVersion: '1.0.5'
# featured image
image: 'https://github.com/author/reponame/raw/master/path-of-img.png'
# readme path
readme: 'master:README.md'
# package hunter name (github username)
hunter: author

# Using Package Add Form

Package hunters can use the package add form, to submit the package YAML file. The form will guide you to fill the required information, generate the YAML file, then submit to GitHub as a pull request in the browser.

package add form

The pull request of adding a new package will be merged automatically. The CI will do jobs to update the website and build pipelines. Within a few minutes you can view the package detail page at URL /packages/com.namespace.package-name, and check the build result from the version history and build issues sections.

+--------------+      +--------------+      +---------+
| Package Form | +--> | Pull Request | +--> | Wait CI |
+--------------+      +--------------+      +---------+

# Troubleshooting

# Handling a Repository without Git Tag

Please create an issue on the author's repository for making GitHub releases. The git tag should be a valid semver. To learn how to automate the release process with GitHub actions, please checkout this tutorial.

# Handling Duplicated Tags for master and upm Branches

A repository may contain duplicated version tags. Likely created by CI tools, one for the master branch, another for the upm branch. i.e

  • 1.0.0 and upm/1.1.0
  • 1.0.0 and 1.1.0-upm
  • 1.0.0-master and 1.1.0-upm

In such cases the tag from the upm branch takes higher priority, another one is ignored.

# Handling Failed Builds

You can check the failed reason at the build issues section on the package detail page. The most common issue is version conflict, means a package with the same version is already published. The package owner need bump the version with a new GitHub release, or re-tag the existing release. Build pipelines will re-build failed releases if detecting that the related git tag was removed or re-tagged.

However, build pipelines will not rebuild an already succeeded release if detecting that the git tag is removed or retagged. Because it's a bad practice for talking off or replacing an existing release for a public registry. If the intention is to fix something, the package owner is recommended to bump the version with a new git tag. Learn more at modifying or deleting a published version.

# Handling Monorepos

Monorepos preset multiple packages in a single repository. Usually layout as below,


For monorepos, multiple package submissions are required. You need submit packages one by one to the OpenUPM platform. Then there're two cases,

  • If you make a single Github release for each new version, it will just works. Our build pipelines will treat each package submission separately, and locate the relevant package.json to process.
  • If you make separate GitHub releases for each new version, you need use a git tag prefix for each package. i.e namespace.a/1.0.0 and namespace.b/1.0.0. Then fill the gitTagPrefix field of the package YAML file. i.e package namespace.a should have gitTagPrefix: "namespace.a/", to avoid wasting resources of build pipelines.