设置 CI/CD 管道

可以为使用 Teams 工具包创建的 Microsoft Teams 应用设置持续集成和持续部署 (CI/CD) 管道。 Teams 应用 CI/CD 管道由三个部分组成:

  1. 生成项目。

  2. 将项目部署到云资源。

  3. 生成 Teams 应用包。

注意

若要为 Teams 应用创建管道,需要准备必要的云资源,例如 Azure Web 应用、Azure Functions或 Azure 静态 Web 应用,并配置应用设置。

若要生成项目,必须编译源代码并创建所需的部署项目。 有两种方法可以部署项目:

使用 Teams 工具包 CLI 设置 CI/CD 管道

注意

使用 Teams 工具包 5.6.0 或更高版本。

可以使用 Teams 工具包命令行界面 (CLI) 为 Teams 应用设置 CI/CD 管道。

先决条件

项目 说明
为 Teams 应用设置所需的资源,例如 Teams 应用 ID、机器人 ID 等。 • 从 文件夹下的 appPackage 文件中手动提取资源manifest.json
• 自动生成以在 Teams 工具包中运行 Provision 命令。
配置 Azure 资源 • 通过检查文件夹下的 infra bicep 文件手动准备资源。
• 使用 Provision Teams 工具包中的 命令自动准备资源。
确保已正确配置服务主体,其中包含对资源的适当访问策略。 Teamsapp命令行接口 (CLI) 支持通过基于证书的身份验证或基于密码的身份验证 (应用程序机密) 登录。 可以使用 基于证书的身份验证创建服务主体 并保存生成的证书、 appId (客户端 ID) 和 tenant (租户 ID) ,或者 创建机密 并保存服务主体的客户端 ID、客户端密码和租户 ID。
屏幕截图显示了服务主体机密。
有关服务主体的详细信息,请参阅:
使用 Entra 门户创建服务主体
使用 Azure CLI 创建服务主体

完成先决条件后,让我们设置一个管道:

使用 GitHub 设置管道

若要使用 GitHub 设置管道,请执行以下步骤:

  1. 打开 Visual Studio Code。

  2. 在文件夹中的项目中.github/workflows创建一个cd.yml文件,并在文件中添加以下代码:

    on:
      push:
        branches:
          - main
    jobs:
      build:
        runs-on: ubuntu-latest
        env:
          TEAMSAPP_CLI_VERSION: "3.0.4"
          # Add extra environment variables here so that teamsapp cli can use them.
    
        steps:
          - name: "Checkout GitHub Action"
            uses: actions/checkout@v4
    
          - name: Setup Node 20.x
            uses: actions/setup-node@v1
            with:
              node-version: "20.x"
    
          - name: install cli
            run: |
              npm install @microsoft/teamsapp-cli@${{env.TEAMSAPP_CLI_VERSION}}
    
          - name: Retrieve the secret and decode it to a file
            env:
              CERTIFICATE_BASE64: ${{ secrets.AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64 }}
            run: |
              echo $CERTIFICATE_BASE64 | base64 --decode > cert.pem
    
          - name: Login Azure by service principal
            run: |
              npx teamsapp auth login azure --username ${{vars.AZURE_SERVICE_PRINCIPAL_CLIENT_ID}}  \
              --service-principal true \
              --tenant ${{vars.AZURE_TENANT_ID}} \
              --password cert.pem \
              --interactive false
    
          - name: Deploy to hosting environment
            run: |
              npx teamsapp deploy --ignore-env-file true \
              --interactive false
    
          - name: Package app
            run: |
              npx teamsapp package
    
          - name: upload appPackage
            uses: actions/upload-artifact@v4
            with:
              name: artifact
              path: appPackage/build/appPackage.zip
    
  3. 转到 GitHub。

  4. 更新在先决条件期间创建的以下变量和机密:

    • AZURE_SERVICE_PRINCIPAL_CLIENT_IDAZURE_TENANT_IDAZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64 是已生成的证书的 Base64 字符串编码内容。

      屏幕截图显示了存储库设置。

      注意

      变量 AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64 必须设置为机密。 将 GitHub 环境 用于不同的变量集。

    • 转到 teamsapp.yml 文件。 在 deploy 阶段中,括在 中的 ${{}} 值是所需的变量键。 如果已使用 Teams 工具包中的 provision 命令,则可以在 文件夹中的环境文件中 .env 查找值。

      BOT_AZURE_APP_SERVICE_RESOURCE_ID将 设置为存储库变量:

      屏幕截图显示了 teamsapp.yml 文件中的机器人 Azure 应用服务资源 ID。

    • 转到 appPackage/manifest.json 文件。 括在 中的 ${{}} 值是所需的变量键。 如果已使用 Teams 工具包中的 provision 命令,则可以在 文件夹中的环境文件中 .env 查找值。

      TEAMS_APP_ID将 设置为存储库变量:

      屏幕截图显示清单文件中的 Teams 应用 ID。

  5. 在 GitHub 中,导航到存储库的 “设置” ,然后选择“ 机密和变量>操作”。

    更新为以下变量收集的变量键:

    • AZURE_SERVICE_PRINCIPAL_CLIENT_ID
    • AZURE_TENANT_ID
    • AZURE_SERVICE_PRINCIPAL_CLIENT_SECRETAZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64
    • BOT_AZURE_APP_SERVICE_RESOURCE_ID
    • TEAMS_APP_ID

    将存储库中定义的变量直接添加到 yml 文件中,不包括以下三个变量:

    • AZURE_SERVICE_PRINCIPAL_CLIENT_ID

    • AZURE_TENANT_ID

    • AZURE_SERVICE_PRINCIPAL_CLIENT_SECRETAZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64

      屏幕截图显示修改后的管道 yml。

  6. 运行管道。

    将代码推送到存储库以触发管道。

    注意

    无需将 env 文件夹下的 env 文件提交到存储库。 执行 CI/CD 管道所需的 env 变量已在存储库变量中设置。

    管道成功执行后,日志会显示代码已部署到 Azure 并在 appPackage 项目中生成。

    屏幕截图显示项目中生成的“appPackage”。

