Home

Awesome

Delivery CLI

A command line tool for continuous delivery workflow. The delivery command is a component of Chef Delivery. It can be used to setup and execute phase jobs as well as interact with a Chef Delivery server.

It is a part of the ChefDK and can be downloaded here.

Getting Started With Delivery

In particular, you will want to be familar with:

Development

To get started make sure you have the following installed:

Main technologies used in this project:

We use make to perform various development operations like building and testing. The commands reside in the Makefile, but the Makefile is only used for development. It is not used by omnibus or our delivery cookbooks.

Make targets:

After you make the project, you can execute your compiled binary by running target/debug/delivery <delivery_args>. So, you could run something like

$ target/debug/delivery review

to test the review command with your code in it.

If, for whatever reason, you want to compile and test with cargo's --release flag, run make release, and use target/release/delivery, but it will take longer to compile.

Tips

Cucumber Testing

We heavily rely on git in the project. Some of the cucumber tests mock out parts of git. Those mocks exist in features/support/fakebin/git.

To mock a git call in your cucumber test, set <NAME_OF_GIT_COMMAND>_MOCKED to true in your cucumber test. For example, features/job.feature mocks several git commands with:

  Given I set the environment variables to:
    | variable             | value      |
    | CHECKOUT_MOCKED      | true       |
    | MERGE_MOCKED         | true       |
    | CLEAN_MOCKED         | true       |
    | RESET_MOCKED         | true       |

You can also mock all of git by setting MOCK_ALL_BASH to true:

  Given I set the environment variables to:
    | variable           | value      |
    | MOCK_ALL_BASH      | true       |

NOTE THAT A FEW COMMANDS ARE MOCKED BY DEFAULT STILL! We want to change this eventually. They are:

These commands will never actuall execute until their mocks are refactored out of features/support/fakebin/.

Updating Rust Version

When a new version of Rust comes out and it is on homebrew, it's time to update the Rust version in this repo. There are a few spots to update:

  1. At the very top of the Makefile, change RUST_VERSION
  2. omnibus-software's rust definitions default version (or override appropriately)

You should also run make release to bump the Cargo.lock file to get new versions of our dependencies.

Delivery Job Implementation Details

The delivery job subcommand is used to execute phase recipes for a project in a workspace. The Delivery server uses delivery job to execute the phases of each stage in the pipeline. The same command can be used locally to execute a phase job in the same way. You can also wire delivery job into your own pipeline orchestration if you are not using the Delivery server.

Jobs are run by specifying the stage and the phase. For example, the following command will run the unit phase of the verify stage:

delivery job verify unit --local

The delivery job subcommand will execute the phase recipe by carrying out the following steps:

  1. Currently, the job command assumes the current branch is a feature branch with commits that are not on the target branch.

  2. Clone the project repository to a workspace. The location can be customized using --job-root.

  3. Merge the feature branch into the target branch. This merge will not be pushed anywhere and is often referred to as "the hypothetical merge"; it is the merge that would result if this change were to be approved at this time.

  4. Fetch the build cookbook for the project. The build cookbook location is specified in the project's .delivery/config.json file.

  5. Use berks to fetch dependencies of the build cookbook (as specified in the build cookbook's Berksfile).

  6. Run chef-client in local mode with a run list consisting of only the default recipe of the build cookbook. The default recipe is intended for preparing a given node to be a "build node" for the project. Typical setup handled in the default recipe might include installing compilers, test frameworks, and other build and test dependencies. The default recipe is skipped when delivery job is invoked by a non-root and when the --skip-default option is specified.

  7. Run chef-client in local mode with a run list consisting of only the specified phase recipe (e.g. unit).

Without the --local option, the command will look for configuration required when interacting with a Delivery server from either .delivery/cli.toml or additional command line options.

For local use, you can run multiple phases within a single run like so:

delivery job verify "lint syntax unit"

Node Attributes

Attributes specific to the project and change are made available for use in build cookbook recipes.

The global workspace path is accesssible at node['delivery']['workspace_path']

Workspace Details

Attributes in the node['delivery']['workspace'] namespace provide paths to the various directories in your change's workspace on your build node.

Change Details

Attributes in the node['delivery']['change'] namespace provide details about this particular job execution.

Project Configuration Details

The contents of your .delivery/config.json file are made available to you in the node['delivery']['config'] namespace.

Note for Git Bash + MinTTY Users

If you're running delivery token on Windows in Git Bash with MinTTY you must include winpty before delivery token to avoid errors.

Contributing

For information on contributing to this project see https://github.com/chef/chef/blob/master/CONTRIBUTING.md

License & Authors

Copyright:: 2015 Chef Software, Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.