配置管道的计划

Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020

Azure Pipelines 提供了多种类型的触发器来配置管道的启动方式。

  • 计划触发器会根据计划(如夜间生成)启动管道。 本文提供有关使用计划触发器基于计划运行管道的指导。
  • 基于事件的触发器启动管道以响应事件,例如创建拉取请求或推送到分支。 有关使用基于事件的触发器的信息,请参阅 Azure Pipelines 中的触发器

可以在管道中合并计划触发器和基于事件的触发器,例如,每次进行推送(CI 触发器)、发出拉取请求时(PR 触发器)和夜间生成(计划触发器)时验证生成。 如果只想按计划生成管道,而不是响应基于事件的触发器,请确保管道未启用任何其他触发器。 例如,GitHub 存储库中的 YAML 管道默认启用 CI 触发器和 PR 触发器。 有关禁用默认触发器的信息,请参阅 Azure Pipelines 中的触发器 ,并导航到涵盖存储库类型的部分。

计划的触发器

重要

使用 YAML 管道设置 UI 定义的计划触发器优先于 YAML 计划触发器。

如果 YAML 管道同时具有 YAML 计划触发器和 UI 定义的计划触发器,则仅运行定义的计划触发器的 UI。 若要在 YAML 管道中运行 YAML 定义的计划触发器,必须删除 YAML 管道设置 UI 中定义的计划触发器。 删除所有 UI 计划触发器后,必须进行推送,以便 YAML 计划触发器开始评估。

若要从 YAML 管道中删除 UI 计划触发器,请参阅 UI 设置替代 YAML 计划触发器

计划触发器将管道配置为使用 cron 语法定义的计划运行。

schedules:
- cron: string # cron syntax defining a schedule
  displayName: string # friendly name given to a specific schedule
  branches:
    include: [ string ] # which branches the schedule applies to
    exclude: [ string ] # which branches to exclude from the schedule
  always: boolean # whether to always run the pipeline or only if there have been source code or pipeline settings changes since the last successful scheduled run. The default is false.
schedules:
- cron: string # cron syntax defining a schedule
  displayName: string # friendly name given to a specific schedule
  branches:
    include: [ string ] # which branches the schedule applies to
    exclude: [ string ] # which branches to exclude from the schedule
  always: boolean # whether to always run the pipeline or only if there have been source code or pipeline settings changes since the last successful scheduled run. The default is false.
  batch: boolean # Whether to run the pipeline if the previously scheduled run is in-progress; the default is false.
  # batch is available in Azure DevOps Server 2022.1 and higher

YAML 中的计划管道具有以下约束。

  • cron 计划的时区为 UTC。 可以从 GitHub Copilot 获取 AI 帮助来创建 cron 表达式
  • 如果指定exclude了没有子句的include子句branches,则等效于在*子句中指定include
  • 指定计划时,不能使用管道变量。
  • 如果在 YAML 文件中使用模板,则必须在主 YAML 文件中指定计划,而不是在模板文件中指定计划。
  • 如果禁用管道,则对其 YAML 文件的更新不会自动刷新计划触发器。

计划触发器的分支注意事项

发生以下事件时,会针对分支评估计划触发器。

  • 创建管道。
  • 管道的 YAML 文件是从推送更新的,或通过在管道编辑器中对其进行编辑来更新。
  • 管道的 YAML 文件路径已 更新,以引用其他 YAML 文件。 此更改只会更新默认分支,因此只会在默认分支的更新的 YAML 文件中选取计划。 如果任何其他分支随后合并默认分支,例如 git pull origin main,将为该分支评估新引用的 YAML 文件中的计划触发器。
  • 将创建一个新分支。

在分支中发生其中一个事件后,如果该分支与该分支中包含的 YAML 文件中包含的计划触发器的分支筛选器匹配,则添加该分支的任何计划运行。

重要

仅当分支与该 特定分支中 YAML 文件中的计划触发器的分支筛选器匹配时,才会添加分支的计划运行。

例如,使用以下计划创建管道,此版本的 YAML 文件将签入 main 分支。 此计划每天生成 main 分支。

# YAML file in the main branch
schedules:
- cron: '0 0 * * *'
  displayName: Daily midnight build
  branches:
    include:
    - main