使用 Azure DevOps 设置管道

若要使用 Azure DevOps 设置管道,请执行以下步骤:

  1. 打开 Visual Studio Code。

  2. 在项目中创建一个 cd.yml 文件,并在文件中添加以下代码:

    trigger:
      - main
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      TEAMSAPP_CLI_VERSION: 3.0.4
    
    steps:
      - task: NodeTool@0
        inputs:
          versionSpec: "20"
          checkLatest: true
    
      - script: |
          npm install @microsoft/teamsapp-cli@$(TEAMSAPP_CLI_VERSION)
        displayName: "Install CLI"
    
      - task: DownloadSecureFile@1  
        name: certFile  
        displayName: 'Download Certificate File'  
        inputs:  
          secureFile: 'azure_sp_cert.pem' 
    
      - script: |
          npx teamsapp auth login azure --username $(AZURE_SERVICE_PRINCIPAL_CLIENT_ID) --service-principal true --tenant $(AZURE_TENANT_ID) --password $(certFile.secureFilePath) --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
        displayName: "Package app"
        workingDirectory: $(System.DefaultWorkingDirectory)
    
      - publish: $(System.DefaultWorkingDirectory)/appPackage/build/appPackage.zip
        artifact: artifact
    
  3. 将代码推送到存储库。

  4. 设置 Azure 管道。

    将代码推送到存储库后,导航到 “管道 ”并选择“ 新建管道”。 选择存储库和现有 yml 文件以配置管道。

  5. 更新以下变量并设置在先决条件期间创建的证书:

    • AZURE_SERVICE_PRINCIPAL_CLIENT_ID, AZURE_TENANT_ID

    • 转到 teamsapp.yml 文件。 在 deploy 阶段中,括在 中的 ${{}} 值是所需的变量键。 如果已使用 Teams 工具包中的 provision 命令,则可以在 文件夹中的环境文件中 .env 查找值。

      BOT_AZURE_APP_SERVICE_RESOURCE_ID将 设置为存储库变量:

      屏幕截图显示了 teamsapp.yml 文件中的机器人 Azure 应用服务资源 ID。

    • 转到 appPackage/manifest.json 文件。 括在 中的 ${{}} 值是所需的变量键。 如果已使用 Teams 工具包中的 provision 命令,则可以在 文件夹中的环境文件中 .env 查找值。

      TEAMS_APP_ID将 设置为存储库变量:

      屏幕截图显示清单文件中的 Teams 应用 ID。

    需要在存储库中设置以下键名称变量:

    • AZURE_SERVICE_PRINCIPAL_CLIENT_ID
    • AZURE_TENANT_ID
    • BOT_AZURE_APP_SERVICE_RESOURCE_ID
    • TEAMS_APP_ID

    若要在管道中设置变量,请转到管道并选择 “编辑>变量”。

    在 Azure DevOps 项目中,导航到“管道”>并添加新的安全文件。 上传证书 (.pem) 文件,并将该文件命名为 azure_sp_cert.pem

  6. 运行管道。

    将代码推送到存储库以触发管道。

    注意

    无需将 env/ 文件夹下的 env 文件提交到存储库。 执行 CI/CD 管道所需的 env 变量已在管道变量中建立。

    管道成功执行后,日志会显示代码已部署到 Azure 并在 appPackage 项目中生成。

    屏幕截图显示管道成功运行。

