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:
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:
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 onmain
andhotfix
branches. This uses the default delivery condition ofonly_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 theonly_on_change
property tofalse
. These targets will then only be delivered on a branch that starts withrelease/
.
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:
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.build/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:
tasks:
- delivery:
stamp_flags:
- --stamp
- --workspace_status_command="${PWD}/workspace_status.sh"
or with a .bazelrc
config flag such as:
tasks:
- delivery:
stamp_flags:
- --config=release
where your .bazelrc
contains:
build:release --stamp
build:release --workspace_status_command="${PWD}/workspace_status.sh"
Manual Delivery
Examples of when to use manual delivery:
- The
main
branch is red and a product team believes that the breakage is unrelated to their application and feels strong pressure to ship. - Shipping an application using a manual cadence.
To facilitate these cases and others, 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 space-separated list of targets instead.workspace
: The workspace that thedelivery_targets
live within.
Each CI system has a slightly different process to access manual delivery:
- Buildkite
- CircleCI
- GitHubActions
From a branch that has an associated delivery rule, create a "New Build" and put "Deliver" or "Delivery" in the message field.
From your branch, select "Trigger Pipeline" and manually "Add Parameters" for each parameter listed above (as `string` parameter). Additionally, add a `boolean` parameter of `perform_delivery: true`.
As part of Workflows, there will be a delivery workflow named "delivery", "aspect-workflows-delivery" or similar which can be triggered manually with the above parameters provided.
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.