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}}
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
Since Azure Pipelines are only an automation tool, please make sure your Teams Toolkit CLI works before integrating those commands in a pipeline.