## Exercise 4: Use git tags to create a named version of a docker image ## ### Objective ### Use git tags to create automatically labelled versions of docker images. See how to use git tags to add extra steps to the CI/CD pipeline, for more detailed testing and verification of your code. ### Using the git tag to tag the docker image ### Gitlab directly supports specifying that certain stages will run only for git branches other than the 'master' branch, or only if the code has been tagged with 'git tag'. By using a combination of YAML directives and the environment variables that gitlab provides to the build, you can build a docker image which is tagged with the same name as your git tag or branch. Once the **.gitlab-ci.yml** file has been correctly set up, creating a tagged docker image is as simple as this: ``` git tag v1.0 git push --tags ``` While you're waiting for the build to complete, inspect the **.gitlab-ci.yml** file to see how it uses the tag. There are a few places where the magic happens: - the **variables** section defines two variables: **RELEASE_IMAGE** and **LATEST_IMAGE**, differing only in that one uses the **CI_BUILD_REF_NAME** environment variable, the other hardwires the name **latest** - the **before_script** stanza sets **DOCKER_IMAGE** to one or the other of these variables, depending on the value of **CI_BUILD_REF_NAME**. For the **master** branch, **CI_BUILD_REF_NAME** will be **master**, this bit of code effectively changes that to **latest** instead. - in the **install** step, the **DOCKER_IMAGE** variable is used to actually tag the image that's pushed to the registry Most of the complication there comes from the fact that the default branch name in git is **master**, while the default tag name in docker is **latest**. We could remove the **before_script** part and just use the **RELEASE_IMAGE** variable everywhere, but then we'd end up with docker images tagged **master**, which isn't nice. ### Using the git tag to control the build ### If you look at the **CICD** -> **Pipelines** page after your tagged build has completed, you'll see it has three steps to it. There is a **run** step that executes the **test** stage, this isn't executed unless the code has been tagged in git. The **only:** directive in the **.gitlab-ci.yml** file controls that behaviour. Since you are likely to commit code much more often than you are to tag it, you can see how this can be used to test tagged code in-depth, in ways that might be wasteful of resources if you tested every single commit to the same level. ### Check your Registry to see the named docker image ### Once the build completes, go to your Registry page again, and click on your project link at the top-left to see what images you have. You now have a **latest** and a **v1.0** version of your docker image. Check you can run that tagged version from the command line: ``` > docker run registry.gitlab.com/tonywildish/tiny-test:v1.0 Unable to find image 'registry.gitlab.com/tonywildish/tiny-test:v1.0' locally v1.0: Pulling from tonywildish/tiny-test 7413c47ba209: Already exists 0fe7e7cbb2e8: Already exists 1d425c982345: Already exists 344da5c95cec: Already exists 69e5cbbf5881: Pull complete 737987b4e0ef: Pull complete Digest: sha256:e1445aff15c845b2f795fc49f8b2bcb41f34cd4a6a3c3eef98bb61bea26a986b Status: Downloaded newer image for registry.gitlab.com/tonywildish/tiny-test:v1.0 Hello World Compiled on Tue Jul 30 10:58:09 UTC 2019 ``` ### Bonus exercise: git branches ### What happens if you use a git branch, instead of a tag? The CI/CD pipeline will still fire, and will know the branch name, so it uses that in the docker image tag. However, since your **.gitlab-ci.yml** file only runs the **test** stage for git _tags_ and not for git _branches_, you will only get a two-stage pipeline. Can you modify the YAML file so it runs for branches too? [Check the documentation](https://docs.gitlab.com/ee/ci/yaml/#onlyexcept-basic) for help. If you're on a branch, and you use a tag too, what do you think gitlab will do? Try it and find out. ### Conclusion ### You now know how to control the activities in a build when using git tags, and how to use those tags to automatically tag the docker image with the same name. ### Best Practices ### - Use git tags to define important versions of your code. - Use the **only:** directive in your builds to make sure that tagged code is tested thoroughly.