github.com/bilus/oya@v0.0.3-0.20190301162104-da4acbd394c6/README.md (about) 1 # This repository has moved to [github.com/tooploox/oya](https://github.com/tooploox/oya) 2 3 # Oya 4 5 ## Contributing 6 7 1. Install go 1.11 (goenv is recommended, example: `goenv install 1.11.4`). 8 2. Checkout oya outside GOHOME. 9 3. Install godog: `go get -u github.com/DATA-DOG/godog/cmd/godog`. 10 4. Run acceptance tests: `godog`. 11 5. Run tests: `go test ./...`. 12 6. Run Oya: `go run oya.go`. 13 14 15 16 # Documentation below is a draft and is likely incompatible with the current version. 17 18 19 ## Usage 20 21 1. Install oya and its dependencies: 22 23 curl https://raw.githubusercontent/bilus/oya/master/scripts/setup.sh | sh 24 25 1. Initialize project to use a certain CI/CD tool and workflow. Example: 26 27 oya init jenkins-monorepo 28 29 It boostraps configuration for Jenkins pipelines supporting the 1.a workflow 30 (see Workflows below), an Oyafile and supporting scripts and compatible 31 generators. 32 33 1. Define a task you can run: 34 35 mkdir app1 36 cat > Oyafile 37 build: echo "Hello, world" 38 39 1. Run the task: 40 41 oya run build 42 Hello, world 43 44 The task in the above example is called "build" but there's nothing special about the name. In fact, a task name is any camel case identifier as long as it starts with a lower-case letter. You can have as many different tasks as you like. 45 46 ## Plugins 47 48 oya vendor p github.com/bilus/oya/packs/circleci-helm-platform 49 50 installs into vendor/ 51 symlinks vendor/p to it 52 symlinks all in vendor/p/bin/ to oya/bin/p 53 54 cd delivery/broadcasts/Oyafile 55 oya p/generate/docker 56 57 delivery/broadcasts/Oyafile 58 59 Import: 60 - github.com/bilus/oya/packs/jenkins-monorepo 61 62 -- 63 64 Path: 65 jm: github.com/bilus/oya/packs/jenkins-monorepo/bin 66 67 buildDocker: 68 jm/buildDocker 69 70 buildChart: 71 jm/buildChart 72 73 74 ## How it works 75 76 A directory is included in the build process if contains an Oyafile regardless of how deeply nested it is. You can use Oyafiles in these directories to define their own tasks. 77 78 For example, to set up a CI/CD pipeline in a mono-repository containing several 79 microservices, you'd put each microservice in its directory, each with its own 80 Oyafile containing the tasks necessary to support the CI/CD workflow. 81 82 83 Imagine you have the following file structure: 84 85 ```yaml 86 # ./Oyafile 87 88 build: | 89 echo "Top-level directory" 90 ``` 91 92 ```yaml 93 # ./subdir/Oyafile 94 95 build: | 96 echo "Sub-directory" 97 ``` 98 99 When you run `oya run build`, Oya first walks the directory tree, starting from 100 the current directory, to build the **changeset**: the list of directories that 101 are marked as changed. In the above example it would be, as you probably 102 guessed, `.` (the top-level directory) and `subdir` (the sub-directory). 103 104 Finally, Oya executes the task you specified for every directory marked as 105 changed, starting from the top directory. Going back to our example, it would 106 generate the following output: 107 108 ``` 109 Top-level directory 110 Sub-directory 111 ``` 112 113 As you say, tasks and their corresponding scripts are defined in `Oyafile`s. 114 Their names must be camel-case yaml identifiers, starting with a lower-case 115 letter. Built-in tasks start with capital letters. 116 117 More realistic example of an `Oyafile`: 118 119 ``` 120 build: docker build . 121 test: pytest 122 ``` 123 124 ## Changesets 125 126 TODO 127 128 * `Changeset` -- (optional) modifies the current changeset (see Changesets). 129 130 Oya first walks all directories to build the changeset: a list of directories 131 containing an Oyafile that are marked as "changed". 132 133 It then walks the list, 134 running the matching task in each. CI/CD tool-specific script outputting list of 135 modified files in buildable directories given the current task name. 136 - each path must be normalized and prefixed with `+` 137 - cannot be overriden, only valid for top-level Oyafile 138 - in the future, you'll be able to override for a buildable directory and 139 use `-` to exclude directories, `+` to include additional ones, and use 140 wildcards, this will allow e.g. forcing running tests for all apps when 141 you change a shared directory 142 - git diff --name-only origin/master...$branch 143 - https://dzone.com/articles/build-test-and-deploy-apps-independently-from-a-mo 144 - https://stackoverflow.com/questions/6260383/how-to-get-list-of-changed-files-since-last-build-in-jenkins-hudson/9473207#9473207 145 146 Generation of the changeset is controlled by the optional changeset key in 147 Oyafiles, which can point to a script executed to generate the changeset: 148 149 1. No directive -- includes all directories containing on Oyafile. 150 2. Directive pointing to a script. 151 152 .oyaignore lists files whose changes do not trigger build for the containing 153 buildable directory 154 155 ## Features/ideas 156 157 1. Generators based on packs. https://github.com/Flaque/thaum + draft pack 158 plugin 159 160 ## Workflows 161 162 ### Repo structure 163 164 1. Mono-repo: 165 - Each app has its own directory 166 - There is a directory/file containing deployment configuration 167 168 2. Multi-repo: 169 - Each app has its own repo 170 - Deployment configurations in its own repo 171 172 3. Mix: 173 - Some/all apps share repos, some may have their own 174 - Deployment configurations in its own repo 175 176 > Also submodules tried for NT/Switchboard and eventually ditched. 177 178 ### Change control 179 180 a. Each environment has its own directory 181 182 b. Each environment has its own branch 183 184 ### Evaluation 185 186 | Workflow | Projects | Pros | Cons | 187 |----------|-------------|--------------------------------------------|---------------------------------------------------------| 188 | 1.a | E | "Can share code" | Merge order dependent [1] | 189 |----------|-------------|--------------------------------------------|---------------------------------------------------------| 190 | 1.b | C | Single checkout | Complex automation [2] | 191 |----------|-------------|--------------------------------------------|---------------------------------------------------------| 192 | 2.a | | Same as 2.b | Same as 2.b plus need to detect which directory changed | 193 |----------|-------------|--------------------------------------------|---------------------------------------------------------| 194 | 2.b | S | Better isolation [3] Simple automation [4] | More process overhead [5] | 195 |----------|-------------|--------------------------------------------|---------------------------------------------------------| 196 | 3.a | P | Can divide up a project however you like | Complex automation [2] | 197 |----------|-------------|--------------------------------------------|---------------------------------------------------------| 198 | 3.b | P | Simple deployment automation | Same as 3.a | 199 200 * [1] Code gets merged from branch to branch; works for small team. 201 * [2] Need to detect what changed between commits. Many CI/CD tools allow only 202 one configuration per repo and require coding around the limitations, example: 203 https://discuss.circleci.com/t/does-circleci-2-0-work-with-monorepos/10378/13 204 * [3] No way to just share code, need to package into libraries. Great for 205 microservices and must have for large teams. 206 * [4] Just put a CI/CD config into the root. 207 * [5] No way to just share code, need to package into libraries. Bad for small 208 teams wanting to quickly prototype. 209 210 211 -- 212 213 ## Adding CircleCI integration 214 215 1. Install Oya 216 217 ``` 218 curl https://raw.githubusercontent/bilus/oya/master/scripts/setup.sh | sh 219 ``` 220 221 2. Initialize project 222 223 ``` 224 oya init 225 oya +github.com/bilus/oya-packs/circleci 226 oya vendor 227 ``` 228 229 3. Push to git 230 231 ## Secrets 232 233 Secrets requires [Sops](https://github.com/mozilla/sops) to be installed. 234 235 ### PGP keys 236 237 $ gpg --list-keys 238 $ gpg --fingerprint 239 240 Generate/Export/Import 241 242 $ gpg --gen-key 243 $ gpg --export-secret-keys --armor {{fingerprint}} > private.rsa 244 $ gpg --import private.rsa 245 246 Remove 247 248 $ gpg --delete-keys {{fingerprint}} 249 $ gpg --delete-secret-keys {{fingerprint}} 250 251 ## Tests PGP keys 252 253 To have all tests passing successfull it's require to have our pgp key for secrets 254 255 $ gpg --import testutil/pgp/private.rsa