github.com/chenbh/concourse/v6@v6.4.2/CONTRIBUTING.md (about) 1 # Contributing to Concourse 2 3 It takes a lot of work from a lot of people to build a great CI system. We 4 really appreciate any and all contributions we receive, and are dedicated to 5 helping out anyone that wants to be a part of Concourse's development. 6 7 This doc will go over the basics of developing Concourse and testing your 8 changes. 9 10 If you run into any trouble, feel free to hang out and ask for help in in 11 [Discord][discord]! We'll grant you the `@contributors` role on request (just 12 ask in `#introductions`), which will allow you to chat in the `#contributors` 13 channel where you can ask for help or get feedback on something you're working 14 on. 15 16 17 ## From ideas to implementation 18 19 The Concourse project uses Issues for project backlog and bug reports, 20 Discussions for support and ideation, and Pull Requests for accepting 21 contributions. 22 23 Bugs can be reported directly as [Issues on the `concourse` 24 repo][concourse-issues], and questions and technical support can be requested as 25 [Discussions on the `concourse` repo][concourse-discussions]. 26 27 The project backlog is maintained by the Concourse team at VMware. Instead of 28 requesting features, we strongly encourage the use of [Discussions on the `rfcs` 29 repo][rfcs-discussions] for incubating ideas, with a primary focus on forming a 30 shared understanding the problem at hand; the context is more important than the 31 solution itself. 32 33 Our collective responsibility as the stewards of the Concourse product is to 34 uphold its promise of being "automation that scales with your project." This 35 promise is upheld by keeping the mental overhead small as the automation needs 36 of your project expand. Thus, requests for core features fall under heavy 37 scrutiny. Rather than addressing each individual request, we need to think of 38 the product holistically, steering it carefully and refining or replacing 39 existing concepts rather than introducing new ones all the time. 40 41 While this may feel overkill for requests which seem small in scope, connections 42 can often be made between features which seem unrelated at the surface. Once 43 those connections are identified, a higher impact change can often be planned 44 which satisfies many underlying needs at once while minimizing the amount of 45 "stuff" that users need to internalize in order to be effective with Concourse. 46 47 Once consensus is reached on a direction to take, a proposal can be submitted as 48 a [Pull Request to the `rfcs` repo][rfcs-prs], following the [RFC 49 process][rfcs-process], allowing the contributors to collaborate through PR 50 review. A full blown RFC may not be necessary for smaller changes, but going 51 through this process can reduce painful feedback cycles for larger code changes. 52 53 [Pull Requests to the `concourse` repo][concourse-prs] may be submitted at any 54 time. The rest of this document provides guidance on how to do just that. In the 55 end, we are really grateful for any contribution made to the project - whether 56 that's just chiming in on a discussion, helping others out in the community, or 57 indeed submitting a code change. Cheers! 🍻 58 59 [concourse-issues]: https://github.com/concourse/concourse/issues 60 [concourse-prs]: https://github.com/concourse/concourse/pulls 61 [concourse-discussions]: https://github.com/concourse/concourse/discussions 62 [rfcs-prs]: https://github.com/concourse/rfcs/pulls 63 [rfcs-discussions]: https://github.com/concourse/rfcs/discussions 64 [rfcs-process]: https://github.com/concourse/rfcs/blob/master/README.md 65 66 67 ## Contribution process 68 69 * [Fork this repo][how-to-fork] into your GitHub account. 70 71 * Install the [development dependencies](#development-dependencies) and follow 72 the instructions below for [running](#running-concourse) and 73 [developing](#developing-concourse) Concourse. 74 75 * Commit your changes and push them to a branch on your fork. 76 77 * Don't forget to write tests; pull requests without tests are unlikely to be 78 merged. For instruction on writing and running the various test suites, see 79 [Testing your changes](#testing-your-changes). 80 81 * All commits must have a signature certifying agreement to the [DCO][dco]. 82 For more information, see [Signing your work](#signing-your-work). 83 84 * Write release notes by adding onto the `latest.md` file in the 85 `release-notes/` directory! For formatting and style examples, 86 see previous release notes in the same directory. 87 88 * Run [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) 89 to ensure your code follows our code style guidelines. 90 91 * *Optional: check out our [Go style guide][style-guide]!* 92 93 * Putting this all together, here is a sample anatomy of an ideal commit: 94 95 ``` 96 i ii iii 97 | | | 98 web: structure: add var declarations 99 100 Since scripts are run in module mode, they follow the "strict mode" 101 semantics. Variables must be declared prior to being assigned (e.g. - iv 102 cannot have `x = 1` without declaring x (using var, let, or const) 103 104 concourse/concourse#5131 -------------------------------------------- v 105 106 Signed-off-by: Aidan Oldershaw <aoldershaw@pivotal.io> -------------- vi 107 ``` 108 109 1. [component changed](#developing-concourse) 110 1. [structure vs behaviour](#structure-and-behaviour) 111 1. brief, imperative-tense description of the change 112 1. a message that [tells a story][fav-commit] 113 1. mention the issue this change contributes to solving 114 1. [sign-off line](#signing-your-work) 115 116 * When you're ready, [submit a pull request][how-to-pr]! 117 118 * You will be invited to join `Contributors` team under `Concourse` org on 119 Github. Upon accepting the invite you will be able to login to our CI and 120 manage the build of your pull request in 121 [PRs pipeline](https://ci.concourse-ci.org/teams/contributor/pipelines/prs). 122 123 ### Structure and Behaviour 124 125 In an ideal world, every pull request is small, but the codebase is large and 126 sometimes complex changes cannot be avoided. To ease PR reviews, there are a few 127 practices we've found helpful: 128 129 * Focus your commits so that they only change a single component at a time. 130 * Isolate [structure changes from behaviour changes][sb-changes] and label the 131 commits appropriately - even better, batch commits of the same type into 132 contiguous blocks. 133 * Give clear prose justifications for your changes in the commit messages - it's 134 not unusual that you do some digging to uncover the motivation for a change, 135 but if you don't mention it in the commit message the diff can feel pretty 136 opaque. 137 138 ## Development dependencies 139 140 You'll need a few things installed in order to build, test and run Concourse during 141 development: 142 143 * [`go`](https://golang.org/dl/) v1.13+ 144 * [`git`](https://git-scm.com/) v2.11+ 145 * [`yarn`](https://yarnpkg.com/en/docs/install) 146 * [`docker-compose`](https://docs.docker.com/compose/install/) 147 * [`postgresql`](https://www.postgresql.org/download/) 148 149 > *Concourse uses Go 1.11's module system, so make sure it's **not** cloned 150 > under your `$GOPATH`.* 151 152 153 ## Running Concourse 154 155 To build and run Concourse from source, run the following in the root of this 156 repo: 157 158 ```sh 159 $ yarn install 160 $ yarn build 161 $ docker-compose up 162 ``` 163 164 Concourse will be running at [localhost:8080](http://localhost:8080). 165 166 ### Building `fly` and targeting your local Concourse 167 168 To build and install the `fly` CLI from source, run: 169 170 ```sh 171 $ go install ./fly 172 ``` 173 174 This will install a `fly` executable to your `$GOPATH/bin`, so make sure that's 175 on your `$PATH`! 176 177 Once `fly` is built, you can get a test pipeline running like this: 178 179 **Log in to the locally-running Concourse instance targeted as `dev`:** 180 ```sh 181 $ fly -t dev login -c http://localhost:8080 -u test -p test 182 ``` 183 184 **Create an example pipeline that runs a hello world job every minute:** 185 [concourse/examples](https://github.com/concourse/examples) provides a collection 186 of example Concourse pipelines. Use its `time-triggered.yml` pipeline to create a 187 hello world job: 188 189 ```sh 190 $ git clone git@github.com:concourse/examples.git 191 $ fly -t dev set-pipeline -p example -c examples/time-triggered.yml 192 ``` 193 194 **Unpause the example pipeline:** 195 ```sh 196 $ fly -t dev unpause-pipeline -p example 197 ``` 198 199 200 ## Developing Concourse 201 202 Concourse's source code is structured as a monorepo containing Go source code 203 for the server components and Elm/Less source code for the web UI. 204 205 Currently, the top-level folders are ~~confusingly~~ cleverly named, because 206 they were originally separate components living in their own Git repos with 207 silly air-traffic-themed names. 208 209 | directory | description | 210 | :-------------- | :----------- | 211 | `/atc` | The "brain" of Concourse: pipeline scheduling, build tracking, resource checking, and web UI/API server. One half of `concourse web`. | 212 | `/fly` | The [`fly` CLI](https://concourse-ci.org/fly.html). | 213 | `/testflight` | The acceptance test suite, exercising pipeline and `fly` features. Runs against a single Concourse deployment. | 214 | `/web` | The Elm source code and other assets for the web UI, which gets built and then embedded into the `concourse` executable and served by the ATC's web server. | 215 | `/go-concourse` | A Go client libary for using the ATC API, used internally by `fly`. | 216 | `/skymarshal` | Adapts [Dex](https://github.com/dexidp/dex) into an embeddable auth component for the ATC, plus the auth flag specifications for `fly` and `concourse web`. | 217 | `/tsa` | A custom-built SSH server responsible for securely authenticating and registering workers. The other half of `concourse web`. | 218 | `/worker` | The `concourse worker` library code for registering with the TSA, periodically reaping containers/volumes, etc. | 219 | `/cmd` | This is mainly glue code to wire the ATC, TSA, [BaggageClaim](https://github.com/concourse/baggageclaim), and Garden into the single `concourse` CLI. | 220 | `/topgun` | Another acceptance suite which covers operator-level features and technical aspects of the Concourse runtime. Deploys its own Concourse clusters, runs tests against them, and tears them down. | 221 222 ### Rebuilding to test your changes 223 224 After making any changes, you can try them out by rebuilding and recreating the 225 `web` and `worker` containers: 226 227 ```sh 228 $ docker-compose up --build -d 229 ``` 230 231 This can be run in a separate terminal while the original `docker-compose up` 232 command is still running. 233 234 In certain cases, when a change is done to the underlying development image (e.g. Go upgrade from 1.11 to 1.12), you 235 will need to pull the latest version of `concourse/dev` image, so that `web` and `worker` containers can be built locally 236 using the fresh image: 237 ```sh 238 $ docker pull concourse/dev 239 $ docker-compose up --build -d 240 ``` 241 242 If you're working on a dependency that doesn't live under this repository (for instance, 243 `baggageclaim`), you'll need to update `go.mod` with a `replace` directive with the exact 244 reference that the module lives at: 245 246 ```sh 247 # after pushing to the `sample` branch in your baggageclaim fork, 248 # try to fetch the module revision and get the version. 249 $ go mod download -json github.com/your-user/baggageclaim@sample | jq '.Version' 250 go: finding github.com/cirocosta/baggageclaim sample 251 "v1.3.6-0.20190315100745-09d349f19891" 252 253 # with that version, update `go.mod` including a replace directive 254 $ echo 'replace github.com/concourse/baggageclaim => github.com/your-user/baggageclaim v1.3.6-0.20190315100745-09d349f19891' \ 255 > ./go.mod 256 257 # run the usual build 258 $ docker-compose up --build -d 259 ``` 260 261 ### Working on the web UI 262 263 Concourse is written in Go, but the web UI is written in 264 [Elm](https://elm-lang.org) and [Less](http://lesscss.org/). 265 266 After making changes to `web/`, run the following to rebuild the web UI assets: 267 268 ```sh 269 $ yarn build 270 ``` 271 272 When new assets are built locally, they will automatically propagate to the 273 `web` container without requiring a restart. 274 275 ### Debugging with `dlv` 276 277 With concourse already running, during local development is possible to attach 278 [`dlv`](https://github.com/go-delve/delve) to either the `web` or `worker` instance, 279 allowing you to set breakpoints and inspect the current state of either one of those. 280 281 To trace a running web instance: 282 283 ```sh 284 $ ./hack/trace web 285 ``` 286 287 To trace a running worker instance: 288 289 ```sh 290 $ ./hack/trace worker 291 ``` 292 293 To attach IDE debugger to a running instance, you can use the `--listen` flag followed by a port and the dlv will be started in headless mode listening on the specified port. 294 295 To debug a running web instance: 296 297 ```sh 298 $ ./hack/trace web --listen 2345 299 ``` 300 301 To debug a running worker instance: 302 303 ```sh 304 $ ./hack/trace worker --listen 2345 305 ``` 306 307 After this is done, the final step is to connect your IDE to the debugger with the following parameters: 308 * host: `localhost` 309 * port: `2345` 310 311 For GoLand you can do so by going to Run | Edit Configurations… | + | Go Remote and fill in the parameters. 312 313 314 ### Trying out distributed tracing with Jaeger 315 316 Under `./hack`, a docker-compose override file named `jaeger.yml` provides the 317 essentials to get [Jaeger] running alongside the other components, as well as 318 tying Concourse to it through the right environment variables. 319 320 [Jaeger]: https://jaegertracing.io 321 322 To leverage that extension, run `docker-compose up` specifying where all the 323 yaml files are: 324 325 ```sh 326 $ docker-compose \ 327 -f ./docker-compose.yml \ 328 -f ./hack/overrides/jaeger.yml \ 329 up -d 330 ``` 331 332 ### Using the experimental `containerd` garden backend locally 333 334 There a docker-compose override (`./hack/overrides/containerd.yml`) that sets up 335 the necessary environment variables needed to have [`containerd`] up an running as 336 a Garden backend. 337 338 [`containerd`]: https://containerd.io 339 340 341 ### Running Vault locally 342 343 1. Make sure you have [`certstrap`] 344 2. Run `./hack/vault/setup`, and follow the instructions. 345 346 See more about in the section [The Vault credential manager]. 347 348 [The Vault credential Manager]: https://concourse-ci.org/vault-credential-manager.html 349 [`certstrap`]: https://github.com/square/certstrap 350 351 352 ### Running Prometheus locally 353 354 Just like for Jaeger, we have a docker-compose override file that enhances the 355 base `docker-compose.yml` with the [Prometheus] service, bringing with it the 356 necessary configuraton for collecting Concourse metrics. 357 358 [Prometheus]: https://prometheus.io 359 360 361 ```sh 362 $ docker-compose \ 363 -f ./docker-compose.yml \ 364 -f ./hack/overrides/prometheus.yml \ 365 up -d 366 ``` 367 368 Now head to http://localhost:9090, and you'll be able to graph `concourse_` 369 Prometheus metrics. 370 371 372 ### Connecting to Postgres 373 374 If you want to poke around the database, you can connect to the `db` node using 375 the following parameters: 376 377 * host: `localhost` 378 * port: `6543` 379 * username: `dev` 380 * password: (blank) 381 * database: `concourse` 382 383 A utility script is provided to connect via `psql` (or `pgcli` if installed): 384 385 ```sh 386 $ ./hack/db 387 ``` 388 389 To reset the database, you'll need to stop everything and then blow away the 390 `db` container: 391 392 ```sh 393 $ docker-compose stop # or Ctrl+C the running session 394 $ docker-compose rm db 395 $ docker-compose start 396 ``` 397 398 ### Adding migrations 399 400 Concourse database migrations live under `atc/db/migration/migrations`. They are 401 generated using Concourse's own inbuilt migration library. The migration file 402 names are of the following format: 403 ``` 404 <migration_version>_<migration_name>.(up|down).(sql|go) 405 ``` 406 407 The migration version number is the timestamp of the time at which the migration 408 files are created. This is to ensure that the migrations always run in order. 409 There is a utility provided to generate migration files, located at 410 `atc/db/migration/cli`. 411 412 To generate a migration, you have two options: 413 414 #### The short way 415 416 Use the `create-migration` script: 417 418 ```sh 419 $ ./atc/scripts/create-migration my_migration_name 420 # or if you want a go migration, 421 $ ./atc/scripts/create-migration my_migration_name go 422 ``` 423 424 #### The long way 425 426 1. Build the CLI: 427 ```sh 428 $ cd atc/db/migration 429 $ go build -o mig ./cli 430 ``` 431 2. Run the `generate` command. It takes the migration name, file type (SQL or Go) 432 and optionally, the directory in which to put the migration files (by default, 433 new migrations are placed in `./migrations`): 434 435 ```sh 436 $ ./mig generate -n my_migration_name -t sql 437 ``` 438 439 This should generate two files for you: 440 ``` 441 1510262030_my_migration_name.down.sql 442 1510262030_my_migration_name.up.sql 443 ``` 444 445 Now that the migration files have been created in the right format, you can fill 446 the database up and down migrations in these files. On startup, `concourse web` 447 will look for any new migrations in `atc/db/migration/migrations` and will run 448 them in order. 449 450 ## Testing your changes 451 452 Any new feature or bug fix should have tests written for it. If there are no 453 tests, it is unlikely that your pull request will be merged, especially if it's 454 for a substantial feature. 455 456 There are a few different test suites in Concourse: 457 458 * **unit tests**: Unit tests live throughout the codebase (`foo_test.go` 459 alongside `foo.go`), and should probably be written for any contribution. 460 461 * `testflight/`: This suite is the "core Concourse" acceptance tests 462 suite, exercising pipeline logic and `fly execute`. A new test should be 463 added to `testflight` for most features that are exposed via pipelines or `fly`. 464 465 * `web/elm/tests/`: These test the various Elm functions in the web UI code 466 in isolation. For the most part, the tests for `web/elm/src/<module name>.elm` 467 will be in `web/elm/tests/<module name>Tests.elm`. We have been finding it 468 helpful to test the `update` and `view` functions pretty exhaustively, 469 leaving the models free to be refactored. 470 471 * `web/wats/`: This suite covers specifically the web UI, and run against a 472 real Concourse cluster just like `testflight`. This suite is still in its 473 early stages and we're working out a unit testing strategy as well, so 474 expectations are low for PRs, though we may provide guidance and only require 475 coverage on a case-by-case basis. 476 477 * `topgun/`: This suite is more heavyweight and exercises behavior that 478 may be more visible to operators than end-users. We typically do not expect 479 pull requests to add to this suite. 480 481 If you need help figuring out the testing strategy for your change, ask in 482 Discord! 483 484 Concourse uses [Ginkgo](http://github.com/onsi/ginkgo) as its test framework 485 and suite runner of choice for Go code. You'll need to install the `ginkgo` CLI 486 to run the unit tests and `testflight`: 487 488 ```sh 489 $ go get github.com/onsi/ginkgo/ginkgo 490 ``` 491 492 We use [Counterfeiter](https://github.com/maxbrunsfeld/counterfeiter) to generate 493 fakes for our unit tests. You may need to regenerate fakes if you add or modify an 494 interface. To do so, you'll need to install `counterfeiter` as follows: 495 496 ```sh 497 $ go get -u github.com/maxbrunsfeld/counterfeiter/v6 498 ``` 499 500 You can then generate the fakes by running 501 502 ```sh 503 $ go generate ./... 504 ``` 505 506 in the directory where the interface is located. 507 508 ### Running unit tests 509 510 Concourse is a ton of code, so it's faster to just run the tests for the 511 component you're changing. 512 513 To run the tests for the package you're in, run: 514 515 ```sh 516 $ ginkgo -r -p 517 ``` 518 519 This will run the tests for all packages found in the current working directory, 520 recursively (`-r`), running all examples within each package in parallel (`-p`). 521 522 You can also pass the path to a package to run as an argument, rather than 523 `cd`ing. 524 525 Note that running `go test ./...` will break, as the tests currently assume only 526 one package is running at a time (the `ginkgo` default). The `go test` default 527 is to run each package in parallel, so tests that allocate ports for test 528 servers and such will collide with each other. 529 530 #### Running elm tests 531 532 You can run `yarn test` from the root of the repo or `elm-test` from the 533 `web/elm` directory. They are pretty snappy so you can comfortably run the 534 whole suite on every change. 535 536 ### Elm static analysis 537 538 Running `yarn analyse` will run many checks across the codebase and report 539 unused imports and variables, potential optimizations, etc. Powered by 540 [elm-analyse](https://github.com/stil4m/elm-analyse). If you add the `-s` flag 541 it will run a server at `localhost:3000` which allows for easier browsing, and 542 even some automated fixes! 543 544 ### Elm formatting 545 546 Run `yarn format` to format the elm code according to the official Elm Style 547 Guide. Powered by [elm-format](https://github.com/avh4/elm-format). 548 549 ### Elm benchmarking 550 551 Run `yarn benchmark`. 552 553 ### Running the acceptance tests (`testflight`) 554 555 The `testflight` package contains tests that run against a real live Concourse. 556 By default, it will run against `localhost:8080`, i.e. the `docker-compose up`'d 557 Concourse. 558 559 If you've already got Concourse running via `docker-compose up`, you should be 560 able to just run the acceptance tests by running `ginkgo` the same way you would 561 run it for unit tests: 562 563 ```sh 564 $ ginkgo -r -p testflight 565 ``` 566 567 Note: because `testflight` actually runs real workloads, you *may* want to limit 568 the parallelism if you're on a machine with more than, say, 8 cores. This can be 569 done by specifying `--nodes`: 570 571 ```sh 572 $ ginkgo -r --nodes=4 testflight 573 ``` 574 575 ### Running the web acceptance tests (`web/wats`) 576 577 Run `yarn test` from the `web/wats` directory. They use puppeteer to run 578 a headless Chromium. A handy fact is that in most cases if a test fails, 579 a screenshot taken at the moment of the failure will be at 580 `web/wats/failure.png`. There is a known 581 [issue](https://github.com/concourse/concourse/issues/3890) with running these 582 tests in parallel (which is the default setting). The issue stems from an 583 upstream dependency, so until it is fixed you can run `yarn test --serial` to 584 avoid it. 585 586 ### Running Kubernetes tests 587 588 Kubernetes-related testing are all end-to-end, living under `topgun/k8s`. They 589 require access to a real Kubernetes cluster with access granted through a 590 properly configured `~/.kube/config` file. 591 592 [`kind`] is a great choice when it comes to running a local Kubernetes cluster - 593 all you need is `docker`, and the `kind` CLI. If you wish to run the tests with 594 a high degree of concurrency, it's advised to have multiple kubernetes nodes. 595 This can be achieved with the following `kind` config: 596 597 ```yaml 598 kind: Cluster 599 apiVersion: kind.x-k8s.io/v1alpha4 600 nodes: 601 - role: control-plane 602 - role: worker 603 - role: worker 604 - role: worker 605 - role: worker 606 ``` 607 608 609 With the cluster up, the next step is to have a proper [Tiller] setup (the tests 610 still run with Helm 2): 611 612 613 ```bash 614 kubectl create serviceaccount \ 615 --namespace kube-system \ 616 tiller 617 618 kubectl create clusterrolebinding \ 619 tiller-cluster-rule \ 620 --clusterrole=cluster-admin \ 621 --serviceaccount=kube-system:tiller 622 623 helm init \ 624 --service-account tiller \ 625 --upgrade 626 ``` 627 628 629 The tests require a few environment variables to be set: 630 631 - `CONCOURSE_IMAGE_TAG` or `CONCOURSE_IMAGE_DIGEST`: the tag or digest to use 632 when deploying Concourse in the k8s cluster 633 - `CONCOURSE_IMAGE_NAME`: the name of the image to use when deploying Concourse 634 to the Kubernetes cluster 635 - `HELM_CHARTS_DIR`: path to a clone of the [`helm/charts`][helm-charts] repo. This is used 636 to define the postgres chart that Concourse depends on. 637 - `CONCOURSE_CHART_DIR`: location in the filesystem where a copy of [`the Concourse Helm 638 chart`][concourse-helm-chart] exists. 639 640 641 With those set, go to `topgun/k8s` and run Ginkgo: 642 643 ```sh 644 # run the test cases serially 645 ginkgo . 646 647 # run the test cases with a concurrency level of 16 648 ginkgo -nodes=16 . 649 ``` 650 651 [`kind`]: https://kind.sigs.k8s.io/ 652 [Tiller]: https://v2.helm.sh/docs/install/ 653 654 655 ### A note on `topgun` 656 657 The `topgun/` suite is quite heavyweight and we don't currently expect most 658 contributors to run or modify it. It's also kind of hard for ~~mere mortals~~ 659 external contributors to run anyway. 660 661 To run `topgun`, a BOSH director up and running is required - the only 662 requirement with regards to where BOSH sits is having the ability to reach the 663 instance that it creates (the tests make requests to them). 664 665 You can have a local setup by leveraging the `dev` scripts in 666 the [concourse-bosh-release] repo: 667 668 [concourse-bosh-release]: https://github.com/concourse/concourse-bosh-release 669 670 ```bash 671 # clone the concourse-bosh-release repository 672 # 673 git clone https://github.com/concourse/concourse-bosh-release cbr && cd $_ 674 675 676 # run the setup script 677 # 678 ./dev/vbox/setup 679 ``` 680 681 `setup` will take care of creating the BOSH director (aliased as `vbox`), 682 uploading basic releases that we need for testing, as well as a BOSH Lite 683 stemcell. 684 685 With the director up, we can head to the tests. 686 687 ```bash 688 # fetch the concourse repo, and get into it 689 # 690 git clone https://github.com/concourse/concourse concourse && cd $_ 691 692 # get inside the topgun suite that you want to work on. 693 # 694 cd ./topgun/$SUITE 695 696 # run the tests of that suite 697 # 698 BOSH_ENVIRONMENT=vbox ginkgo -v . 699 ``` 700 701 ps.: you must have already installed the BOSH cli first. 702 703 704 705 ## Signing your work 706 707 Concourse has joined other open-source projects in adopting the [Developer 708 Certificate of Origin](https://developercertificate.org/) process for 709 contributions. The purpose of the DCO is simply to determine that the content 710 you are contributing is appropriate for submitting under the terms of our 711 open-source license (Apache v2). 712 713 The content of the DCO is as follows: 714 715 ``` 716 Developer Certificate of Origin 717 Version 1.1 718 719 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 720 1 Letterman Drive 721 Suite D4700 722 San Francisco, CA, 94129 723 724 Everyone is permitted to copy and distribute verbatim copies of this 725 license document, but changing it is not allowed. 726 727 728 Developer's Certificate of Origin 1.1 729 730 By making a contribution to this project, I certify that: 731 732 (a) The contribution was created in whole or in part by me and I 733 have the right to submit it under the open source license 734 indicated in the file; or 735 736 (b) The contribution is based upon previous work that, to the best 737 of my knowledge, is covered under an appropriate open source 738 license and I have the right under that license to submit that 739 work with modifications, whether created in whole or in part 740 by me, under the same open source license (unless I am 741 permitted to submit under a different license), as indicated 742 in the file; or 743 744 (c) The contribution was provided directly to me by some other 745 person who certified (a), (b) or (c) and I have not modified 746 it. 747 748 (d) I understand and agree that this project and the contribution 749 are public and that a record of the contribution (including all 750 personal information I submit with it, including my sign-off) is 751 maintained indefinitely and may be redistributed consistent with 752 this project or the open source license(s) involved. 753 ``` 754 755 This is also available at <https://developercertificate.org>. 756 757 All commits require a `Signed-off-by:` signature indicating that the author has 758 agreed to the DCO. This must be done using your real name, and must be done on 759 each commit. This line can be automatically appended via `git commit -s`. 760 761 Your commit should look something like this in `git log`: 762 763 ``` 764 commit 8a0a135f8d3362691235d057896e6fc2a1ca421b (HEAD -> master) 765 Author: Alex Suraci <asuraci@example.com> 766 Date: Tue Dec 18 12:06:07 2018 -0500 767 768 document DCO process 769 770 Signed-off-by: Alex Suraci <asuraci@example.com> 771 ``` 772 773 If you forgot to add the signature, you can run `git commit --amend -s`. Note 774 that you will have to force-push (`push -f`) after amending if you've already 775 pushed commits without the signature. 776 777 [discord]: https://discord.gg/MeRxXKW 778 [dco]: https://developercertificate.org 779 [style-guide]: https://github.com/concourse/concourse/wiki/Concourse-Go-Style-Guide 780 [how-to-fork]: https://help.github.com/articles/fork-a-repo/ 781 [how-to-pr]: https://help.github.com/articles/creating-a-pull-request-from-a-fork/ 782 [concourse-helm-chart]: https://github.com/concourse/concourse-chart/blob/master/README.md 783 [helm-charts]: https://github.com/helm/charts/blob/master/README.md 784 [fav-commit]: https://dhwthompson.com/2019/my-favourite-git-commit 785 [sb-changes]: https://medium.com/@kentbeck_7670/bs-changes-e574bc396aaa