接下来,基于名为 <a0/a0> 的新分支创建。 读取新分支中 YAML 文件中的计划触发器,并且由于分支不匹配 new-feature ,因此不会对计划生成进行更改,并且 new-feature 不会使用计划触发器生成分支。

如果 new-feature 已添加到 branches 列表中,并将此更改推送到 new-feature 分支,则会读取 YAML 文件,并且现在 new-feature 位于分支列表中,因此 new-feature 会为分支添加计划的生成。

# YAML file in the new-feature-branch
schedules:
- cron: '0 0 * * *'
  displayName: Daily midnight build
  branches:
    include:
    - main
    - new-feature

现在,请考虑创建基于分支release命名main的分支,然后将release它添加到分支中的 YAML 文件中main的分支筛选器,但不添加到新创建的release分支中。

# YAML file in the release branch
schedules:
- cron: '0 0 * * *'
  displayName: Daily midnight build
  branches:
    include:
    - main

# YAML file in the main branch with release added to the branches list
schedules:
- cron: '0 0 * * *'
  displayName: Daily midnight build
  branches:
    include:
    - main
    - release

由于 release 已添加到分支中的 main 分支筛选器,但 添加到分支中的 release 分支筛选器中, release 因此不会基于该计划生成分支。 release只有在将分支添加到发布分支的 YAML 文件中的分支筛选器时,计划生成才会添加到计划程序。

计划触发器的批处理注意事项

注释

batch 属性在 Azure DevOps Server 2022.1 及更高版本上可用。

batch 属性配置在先前计划的运行正在进行时是否运行管道。 如果是batchtrue,如果以前的管道运行仍在进行中,则由于计划,新的管道运行不会启动。 默认值为 false

batch 属性受属性设置 always 的影响。 如果 alwaystrue,则管道会根据 cron 计划运行,即使 batch 正在运行 true 且正在进行中运行也是如此。

始终 Batch 行为
false false 仅当上次成功的计划管道运行发生更改时,管道才会运行,即使上次计划的触发器正在进行中运行也是如此。
false true 仅当上次成功的计划管道运行发生更改且没有正在进行的计划管道运行时,管道才会运行。
true false 管道根据 cron 计划运行。
true true 即使有正在进行的运行,管道也根据 cron 计划运行。

Build.CronSchedule.DisplayName 变量

注释

Build.CronSchedule.DisplayName 变量在 Azure DevOps Server 2022.1 及更高版本上可用。

当管道由于 cron 计划触发器而运行时,预定义 Build.CronSchedule.DisplayName 的变量包含 displayName 触发管道运行的 cron 计划。

YAML 管道可能包含多个 cron 计划,你可能希望管道基于哪个 cron 计划运行不同的阶段或作业。 例如,你有一个夜间生成和每周生成,并且你想要仅在夜间生成期间运行特定阶段。 可以使用 Build.CronSchedule.DisplayName 作业或阶段条件中的变量来确定是运行该作业还是阶段。

- stage: stage1
  # Run this stage only when the pipeline is triggered by the 
  # "Daily midnight build" cron schedule
  condition: eq(variables['Build.CronSchedule.DisplayName'], 'Daily midnight build')

有关更多示例,请参阅 schedules.cron 示例

选择想要使用经典编辑器运行生成的日期和时间。

