Skip to content

Instantly share code, notes, and snippets.

@michaelmaillot
Created April 19, 2022 07:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelmaillot/634036bae9e636cef432f18e4657732a to your computer and use it in GitHub Desktop.
Save michaelmaillot/634036bae9e636cef432f18e4657732a to your computer and use it in GitHub Desktop.
Build & Deploy SPFx package in multiple environments (GitHub Actions & CLI for Microsoft 365)
name: build
on:
workflow_call: # only callable from another workflow
inputs:
include_tests:
description: 'Indicates whether build job has to run tests or not'
default: false
required: false
type: string
jobs:
build: # job name here, can be anything else
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Use Node 14.x
uses: actions/setup-node@v2
with:
node-version: '14'
cache: 'npm'
- name: npm ci
run: npm ci
- name: Bundle project
run: gulp bundle --ship
- name: npm test
if: ${{ inputs.include_tests == true }}
run: npm test
- name: Package solution
run: gulp package-solution --ship
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
path: sharepoint/solution/*.sppkg
name: deploy with cli m365
on:
workflow_call:
inputs:
environment_name:
description: 'Target environment to deploy to'
required: true
type: string
site_url_prd:
description: 'SharePoint PRD site URL'
required: false
type: string
site_url_uat:
description: 'SharePoint UAT site URL'
required: false
type: string
app_catalog_site_url:
description: 'SharePoint app catalog site URL (tenant or site collection)'
default: ""
required: false
type: string
app_catalog_scope:
description: 'Indicates the PRD app catalog scope (tenant or site collection)'
default: ""
required: false
type: string
secrets:
AAD_APP_ID:
required: true
AAD_APP_PASSWORD:
required: true
AAD_APP_ENCODED_CERTIFICATE:
required: true
AAD_APP_THUMBPRINT:
required: true
AAD_TENANT_ID:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment_name }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v2
- name: Use Node 16.x
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install CLI for Microsoft 365
run: npm install -g @pnp/cli-microsoft365
- name: Login to Microsoft 365
shell: pwsh
run: |
m365 login --authType certificate --certificateBase64Encoded ${{ secrets.AAD_APP_ENCODED_CERTIFICATE }} --thumbprint ${{ secrets.AAD_APP_THUMBPRINT }} -p ${{ secrets.AAD_APP_PASSWORD }} --appId ${{ secrets.AAD_APP_ID }} --tenant ${{ secrets.AAD_TENANT_ID }}
- name: Configuring CLI for Microsoft 365 output error handling
shell: pwsh
run: |
m365 cli config set --key output --value json
m365 cli config set --key errorOutput --value stdout
- name: Get generated *.sppkg filename
id: package
shell: pwsh
run: |
$package = Get-ChildItem -Path artifact -Recurse -Filter '*.sppkg' | Select Name | Select-Object -First 1
echo "::set-output name=name::$($package.Name)"
- name: Get target site URL (${{ inputs.environment_name }})
id: site
shell: pwsh
run: |
$uri = [System.Uri]"${{ inputs.site_url_uat }}"
if ('${{ inputs.environment_name }}' -eq 'PRD') {
$uri = [System.Uri]"${{ inputs.site_url_prd }}"
}
echo "::set-output name=url::$uri"
- name: Set site collection context (${{ inputs.environment_name }})
shell: pwsh
run: |
$uri = "${{ steps.site.outputs.url }}"
m365 spo set --url $uri
- name: Upload SharePoint package to ${{ inputs.app_catalog_scope }} App Catalog (${{ inputs.environment_name }})
shell: pwsh
run: |
$appCatalogScope = "sitecollection"
$appCatalogUrl = "${{ inputs.site_url_uat }}"
if ('${{ inputs.environment_name }}' -eq 'PRD') {
$appCatalogScope = "${{ inputs.app_catalog_scope }}"
$appCatalogUrl = "${{ inputs.site_url_prd }}"
}
m365 spo app add --filePath "artifact/${{ steps.package.outputs.name }}" --appCatalogUrl $appCatalogUrl --scope $appCatalogScope --overwrite
- name: Deploy SharePoint package (${{ inputs.environment_name }})
shell: pwsh
run: |
$appCatalogScope = "sitecollection"
$appCatalogUrl = "${{ inputs.site_url_uat }}"
if ('${{ inputs.environment_name }}' -eq 'PRD') {
$appCatalogScope = "${{ inputs.app_catalog_scope }}"
$appCatalogUrl = "${{ inputs.app_catalog_site_url }}"
}
m365 spo app deploy --name ${{ steps.package.outputs.name }} --appCatalogUrl $appCatalogUrl --scope $appCatalogScope
name: main
on:
push:
branches:
- main
workflow_dispatch: # Can be triggered manually
jobs:
build:
uses: meganb/helloworld/.github/workflows/build-spfx.yml@main
deploy_uat:
needs: build
uses: meganb/helloworld/.github/workflows/deploy-spfx-cli-m365.yml@main
with:
environment_name: UAT
site_url_uat: https://contoso.sharepoint.com/sites/CommSite-UAT
secrets:
AAD_APP_ID: ${{ secrets.AAD_APP_ID }}
AAD_APP_PASSWORD: ${{ secrets.AAD_APP_PASSWORD }}
AAD_APP_ENCODED_CERTIFICATE: ${{ secrets.AAD_APP_ENCODED_CERTIFICATE }}
AAD_APP_THUMBPRINT: ${{ secrets.AAD_APP_THUMBPRINT }}
AAD_TENANT_ID: ${{ secrets.AAD_TENANT_ID }}
deploy_prd:
needs: deploy_uat
uses: meganb/helloworld/.github/workflows/deploy-spfx-cli-m365.yml@main
with:
environment_name: PRD
site_url_prd: https://contoso.sharepoint.com/sites/CommSite
app_catalog_scope: tenant
app_catalog_site_url: https://contoso.sharepoint.com/sites/app
secrets:
AAD_APP_ID: ${{ secrets.AAD_APP_ID }}
AAD_APP_PASSWORD: ${{ secrets.AAD_APP_PASSWORD }}
AAD_APP_ENCODED_CERTIFICATE: ${{ secrets.AAD_APP_ENCODED_CERTIFICATE }}
AAD_APP_THUMBPRINT: ${{ secrets.AAD_APP_THUMBPRINT }}
AAD_TENANT_ID: ${{ secrets.AAD_TENANT_ID }}
@michaelmaillot
Copy link
Author

Abstract

This sample provides a ready-to-use GitHub Action workflow that will build an SPFx package, then deploy it on an existing site (in a site collection app catalog) dedicated to test out new features / bug fixes. Then the pipeline will be deployed on the tenant app catalog (or a production site collection app catalog). This sample will use CLI for Microsoft 365 in order to connect to SharePoint Online and deploy the SPFx package. Below the different files description:

  • main.yml: the main pipeline that will be triggered as the initiator
  • build-spfx.yml: CI pipeline
  • deploy-spfx-cli-m365.yml: CD pipeline

Configuration

Solution

The SPFx solution can be ordered like this:

│   .gitignore
│   .npmignore
│   .yo-rc.json
│   gulpfile.js
│   package-lock.json
│   package.json
│   README.md
│   tsconfig.json
│   tslint.json
│
├───.github
│   └───workflows
│          build-spfx.yml  --------> CI pipeline
│          deploy-spfx-cli-m365.yml  --------> CD pipeline
│          main.yml  --------> main pipeline
│
├───.vscode
│
├───config
│
├───src
│   │   index.ts
│   │
│   └───webparts
│       └───helloWorld
│           │   HelloWorldWebPart.manifest.json
│           │   HelloWorldWebPart.ts
│           │
│           ├───components
│           │       HelloWorld.module.scss
│           │       HelloWorld.module.scss.ts
│           │       HelloWorld.tsx
│           │       IHelloWorldProps.ts
│           │
│           └───loc
│                   en-us.js
│                   mystrings.d.ts
│
├───teams

Environments

The environments will be necessary for approving a pipeline before being run. You'll have to add two environments:

  • UAT (testing)
  • PRD (production)

Environments can be configured here: https://github.com/[ORGANIZATION]/[PROJECT]/settings/environments.

/!\ Beware that in order to use multiple environments, your repo has to be public or your subscription has to be a Pro one.

Approvers

For each environment, you can add an approver by enabling the checkbox marked "Required reviewers", then adding at least one reviewer account then click on "Save protection rules".

Environment secrets

Environment secrets can be configured here: https://github.com/[ORGANIZATION]/[PROJECT]/settings/environments/[ENVIRONMENT_ID]/edit.

Below the secrets used in the workflows:

Name Description
AAD_APP_ID The Azure AD application ID with which the authentication to SharePoint will be done
AAD_APP_PASSWORD The certificate password necessary for the authentication
AAD_APP_ENCODED_CERTIFICATE Base64 encoded certificate
AAD_APP_THUMBPRINT Certificate thumbprint
AAD_TENANT_ID ID or domain (for example "contoso.onmicrosoft.com") of the tenant from which accounts should be able to authenticate

CD Workflow parameters

Below the parameters used in the deploy-spfx-cli-m365.yml workflow, depending on the environment:

Name UAT PRD Definition
environment_name YES YES The deployment environment (can be 'UAT' or 'PRD')
site_url_uat YES NO SharePoint UAT site URL where the SPFx package will be deployed
site_url_prd NO YES SharePoint PRD site URL where the SPFx package will be deployed
app_catalog_scope NO YES Production app catalog scope (can be "tenant" or "site collection")
app_catalog_site_url NO YES Production app catalog site URL (can be a tenant or a site collection one)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment