When Project Labels are not Just to Categorize Things

Whether you are a fan of Github, Gitlab, BitBucket, or any git-based repo hosting platform, I am sure you must be farmiliar with project labels.

Categorizing (Messy) Project Issues

A common use case of project labels is to categorize project issues of a repo. For engineering discussion, we use Slack (or any alternative for instant messaging platform) only for quick discussions. Those usually end shortly. If such a discussion become lengthy, probably you used the wrong communication channel 😀? The rest (usually long discussions) which involve more effort to explain one’s points, we prefer to communicate via project issues.

So, project issues are used not only for bug reporting but also for any kinds of discussions within our team. One can just create an issue to point out a code smell in the project and propose an idea to refactor it. Or, if you are a maintainer of an open source project, you probably received more than one issue submitted to request for certain supports.

Now, as you see, project issues become a bit messy with various types of issues floating around. To organize them, engineers usually use labels to indicate:

project label

Fig. 1. An issue reported in Fastlane repo with 3 labels tool:scan, tool:snapshot and type:feature

Labels on Merge Requests

For merge requests (MRs), we also use labels pretty much the same way we do with project issues. In our project, apart from the use cases above, labels also serve some CI/CD purposes.

Label-based Configuration

This is the main use case for our CI/CD. For example, a merge request to fix a regression issue should be prioritized in order to unblock the release that is going to be live. With the label regression set on the MR, we expedite the CI pipelines running against that change by allocating more CI resources (5 UI test jobs, instead of 3).

Another use case is the cherry-pick workflow in trunk based development when fixing regression issues. We sometimes face the problem in which an engineer raised an MR to fix a bug, got it merged and then realized that the change was not cherry-pickable due to conflicts. In this case, he/she had waited for CI pipelines to finish in around 40 minutes… It was quite late to spot the cherry-pick issue (not to mention the time to address code review comments). To mitigate this, we added a job to detect cherry-pick conflicts on MRs that’s labelled either regression or need cherry-pick.

Let me tell you a story about why we need label-based configuration. Sometime ago, we were migrating our project from Xcode 10 to Xcode 11. Due to many dependencies in the project, it is not something we could get done overnight. Migrating bit by bit seemed to be the right choice for us (and for other large-scale projects as well, I believe). We add extra jobs for Xcode 11 to bring visibility to the migration progress and spot issues as early as possible. The jobs we added are enabled to all pipelines running on protected branches and on merge requests. Engineers working on the migration could just check Xcode 11 related jobs to verify the compatibility in the pre-merge flow. Of course those jobs are allowed to fail (ie. whether they fail or not does not affect the pipeline status).

Problems arose when engineers started to realized some newly added manual jobs. They, by instinct, triggered them. This wasted our CI resources and the jobs would fail eventually. Even worse, seeing those failures somehow triggered their “panic mode”. They asked us about the failures and it costed us more communication to explain that it was expected and everything was fine. We realized that the jobs we added for MRs only served dedicated engineers for the migration, but it caused more problems in the working process. This was like a bad UX.

Therefore, we decided to slightly change the configuration:

This way, it saved our CI resources and communication.

A/B Testing in CI/CD

Another example is when it comes to A/B testing in our CI/CD. There are some CI/CD features we enable by default, under certain conditions, to optimize our system. When there is any issue because of a CI/CD optimization, one can just force-disable it by labelling his/her merge request with a dedicated label - something like ci-<feature-name>::disabled.

Conclusion

In this post, we’ve gone through the most common use case of project labels which is to categorize issues, discussions, merge requests, etc.. We also know some use cases in which project labels play an interesting roles in our CI/CD setup, to manipulate certain actions. Hope you could make good use of them.