Background
Kubernetes is the new trend to manage cloud-based applications and also our main tool for orchestration. Each of our service is running inside an individual docker container and we use helm charts to configure each pod. For codebase management, we use gitlab, which is perfect for collaboration inside a team that hosts code server by themselves.
In production, everytime that we update our service version (either front end or back end), we need to update the hash inside the helm charts. Since we have a requirement for release notes to include bug fix or new features, related commits or tickets have to be included inside the body of gitlab merge request.
We are all lazy developers and try to avoid tedious work that could be automated by codes.
So the workflow I want to achieve is that whenever we merge a feature branch to the master, we collect all the related issues and squashed commits. Ideally, we set a merge request interval to avoid too frequent merge requests. Then we compare the latest master hash and the one in the helm charts, checking if the interval is longer enough for us to create a new merge request. Last but not the least, the whole step should be a phase in the gitlab CI.
Luckily, gitlab API provides all the functions we need.
Tools
Before we proceed, we need a set of command line tools to boost our efficiency.
jq
jq is like sed for JSON data
You can usejq
to easily extract useful information and format them in the way you want. For example:
- extract the first element from a
json array
:
cat json | jq .[0]
- get a new json in the given format:
jq '.[] | {message: .commit.message, name: .commit.committer.name}'
You can even use conditional operator or loop functions with jq
, which is definitely worth checking out the manual if you are dealing with json form cli a lot.
yq
yq is similar to jq, but especially for yaml
files. It’s also written in python.
gsed(sed)
sed
is a very handy tool on the unix system to perform basic text transformations on an input stream. However, sed
on the linux
and mac
has slight differences, so we can use gsed
here to keep it consistent.
curl
curl
is basically the postman on the command line, which will be our best friend to test apis from the terminal.
base64
base64
encoding is a common way to use textual data to store the binary data or serialize the files.
Step by step
I’m using node client from gitlab here, but you can use any language to write the script.
Import the dependencies
Here’s the modules that I use:
1 | const { ProjectsBundle } = require("gitlab"); |
Fetch helm-chart file
We use gitlab client to set up the project info:
1 | const service = new ProjectsBundle({ |
Then we fetched the values.yaml
file.
1 | try { |
The response we get from the api so far is encoded in base64
, so we need to decode it in plain text:
1 | const { content } = valuesFile; |
Compare the commit diff and time diff
Next, We check whether the commit hash changed and whether time interval met our requirement, otherwise we don’t need to make next move.
1 | // get commit hash from helm chart |
- get related
merge requests
andcommit messages
In order to create a merge request with enough information, we can fetch merge requests and commit messages that are related to this specific commit.
1 | const description = { |
- Create a new merge request
In the final step, we create a new branch and apply the hash change that we made. Then we make a new merge request with all the useful information.
1 | const newBranch = `change-hash-${hashInManifold}`; |
Things to improve
Above are a relatively simple and straightforward way to create merge requests base on changes. We did observe several problems in the process and find improvements to be done in future.
-
Only create MRs in batches or close the MRs that are included in the current MR. MRs are created for each change now, then populate the whole merge list if the previous ones are not merge in time.
-
It would be nice that we provide a link with
Create MR
button for users to trigger the creation. -
Better code abstraction for different project usage.
-
Better organization of description and commit messages.