将持续集成添加到容器生成

持续集成是一种软件开发过程,其中应用程序通过向特定代码库的每个提交提供自动生成,使应用程序保持持续可发布状态。 可以向几乎任何生成系统添加持续集成,但两个特别方便的生成系统是GitHub Actions和 Azure Pipelines。 在本主题中,你将了解如何使用 GitHub Actions 或 Azure Pipelines 自动执行使用容器生成 Azure Sphere 应用中所述的 Docker 生成步骤。

使用GitHub Actions自动生成容器

GitHub Actions允许直接从 GitHub 存储库自动执行生成过程。 因此,使用 GitHub Actions 的第一步是创建或打开包含应用程序代码的 GitHub 存储库。 本主题假定你已创建一个 GitHub 存储库,其中包含 在教程:生成高级应用程序 中生成的 Blink 应用程序,并且项目名为“Blink”。 与任何持续集成项目一样,在尝试自动执行该过程之前,请确保项目在本地生成并提供预期的项目。 在此示例中,我们假定成功生成后, out 目录包含 Blink.imagepackage 文件。

在 GitHub 存储库的顶级目录中,创建名为 .devcontainer 的目录,并在该目录中创建一个名为 Dockerfile 的文件,其中包含以下内容:

FROM mcr.microsoft.com/azurespheresdk:latest AS dev

FROM dev AS build
COPY ./ /src/
WORKDIR /out
RUN cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="/opt/azurespheresdk/CMakeFiles/AzureSphereToolchain.cmake" \
    -DAZURE_SPHERE_TARGET_API_SET="latest-lts" -DCMAKE_BUILD_TYPE="Release" "/src"
ENTRYPOINT [ "ninja" ]

初始 FROM 行将标准 Azure Sphere Docker 映像指定为基本开发容器,第二行指定使用该基本容器作为生成环境。 该 COPY 行将存储库的内容复制到容器的 /src/ 目录中。 指定 WORKDIR 生成目录。 命令 RUN 提供 CMake 命令来生成生成文件。 最后, ENTRYPOINT 指定应调用 ninja 来实际生成应用程序。

在存储库的顶级目录中,创建 .github/workflows 目录,并添加一个名为 ci.yml 的文件,其中包含以下内容:

# This is a basic workflow to help you get started with Actions

name: ContinuousIntegration

# Controls when the action will run. Triggers the workflow on push or pull request
# events, but including workflow_dispatch also allows manual execution
on:
  push:
  pull_request:
  workflow_dispatch:


jobs:
  build:
    runs-on: ubuntu-latest
    name: Build Azure Sphere Apps
    steps:
    - name: Checkout
      uses: actions/checkout@v2
    - name: Build image for az sphere builds and Start container from build image
      run: |
        docker build --target build -t hlbuildimage -f .devcontainer/Dockerfile .
        docker run --name hlbuildcontainer hlbuildimage
    - name: Copy container build output
      run:
        docker cp hlbuildcontainer:/out HLOutput
    - name: Publish HL imagepackage
      uses: actions/upload-artifact@v2
      with:
        name: HL imagepackage
        path: ${{ github.workspace }}/HLOutput/Blink.imagepackage

此工作流只有一个作业 - 生成应用程序;作业在GitHub Actions运行器上运行,在本例ubuntu-latest中为 ,有四个步骤:

  1. 步骤 1 Checkout是一个标准的 GitHub 操作,只需将存储库签出到 ubuntu-latest 运行器。

  2. 步骤 2 () docker build 生成映像,并启动容器 (docker run) 。

  3. 步骤 3 将输出从容器复制到运行器。

  4. 步骤 4(发布 HL 映像包)将高级应用程序映像包发布为 项目

将这些更改提交到 main 分支,然后选择“操作”。 现在应看到一个标记为“所有工作流”的页面,其中至少有一个工作流正在运行或已完成。 如果工作流成功完成,则旁边会显示绿色检查标记。 单击成功的工作流,应会看到一个标记为“项目”的框,其中包含一个标记为“HL imagepackage”的项目。 下载此项目并解压缩 imagepackage 文件;然后,可以 创建部署将应用程序旁加载到设备

使用 Azure Pipelines 自动生成容器

Azure Pipelines 允许直接从 GitHub 存储库 (和许多其他代码存储库以及) 自动执行生成过程。 本主题假定你已属于具有 Azure DevOps 项目的组织,并且有权访问 Azure Pipelines。 使用 Azure Pipelines 的第一步是创建或打开包含应用程序代码的存储库。 本主题假定你已创建一个 GitHub 存储库,其中包含 在教程:生成高级应用程序中生成的 Blink 应用程序。

