持续集成
Deno 的内置工具使为您的项目设置持续集成 (CI) 管道变得容易。代码的测试、代码风格检查和格式化都可以通过相应的命令 deno test
、deno lint
和 deno fmt
完成。此外,您还可以使用管道中的 deno coverage
从测试结果生成代码覆盖率报告。
在本页中,我们将讨论
设置基本管道
本页将向您展示如何在 GitHub Actions 中为 Deno 项目设置基本管道。本页解释的概念在很大程度上也适用于其他 CI 提供商,例如 Azure Pipelines、CircleCI 或 GitLab。
构建 Deno 的管道通常从检出存储库和安装 Deno 开始
name: Build
on: push
jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: denoland/setup-deno@v1
with:
deno-version: v1.x # Run with latest stable Deno.
要扩展工作流程,只需添加您可能需要的任何 deno
子命令
# Check if the code is formatted according to Deno's default
# formatting conventions.
- run: deno fmt --check
# Scan the code for syntax errors and style issues. If
# you want to use a custom linter configuration you can add a configuration file with --config <myconfig>
- run: deno lint
# Run all test files in the repository and collect code coverage. The example
# runs with all permissions, but it is recommended to run with the minimal permissions your program needs (for example --allow-read).
- run: deno test --allow-all --coverage=cov/
# This generates a report from the collected coverage in `deno test --coverage`. It is
# stored as a .lcov file which integrates well with services such as Codecov, Coveralls and Travis CI.
- run: deno coverage --lcov cov/ > cov.lcov
跨平台工作流程
作为 Deno 模块维护者,您可能想知道您的代码是否在当今使用的所有主要操作系统上都能正常工作:Linux、MacOS 和 Windows。跨平台工作流程可以通过运行一组并行作业来实现,每个作业都在不同的操作系统上运行构建
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-22.04, macos-12, windows-2022 ]
steps:
- run: deno test --allow-all --coverage cov/
注意:GitHub Actions 在处理 Windows 风格的行尾 (CRLF) 方面存在已知 问题。这可能会在运行
windows
上运行作业的管道中运行deno fmt
时导致问题。为了防止这种情况,请在运行actions/checkout@v3
步骤之前将 Actions 运行器配置为使用 Linux 风格的行尾git config --system core.autocrlf false
git config --system core.eol lf
如果您正在使用实验性或不稳定的 Deno API,您可以包含一个运行 Deno 预览版的矩阵作业。这有助于尽早发现重大更改
jobs:
build:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.canary }} # Continue in case the canary run does not succeed
strategy:
matrix:
os: [ ubuntu-22.04, macos-12, windows-2022 ]
deno-version: [ v1.x ]
canary: [ false ]
include:
- deno-version: canary
os: ubuntu-22.04
canary: true
加速 Deno 管道
减少重复
在跨平台运行中,管道中的某些步骤不一定需要针对每个操作系统运行。例如,在 Linux、MacOS 和 Windows 上生成相同的测试覆盖率报告有点冗余。在这些情况下,您可以使用 GitHub Actions 的 `if` 条件关键字。以下示例展示了如何仅在 `ubuntu`(Linux)运行器上运行代码覆盖率生成和上传步骤
- name: Generate coverage report
if: matrix.os == 'ubuntu-22.04'
run: deno coverage --lcov cov > cov.lcov
- name: Upload coverage to Coveralls.io
if: matrix.os == 'ubuntu-22.04'
# Any code coverage service can be used, Coveralls.io is used here as an example.
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }} # Generated by GitHub.
path-to-lcov: cov.lcov
缓存依赖项
随着项目规模的增长,越来越多的依赖项会被包含进来。Deno 会在测试期间下载这些依赖项,如果工作流程每天运行多次,这可能会成为一个耗时的过程。一个常见的解决方案是缓存依赖项,这样就不需要重新下载它们。
Deno 将依赖项存储在本地缓存目录中。在管道中,可以通过设置 `DENO_DIR` 环境变量并将缓存步骤添加到工作流程中来保留工作流程之间的缓存
# Set DENO_DIR to an absolute or relative path on the runner.
env:
DENO_DIR: my_cache_directory
steps:
- name: Cache Deno dependencies
uses: actions/cache@v2
with:
path: ${{ env.DENO_DIR }}
key: my_cache_key
最初,当此工作流程运行时,缓存仍然为空,像 `deno test` 这样的命令仍然需要下载依赖项,但当作业成功时,`DENO_DIR` 的内容将被保存,任何后续运行都可以从缓存中恢复它们,而不是重新下载。
上述工作流程中仍然存在一个问题:目前缓存键的名称被硬编码为 `my_cache_key`,这将每次都恢复相同的缓存,即使一个或多个依赖项被更新。这会导致在管道中使用旧版本,即使您已经更新了一些依赖项。解决方案是每次需要更新缓存时生成一个不同的键,这可以通过使用锁定文件和使用 GitHub Actions 提供的 `hashFiles` 函数来实现
key: ${{ hashFiles('deno.lock') }}
为了使此工作正常进行,您还需要在 Deno 项目中有一个锁定文件,这将在 这里 详细讨论。现在,如果 `deno.lock` 的内容发生更改,将创建一个新的缓存并在随后的管道运行中使用。
为了演示,假设您有一个使用 `deno.land/std` 中的日志记录器的项目
import * as log from "https://deno.land/[email protected]/log/mod.ts";
为了增加此版本,您可以更新 `import` 语句,然后重新加载缓存并在本地更新锁定文件
deno cache --reload --lock=deno.lock --lock-write deps.ts
运行完此操作后,您应该会看到 lockfile 内容发生变化。当此操作被提交并通过管道运行时,您应该会看到 hashFiles
函数保存了一个新的缓存,并在随后的任何运行中使用它。
清除缓存
有时您可能会遇到损坏或格式错误的缓存,这可能由于各种原因发生。您可以从 GitHub Actions UI 中清除缓存,或者您只需更改缓存键的名称。一种无需强制更改 lockfile 即可实现此目的的实用方法是向缓存键名称添加一个变量,该变量可以存储为 GitHub 密钥,并在需要新缓存时更改。
key: ${{ secrets.CACHE_VERSION }}-${{ hashFiles('deno.lock') }}