Note: In this exercise we use the term "main" to refer to the main stabilization branch, or the default branch. This can also have the name "trunk" or "master", but all is refering back to the same thing.
The defacto-standard workflow now-adays is the Pull Request workflow (also known as the GitHub flow)
It utilizes the pull request feature to merge code from developer branches to main.
We do not want everybody to be able to push
directly to main, without the CI server checking
the quality of the code. So we need our Git
repository to block incoming pushes directly to
main. In that way we can ensure that the only
way in to main is through a PR. This can be done
in
GitHub
under settings->Branches
, Branch protection
rules and then click on add rule
.
-
Go to your repository on GitHub enter settings.
-
Go to
Branches
and add a branch protection rule. -
Give it the pattern
main
. -
Require status checks to pass before merging
Will block the pull request from merging until the tests have passed. -
Require branches to be up to date before merging
The branch must be up to date with the base branch before merging. -
Add the following jobs to the
Status checks that are required
selection:Test
,Build
,Docker-image
. In that way, no one can push to main without having the tests pass. -
Do not allow bypassing the above settings
Makes the rules apply to everyone (yes, you too!). -
OPTIONAL:
Require linear history
requires the PR branch to be rebased with the target branch, so a linear history can be obtained. Further explanaition here. This is a very strict way of using git, and is only here for inspiration for experiments. -
Try to push to main to verify that you cannot.
So how do we then get the CI server to run the tests on a PR? Right now our pipeline gets triggered by any push to any branch.
We want our pipeline to trigger on both pushes and pull requests towards main only.
The way thar pipelines gets triggered is by using the on
field in the workflow.
-
Take a look at the documentation on what events that can trigger a pipeline.
-
By using the resource above, make the pipleine only trigger on pushes and PR's to
main
branch.
Hint if you get stuck
on:
# Trigger the workflow on push or pull request,
# but only for the main branch
push:
branches:
- main
pull_request:
branches:
- main
- Try to make a couple of different branches that you push up to github and make pull requests on. It could be that you in one broke the unit tests to see that the CI system caught that, and another where you make your branch diverge from what is on main now, triggering the build-in github rules.
Note: When you make a pull request on your forked repository, GitHub will make target branch the main of the original repo. You need to change it manually to make the pull request based on your fork.
Looking at your pull requests, you should see that the pipeline is triggered for each of them, and that only if the tests are passing that you can merge the PR.
You want to run tests on your development branches as well, even if you are not pushing to main right away.
For that we need to add another workflow to the repository.
We want to run a slightly shorter workflow, excluding the component test, and the push of docker images. We want to run in on all branches that has the prefix dev/
.
- Copy the
workflows/pr-workflow.yml
file to a new file calledworkflows/dev-workflow.yml
. - Change the
on
field to:
on:
push:
branches:
- "dev/**"
- delete the
Component-test:
job from thejobs
section. - delete the
name: push docker
step from theDocker-image
job.
Congratulations! If everything works as intended, you now have a full "grown up" pipeline, with conditions, and security that your main branch always contains tested code. Go ahead and try it out, to see what it feels like.