npmazure-pipelinesmicrosoft-teamsnpxteams-toolkit

Deploying Teams Toolkit app via CI/CD fails with 'This command only works for project created by Teams Toolkit' error


My MS Teams app (a chatbot) provisions, deploys and runs fine locally, in testtool and in Azure.

So I've decided to finally take it that one step further and set CI/CD up as well, since I have it set up for all my other projects. However, it's the first time for me setting CI/CD up for Node.js project.

I'm following these instructions on how to set up pipeline with Azure DevOps, but the deployment step fails when executing npx teamsapp deploy command with the following:

Starting: Deploy to Azure
==============================================================================
Task         : Command line
Description  : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
Version      : 2.237.1
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
==============================================================================
Generating script.
========================== Starting Command Output ===========================
/usr/bin/bash --noprofile --norc /home/vsts/work/_temp/45easss6-ddd-4c39-9b3c-xxx.sh
(✖) Error: coordinator.InvalidProjectError: This command only works for project created by Teams Toolkit.

##[error]Bash exited with code '1'.
Finishing: Deploy to Azure

My teamsapp.yml is pretty standard for a Teams Toolkit app, so I'm not sure why would the deployment script consider the project not being created by Teams Toolkit?

YAML pipeline code used:

trigger:
  - dev

pool:
  vmImage: ubuntu-latest

variables:
  TEAMSAPP_CLI_VERSION: 3.0.0

steps:
  - task: NodeTool@0
    inputs:
      versionSpec: "20"
      checkLatest: true

  - script: |
      npm install @microsoft/teamsapp-cli@$(TEAMSAPP_CLI_VERSION)
    displayName: "Install CLI"

  - script: |
      npx teamsapp auth login azure --username $(AZURE_SERVICE_PRINCIPAL_CLIENT_ID) \
      --service-principal true \
      --tenant $(AZURE_TENANT_ID) \
      --password $(AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET) \
      --interactive false
    displayName: "Login to Azure by service principal"

  - script: |
      npx teamsapp deploy \
      --ignore-env-file true \
      --interactive false
    displayName: "Deploy to Azure"
    workingDirectory: $(System.DefaultWorkingDirectory)

  - script: |
      npx teamsapp package
    displayName: "Package app"
    workingDirectory: $(System.DefaultWorkingDirectory)

  - publish: $(System.DefaultWorkingDirectory)/appPackage/build/appPackage.zip
    artifact: artifact

My teamsapp.yml:

# Triggered when 'teamsfx deploy' is executed
deploy:
  # Run npm command
  - uses: cli/runNpmCommand
    name: install dependencies
    with:
      args: install
  - uses: cli/runNpmCommand
    name: build app
    with:
      args: run build --if-present
  # Deploy your application to Azure App Service using the zip deploy feature.
  # For additional details, refer to https://aka.ms/zip-deploy-to-app-services.
  - uses: azureAppService/zipDeploy
    with:
      # Deploy base folder
      artifactFolder: .
      # Ignore file location, leave blank will ignore nothing
      ignoreFile: .webappignore
      # The resource id of the cloud resource to be deployed to.
      # This key will be generated by arm/deploy action automatically.
      # You can replace it with your existing Azure Resource id
      # or add it to your environment variable file.
      resourceId: ${{BOT_AZURE_APP_SERVICE_RESOURCE_ID}}

Solution

  • Generally speaking, the CI/CD workflow via Azure Pipelines introduced in this document is running Teams Toolkit CLI in script tasks to authenticate access to Azure and deploy the Teams app project to Azure Web App.

    Please note that the root directory of your repo will be checked out into the $(System.DefaultWorkingDirectory) on the pipeline agent machine; expanded as /home/vsts/work/1/s/ on a Microsoft-hosted ubuntu-latest agent machine.

    You haven't shared the file structure of your repo. Here is my sample repo and YAML pipeline to deploy my ChatBot Teams app for your reference.

    pool:
      vmImage: ubuntu-latest
    
    variables:
      TEAMSAPP_CLI_VERSION: 3.0.0
      TEAMSFX_ENV: $(Build.SourceBranchName)
      BOT_AZURE_APP_SERVICE_RESOURCE_ID: /subscriptions/$(AZURE_SUBSCRIPTION_ID)/resourcegroups/$(AZURE_RESOURCE_GROUP_NAME)/providers/Microsoft.Web/sites/$(AZURE_WEB_APP_NAME)
    
    steps:
      - task: NodeTool@0
        inputs:
          versionSpec: "20"
          checkLatest: true
    
      - script: |
          npm install @microsoft/teamsapp-cli@$(TEAMSAPP_CLI_VERSION)
        displayName: "Install CLI"
    
      - script: |
          npx teamsapp auth login azure \
            --username $(AZURE_SERVICE_PRINCIPAL_CLIENT_ID) \
            --service-principal true --tenant $(AZURE_TENANT_ID) \
            --password $(AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET) \
            --interactive false
        displayName: "Login Azure by service principal"
    
      - script: |
          npx teamsapp deploy --ignore-env-file true --interactive false
        displayName: "Deploy to Azure"
        workingDirectory: $(System.DefaultWorkingDirectory)
    
      - script: |
          npx teamsapp package --env $(TEAMSFX_ENV)
        displayName: "Package app"
        workingDirectory: $(System.DefaultWorkingDirectory)
    
      - publish: $(System.DefaultWorkingDirectory)/appPackage/build/appPackage.$(TEAMSFX_ENV).zip
        artifact: artifact
    

    Image

    Image Since Azure Pipelines are only an automation tool, please make sure your Teams Toolkit CLI works before integrating those commands in a pipeline.