|
| 1 | +# How to use CircleCI multi-file config |
| 2 | + |
| 3 | +This README and the Makefile should be in your `.circleci` directory, |
| 4 | +in the root of your repository. |
| 5 | +All path references in this README assume we are in this `.circleci` directory. |
| 6 | + |
| 7 | +The `Makefile` in this directory generates `./config.yml` in CircleCI 2.0 syntax, |
| 8 | +from the tree rooted at `./config/`, which contains files in CircleCI 2.0 or 2.1 syntax. |
| 9 | + |
| 10 | + |
| 11 | +## Quickstart |
| 12 | + |
| 13 | +The basic workflow is: |
| 14 | + |
| 15 | +- Edit source files in `./config/` |
| 16 | +- When you are done, run `make ci-config` to update `./config.yml` |
| 17 | +- Commit this entire `.circleci` directory, including that generated file together. |
| 18 | +- Run `make ci-verify` to ensure the current `./config.yml` is up to date with the source. |
| 19 | + |
| 20 | +When merging this `.circleci` directory: |
| 21 | + |
| 22 | +- Do not merge the generated `./config.yml` file, instead: |
| 23 | +- Merge the source files under `./config/`, and then |
| 24 | +- Run `make ci-config` to re-generate the merged `./config.yml` |
| 25 | + |
| 26 | +And that's it, for more detail, read on! |
| 27 | + |
| 28 | + |
| 29 | +## How does it work, roughly? |
| 30 | + |
| 31 | +CircleCI supports [generating a single config file from many], |
| 32 | +using the `$ circleci config pack` command. |
| 33 | +It also supports [expanding 2.1 syntax to 2.0 syntax] |
| 34 | +using the `$ circleci config process` command. |
| 35 | +We use these two commands, stitched together using the `Makefile` |
| 36 | +to implement the workflow. |
| 37 | + |
| 38 | +[generating a single config file from many]: https://circleci.com/docs/2.0/local-cli/#packing-a-config |
| 39 | +[expanding 2.1 syntax to 2.0 syntax]: https://circleci.com/docs/2.0/local-cli/#processing-a-config |
| 40 | + |
| 41 | + |
| 42 | +## Prerequisites |
| 43 | + |
| 44 | +You will need the [CircleCI CLI tool] installed and working, |
| 45 | +at least version `0.1.5607`. |
| 46 | +You can [download this tool directly from GitHub Releases]. |
| 47 | + |
| 48 | +``` |
| 49 | +$ circleci version |
| 50 | +0.1.5607+f705856 |
| 51 | +``` |
| 52 | + |
| 53 | +[CircleCI CLI tool]: https://circleci.com/docs/2.0/local-cli/ |
| 54 | +[download this tool directly from GitHub Releases]: https://github.com/CircleCI-Public/circleci-cli/releases |
| 55 | + |
| 56 | + |
| 57 | +## Updating the config source |
| 58 | + |
| 59 | +Before making changes, be sure to understand the layout |
| 60 | +of the `./config/` file tree, as well as circleci 2.1 syntax. |
| 61 | +See the [Syntax and layout] section below. |
| 62 | + |
| 63 | +To update the config, you should edit, add or remove files |
| 64 | +in the `./config/` directory, |
| 65 | +and then run `make ci-config`. |
| 66 | +If that's successful, |
| 67 | +you should then commit every `*.yml` file in the tree rooted in this directory. |
| 68 | +That is: you should commit both the source under `./config/` |
| 69 | +and the generated file `./config.yml` at the same time, in the same commit. |
| 70 | +The included git pre-commit hook will help with this. |
| 71 | +Do not edit the `./config.yml` file directly, as you will lose your changes |
| 72 | +next time `make ci-config` is run. |
| 73 | + |
| 74 | +[Syntax and layout]: #syntax-and-layout |
| 75 | + |
| 76 | + |
| 77 | +### Verifying `./config.yml` |
| 78 | + |
| 79 | +To check whether or not the current `./config.yml` is up to date with the source |
| 80 | +and valid, run `$ make ci-verify`. |
| 81 | +Note that `$ make ci-verify` should be run in CI, |
| 82 | +in case not everyone has the git pre-commit hook set up correctly. |
| 83 | + |
| 84 | + |
| 85 | +#### Example shell session |
| 86 | + |
| 87 | +```sh |
| 88 | +$ make ci-config |
| 89 | +config.yml updated |
| 90 | +$ git add -A . # The -A makes sure to include deletions/renames etc. |
| 91 | +$ git commit -m "ci: blah blah blah" |
| 92 | +Changes detected in .circleci/, running 'make -C .circleci ci-verify' |
| 93 | +--> Generated config.yml is up to date! |
| 94 | +--> Config file at config.yml is valid. |
| 95 | +``` |
| 96 | + |
| 97 | + |
| 98 | +### Syntax and layout |
| 99 | + |
| 100 | +It is important to understand the layout of the config directory. |
| 101 | +Read the documentation on [packing a config] for a full understanding |
| 102 | +of how multiple YAML files are merged by the circleci CLI tool. |
| 103 | + |
| 104 | +[packing a config]: https://circleci.com/docs/2.0/local-cli/#packing-a-config |
| 105 | + |
| 106 | +Here is an example file tree (with comments added afterwards): |
| 107 | + |
| 108 | +```sh |
| 109 | +$ tree . |
| 110 | +. |
| 111 | +├── Makefile |
| 112 | +├── README.md # This file. |
| 113 | +├── config # The source code for config.yml is rooted here. |
| 114 | +│ ├── @config.yml # Files beginning with @ are treated specially by `circleci config pack` |
| 115 | +│ ├── commands # Subdirectories of config become top-level keys. |
| 116 | +│ │ └── go_test.yml # Filenames (minus .yml) become top-level keys under |
| 117 | +│ │ └── go_build.yml # their parent (in this case "commands"). |
| 118 | +│ │ # The contents of go_test.yml therefore are placed at: .commands.go_test: |
| 119 | +│ └── jobs # jobs also becomes a top-level key under config... |
| 120 | +│ ├── build.yml # ...and likewise filenames become keys under their parent. |
| 121 | +│ └── test.yml |
| 122 | +└── config.yml # The generated file in 2.0 syntax. |
| 123 | +``` |
| 124 | + |
| 125 | +About those `@` files... Preceding a filename with `@` |
| 126 | +indicates to `$ circleci config pack` that the contents of this YAML file |
| 127 | +should be at the top-level, rather than underneath a key named after their filename. |
| 128 | +This naming convention is unfortunate as it breaks autocompletion in bash, |
| 129 | +but there we go. |
| 130 | + |
0 commit comments