如果存储库是 Azure Repos Git、GitHub 或其他 Git,则还可以指定要包含和排除的分支。 如果要使用通配符,请键入分支规范(例如), features/modules/*然后按 Enter。

计划的触发器 UTC + 5:30 时区

例子

以下示例定义了两个计划:

schedules:
- cron: '0 0 * * *'
  displayName: Daily midnight build
  branches:
    include:
    - main
    - releases/*
    exclude:
    - releases/ancient/*
- cron: '0 12 * * 0'
  displayName: Weekly Sunday build
  branches:
    include:
    - releases/*
  always: true

第一个计划,每日午夜生成,每天午夜运行一个管道,但前提是代码自上次成功运行main以来已更改,以及除以下分支以外的releases/*所有releases/ancient/*分支。

第二个计划 ,每周星期天生成,在周日中午运行管道,无论代码自上次运行以来是否已更改,所有 releases/* 分支。

注释

cron 计划的时区为 UTC,因此在这些示例中,午夜生成和中午生成在 UTC 午夜和中午。

有关更多示例,请参阅 从经典编辑器迁移

示例:多个时区中的 Git 存储库的夜间生成

在此示例中,经典编辑器计划触发器有两个条目,它们生成以下版本。

  • 每个星期一 - 星期五上午 3:00 (UTC + 5:30 时区),生成符合分支筛选条件的 features/india/* 分支

    计划的触发器 UTC + 5:30 时区

  • 每个星期一 - 星期五上午 3:00 (UTC - 5:00 时区),生成符合分支筛选条件的 features/nc/* 分支

    计划的触发器 UTC -5:00 时区

示例:具有不同频率的夜间生成

在此示例中,经典编辑器计划触发器有两个条目,生成以下版本。

  • 每个星期一 - 星期五上午 3:00 UTC,生成满足和main分支筛选条件的releases/*分支

    计划的触发器频率 1、Azure Pipelines 和 Azure DevOps 2019 服务器。

  • 每天上午 3:00 UTC,生成 releases/lastversion 分支,即使源或管道未更改

    计划的触发器频率 2、Azure Pipelines 和 Azure DevOps 2019 服务器。

Cron 语法

每个 Azure Pipelines 计划触发器 cron 表达式都是一个空格分隔的表达式,其五个条目按以下顺序排列。 表达式用单引号 '引起来。

mm HH DD MM DW
 \  \  \  \  \__ Days of week
  \  \  \  \____ Months
   \  \  \______ Days
    \  \________ Hours
     \__________ Minutes
领域 接受的值
分钟 0 到 59
小时 0 到 23
天数 1 到 31
月份 1 到 12, 全英文名称, 前三个字母的英语名称
星期几 0 到 6 (从星期日开始), 全英语名称, 前三个字母的英语名称

值可以具有以下格式。

Format Example Description
通配符 * 匹配此字段的所有值
单个值 5 为此字段指定单个值
逗号分隔 3,5,6 为此字段指定多个值。 可以组合多种格式,例如 1,3-6
范围 1-3 此字段的值的非独占范围
时间间隔 */41-5/2 要与此字段匹配的间隔,例如第四个值或范围 1-5,步骤间隔为 2
Example Cron 表达式
每周一、星期三和星期五下午 6:00 生成 0 18 * * Mon,Wed,Fri0 18 * * 1,3,50 18 * * 1-5/2
每隔 6 小时生成一次 0 0,6,12,18 * * *0 */6 * * *0 0-18/6 * * *
从上午 9:00 开始每隔 6 小时生成一次 0 9,15,21 * * *0 9-21/6 * * *

有关支持的格式的详细信息,请参阅 Crontab 表达式

使用 GitHub Copilot 创建 cron 表达式

可以从 GitHub Copilot 获取 AI 帮助,以生成 cron 表达式,或将现有 cron 表达式从本地时区转换为 UTC。

Azure Pipelines cron 计划以 UTC 格式定义,因此必须使用 cron 语法创建 每个星期一、星期三和星期五 (如生成)的计划,并将其从本地时区转换为 UTC。

自定义以下提示以创建 cron 表达式,或从用于创建表达式的时区将 cron 表达式转换为 UTC。

在以下示例中,系统提示 Copilot 创建 UTC cron 计划,以在东部标准时间下午 6:00 生成每个星期一、星期三和星期五。

Build a UTC cron expression for Monday, Wednesday, and Friday at 6:00 PM Eastern Standard Time

如果本地时区中已有 cron 表达式,可以要求 Copilot 将其转换为 UTC。 在此示例中,每周一、星期三和星期五下午 6:00(0 18 * * Mon,Wed,Fri) 东部标准时间的 cron 计划将转换为 UTC。

Convert the following cron expression from Eastern Standard Time to UTC: 0 18 * * Mon,Wed,Fri

将 cron 表达式转换为 UTC 可能需要更改表达式中的星期几。 在以下示例中,Copilot 系统会提示创建 UTC cron 计划,以便于周一到周五上午 12:30 在中欧标准时间上午 12:30 生成。 中欧标准时间领先 UTC,因此生成的表达式在周日深夜而不是周一清晨开始,并在周四结束。

