将 Angular 与 Azure DevOps 持续集成
介绍
Angular应用程序
创建 Azure DevOps 项目
将代码添加到 Azure DevOps
创建构建管道
结论
介绍
Azure DevOps 是微软的一款产品,它除了源代码管理和项目管理等其他功能外,还允许您的团队为其项目设置持续集成。
持续集成是一种开发实践,它使您的团队能够提高质量,并交付更稳定的软件,从而使团队和最终用户都受益。
通过持续集成,系统会在特定触发事件(例如代码变更)发生时自动运行多个检查(称为流水线)。这些检查通常确保代码能够成功编译,并且所有测试都能通过。在隔离环境中自动运行这些检查,可以消除大部分在我本地机器上运行正常的问题,并确保我们的代码库始终保持良好状态。
Angular应用程序
在本演示中,我们将使用一个默认的 Angular CLI 应用程序,并为其在 Azure DevOps 上添加一个构建管道。
@angular/cli请确保运行最新版本npm install --global @angular/cli,并使用创建一个新的 Angular 应用程序ng new ng-azure-devops --skipInstall=true;我们不需要 Angular 路由,您可以选择自己喜欢的样式表格式。
创建 Azure DevOps 项目
如果您还没有 Azure DevOps 项目,请访问https://dev.azure.com,为本次演示创建一个新项目,并提供项目名称和(可选)项目描述。您可以选择所需的可见性。我选择的是公开可见性,但私有可见性也完全可以。
项目创建完成后,您将进入项目仪表盘。
将代码添加到 Azure DevOps
在项目侧边栏中,您应该能找到“仓库”选项。点击它将打开为该项目创建的默认 Git 仓库。如有需要,您可以向项目中添加更多仓库,这样即使您的应用程序分布在多个 Git 仓库中,也无需创建多个项目。本文仅需一个仓库,因此我们将使用默认创建的仓库。
仓库主页应该会显示仓库为空,并提供将代码推送到仓库的说明。
您需要配置 SSH 密钥或使用Git 凭据管理器才能向 Azure DevOps 上的存储库提交更改。
身份验证配置完成后,提交并推送我们使用 Angular CLI 创建的 Angular 项目。
如果您想使用 GitHub,可以将代码添加到 GitHub,然后通过转到“项目设置”>“GitHub 连接”(位于“项目设置”的“看板”类别下)在 Azure DevOps 中连接您的 GitHub 帐户。您需要选择 GitHub 组织以及要集成到当前项目中的存储库。
接下来的步骤对于 GitHub 存储库和 Azure DevOps 存储库都相同。
创建构建管道
现在,我们的代码已经位于 Azure DevOps 存储库或 GitHub 上(通过项目设置连接我们的 GitHub 帐户),我们可以通过从项目侧边栏导航到“管道”来为该存储库创建构建管道。
单击“新建管道”,选择 Azure Repos Igit 或 GitHub(如果您使用其他可用选项,则选择其他选项),单击相应的存储库(如果您选择 GitHub,系统会提示您授权 Azure Pipelines),然后选择“Node.js with Angular”作为管道配置。这将预配置管道以运行npm install和ng build —-prod。
在审核步骤中,我们将看到 Azure DevOps 生成的 yaml 文件示例。
# Node.js with Angular
# Build a Node.js project that uses Angular.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install -g @angular/cli
npm install
ng build --prod
displayName: 'npm install and build'
默认配置会在主分支上的每次更改时触发。它将使用 Ubuntu 镜像,并执行以下两个步骤:
- 安装 Node.js
- 安装依赖项并构建应用程序。
点击“保存并运行”会将 YAML 文件添加到您的代码仓库中,从而将您的构建管道配置与源代码一起保存。我们甚至可以在本地修改 YAML 文件并提交更改,Azure DevOps 会自动获取这些更改,并相应地更新您的构建管道。
创建单独的分支并发起拉取请求,可以让您在完全按照预期配置之前,无需将此配置合并到主分支。为了简化操作,我们将直接把更改提交到主分支。
如果您希望使用单独的分支,仍然可以这样做。但是,请注意,只要 master 分支上没有 azure-pipelines.yml 文件,构建就不会自动触发。这意味着您需要手动触发构建,直到您的配置合并到 master 分支为止。
创建管道时,单击“保存并运行”按钮无论如何都会运行它,但由于我们将修改源代码,因此构建不会自动触发。
配置文件保存后,将触发新的构建过程,过一段时间后,所有步骤应该都会成功完成。
以上部分步骤由 Azure DevOps 添加(准备、初始化、检出、检出后和最终化),其他步骤则定义在我们的 YAML 配置中(安装 Node.js 和 npm install 以及构建)。如果您想了解特定步骤的更多信息,点击该步骤将显示该步骤的所有输出:
优化构建流程
我们尚未对默认的 Node.js 与 Angular 配置进行任何更改。在添加其他步骤之前,让我们先修改配置,将依赖项的安装和项目构建分开:移除全局安装@angular/cli,改用npx。
要编辑构建管道,请点击项目侧边栏中的“管道”,选择相应的构建管道,然后点击右上角的“编辑”按钮:
点击“编辑”后,Azure DevOps 将打开之前创建的 YAML 文件编辑器。请编辑该文件的内容,使其与以下 YAML 配置完全一致:
# Node.js with Angular
# Build a Node.js project that uses Angular.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Setup Environment'
- script: npm install
displayName: 'Install Dependencies'
- script: npx ng build --prod
displayName: 'Build'
保存配置后应该会触发新的构建。您应该会看到“安装依赖项”和“构建”这两个独立的步骤。
Azure DevOps 现在已集成,会ng build在每次提交到 master 分支时运行。除了构建项目之外,我们可能还需要运行所有单元测试,以确保所有代码仍然按预期运行。
在 Azure DevOps 上运行单元测试
在 Azure DevOps 上运行单元测试之前,我们需要对使用 Angular CLI 生成的项目进行一些更改。
由于管道执行所有自动化步骤的主机上没有安装 Chrome,我们需要添加 puppeteer 才能在 Azure DevOps 上使用 ChromeHeadless。
npm install puppeteer --save-dev
打开 karma.conf.js 文件,并在文件顶部添加以下内容:
const process = require('process');
process.env.CHROME_BIN = require('puppeteer').executablePath();
这将加载 puppeteer,并将其 executablePath 用于 CHROME_BIN 环境变量,从而允许 karma 在运行 Chrome 或 ChromeHeadless 时使用 puppeteer。
最后一步,更新 karma.conf.js 文件以使用ChromeHeadless浏览器。
{
//...
browsers: ['ChromeHeadless']
//...
}
更新 karma.conf.js 以使用 puppeteer 也会在您的本地计算机上使用 puppeteer。如果您不希望这样做,可以创建 karma.conf.js 文件的副本,将其命名为 karma.conf.ci.js(或您喜欢的任何名称),并
ng test --karmaConfig karma.conf.ci.js在管道中运行命令时将其传递给该命令(我们稍后会进行配置)。
提交并将这些更改推送到代码库。这将触发构建,但不会立即执行测试,因为我们需要先更新构建管道以运行测试。在 Azure DevOps 的配置中添加一个新步骤,该步骤可以位于构建步骤之前或之后。
- script: npx ng test --watch=false
displayName: 'Tests'
保存后,构建过程应该会触发并成功完成,其中包括测试步骤。点击测试步骤应该会显示与本地运行时相同的信息ng test。
尽管这为我们提供了有关测试的所有必要信息,但 Azure DevOps 具有显示测试报告的内置功能,使您能够更轻松地浏览成功/失败的测试。
将测试结果发布到 Azure DevOps
我们需要以 Azure DevOps 可以解析的格式发布测试结果。为了了解支持哪些格式,让我们转到构建管道,然后单击“编辑”。
在构建管道编辑界面的右侧,您应该会看到可用任务列表。找到名为“发布测试结果”的任务并选中它。
在任务详情界面,您会看到一个用于选择测试结果格式的下拉菜单。您可以使用任何可用的格式,只要您的测试运行器允许您以指定格式导出结果即可。由于 Karma 支持 JUnit,我们将使用 JUnit 格式。
添加完成后,yaml 配置中将包含一个用于发布测试结果任务的新部分:
- task: PublishTestResults@2
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/TEST-*.xml'
确保此部分是在正在运行的步骤之后添加的npx ng test,并进行以下更改,使其具有显示名称,并为其提供一个条件,以便即使测试失败也能发布测试结果(因为我们也希望能够检查失败的测试)。
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: 'JUnit'
# Make sure you've changed testResultsFiles to the one below
testResultsFiles: '**/TESTS-*.xml'
displayName: 'Publish Test Results'
由于我们尚未将 Angular 应用程序配置为以 JUnit 格式发布测试结果,因此保存上述更改后触发的构建将不会发布任何测试结果。
配置 Karma 发布 JUnit
通过运行以下命令,在 Angular 项目中安装适用于 JUnit 的报告器npm install karma-junit-reporter --save-dev。
更新 karma.conf.js,将karma-junit-reporter插件添加到其中,并将其添加junit为报告器之一。
module.exports = function (config) {
config.set({
...
plugins: [
...,
require('karma-junit-reporter')
],
...,
reporters: ['progress', 'kjhtml', 'junit'],
...
});
};
为了将单元测试完全集成到 Azure DevOps 中,我们只需要做这些更改。提交并推送您所做的更改到存储库即可。
这应该会触发一个新的构建,构建完成后,您应该会在构建详情的“测试”部分看到 3 个默认测试(您可能需要检查过滤器,默认情况下它只显示失败的测试)。
通过将测试与 Azure DevOps 集成,我们获得了一个结构化的用户界面来跟踪所有单元测试。每当测试失败时,我们无需在测试步骤中滚动浏览控制台输出。相反,我们可以查看所有测试,并筛选出我们需要的测试。
如果测试失败,我们甚至可以点击它来显示出错的详细信息,显示的信息与在控制台中看到的信息相同:
在构建管道中显示代码覆盖率
Azure DevOps 允许我们展示应用程序单元测试的代码覆盖率概览。为此,就像以特定格式发布测试结果一样,我们需要以受支持的格式发布代码覆盖率结果。目前,Azure DevOps 同时支持 Cobertura 和 JaCoCo。Angular CLI 使用的代码覆盖率工具 Istanbul 内置了对 Cobertura 的支持,因此我们无需添加任何依赖项即可使用 Cobertura。
我们需要更新 karma 配置,将 Cobertura 添加到 coverageIstanbulReporter 的报告中:
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/ng-azure-devops'),
reports: ['html', 'lcovonly', 'text-summary', 'cobertura'],
fixWebpackSourcePaths: true
},
这将在 ./coverage/ng-azure-devops 目录下生成一个名为 cobertura-coverage.xml 的文件。我们需要在构建管道中使用此路径。
提交并将这些更改推送到您的存储库(这将触发一个尚未发布代码覆盖率的构建),然后转到 Azure DevOps 上的构建管道配置并添加以下步骤:
- task: PublishCodeCoverageResults@1
condition: succeededOrFailed()
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(Build.SourcesDirectory)/coverage/ng-azure-devops/cobertura-coverage.xml'
displayName: 'Publish Code Coverage Results'
就像发布测试结果一样,我们也希望包含失败测试的代码覆盖率结果。这就是为什么我们要设置条件的原因succeededOrFailed()。我们还需要提供摘要文件(由 istanbul 创建)的位置,并确保它与 istanbul 生成的文件位置一致。
为了能够发布代码覆盖率结果,我们需要ng test使用该--code-coverage标志运行命令。请更新构建管道配置中的相应步骤,以包含该标志:
- script: npx ng test --watch=false --codeCoverage=true
displayName: 'Tests'
保存配置后,应该会运行一个构建过程,完成后,会在构建详情页面上显示“代码覆盖率”部分。
发布代码覆盖率结果后,系统会生成一份报告,并将其作为工件附加到您的构建中。如果您想查看该报告,可以打开右上角的“工件”菜单进行下载。通常,您可以在 Azure DevOps 的“代码覆盖率”选项卡中找到大部分相关信息。
添加绒毛
我们可以通过集成代码检查工具来确保当代码不符合编码规范时构建流程会失败。让我们添加一个步骤来运行代码检查工具npx ng lint,该步骤可以在构建步骤之前或之后运行。
- script: npx ng lint
displayName: 'Code Analysis'
这将添加与我们代码检查工具的基本集成。Azure DevOps 没有内置的代码质量跟踪机制。但是,它提供了一些任务,可以集成 SonarQube 等第三方工具(如果您需要集成的话)。
出版作品
现在我们有了自动验证源代码是否编译通过、所有单元测试是否成功运行以及代码是否符合编码规范的方法,我们可以发布输出结果,ng build以便我们可以手动或自动地使用它进行部署。
在构建管道配置的末尾添加以下步骤
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: 'dist/ng-azure-devops'
ArtifactName: 'web-app'
publishLocation: 'Container'
displayName: 'Publish Artifacts'
要发布工件,我们需要提供 PathtoPublish(即ng build命令的输出文件夹)、工件名称和 publishLocation。将 publishLocation 设置为“Container”意味着工件将作为 Azure Pipeline 的一部分发布。
保存更改,并等待构建完成。完成后,您可以从构建结果页面下载构建产物:
每次构建成功后,最新版本都会作为构建产物发布。这样,我们可以下载它,也可以使用自动化方式部署我们的应用程序。
结论
借助 Azure DevOps,我们可以轻松集成 Angular 应用程序,从而确保代码库始终处于良好状态。这可以降低发布 bug 的风险,带来更稳定的软件,让团队和最终用户都更加满意。
我们还以自动化的方式创建构建工件,从而减少部署应用程序所需的时间和复杂性。
在后续文章中,我们将设置发布管道以自动部署构建产物。
本文作者是This Dot 公司的软件工程师 Frederik Prijck 。
你可以在推特上关注他,账号是@frederikprijck。
需要 JavaScript 咨询、指导或培训方面的帮助吗?请查看This Dot Labs提供的服务列表。
文章来源:https://dev.to/thisdotmedia/continuously-integrating-angular-with-azure-devops-2k9l












