Share and Enjoy !


Last month I put together a beginner’s guide to using the Azure DevOps Build and Release process for SPPKG packages that focused primarily on the Pipeline Build process.  This blog will detail the second part of that process, creating a Release job that will deploy SPPKG files, which is the eventual output from your build.  If you are unfamiliar with the build process, I recommend reviewing that blog first so that you have a starting point for this one.

This blog is also styled as a beginner’s guide as well and does not go into depth on the many advanced options that are available for you to use.  I’ll leave exploring those for your homework as you get more versed in Builds and Releases.

Building a Pipeline release is an important second step when implementing Continuous Integration for your project, as it is the step that gives you the ability to trigger the deployment of your newly built code into a specified environment.  This trigger can be either manual or automated based on your needs.  For our project, we created a manually triggered Release pipeline so that our QA person could trigger a new deployment on his timeline, whenever he was ready for the next wave of changes for testing.  It worked well for us.

The Release Process

This blog assumes you already have a project with an associated repository and that you have a build process in place.  If not, you will need to get these pieces in place before proceeding (see my previous blog post for details).

To get started with your first Release job, go into Azure DevOps and click on the Releases link found under Pipelines.  In the screenshot below, you’ll see that we have 3 Release Pipelines already defined.  One is for use by our QA resource for deployment to his environment and the other two are for the two developers (myself and a coworker) to deploy SPPKG files to our own dev tenants, when needed.

Create a Azure DevOps Release

Create the New Release Pipeline

To create a new Release Pipeline, click on the New button found at the top of this list and select ‘New Release Pipeline’.  Note that this is different from the ‘Create release’ button found on the right side of the page, which is used to kick off an existing release pipeline.  The terminology used here can definitely cause confusion and could have been made a little bit clearer, I think.

Azure DevOps Deployment

As with the Build process, there are templates you can start with or you can start with an empty job.

For our purposes today, let’s start with an empty job.  When the ‘Empty job’ link is clicked, an empty release will be displayed and you will be presented with the property pane for the Stage section.  Here you can rename it and check/change the stage owner.  For our purposes, let’s call it ‘Deployment Stage’ (or you can leave it with the default of Stage 1).  Click the ‘x’ to close this pane.

Note that within a release pipeline there are two main sections, as highlighted above.  The Artifacts section is where you specify which build you want to use as the source.  The second section – Stages – is where you tell it what to do with the build.  You can have as many Artifacts and Stages as your job needs.  For this example, we only need one of each.

Specify the Build

To specify the build to use, click either the Add button next to the Artifacts tag or click on the big button in the middle of the section called ‘Add an artifact’.  You will be presented with the artifacts property pane where you can select a build in the Source dropdown.  All build pipelines for the repository will be displayed in the dropdown, even ones that might be a test or in-process.  Select the one that applies for your job.  In my case, I’ll be selecting the bottom one.

Once selected, you will be presented with some other options to consider before adding, including an option for specifying the default version, which allows some interesting choices and a lot of flexibility in your source choice.  For this exercise, simply choose Latest, then click the blue Add button.

Specify the Source Alias

The final configuration you need to make is to specify a ‘Source alias’ for your artifacts.  This will be important when we start adding tasks to our Stage as we will refer back to this location.  If you leave this value at its default, it is likely to be some long, ungainly thing that will ultimately cause you problems.  Here I named it SPPKGFiles, since it is a SharePoint package we’re going to deploy.

Tasks to Complete to Deploy SPPKG Files

After adding your source, it is now time to build out the tasks that will actually do the deployment.  Our goal in this release is to deploy an SPFx package into an app catalog in SharePoint Online, at the site collection level.  Here are the tasks we need to add to do this:

  • Install Node.js, version 10 (so we can use npm to install the cli)
  • Run an NPM command to install the PnP Office365 CLI so we can connect and do stuff
  • Run a PnP command, in a command line prompt, to connect to SPO
  • Run a PnP command, in a command line prompt, to add the .sppkg to the app catalog
  • Run a PnP command, in a command line prompt, to deploy the solution to the site

To add these tasks to a stage, click on the blue link found within the Stage box.  The default text for this is ‘1 job, 0 task’ until you have added some things to do.

After clicking on the link, you will be presented with a blank slate (or pre-defined tasks if you chose a template) – this is where the work is done. 

Install Node.js

Since the project I’m working on is an SPFx project, I’ll need to connect to O365 and run some PnP commands to deploy, which means the first task we need to add is to install Node.js.  Like in the build process, when you click the plus sign to add a task, you are presented with a list to choose from.  Scroll down until you find the Node.js tool installer, click the Add button and you will then see it in your Agent job on the left.

Configuration of this task allows you to set the version to whatever you need for your project.  In my case, I need to use version 10, so I set it as such and renamed the task to reflect this.  Very handy!

Connect to SharePoint Online

Since this is an SPFx project, we know that we will need to connect to SharePoint Online.  In order to do that, we need to install the PnP Office365 CLI so we can log in.  Click the big plus sign again, find the ‘npm’ task in the list presented and click the Add button.  You should see an ‘npm install’ task now added.  Click on this to bring up its property page.  Since we only need to install one package, we need to choose the ‘custom’ option in the Command dropdown so we can tell it specifically what we need to do.

Selecting this presents us with a field where we can enter our specific command.  Insert the following in the ‘Command and arguments’ box:

install -g @pnp/office365-cli

There are other sections in the Property pane which can be left at their default values.

Final Three Tasks

Now that we have the O365 CLI installed, we can now connect, add and deploy our package.  The final three tasks needed are all run from a command line prompt, so let’s go ahead and add all 3 that we will need.  Once again click on the big plus sign and find the ‘Command line’ task in the list presented.  This time, since we know we need 3 of them, click on the Add button three times to go ahead and add them all.

