Universal packages with Azure DevOps Artifacts

If you are already familiar with Azure Artifacts in Azure DevOps probaly you know about Nuget, Maven, or NPM. But there is another kind of artifact less known, and which is really useful, the Universal Packages.

Surely you have need to share a set of files with different projects, we are not talking of assemblies, nodejs packages, just plain files like for example an HTML, images, or what-ever-the-file, some people will go with git submodules for example, but we know this is usually painful. So here comes Universal Packages (Disclaimer: at the time of publishing this post this is in public preview).

Universal Packages is just a type of package which store any set of files, and when downloaded it just unpack this files locally. Let’s imagine we want to share a couple of files in our repo which we cant to share with other projects and repositories:


Of course this files will change over time (probably …), so we keep them in a repository, but also, we will keep the Universal Package versioned, so we just create a new build definition in Azure Pipelines to publish the package, and we will use the Universal Packages task which comes with Azure Artifacts extension. With this definition (for this demo scenario):


In this task definition, apart from the obvious display name, we have several other values:

  • Command: Which command we want to execute agains the Universal Package, it can be Publish, when we are publishing a new version of the package or Download to download it locally during the build for use it in another project.
  • Path to file(s) to publish: It points to the folder or particular file in the repository to generate the package with this files. (If we are downloading this changes to the folder in which to download the package files).
  • Feed location: Just to use with this or another Azure DevOps collection.
  • Destionantion feed: which feed we will use to publish the package.
  • Package name: name of the package to publish. If it does not exists it will create a new one with this name.
  • Version: how we want to generate the new version to publish, I highly recommend to use SemVer package versioning.
  • Description: just a description for the package listing.

Once executed the build pipeline, if everything is correct we will see the Universal Package in the feed:


So, now, how we consume it locally? for use in pipelines we have already seen we can use the same task as Publish, but for download, so let’s see how to consume it locally. For this we will need:

  1. Latest version of Azure CLI
  2. Azure DevOps extension of Azure CL(install with this command line: az extension add –name azure-devops)

Now we will login to Azure DevOps from the Azure CLI, we have to run two commands (NOTICE: depending on your url for your Azure Devops subscription it can change to https:/[your-org].visualstudio.com more info):

  1. az login
  2. az devops configure –defaults organization=https://dev.azure.com/[your-organization] project=ContosoWebApp

Next step, if everything has gone correctly, we can download locally the package to a folder with this command line:

And the package will download locally with the version you just set in the folder, showing the two files we published.

Try it out and let me know how it goes, I’m find it particular useful to avoid sharing files with submodules or whatever other tricks, and keep them versioned.

More info here.