This blog post will show you how to simplify the deployment of SPFx solutions using a .devcontainer setup, automate SharePoint site configurations, and make the process accessible — even for non-professionals. We’ll also look at using Docker and PowerShell to automate building, provisioning, and deployment.

PuntoBello Installer

Looking for a standardized way to build and deploy all our PuntoBello solutions we decided to create the PuntoBello Installer. The Installer should contain the complete tooling to build and deploy SPFx solutions as well as all the scripts required in the process. Every solution has different requirements for the deployment to SharePoint. One solution may need a list with specific fields or permissions, another solution may depend on terms from the TermStore and so on. We decided to define a JSON file (solutions.json) which contains all the relevant information for the deployment scripts. Last but not least, we wanted to create an installer that fits different usage scenarios. Whether you work on a Mac or a Windows PC with different CPU architectures, on your local system or in a devcontainer, the PuntoBello Installer has you covered. It can even be implemented in a CI/CD pipeline.

Installer requirements

To build the PuntoBello Installer we have different requirements that need to be met in order to ensure successful build and deployment. These requirements include having the necessary tooling to build the SPFx solutions, as well as scripts to deploy them. Additionally, the installer must be able to configure all required SharePoint elements, such as sites, lists and termsets. It is also important that the installer is compatible with different platforms, including local environments, Docker and CI/CD pipelines. This ensures that the solutions can be built and deployed in a variety of settings and that the installation process is as seamless as possible.

Tooling

When developing SPFx solutions, it’s essential to have a consistent development environment. We made use of a .devcontainer that allows us to package all the tools and configurations needed for the project inside a Docker container. This way, every developer (or non-developer!) who works on the project has the same environment—no more “it works on my machine” problems. The Docker image is based on CBL-Mariner and contains the required tooling for our installer:

  • NodeJS
  • SPFx
  • Gulp
  • Yeoman
  • M365 CLI
  • PowerShell (PnP, Az)

In addition to the tools and configurations needed for the project, the devcontainer.json file used in the development of SPFx solutions also includes a variable called ARCH. This variable allows developers to change the CPU architecture between arm64 and amd64, which in turn enables the Docker container to be built and run on different platforms. This flexibility is important because it allows developers to work on the project using the platform of their choice, without having to worry about compatibility issues. By including the ARCH variable in the devcontainer.json file, the development environment can be customized to meet the needs of each individual developer, making it easier to collaborate on the project and ensuring that everyone has access to the same tools and configurations.

The installer is maintained as a stand-alone project. To use it in an existing SharePoint solution, add the PuntoBello Installer as a submodule to your current project:

git submodule add https://github.com/diemobiliar/puntobello-installer.git .devcontainer

Our showcases Multilingual Document Cards and User Apps are already configured with the installer as submodule and can be cloned with the “–recurse-submodules“-parameter.

Connecting to SharePoint

There are many different ways to authenticate with SharePoint when using PnP.Powershell. To make your life a little easier, the PuntoBello installer supports most of them. The config.psm1 file in the installers ./scripts directory allows you to define your tenant name, a user which is used as SiteCollection Admin if a new site collection is created and your preferred authentication method.

$global:M365_TENANTNAME = "puntobello"
$global:adminUser = admin@$($global:M365_TENANTNAME).onmicrosoft.com

# Login parameters
$global:loginSelector = 1

As of September 9th 2024 an Entra ID Application registration is required for all login methods – even interactive login . See the following Article for a detailed description of the different authentication options for PnP.Powershell. Choose one of the authentication methods and set the corresponding parameters. We will address these methods and share our experiences with them in a future blog post.

Provisioning SharePoint Artefacts

There is a folder called “spo” in every PuntoBello solution. It contains all the information required to provision the required SharePoint elements and deploy the solution to the correct sites. Its format is as follows:

