Skip to content
Deploying SPFx apps with heft and DevOps pipelines
Albert-Jan Schot
Albert-Jan Schot

· 3 min read

Post

Deploying SPFx apps with heft and DevOps pipelines

In this post, we will explore how to deploy SharePoint Framework (SPFx) applications using Heft and DevOps pipelines. Heft is a build system that provides a streamlined workflow for building and deploying SPFx solutions introduced with SPFx 1.21.

Martin wrote an awesome step by step blog post on how to set up a DevOps pipeline for SPFx solutions: Deploying SPFx apps with Azure DevOps pipelines (all YAML), yet with SPFx 1.21 you can now use Heft to simplify the build and deployment process even further. All steps to upgrade your local development environment and your DevOps pipelines are described in the official documentation: SharePoint Framework v1.21 release notes.

Devops Pipeline

The general setup will be exactly the same as before, but gulp is gone and heft is in, and heft does require a slightly different call. So assuming you have updated your local development environment and your SPFx solution to 1.21, you can update your pipeline to use Heft instead of gulp. If you want to learn more about heft read up on Understanding the Heft-based toolchain (how it works).

You can keep the exact same settings as Martin has described and introduce npx heft test --clean --production instead of gulp build --ship and npx heft package-solution --production instead of gulp bundle --ship and gulp package-solution --ship, resulting in the following full YAML pipeline:

trigger:
  branches:
    include:
      - main

pool:
  vmImage: "ubuntu-latest"

stages:
  - stage: Build
    variables:
      - group: "Deployment Production"

    jobs:
      - job: Build
        steps:
          - task: NodeTool@0
            displayName: "Use Node 22.x"
            inputs:
              versionSpec: "22.x"

          - task: Npm@1
            displayName: "npm install"
            inputs:
              command: "install"

          - script: npx heft test --clean --production
            displayName: "Heft build & test"

          - script: npx heft package-solution --production
            displayName: "Heft package-solution"

          - task: CopyFiles@2
            displayName: "Copy sppkg to staging"
            inputs:
              Contents: "sharepoint/**/*.sppkg"
              TargetFolder: "$(Build.ArtifactStagingDirectory)"
              flattenFolders: true

          - task: PublishBuildArtifacts@1
            displayName: "Publish artifact"
            inputs:
              artifactName: "drop"

  - stage: ReleaseToProduction
    displayName: "Release to Production"
    condition: succeeded('Build')

    variables:
      - group: "Deployment Production"

    jobs:
      - deployment: ReleaseToProduction
        displayName: "Release to Production"
        environment: "Production"

        strategy:
          runOnce:
            deploy:
              steps:
                - task: DownloadSecureFile@1
                  name: caCertificate
                  displayName: "Download certificate"
                  inputs:
                    secureFile: "CI-CD-Certificate.pfx"

                - task: NodeTool@0
                  displayName: "Use Node 22.x"
                  inputs:
                    versionSpec: "22.x"

                - task: Npm@1
                  displayName: "Install CLI for Microsoft 365"
                  inputs:
                    command: custom
                    verbose: false
                    customCommand: "install -g @pnp/cli-microsoft365"

                - script: |
                    m365 login --authType certificate --certificateFile "$(caCertificate.secureFilePath)" --password "$(CertificatePassword)" --appId "$(EntraIDAppId)" --tenant "$(TenantId)"
                    m365 spo set --url "$(SharePointBaseUrl)"
                    m365 spo app add --filePath "$(Pipeline.Workspace)/drop/mypackage.sppkg" --overwrite
                    m365 spo app deploy --name "mypackage.sppkg"
                  displayName: "Add and deploy app"

All in all a pretty small change, but it does simplify the build and deployment process and makes it more consistent with the local development experience.

Albert-Jan Schot

Albert-Jan Schot

CTO, Microsoft MVP & FastTrack Recognized Solution Architect

I am Albert-Jan Schot, CTO at Blis Digital, Microsoft MVP, and FastTrack Recognized Solution Architect focused on Microsoft 365, Azure, and AI agents. I help teams turn complex Microsoft Cloud challenges into practical architecture decisions and shipped outcomes.

Copilot Studio Microsoft 365 Agent Flows

Zuid Holland, Netherlands

Related Posts