Skip to main content
Version: 5.9.x

Background

The Workflows configuration for CD is based on Aspect's approach to delivering artifacts from Bazel CI builds.

Before configuring this subsystem, read our Continuous Delivery Guide to understand how this approach models the steps.

Configuration

Which targets to deliver

By default, Workflows delivers all targets tagged with tags = ["deliverable"]. This tag can be added on each deliverable target, or macro might add this tag to all targets of that rule kind.

This behavior may be customized with a Bazel query expression that identifies deliverable targets. For example, to deliver all container_push targets:

.aspect/workflows/config.yaml
tasks:
- delivery:
rules:
- deliverable: 'kind("container_push_ rule", //...)'

Deliverable targets must be executable, as explained in the Continuous Delivery Guide.

Which changes to deliver

Any deliverable target that differs from a previous delivery step will be released, as described in the Continuous Delivery Guide.

To make it easy to diagnose issues, Workflows uploads the list of targets as a "delivery manifest" found in delivery.mf in the artifacts uploaded by the CI pipeline.

First-time delivery

When migrating to Aspect Workflows Delivery from some other pipeline, your artifact storage is already populated with results from the legacy pipeline.

If this is not the case, after setting up Continuous Delivery it may be useful to perform a one-time "deliver everything" to populate the artifact storage.

To do this, simply run the query from the Which targets to deliver step above to list all the deliverable targets. Then copy-paste that list into the delivery_targets in a break the glass manual delivery step.

This should cause all targets to be delivered without regard for whether they are "changed".

Which branch(es) to deliver

Workflows delivers by default when running on a "release branch", which it considers to be either "^main$" and "^master$".

This can be configured in the condition property within a rule by setting branches. This property also supports a tags attribute that applies the same delivery behaviour, but based on the git tag that triggered the build.

Note that the expression is always treated as a regular expression, and will be automatically wrapped with ^ and $ if not included.

For example:

.aspect/workflows/config.yaml
tasks:
- delivery:
rules:
- condition:
branches:
- '^main$'
- '^hotfix-.*$'

Multiple rules with different deliverable queries can also be supplied for more complex delivery conditions. Each rule can also be set to only deliver if the target has changed (as determined by the manifest), or to always deliver.

The example below shows two delivery rules.

  • First rule defines a deliverable of all container_push rules that will be delivered if they have changed on main and hotfix branches. This uses the default delivery condition of only_on_change: true which will only delivery targets that have changed within the rule.
  • Second rule defines a deliverable of a single target //services/bazel that will always be delivered regardless of whether the inputs to the target have changed. This is controlled by setting the only_on_change property to false. These targets will then only be delivered on a branch that starts with release/.
.aspect/workflows/config.yaml
tasks:
- delivery:
rules:
- deliverable: 'kind("container_push_ rule", //...)'
condition:
branches:
- '^main$'
- '^hotfix-.*$'
- deliverable:
- //services/bazel
condition:
only_on_change: false
branches:
- 'release/.*'

When to deliver

By default, delivery is manual. A Release Engineer will manually create the Delivery workflow step by logging into the CI system and triggering the workflow.

Set auto_deliver in the configuration to automatically run the delivery based on the delivery manifest:

.aspect/workflows/config.yaml
tasks:
- delivery:
auto_deliver: true

In this case, any green build on a release branch will trigger a Delivery workflow step.

Stamping

Workflows relies on the Bazel stamping setup in the workspace. When an artifact is built with --stamp (or some other Bazel flags that include it, such as --config=release), this should create release artifacts that satisfy the deployment system.

The version used is user-controlled. Read our blog article https://blog.aspect.dev/versioning-releases-from-a-monorepo for more about choices in how to version artifacts.

By default, Workflows runs the delivery with bazel run --stamp. To use different stamping flags, set the stamp_flags property in the configuration, like so:

.aspect/workflows/config.yaml
tasks:
- delivery:
stamp_flags: ['--config=release']

Break glass (deliver on red)

Rarely, the main branch is red and the BuildCop isn't able to quickly resolve it. During this time, a product team believes that the breakage is unrelated to their application and feels strong pressure to ship.

In this case, the release engineer can navigate to the CI webpage and trigger the delivery pipeline manually, providing special parameters:

  • delivery_commit: what commit to check out and deliver.
  • delivery_targets: override the affected targets, and deliver this comma-separated list of targets instead.

In the future we plan a more auditable option for this, where the release engineer can trigger the delivery with a GitHub comment on a commit.

Deployment

Deploying the artifacts is out-of-scope from Workflows. We assume the existence of some system that promotes releases from one environment to another, for example some clients use https://harness.io/.

API Doc

The exhaustive list of attributes for the delivery task are found at delivery.md.