Note that we could likely combine the 3 commands within one Command line task, but I like to have full control over each command and when to abort if there are errors.  If we treat each as its own task, we can set these options for each step.  Again, this is a personal preference.  Feel free to combine if it’s is helpful to you and makes more sense.

Configure the First Command Line Task

Click on the first command line task and you will see that there is a default value in the ‘Script’ box.  This can be removed as we will be adding our own.  For this first one, we need to connect to SPO, so the following command should be entered into the Script box:

o365 login https://$(tenant)$(sitecollection) –authType password -u $(username) -p $(password)

There are a number of things to note here.  First and foremost, you will be using the latest o365 login command, which does NOT require adding ‘spo’ like most other O365 commands do.  This has tripped up many folks (including me!), so be sure to leave it out for this command.  Check out this link for more details on the ‘login’ command.

Using Variables to Keep Sign-On Information Secure

The second thing to note is the use of variables within our command.  There are a number of ways to handle keeping our sign-on information secure but I chose the simpler way of adding variables within my agent job.  To do this, note that to the right of the ‘Tasks’ tab, there is one called ‘Variables’.  It is here that we will configure the information needed to successfully sign-on and other variables that will be used in several of the tasks.

Once you click on the tab, you will be presented with a panel for adding variables.  Click on the Add link in the righthand pane to add your first variable, then do this 3 more times to add the others needed in this exercise.  You will be adding the following:

  • password
  • sitecollection
  • tenant
  • username

All but the password will be simple string variables so go ahead and add the correct values for your environment.  For the password field, we will want to make sure this is protected though.  Note that for each field, there is a switch that will turn the variable into a ‘secret’ variable.  Click on this and the field is no longer plain text, which is what we need for our password field.  You will also note that it gives you a ‘peek’ option so you can be sure you spelled it correctly.  Always a good thing for me!

Specifying the Scope

The other thing I’d like you to note is the Scope column.  Here you can specify if the variable is scoped to the entire Release job or is only specific to a stage.  This can be very handy if you have a large release job with many stages and environments.  Our example is simple, so I’m leaving this at Release.

Configure the Second Command Line Task

Now that you have the variables added, let’s go back and configure the other two command-line tasks.  Our second command will be for adding our .sppkg package to the app catalog.  The command we want to execute is this:

o365 spo app add -p $(System.DefaultWorkingDirectory)/SPPKGFiles/drop/debug/sharepoint/solution/apppackagename.sppkg -s sitecollection -u https://$(tenant)$(sitecollection) –overwrite

This command is saying that we need to add an app package (spo app add), found at this location (-p), inside this site collection (-s), within this tenant (-u) and that we should overwrite it if it already exists.  For more details on all the parameters used here and other options, you can visit the page for ‘spo app add’ command.

Another thing to note is that this is where we are using the ‘Source alias’ value we specified earlier in the Artifacts step (bolded text above).  If we don’t use this, it will not be able to find our package.

I’m also changing the Display name of all the tasks as I go along so that it is clear exactly what each task is doing when reviewing the Agent job.

Configure the Final Command Line Task

Our final Command line task will contain our deployment command, as follows:

o365 spo app deploy -n apppackagename.sppkg -s sitecollection -u https://$(tenant)$(sitecollection)

This command is saying that we need to deploy the uploaded app package (spo app deploy), named this (-n), inside this site collection (-s) within this tenant (-u).  For more details on all the parameters used here and other options, you can visit the page on the ‘spo app deploy’ command found here.

And that is the last step to configure so go ahead and save your Release Pipeline.  When you click on the Save button, you will be presented with a dialog that will allow you to change the folder where the release job will live and to add comments.

Granting Office 365 CLI Consent for the first time

Now that the job is saved, we have one more configuration task to perform (outside of Azure DevOps) before we can run our new job.  This process only needs to be done one time for your tenant and is required before you can use Office 365 CLI commands to manage things like we are doing in our release job. 

If you’ve already done this for another process in your tenant, you can skip this section.  I think anyway.  I confess to not knowing a ton about this and have only had to do it a couple of times myself.  For more information on the Office 365 CLI and logging in, I’d recommend visiting this site and reading through the guide.

Manually Log In To Your Tenant

Before you can run any Office 365 CLI commands you have to do a manual log in to your tenant and grant ‘permissions’ to your device.  To do this, follow these steps:

  • Open a command prompt on your desktop
  • run ‘npm i -g @pnp/office365-cli’

(This will install the Office 365 CLI so you can log in)

  • Type in ‘office365’ and hit enter. This will put you into ‘immersive’ mode so you can interact with the CLI.
  • Enter ‘login’ at the prompt. You will be presented with a message line and told to navigate to this Microsoft website – – where you will enter the code that was given in the message to authenticate.
  • Once you’ve entered the code, you will be prompted to login. You should login with the user account associated with the tenant you are going to be deploying the package into.
  • Once you are signed in successfully, you can exit the O365 command-line session by typing exit or quit.

Deploy SPPKG Files

Now that you’ve granted the permissions needed, you should be able to successfully run your release job against your tenant.

Go back into Releases and select your pipeline on the left, then click the blue button labeled ‘Create release’ to kick off a run.  Here you will be prompted with a panel where you can adjust some run parameters if desired.  For now, we are just going to click the Create button.

Once your release is kicked off, you can click on it and watch its progress.  You do this by drilling down into the stage(s), where it will show you information as it progresses through each task.


And that is it!  You’ve now created your first Release Pipeline.  There are, of course, myriad options and unique configurations you can define depending on your needs.  This is meant to be a simple example of how to deploy a SharePoint SPPKG package into a tenant, on-demand.  I hope it has been helpful!

Share and Enjoy !

Related Content: