Skip to content

New command: spfx project azuredevops pipeline add #5763

@Adam-it

Description

@Adam-it

Usage

m365 spfx project azuredevops pipeline add [options]

Description

Adds a Azure DevOps pipeline for a SharePoint Framework project.

Options

Option Description
-n, --name [name] Name of the pipeline run that will be created. If none is specified a default name generated by Azure DevOps will be used
-b, --branchName [branchName] Specify the branch name which should trigger the workflow on push. If none is specified a default will be used which is 'main'
-l, --loginMethod [loginMethod] Specify the login method used for the login action. Possible options are: user, application. Default application
-s, --scope [scope] Scope of the app catalog: tenant, sitecollection. Default is tenant
--siteUrl [siteUrl] The URL of the site collection where the solution package will be added. Required if scope is set to sitecollection
--skipFeatureDeployment When specified the app will be added to all sites. When deployed to the site app catalog it will be added to all sub-sites of that site.

Examples

Adds an Azure DevOps Pipeline for a SharePoint Framework project triggered on push to main

m365 spfx project azuredevops pipeline add

Adds an Azure DevOps Pipeline for a SharePoint Framework project with user login method triggered on push to main

m365 spfx project azuredevops pipeline add --loginMethod "user"

Adds an Azure DevOps Pipeline for a SharePoint Framework project with deployment to a site collection app catalog that will overwrite any existing packages with same name

m365 spfx project azuredevops pipeline add --scope "sitecollection" --siteUrl "https://some.sharepoint.com/sites/someSite" --overwrite

Default properties

No response

Additional Info

The implementation should be very similar to spfx project github workflow add so we should store the pipeline definition as JSON and use yaml npm package that we already have to parse the .json definition to the .yml file.
The pipeline should be created in .azuredevops\pipelines directory (the command should create one if doesn't exist) and the file name should be deploy-spfx-solution.yml so it is consistent with Azure DevOps convention and also with the current GitHub command output. Below we may see a project with both pipeline for azdo and workflow for gh
image

The command should generate the following file (or similar one depending on the options specified) I added comments in the yaml so that it is clear how the yaml should differ based on the options set. We should generate the yaml without those comments of course 😉

name: test  # this line is optional and should only be present if the used specified the name option. Otherwise we should remove it and don't specify any name. In that case Azure DevOps generates default naming based on date and run number.

trigger:
  branches:
    include:
      - main # depends on what user passed in option branchName. default is main

pool:
  vmImage: "ubuntu-latest"

variables:
  - name: CertificateBase64Encoded # this should be visible only when application login method was used which is the default one.
    value: "" # this should be filled manually by the user
  - name: CertificateSecureFileId # this should be visible only when application login method was used which is the default one
    value: "" # this should be filled manually by the user
  - name: CertificatePassword # this should be visible only when application login method was used which is the default one
    value: "" # this should be filled manually by the user
  - name: EntraIDAppId # this should be visible only when application login method was used which is the default one
    value: "" # this should be filled manually by the user
  - name: UserName # this should be visible only when user login method was used
    value: "" # this should be filled manually by the user
  - name: Password # this should be visible only when user login method was used
    value: "" # this should be filled manually by the user
  - name: TenantId
    value: "2942bb31-1d49-4da6-8d3d-d0f9e1141486" # I think we should be able to retrive that and prefil. But only if the user is logged in as the spfx commands do not require being logged in to m365 tenant
  - name: SharePointBaseUrl
    value: "https://tenanttocheck.sharepoint.com"  # I think we should be able to retrive that and prefil. But only if the user is logged in as the spfx commands do not require being logged in to m365 tenant
  - name: PackageName
    value: "demo-1.sppkg" # we should prefil that
  - name: SiteAppCatalogUrl # this option and it's value should only be present in the flow if the siteUrl option was used in the command
    value: "https://tenanttocheck.sharepoint.com/sites/PnPDemo2/AppCatalog"

stages:
  - stage: "Build_and_Deploy"
    jobs:
      - job: "Build_and_Deploy"
        steps:
          - task: NodeTool@0
            displayName: "Use Node.js"
            inputs:
              versionSpec: "18.x"

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

          - task: Gulp@0
            displayName: "Gulp bundle"
            inputs:
              gulpFile: ./gulpfile.js
              targets: bundle
              arguments: "--ship"

          - task: Gulp@0
            displayName: "Gulp package"
            inputs:
              targets: "package-solution"
              arguments: "--ship"

          - 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 --certificateBase64Encoded "$(CertificateBase64Encoded)" --password "$(CertificatePassword)" --appId "$(EntraIDAppId)" --tenant "$(TenantId)"
              m365 spo set --url "$(SharePointBaseUrl)"
              m365 spo app add --filePath "$(Build.SourcesDirectory)/sharepoint/solution/$(PackageName)" --overwrite
              m365 spo app deploy --name "$(PackageName)" --appCatalogScope sitecollection --appCatalogUrl "($SiteAppCatalogUrl)"
            displayName: "CLI for Microsoft 365 Deploy App"

           # if the site scop was set and the siteUrl option was set we should replace the m365 spo app add command so that it targets siteAppCatalog like
           # m365 spo app add --filePath "$(Build.SourcesDirectory)/sharepoint/solution/$(PackageName)" --appCatalogScope sitecollection --appCatalogUrl "($SiteAppCatalogUrl)" 

          # if skipFeatureDeployment option was set then the m365 spo app deploy command in hte aboce script should have an --skipFeatureDeployment flag as well
          
          # if user login method was used in the command then we should replace the m365 login command in the above script with this one (along with the variables which are present in the upper part of the yaml pipeline
          # m365 login --authType password --userName "$(UserName)" --password "$(Password)"

The above yaml sample is a checked use case that works
image
It is the simplest pipeline possible to get a CI/CD flow and get dev kicked off with development.
The steps in this flow are also aligned with our m365 spfx github workflow add command

Similar to github workflow add command we should add remarks section explaining that application login method is preferable and ready for production use. the user login method will not work with an account that has MFA.
We should also explain that this command only generates the yaml file. After that user need to push it to Azure DevOps and manually create the pipelien based on an existing yaml file. We may provide guidance for those manual steps. Along the way we may mention that it is preferable not to keep those variables in the yaml file but keep them as a dedicated variable group in using library feature in Azure DevOps.
Additionally for application login method we should provide guidance that the user should either use CertificateBase64Encoded or CertificateSecureFileId not both

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions