文档生产部署

CI/CD 实战

用 setup-deno、deno ci 与分层门禁构建可复现的 Deno CI,并把产物发布到静态托管或 Deno Deploy

前提:仓库已提交 deno.jsondeno.lock,本地门禁已通过。本页只讲流水线编排;门禁本身与安全基线见生产工程基线

安装与固定 Deno

GitHub Actions 使用官方 action,并固定 major 版本:

- uses: denoland/setup-deno@v2
  with:
    deno-version: v2.x
  • deno-version 接受 v2.xv2.1.x、精确版本或 lts;追求严格可复现时固定到精确版本,并把升级作为独立变更评审。
  • 也可用 deno-version-file.tool-versions 等文件读取,保证 CI 与本地一致。

缓存依赖

setup-deno 内置缓存,无需手写 actions/cache

- uses: denoland/setup-deno@v2
  with:
    deno-version: v2.x
    cache: true

cache: true 缓存 Deno 下载的依赖(即 DENO_DIR 内容),缓存键由 job id、runner OS/arch 和 deno.lock 哈希组成;需要自定义哈希时用 cache-hash(设置它即隐含开启缓存)。若 workflow 自行设置了 DENO_DIR 环境变量,保证 action 与后续步骤使用同一目录。

安装依赖:deno ci

deno ci

deno ci(Deno 2.8+)是 CI 与 Dockerfile 的可复现安装命令:deno.lock 缺失时报错,删除已有 node_modules,并以 frozen 语义安装——lockfile 必须与配置文件精确匹配,任何漂移都会失败而不是静默更新。构建生产产物时加 --prod 跳过 devDependencies;要连 @types/* 一起排除需另加 --skip-types——它按包名启发式判断,可能误跳过附带运行时代码的包,用前核对产物是否仍完整。

门禁顺序

按"廉价且快失败在前"排序:

deno ci
deno fmt --check
deno lint
deno check "**/*.ts" "**/*.tsx"
deno test

格式与 lint 秒级完成,先拦住机械性问题;类型检查再拦住接口错误;测试最贵,放最后。不要把门禁合并成一条命令,分开才能在 CI 日志里一眼定位失败层级。glob 要加引号交给 Deno 展开(裸 **/*.ts 由 shell 展开,各 runner 行为不一,而且漏掉 .tsx);Fresh 等有自带 check task 的项目直接跑 deno task check

跨 OS/arch 矩阵

库与 CLI 至少跑三个系统:

strategy:
  matrix:
    os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}

Windows 注意 CRLF:在 checkout 前设置 git config --system core.autocrlf false,避免 deno fmt --check 因换行符误报。可用 continue-on-error 加一个 canary Deno 版本任务,提前发现上游变更,但不阻塞合并。覆盖率报告等只需一次的步骤用 if: matrix.os == 'ubuntu-latest' 限定。

构建与发布产物

  • 静态站点:deno task build 生成产物目录,用 actions/upload-artifact 传递或直接交给部署步骤。
  • 单文件二进制:deno compile --target <target> 交叉编译各平台产物,随 release 上传。编译参数以当前 deno help compile 为准。
  • 发布 JSR 包:不要在每个 push 上发布。按 tag 触发,用 OIDC 发布以获得 provenance,完整配置见发布 JSR 包

部署到 Deno Deploy

两条路径,按团队习惯选一条:

  1. 内置 GitHub 集成(默认路径):在 Deno Deploy 控制台把 app 关联到 GitHub 仓库,推送即触发构建,不需要自己维护部署 YAML。
  2. 外部 CI 部署:需要自定义流水线(例如先跑完整矩阵再发布)时,用 deno deploy CLI:
deno deploy --org <org> --app <app> --prod

CLI 在 CI 中的认证方式是组织 token:创建 organization token,存入 GitHub 仓库 secret,通过 DENO_DEPLOY_TOKEN 环境变量传入。注意 Deno Deploy 文档中的 OIDC 页面讲的是运行中的应用向第三方服务(AWS、Vault 等)认证,不是 CLI 部署的认证方式——不要把两者混淆。Deploy Classic 已被官方宣布于 2026-07-20 停用,不要在新项目中使用 deployctl。

完整示例

name: ci
on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    # Windows runner 上先关掉 CRLF 转换,否则 fmt --check 会误报
    steps:
      - run: |
          git config --system core.autocrlf false
          git config --system core.eol lf
      - uses: actions/checkout@v7
      - uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x
          cache: true
      - run: deno ci
      - run: deno fmt --check
      - run: deno lint
      - run: deno check "**/*.ts" "**/*.tsx"
      - run: deno test

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v7
      - uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x
      - run: deno ci --prod
      - run: deno task build # 需要构建步骤的项目
      - run: deno deploy --org my-org --app my-app --prod
        env:
          DENO_DEPLOY_TOKEN: ${{ secrets.DENO_DEPLOY_TOKEN }}

要点:environment: production 配合 GitHub 环境保护规则做人工审批;token 只授予目标组织;deploy job 与测试矩阵使用同一 Deno major 版本。

官方参考:Continuous integrationsetup-denoDeno 2.8 发布说明(deno ci)deno deploy CLI 参考Deno Deploy changelog

输入关键词搜索全部文档。