You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- store_artifacts: #Upload test summary for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
93
+
- store_artifacts: #upload test summary for display in Artifacts
106
94
path: /tmp/test-results
107
95
destination: raw-test-output
108
96
109
-
- store_test_results: #Upload test results for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
97
+
- store_test_results: #upload test results for display in Test Summary
110
98
path: /tmp/test-results
99
+
workflows:
100
+
version: 2
101
+
build-workflow:
102
+
jobs:
103
+
- build
111
104
```
112
105
113
106
{% endraw %}
@@ -141,49 +134,34 @@ This key is used to issue warnings about breaking changes.
141
134
version: 2
142
135
```
143
136
144
-
Next, we have a `jobs` key. Every config file must have a ‘build’ job. This is the only job that will be automatically picked up and run by CircleCI.
137
+
Next, we have a `jobs` key. If we do not use workflows and have only one job, it must be named `build`. Below, our job specifies to use the `docker` executor as well as the CircleCI created docker-image for golang 1.12. Next, we use a *secondary image* so that our job can also make use of Postgres. Finally, we use the `environment` key to specify environment variables for the Postgres container.
145
138
146
-
In the job, we specify a `working_directory`. Go is very strict about the structure of the [Go Workspace](https://golang.org/doc/code.html#Workspaces), so we’ll need to specify a path that satisfies those requirements.
This path will be used as the default working directory for the rest of the `job` unless otherwise specified.
156
-
157
-
Directly beneath `working_directory`, we’ll specify [primary container]({{ site.baseurl }}/2.0/glossary/#primary-container) images for this job under `docker`.
158
-
159
-
```yaml
160
-
docker:
141
+
jobs: # basic units of work in a run
142
+
build: # runs not using Workflows must have a `build` job as entry point
143
+
docker: # run the steps with Docker
144
+
# CircleCI Go images available at: https://hub.docker.com/r/circleci/golang/
161
145
- image: circleci/golang:1.12
162
-
```
163
-
164
-
We'll use a custom image which is based on `golang:1.12.0` and includes also `netcat` (we'll need it later).
165
-
166
-
We're also using an image for PostgreSQL, along with 2 environment variables for initializing the database.
167
-
168
-
```yaml
146
+
# CircleCI PostgreSQL images available at: https://hub.docker.com/r/circleci/postgres/
169
147
- image: circleci/postgres:9.6-alpine
170
-
environment:
171
-
POSTGRES_USER: root
148
+
environment:# environment variables for primary container
149
+
POSTGRES_USER: circleci-demo-go
172
150
POSTGRES_DB: circle_test
173
151
```
174
152
175
153
After setting up Docker we will set an environment variable to store the path to
176
-
our test results.
154
+
our test results. Note, this environment variable is set for the entirety of the _job_ whereas the environment variables set for `POSTGRES_USER` and `POSTGRES_DB` are specifically for the Postgres container.
177
155
178
156
```yaml
179
157
environment:
180
158
TEST_RESULTS: /tmp/test-results
181
159
```
182
160
183
-
Now we need to add several `steps` within the `build` job.
161
+
Now we need to add several `steps` within the `build` job. Steps make up the bulk of a job.
184
162
185
163
Use the [`checkout`]({{ site.baseurl }}/2.0/configuration-reference/#checkout) step
186
-
to check out source code. By default, source code is checked out to the path specified by `working_directory`.
164
+
to check out source code.
187
165
188
166
```yaml
189
167
steps:
@@ -199,63 +177,39 @@ Next we create a directory for collecting test results
199
177
Then we pull down the cache (if present). If this is your first run, this won't do anything.
200
178
201
179
```yaml
202
-
- restore_cache:
180
+
- restore_cache: # restores saved cache if no changes are detected since last run
203
181
keys:
204
-
- v1-pkg-cache
182
+
- go-mod-v4-{{ checksum "go.sum" }}
205
183
```
206
184
207
185
And install the Go implementation of the JUnit reporting tool and other dependencies for our application. These are good candidates to be pre-installed in primary container.
208
186
209
-
```yaml
210
-
- run: go get github.com/lib/pq
211
-
- run: go get github.com/mattes/migrate
212
-
- run: go get github.com/jstemmer/go-junit-report
213
-
```
214
-
215
-
Both containers (primary and postgres) start simultaneously, however Postgres may require some time to get ready and if our tests start before that the job will fail. So it's good practice to wait until dependent services are ready. Here we have only Postgres, so we add this step:
187
+
Both containers (primary and postgres) start simultaneously. Postgres, however, may require some time to get ready. If our tests start before Postgres is available, the job will fail. It is good practice to wait until dependent services are ready; in this example Postgres is the only dependent service.
This is why `netcat` installed on the CircleCI Go image. We use it to validate that the port is open.
231
-
232
195
Now we run our tests. To do that, we need to set an environment variable for our database's URL and path to the DB migrations files. This step has some additional commands, we'll explain them below.
Our project uses `make` for building and testing (you can see `Makefile` [here](https://github.com/CircleCI-Public/circleci-demo-go/blob/master/Makefile)), so we can just run `make test`. In order to collect test results and upload them later (read more about test results in the [Project Tutorial]({{ site.baseurl }}/2.0/project-walkthrough/)) we're using `go-junit-report`:
246
-
247
-
```bash
248
-
make test | go-junit-report > ${TEST_RESULTS}/go-test-report.xml
249
-
```
250
-
251
-
In this case all output from `make test` will go straight into `go-junit-report` without appearing in `stdout`. We can solve this by using two standard Unix commands `tee` and `trap`. The first one allows us to duplicate output into `stdout` and somewhere else ([read more](http://man7.org/linux/man-pages/man1/tee.1.html)). The second one allows us to specify some command to be executed on script exit ([read more](http://man7.org/linux/man-pages/man1/trap.1p.html)). So we can do:
The command for running unit tests is more complicated than some of our other
209
+
steps. Here we are using [test splitting]({{ site.baseurl
210
+
}}/2.0/parallelism-faster-jobs/#splitting-test-files) to allocate resources across parallel containers. Test splitting can help speed up your pipeline if your project has a large test suite.
257
211
258
-
Now we know that our unit tests succeeded we can start our service and validate it's running.
212
+
Next we run our actual build command using `make` - the Go sample project uses make to run build commands. If this build happens to pull in new dependencies, we will cache them in the `save_cache` step.
259
213
260
214
```yaml
261
215
- run: make
@@ -264,35 +218,62 @@ Now we know that our unit tests succeeded we can start our service and validate
264
218
key: v1-pkg-cache
265
219
paths:
266
220
- ~/.cache/go-build
221
+
```
222
+
223
+
224
+
Now we will start the Postgres dependent service, using `curl` to ping it to validate that the service is up and running.
After we pull and build the project's dependencies using `make`, we store any built packages in the cache. This is the recommended way to cache dependencies for your Go project.
282
-
283
-
To start the service we need to build it first. After that we use the same environment variables as we did in the testing step for the service to start. We're using `background: true` to keep the service running and proceed to the next step where we use `curl` to validate it successfully started and is responding to our request.
242
+
If all went well, the service ran and successfully responded to the post request at `localhost:8080`.
284
243
285
-
Finally, let's specify a path to store the results of the tests.
244
+
Finally, let's specify a path to store the results of the tests. The
245
+
`store_test_results`step allows you to leverage insights to view how your test
246
+
results are doing over time, while using the `store_artifacts` step allows you
247
+
to upload any type of file; in this case, also the test logs if one would like
248
+
to inspect them manually.
286
249
287
250
```yaml
288
-
- store_test_results:
251
+
- store_artifacts: # upload test summary for display in Artifacts
252
+
path: /tmp/test-results
253
+
destination: raw-test-output
254
+
255
+
- store_test_results: # upload test results for display in Test Summary
289
256
path: /tmp/test-results
290
257
```
291
258
259
+
260
+
Finally, we specify the workflow block. This is not mandatory (as we only have one job to sequence) but it is recommended.
261
+
262
+
```yaml
263
+
264
+
workflows:
265
+
version: 2
266
+
build-workflow: # the name of our workflow
267
+
jobs: # the jobs that we are sequencing.
268
+
- build
269
+
```
270
+
292
271
Success! You just set up CircleCI 2.0 for a Go app. Check out our [Job page](https://circleci.com/gh/CircleCI-Public/circleci-demo-go){:rel="nofollow"} to see how this looks when building on CircleCI.
293
272
294
273
## See Also
295
274
296
275
See the [Deploy]({{ site.baseurl }}/2.0/deployment-integrations/) document for example deploy target configurations.
297
276
277
+
How to use [workflows]({{ site.baseurl }}/2.0/workflows), which are particularly useful for optimizing your pipelines and orchestrating more complex projects.
278
+
298
279
Refer to the [Caching Dependencies]({{ site.baseurl }}/2.0/caching/) document for more caching strategies.
0 commit comments