在此存储库的顶级目录中,创建 .devcontainer 目录,并在该目录中创建包含以下内容的 Dockerfile 文件:

FROM mcr.microsoft.com/azurespheresdk:latest AS dev

FROM dev AS build
COPY ./ /src/
WORKDIR /out
RUN cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="/opt/azurespheresdk/CMakeFiles/AzureSphereToolchain.cmake" \
    -DAZURE_SPHERE_TARGET_API_SET="latest-lts" -DCMAKE_BUILD_TYPE="Release" "/src"
ENTRYPOINT [ "ninja" ]

初始 FROM 行将标准 Azure Sphere Docker 映像指定为基本开发容器,第二行指定使用该基本容器作为生成环境。 该 COPY 行将存储库的内容复制到容器的 /src/ 目录中。 指定 WORKDIR 生成目录。 命令 RUN 提供 CMake 命令来生成生成文件。 最后, ENTRYPOINT 指定应调用 ninja 来实际生成应用程序。

若要创建管道,请执行以下操作:

  1. 登录到 Azure DevOps 项目并打开 Pipelines
  2. 选择“新建管道”,然后在系统询问代码的位置时选择“GitHub”你可能会被带到 GitHub 身份验证页;完成身份验证,然后继续转到页面以选择存储库。
  3. 选择 Blink 存储库。 你将访问标题为 “配置管道”的页面。
  4. 选择 “初学者管道”。 这会在存储库的顶级目录中打开名为 azure-pipelines.yml 的文件,其中包含 Hello, World 任务。
  5. 选择“ 保存并运行”。 接受默认提交消息再次选择“保存并运行”。 azure-pipelines.yml 文件已提交到 GitHub 存储库,并创建管道。

将 azure-pipelines.yml 文件的内容替换为以下内容:

# Docker
# Build a Docker image
# /azure/devops/pipelines/languages/docker

trigger:
- main

resources:
- repo: self

variables:
  tag: '$(Build.BuildId)'

stages:
- stage: Build
  displayName: Build image
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - bash: docker build --target build -t hlbuildimage -f .devcontainer/Dockerfile . &&  docker run --name hlbuildcontainer hlbuildimage && docker cp hlbuildcontainer:/out $(Build.ArtifactStagingDirectory)/HLOutput
      displayName: Build high-level Azure Sphere application in a container and copy the output
    - task: PublishBuildArtifacts@1
      displayName: Publish build artifacts
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)/HLOutput/Blink.imagepackage'
        ArtifactName: 'BlinkSample.imagepackage'
        publishLocation: 'Container'

此工作流只有一个作业 - 生成应用程序;作业在 Azure DevOps 代理上运行(在本例 ubuntu-latest中为 ),有两个步骤:

  1. 步骤 1 () docker build 生成映像,启动容器 (docker run) ,并将输出从容器复制到代理。

  2. 步骤 2(发布生成项目)将高级应用程序映像包发布为 项目

将这些更改提交到 main 分支。 在 Azure DevOps 中,再次打开 Pipelines 。 应会看到管道运行正在进行或刚刚完成。 如果运行显示绿色复选标记,则表示生成成功。 选择成功的运行;在“相关”列中应看到 1 已发布。 下载此项目并解压缩 imagepackage 文件;然后,可以 创建部署将应用程序旁加载到设备

将持续集成添加到 Azure Sphere 示例应用程序

GitHub Actions和 Azure Pipelines 旨在自动执行单个项目的生成,例如从 Microsoft 示例浏览器下载的项目。 GitHub 上的 Azure Sphere 示例 是具有一些共享资源的项目的集合。 若要在持续集成中使用其中一个示例,需要合并任何所需的共享资源。 通常,这意味着至少在项目的顶级目录中创建 HardwareDefinitions 目录,并编辑 CMakeLists.txt 文件以指向本地副本。 例如,如果基于 HelloWorld/HelloWorld_HighLevelApp 示例创建项目,则顶级目录最初如下所示:

.vscode
.gitignore
applibs_versions.h
app_manifest.json
CMakeLists.txt
CMakeSettings.json
launch.vs.json
LICENSE.txt
main.c
README.md

CMakeLists.txt 文件包含以下指向示例存储库中共享 HardwareDefinitions 目录的行:

azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "../../../HardwareDefinitions/mt3620_rdb" TARGET_DEFINITION "sample_appliance.json")

若要使项目能够生成,请将 HardwareDefinitions 文件夹复制到顶级目录中,然后编辑 CMakeLists.txt 文件以使用本地位置:

azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "HardwareDefinitions/mt3620_rdb" TARGET_DEFINITION "sample_appliance.json")

同样,在尝试使用 GitHub Actions 进行自动化之前,请验证项目是否在本地生成。