使用自己的工作流设置 CI/CD 管道

如果 Teams 应用 CLI 不满足管道要求,则可以开发符合需求的自定义部署过程。 本部分提供有关使用自定义方法部署到 Azure 的指南。

注意

如果已有用于部署到 Azure 资源的完整 CI/CD 管道,并且 Teams 应用需要在运行时读取环境变量,请在 Azure 资源的设置中配置这些环境变量。 有关部署后测试,请参阅 生成 Teams 应用包

命令teamsapp deploy执行文件阶段teamsapp.ymldeploy定义的操作。 阶段deploy由 和 deploy 操作组成build。 若要创建自定义部署方法,请根据特定要求和首选项重写这些操作。

例如,基本机器人 TypeScript 项目在其 teamsapp.yml中具有以下部署阶段:

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 this link.
  - 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}}

这些操作执行以下任务:

  • 运行 npm installnpm build 以生成项目。
  • 将代码部署到 Azure 应用服务。

可以在 CI/CD 管道中自定义这些操作。 下面是一个利用 GitHub 操作的示例:

# build
- name: Setup Node 20.x
  uses: actions/setup-node@v1
  with:
    node-version: '20.x'
- name: 'npm install, build'
  run: |
    npm install
    npm run build --if-present

- name: 'zip artifact for deployment'
  run: |
    zip -r deploy.zip . --include 'node_modules/*' 'lib/*' 'web.config'

# deploy
- name: 'Login via Azure CLI'
  uses: azure/login@v1
  with:
    client-id: ${{ vars.CLIENT_ID }}
    tenant-id: ${{ vars.TENANT_ID }}
    subscription-id: ${{ vars.SUBSCRIPTION_ID }}

- name: 'Run Azure webapp deploy action using azure RBAC'
  uses: azure/webapps-deploy@v2
  with:
    app-name: ${{ vars.AZURE_WEBAPP_NAME }}
    package: deploy.zip

Teams 工具包支持 Teams 应用项目,这些项目采用各种编程语言编写,设计用于托管不同的 Azure 服务。 生成和部署的以下操作。 设置 CI/CD 部署管道时使用这些操作。

内部版本:

语言 GitHub Azure Pipeline
JS 或 TS actions/setup-node NodeTool@0
C# actions/setup-dotnet DotNetCoreCLI@2

部署:

资源 GitHub Azure Pipeline
Azure 应用服务 azure/webapps-deploy AzureWebApp@1
Azure Functions Azure/functions-action AzureFunctionApp@2
Azure Static Web Apps Azure/static-web-apps-deploy AzureStaticWebApp@0

登录到 Azure 所需的凭据

通过 CI/CD 将应用代码部署到 Azure 应用服务、Azure Functions 或 Azure 容器应用时,需要 Azure 登录的服务主体。 可以通过两种方式使用服务主体登录到 Azure:

生成 Teams 应用包

若要分发 Teams 应用, appPackage 需要 。 可以在 CLI 中使用 teamsapp packageTeamsapp 命令自动创建 appPackage.zip 。 如果无法使用 Teamsapp CLI,请按照以下步骤手动创建 appPackage

  1. appPackage准备文件夹。
  2. manifest.json 文件放在 appPackage 文件夹中。 Teams 工具包项目中的默认 manifest.json 文件包含占位符,由 ${{}} 表示。 将这些占位符替换为正确的值。
  3. 将应用图标放在 appPackage 文件夹中。 若要准备应用图标,请参阅 应用图标
  4. 压缩文件夹中的文件 appPackage

另请参阅