Aakash Bhardwaj SharePoint, Office 365 and Azure

Deploy SPFx solutions on multiple sites using GitHub Actions and Office 365 CLI

Introduction

Recently I came across a requirement to create a GitHub Action Workflow for the build and deployment of an SPFx solution to a large number of sites that were using site collection scoped app catalogs. The Office 365 CLI Deploy App action provides the option to deploy to either the tenant app catalog or the site collection app catalog. Deploying the app package to all these sites using this action would have been cumbersome as it would require repeating this step with different SITE_COLLECTION_URL values.

Fortunately, there is an alternate approach to achieve this scenario by writing a separate script that would handle the deployment steps and executing this script from the YAML workflow using the Office 365 CLI Run Script action.

YAML Configuration

The GitHub Actions Workflow YAML file for building and deploying the SPFx solution looks like the one below. It consists of the steps for configuring the environment, running automated tests, bundling the sppkg package file, and executing the bash deployment script.

For getting started using GitHub Actions for SPFx please refer to the article Create GitHub actions for SPFx solution from Anoop.

name: SPFx CI CD

on:
  push:
    branches:
      - dev

env:
  packagePath: sharepoint/solution/test-list-items.sppkg

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:

    - name: Checkout code
      uses: actions/checkout@v2

    - name: Setup Node.js environment
      uses: actions/setup-node@v1.4.2
      with:
        node-version: 10.x

    - name: Install dependencies
      run: npm ci
    
    - name: Build solution
      run: gulp build
      
    - name: Test solution
      run: npm test
              
    - name: Bundle and package
      run: |
        gulp bundle --ship
        gulp package-solution --ship
    - name: Upload Build Package
      uses: actions/upload-artifact@v2
      with:
        path: ${{ env.packagePath }}
              
    - name: Office 365 CLI Login
      uses: pnp/action-cli-login@v1.0.0
      with:
        ADMIN_USERNAME: ${{ secrets.adminUsername }}
        ADMIN_PASSWORD: ${{ secrets.adminPassword }}
        
      # Run bash script at the specified path in the repository
    - name: Office 365 CLI Runscript bash
      uses: pnp/action-cli-runscript@v1.0.0
      with:
        O365_CLI_SCRIPT_PATH: './scripts/DeployPackage.sh'

Bash Deployment Script

The below bash script traverses each of the site collections added in the sites array and deploys the app package to its site collection app catalog using the o365 spo app add command. It also checks the app info to see if the app needs to be installed or upgraded using the o365 spo app upgrade and o365 apo app install commands. Lastly, it sends a completion email, using the o365 spo mail send command, once the deployment is completed.

Similar script can also be written using PowerShell when using windows runner

#!/bin/bash

# requires jq: https://stedolan.github.io/jq/

packagePath=$packagePath

sites=("https://contoso.sharepoint.com/sites/Site1" "https://contoso.sharepoint.com/sites/Site2" "https://contoso.sharepoint.com/sites/Site3")

echo "Starting Deployment..."

for siteUrl in "${sites[@]}"; do
  echo "Site URL: $siteUrl"
  app=$(o365 spo app add --filePath $packagePath --scope sitecollection --appCatalogUrl $siteUrl --overwrite)
  o365 spo app deploy --id $app --scope sitecollection --appCatalogUrl $siteUrl
  echo "Deployed App..."
  appInfo=$(o365 spo app get --id $app --scope sitecollection --appCatalogUrl $siteUrl --output json)
  appVersion=$(echo $appInfo | jq -r '.InstalledVersion')
  appCanUpgrade=$(echo $appInfo | jq -r '.CanUpgrade')

  if [[ "$appCanUpgrade" = "true" ]]; then
    o365 spo app upgrade --id $app --siteUrl $siteUrl --scope sitecollection
    echo "Upgraded App..."
  fi
  if [ -z "$appVersion" ]; then
    o365 spo app install --id $app --siteUrl $siteUrl --scope sitecollection
    echo "Installed app..."
  fi
done

o365 spo mail send --webUrl ${sites[0]} --to 'aakash.bhardwaj@in8aakbh.onmicrosoft.com' --subject "Multi Site Deployment Completed" --body "<h2>Deployment Completed</h2> <p>Multi Site Deployment of $packagePath has been completed.</p>"

Notice that the variable packagePath gets its value from the environment variable set in the YAML file

Conclusion

In this way, an SPFx app package can be deployed to multiple site collections from a custom bash script using Office 365 CLI commands.