Skip to main content

Running Action Sets on a Schedule

While Expeditor is built on the ethos of reacting to external events such as the merging of pull requests, it also acknowledges that which is the most pervasive of events: the passage of time.

With the schedules configuration and the schedule_triggered, you can configure your project to execute an action set on a schedule. This pattern is very useful for running routine maintenance tasks via bash actions or Buildkite pipelines.

In this example, we're going to walk through how to set up a schedule that will trigger a Buildkite pipeline every night at 1am UTC. This pattern is useful for running tests that indicate project health but that you don't want to run on every pull request. For the purposes of this example, we're going to assume you've already set up and tested your Buildkite pipeline. A walk-through on how to do that is available here.

There are two steps required for this pattern, all of which can be accomplished in a single pull request.

  1. Configuring the schedule
  2. Setting up the subscription

Configuring the schedule

schedules is a top-level configuration value that contains a array of one or more schedule hashes. Each schedule hash requires three pieces of configuration: a name, a description, and a cronline. The name will be used as part of the workload in your subscription, while the description is used primarily for documentation purposes. The cronline uses the Fugit format (in UTC).

.expeditor/config.yml
pipelines:
  - nightly

schedules:
  - name: nightly_tests
    description: Run long-running tests every night
    cronline: "0 1 * * *"

These schedules are managed using a scheduler internal to Expeditor. On the configured schedule, the Expeditor agent publishes a schedule_triggered workload to which you can subscribe.

Setting up the subscription

Once you have your schedule you can set up your subscription. In your subscriptions block you're going to want to subscribe to the schedule_triggered workload. Your action set will include any number of actions that support the schedule_triggered workload, but by in large you'll be using them to execute bash or trigger_pipeline actions.

.expeditor/config.yml
subscriptions:
  - workload: schedule_triggered:{{agent_id}}:nightly_tests:*
    actions:
      - trigger_pipeline:nightly

Everything all together

Now that we've gone through the configuration and the subscription, let's take a look at what our sample .expeditor/config.yml file might look like.

.expeditor/config.yml
---
pipelines:
  - nightly

schedules:
  - name: nightly_tests
    description: Run long-running tests every night
    cronline: "0 1 * * *"

subscriptions:
  - workload: schedule_triggered:{{agent_id}}:nightly_tests:*
    actions:
      - trigger_pipeline:nightly

This is a pretty straight forward usage, but what happens if you want to run multiple pipelines every night? Maybe you have a pipeline dedicated to tests, but you also want to run a bash script at the same time you trigger your nightly tests. For that, all you need to do is add the bash action to your action set.

.expeditor/config.yml
---
pipelines:
  - nightly

schedules:
  - name: nightly_tests
    description: Run long-running tests every night
    cronline: "0 1 * * *"

subscriptions:
  - workload: schedule_triggered:{{agent_id}}:nightly_tests:*
    actions:
      - trigger_pipeline:nightly
      - bash:.expeditor/your_script.sh

And that's it! If you'd like to see an example of this pattern in action, check out the nightly_tests schedule in chef/automate.