{
    "sites": [
        {
            "Url": "pb_home",
            "Title": "Intranet Home Page",
            "LCID": 1033,
            "solutions": [
                {
                    "Name": "puntobello-userapps-spext"
                }
            ],
            "templates": [
                {
                    "templateName": "AllApps.xml",
                    "relativePath": "./spo/assets/lists",
                    "sortOrder": 100
                }
            ]
        },
    "termStore": []
}

“sites” is an array, containing the definition of all the sites where a solution is deployed. If the site does not exist, it is created with the properties defined. Multiple solutions can be defined for deployment. The “templates” section within the site definition defines templates, which are deployed using “Invoke-PnPTemplate”. Define required terms or termsets in the “termstore” section.

Scripts

“Build-SPWP.ps1” builds all solutions defined in solutions.json. It expects the solutions to be in a subdirectory with the same name. The script “Deploy-SitesAndLists.ps1” creates all elements defined in solutions.json. “Deploy-SPWP.ps1” will deploy the solutions defined in this file to the tenant app catalog as well as the requested site.

Usage scenarios

As described at the beginning of this blog post, the PuntoBello installer run on various environments and CPU architectures. The individual scenarios are described in more detail below. The same scripts will be used regardless of whether they are executed locally, in a Docker container, or in a pipeline.

Use Dev Container in VS code (.devcontainer)

The .devcontainer file is a configuration file used in Visual Studio Code (VS Code) to create a consistent development environment for a project. It specifies the tools, runtime, and other dependencies needed for the project and allows developers to work in a containerized environment.

Using a .devcontainer file has several benefits, including making it easier to onboard new developers to a project, ensuring that everyone is using the same environment, and making it easier to reproduce issues and debug problems. Additionally, because the development environment is containerized, it can be easily moved between different machines or shared with other developers.

To start with Dev Container and learn more about please visit Dev Containers tutorial. The tutorial provides step-by-step instructions to help you get up and running quickly.

Set parameters

Before we start running the Dev Container, we need to set the relevant parameters.

  • Set architecture in devcontainer.json. “arm64” and “amd64” are supported.
  • Set the M365_TENANTNAME, the adminUser and the Login parameters in /scripts/config.psm1.

Deploy SPO Sites and Lists

To start a full deployment, we typically begin with the SPO elements and use the script “Deploy-Sites-AndLists.ps1”.

  1. Use Ctrl + Shift + P (on Windows) or Command + Shift + P (on OS X) to run ‘Dev Containers: Rebuild and Reopen in Container’. This builds the container and attaches the project folder to the container with PowerShell and modules loaded.
  2. Run “Deploy-SitesAndLists.ps1” to create the SPO sites, lists and term sets. The configuration is defined in the folder “./spo”. If you want to change the target urls of sites an, change the configuration in the solutions.json file. The deployment of the lists is based on PnP Site Templates, which can be found at ./spo/assets/lists.

Build and Deploy Webpart and Extensions

  1. Run “Build-SPWP.ps1” in the Dev Container to build the solutions. The script installs every dependencies and creates the sppkg files. These are saved in sharepoint/solution folder of each individual SPFx solution.
  2. Install the solutions in SPO app catalog and sites with the script “Deploy-SPWP.ps1”. If you have them already installed, this script can be used to update the solutions as well.
  3. Sites, Lists and Solutions are ready to use.

Use Docker container without running Dev Container

As an alternative to using the Dev Container with VS Code, it is possible to use the Dockerfile to create the Docker container and execute the scripts in commands. This can be done without attaching the terminal to the container.

Set parameters

Before we start building the Docker container, we need to set the relevant parameters.

  • Set the M365_TENANTNAME, the adminUser and the Login parameters in /scripts/config.psm1.

Build the container

  1. Run docker build command to build the docker container from Dockerfile. Set build argument ARCH to desired CPU architecture (amd64 or arm64)
docker build -t pbspfxtools --build-arg ARCH=amd64 -f ./.devcontainer/Dockerfile ./.devcontainer

Run scripts in container

  1. Run the deploy script for SPO sites and lists.
docker run -v ${PWD}:/spfx -w /spfx pbspfxtools pwsh -Command "Deploy-SitesAndLists.ps1"
  1. Build the solutions using the build script in the docker container.
docker run -v ${PWD}:/spfx -w /spfx pbspfxtools pwsh -Command "Build-SPWP.ps1"
  1. Deploy the solutions to app catalog and sites using the deploy script in the docker container.
docker run -v ${PWD}:/spfx -w /spfx pbspfxtools pwsh -Command "Deploy-SPWP.ps1"

Local in PowerShell

Although all scripts can be used without the Docker container, it is important to ensure that all required tools are installed on your machine. Otherwise you will be faced with errors running the scripts.

Set parameters

Before we start running the script, we need to set the relevant parameters.

  • Set the M365_TENANTNAME, the adminUser and the Login parameters in /scripts/config.psm1.

Deploy SPO Sites and Lists

  1. Run ..devcontainer\scripts\Deploy-SitesAndLists.ps1 in the root of the project to create the SPO sites and lists. The configuration is set in folder spo. If you want to change the target urls of sites an, change the configuration in the solutions.json file.

Build and Deploy Webpart and Extensions

  1. Run ..devcontainer\scripts\Build-SPWP.ps1 in to build the solutions. The script installs every dependencies and creates the sppkg files. These are saved in sharepoint/solution folder of each solution.
  2. Install the solutions in SPO app catalog and sites with the script ..devcontainer\scripts\Deploy-SPWP.ps1. If you have them already installed, this script can be used to update the solutions as well.
  3. Sites, Lists and Solutions are ready to use.

CI/CD Pipeline with GitHub Actions

This setup also works in a CI/CD pipeline. Below you find a rudimentary pipeline definition for GitHub Actions. In this example the docker image is built at runtime. Usually you are better of pulling the image from a docker registry.

name: Build and Deploy

on:
  push:
    branches:
      - main

jobs:
  buildanddeploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Build Docker image
        run: docker build -t pbspfxtools --build-arg ARCH=amd64 -f ./.devcontainer/Dockerfile ./.devcontainer
      - name: Deploy Sites and Lists
        env:
          CLIENT_ID: ${{ vars.CLIENT_ID }}
          SECRET: ${{ secrets.SECRET }}
        run: docker run -v ${PWD}:/spfx -w /spfx -e CLIENT_ID=${CLIENT_ID} -e SECRET=${SECRET} pbspfxtools:latest pwsh -Command Deploy-SitesAndLists.ps1
      - name: Run SPFx builds
        run: docker run -v ${PWD}:/spfx -w /spfx pbspfxtools:latest pwsh -Command Build-SPWP.ps1
      - name: Deploy SPFx solutions
        env:
          CLIENT_ID: ${{ vars.CLIENT_ID }}
          SECRET: ${{ secrets.SECRET }}
        run: docker run -v ${PWD}:/spfx -w /spfx -e CLIENT_ID=${CLIENT_ID} -e SECRET=${SECRET} pbspfxtools:latest pwsh -Command Deploy-SPWP.ps1

Conclusion

Deploying SPFx solutions doesn’t have to be a complicated process. By using .devcontainer for a consistent environment by providing a Docker image with all the right tools and automating site configurations with PowerShell, you can make the process seamless and accessible—even for non-developers. Automation with Gulp and PowerShell scripts allows you to take the manual effort out of building, provisioning, and deploying solutions, leaving you more time to focus on creating amazing SharePoint experiences. Happy coding!