Build a UTC cron expression for Monday through Friday at 12:30 AM Central European Standard Time

若要获取有关 Copilot 生成的 cron 表达式的其他详细信息,可以要求 Copilot 在提示中提供生成的 cron 表达式的说明。

Build a UTC cron expression for Monday through Friday at 12:30 AM Central European Standard Time and explain the different parts of the cron expression

Copilot 由 AI 提供支持,因此可能会带来意外和错误。 有关详细信息,请参阅 Copilot 常规使用常见问题解答

计划运行视图

可以通过从管道的管道详细信息页上的上下文菜单中选择“计划运行”来查看即将推出的计划生成预览。

重要

计划运行视图仅显示计划从当前日期起七天内运行的管道。 如果 cron 计划间隔超过 7 天,并且下一次运行计划从当前日期起七天后开始,则不会显示在 “计划运行 ”视图中。

计划运行菜单

创建或更新计划的触发器后,可以使用 “计划运行 ”视图来验证它们。

计划运行

此示例显示以下计划的计划运行。

schedules:
- cron: '0 0 * * *'
  displayName: Daily midnight build
  branches:
    include:
    - main

计划运行窗口显示转换为计算机上用于浏览到 Azure DevOps 门户的本地时区的时间。 此示例显示在 EST 时区中拍摄的屏幕截图。

注释

如果更新正在运行的管道的计划,则在当前正在运行的管道完成之前, 计划运行 视图不会使用新计划进行更新。

可以通过从管道的管道详细信息页上的上下文菜单中选择“计划运行”来查看即将推出的计划生成预览。

计划运行菜单

创建或更新计划触发器后,可以使用此视图验证它们。

计划运行

即使没有代码更改,也运行

默认情况下,如果自上次成功计划的运行以来没有代码更改,则管道不会按计划运行方式运行。 例如,请考虑已计划每天晚上 9:00 运行管道。 在工作日中,将各种更改推送到代码。 管道按计划运行。 在周末,你不会对代码进行任何更改。 如果自上周五的计划运行以来没有代码更改,则管道不会按计划在周末运行。

若要强制管道运行,即使没有代码更改,也可以使用 always 关键字。

schedules:
- cron: ...
  ...
  always: true

若要仅当自上次生成以来发生更改时才将计划管道配置为生成, 请仅当源或管道发生更改时检查计划生成

计划的触发器 UTC + 5:30 时区

对 YAML 管道中计划的运行数的限制

可以计划管道运行的频率有一定限制。 这些限制已实施,以防止滥用 Azure Pipelines 资源,尤其是Microsoft托管的代理。 限制为:

  • 每个管道每周大约 1000 次运行
  • 每 15 分钟每个管道 10 次运行

从经典编辑器迁移

以下示例演示如何将计划从经典编辑器迁移到 YAML。

示例:多个时区中的 Git 存储库的夜间生成

在此示例中,经典编辑器计划触发器有两个条目,生成以下版本。

  • 每个星期一 - 星期五上午 3:00 (UTC + 5:30 时区),生成符合分支筛选条件的 features/india/* 分支

    计划的触发器 UTC + 5:30 时区

  • 每个星期一 - 星期五上午 3:00 (UTC - 5:00 时区),生成符合分支筛选条件的 features/nc/* 分支

    计划的触发器 UTC -5:00 时区

等效的 YAML 计划触发器为:

schedules:
- cron: '30 21 * * Sun-Thu'
  displayName: M-F 3:00 AM (UTC + 5:30) India daily build
  branches:
    include:
    - /features/india/*
- cron: '0 8 * * Mon-Fri'
  displayName: M-F 3:00 AM (UTC - 5) NC daily build
  branches:
    include:
    - /features/nc/*

在第一个时间表中, M-F 上午 3:00 (UTC + 5:30) 印度每日生成,cron 语法 (mm HH DD MM DW) 为 30 21 * * Sun-Thu

  • 分钟和小时 - 30 21 这映射到 21:30 UTC9:30 PM UTC)。 由于经典编辑器中的指定时区为 UTC + 5:30,因此我们需要从所需的生成时间 3:00 AM 减去 5 小时 30 分钟,才能到达指定 YAML 触发器所需的 UTC 时间。 可以从 GitHub Copilot 获取 AI 帮助来创建 cron 表达式
  • 天数和月份被指定为通配符,因为此计划不指定仅在月份的特定日期或特定月份运行。
  • 一周中的天数 - Sun-Thu 由于时区转换,我们的内部版本要在 UTC + 5:30 印度时区的凌晨 3:00 运行,因此我们需要指定在 UTC 时间前一天启动它们。 还可以将一周中的天数指定为 0-40,1,2,3,4

第二个计划 是 M-F 上午 3:00(UTC - 5) NC 每日生成,cron 语法为 0 8 * * Mon-Fri

  • 分钟和小时 - 0 8 这映射到 8:00 AM UTC。 由于经典编辑器中的指定时区为 UTC - 5:00,因此我们需要从所需的生成时间 3:00 AM 添加 5 小时,才能到达所需的 UTC 时间来指定 YAML 触发器。 可以从 GitHub Copilot 获取 AI 帮助来创建 cron 表达式
  • 天数和月份被指定为通配符,因为此计划不指定仅在月份的特定日期或特定月份运行。
  • 一周中的天数 - Mon-Fri 由于时区转换不会跨越一周中的多个天,因此我们不需要在此处进行任何转换。 还可以将一周中的天数指定为 1-51,2,3,4,5

重要

YAML 计划触发器中的 UTC 时区不考虑夏令时。

小窍门

当使用一周中的 3 个字母天,希望通过 Sun 跨越多个天时,太阳应该被视为一周的第一天,例如,对于周四到周日午夜的日程安排,cron 语法是 0 5 * * Sun,Thu-Sat

示例:具有不同频率的夜间生成

在此示例中,经典编辑器计划触发器有两个条目,生成以下版本。

  • 每个星期一 - 星期五上午 3:00 UTC,生成满足和main分支筛选条件的releases/*分支

    计划的触发器频率 1。

  • 每天上午 3:00 UTC,生成 releases/lastversion 分支,即使源或管道未更改

    计划的触发器频率 2。

等效的 YAML 计划触发器为:

schedules:
- cron: '0 3 * * Mon-Fri'
  displayName: M-F 3:00 AM (UTC) daily build
  branches:
    include:
    - main
    - /releases/*
- cron: '0 3 * * Sun'
  displayName: Sunday 3:00 AM (UTC) weekly latest version build
  branches:
    include:
    - /releases/lastversion
  always: true

在第一个计划 中,M-F 上午 3:00(UTC)每日生成,cron 语法为 0 3 * * Mon-Fri

  • 分钟和小时 - 0 3 这映射到 3:00 AM UTC。 由于经典编辑器中的指定时区为 UTC,因此无需执行任何时区转换。
  • 天数和月份被指定为通配符,因为此计划不指定仅在月份的特定日期或特定月份运行。
  • 一周中的天数 - Mon-Fri 由于没有时区转换,因此一周中的天数直接从经典编辑器计划映射。 还可以将一周中的天数指定为 1,2,3,4,5

第二个时间表是 星期天凌晨 3:00(UTC)每周最新版本生成,cron 语法为 0 3 * * Sun

  • 分钟和小时 - 0 3 这映射到 3:00 AM UTC。 由于经典编辑器中的指定时区为 UTC,因此无需执行任何时区转换。
  • 天数和月份被指定为通配符,因为此计划不指定仅在月份的特定日期或特定月份运行。
  • 一周中的天数 - Sun 由于时区转换不会跨越一周中的多个天,因此我们不需要在此处进行任何转换。 还可以将一周中的天数指定为 0
  • 我们还指定 always: true ,因为此生成计划运行源代码是否已更新。

FAQ

我希望我的管道仅在计划上运行,而不是有人将更改推送到分支时

如果希望管道仅在计划上运行,而不是有人将更改推送到分支或合并到主分支的更改时,则必须显式禁用管道上的默认 CI 和 PR 触发器。

若要禁用默认 CI 和 PR 触发器,请将以下语句添加到 YAML 管道,并 验证是否尚未使用 UI 触发器重写 YAML 管道触发器

trigger: none
pr: none

有关详细信息,请参阅 pr 定义触发器定义

我在 YAML 文件中定义了计划。 但它没有运行。 发生了什么事?

  • 检查 Azure Pipelines 已为管道安排的后续几次运行。 可以通过在管道中选择 “计划运行 ”作来查找这些运行。 该列表经过筛选,仅显示未来几天即将进行的几次运行。 如果这不符合预期,则可能是因为你键入了 cron 计划,或者没有正确分支中定义的计划。 阅读上面的主题,了解如何配置计划。 重新计算 cron 语法。 cron 计划的所有时间都采用 UTC 格式。

  • 对 YAML 文件进行一个小的更改,并将该更新推送到存储库中。 如果之前从 YAML 文件读取计划时出现问题,现在应修复此问题。

  • 如果在 UI 中定义了任何计划,则不遵循 YAML 计划。 通过导航到管道的编辑器并选择 “触发器”,确保没有任何 UI 计划。

  • 可以计划管道的运行数有限制。 详细了解 限制

  • 如果代码没有更改,则 Azure Pipelines 可能无法启动新的运行。 了解如何 重写 此行为。

我的 YAML 计划正常工作。 但是,他们现在停止工作。 如何调试此项?

  • 如果未指定 always:true,则除非对代码进行任何更新,否则不会计划管道。 检查是否存在任何代码更改以及 配置计划的方式。

  • 可以计划管道的次数 有限制 。 检查是否已超过这些限制。

  • 检查某人是否在 UI 中启用了更多计划。 打开管道的编辑器,然后选择 “触发器”。 如果在 UI 中定义了计划,则不会遵循 YAML 计划。

  • 检查管道是否已暂停或禁用。 选择管道 的设置

  • 检查 Azure Pipelines 已为管道安排的后续几次运行。 可以通过在管道中选择 “计划运行 ”作来查找这些运行。 如果未看到预期的计划,请对 YAML 文件进行一个小的更改,并将更新推送到存储库。 这应重新同步计划。

  • 如果使用 GitHub 来存储代码,则尝试启动新运行时,GitHub 可能会限制 Azure Pipelines。 检查是否可以手动启动新运行。

我的代码尚未更改,但会触发计划的生成。 为什么?

  • 你可能已启用一个选项来 始终 运行计划的生成,即使没有代码更改。 如果使用 YAML 文件,请验证 YAML 文件中计划语法。 如果使用经典管道,请验证是否在计划的触发器中选中了此选项。

  • 你可能已更新生成管道或管道的某些属性。 这将导致计划新的运行,即使尚未更新源代码也是如此。 使用经典编辑器验证管道中更改的 历史记录

  • 你可能已更新用于连接到存储库的服务连接。 这将导致计划新的运行,即使尚未更新源代码也是如此。

  • Azure Pipelines 首先检查代码是否有任何更新。 如果 Azure Pipelines 无法访问存储库或获取此信息,它将创建 信息运行。 这是一个虚拟生成,可让你知道 Azure Pipelines 无法访问存储库。

  • 管道可能无法完全成功生成。 为了确定是否计划新生成,Azure DevOps 查找最后一个完全成功的计划生成。 如果找不到,则会触发新的计划生成。 部分成功的计划生成不被视为成功,因此,如果管道只有部分成功的生成,即使代码未更改,Azure DevOps 也会触发计划生成。

我在“计划运行”面板中看到计划的运行。 但是,它当时不会运行。 为什么?

  • 计划运行 ”面板显示所有可能的计划。 但是,除非你对代码进行了真正的更新,否则它可能不会实际运行。 若要强制计划始终运行,请确保已在 YAML 管道中设置 always 属性,或选中选项以始终在经典管道中运行。

YAML 管道中定义的计划适用于一个分支,但不适用于另一个分支。 如何解决此问题?

计划在 YAML 文件中定义,这些文件与分支相关联。 如果希望为特定分支计划管道,例如 features/X,请确保 该分支中的 YAML 文件具有在其中定义的 cron 计划,并且它具有计划的正确分支包含。 分支中的 features/X YAML 文件应在此示例中具有以下内容 schedule

schedules: 
- cron: '0 12 * * 0'   # replace with your schedule
  branches: 
    include: 
    - features/X  

有关详细信息,请参阅 计划的触发器的分支注意事项