How to improve the developer experience in Heptapod/GitLab
Gaumont, Noé
Logilab has been using heptapod, a GitLab fork with mercurial support, for 2 years now. We are maintaining the open source software CubicWeb and its components called cubes. Thus, the code is split in dozens of repositories, depending on one another. Over the years, it has become hard to maintain code quality and good practices in the whole codebase. In this talk, we will present the tools that helped us. Some of them are mercurial specific, but most could be used in GitLab. - Create Merge Request automatically across repositories based on some rules, such as deprecation warnings. - Pick a reviewer for Merge requests based on the developers' preferences - Making sure to commit, tag, update the changelog, publish to PyPi when releasing a new version - Mutualize GitLab CI configurations with templates - Host docker images of your project on the forge - Have up-to-date static websites, documentation or web applications Each use case can be solved easily, but combining them is what truly makes developer life easier.
 Hi, I'm Moigu and I will present you how to improve the developer experience in GitLab and how to automate the do-it-works to focus on development. This presentation is more a use case presentation of how we use Eptapod within Logilab. Eptapod is a friendly fork of GitLab with mercariable support. During this presentation, I will first present Logilab and how our code is organized and what are the problems we are facing within Logilab. What are the existing solutions inside GitLab and GitLab? The main part will be on the tools that we design and are open sourced. We use internally to have some reviewer and some short definition. It really is something on the internet and how to update dependencies. First, Logilab is a small IT company, around 25 people in France. It's focused on scientific computing, web semantics and Python training. We do a lot of custom development for clients. We work almost only with open source software and we contribute with code or money on the project that we are using. Here are some examples. On the left are some associations in France. On the right, we contribute with money and also some examples that we contribute with code. As we are developing applications for our clients, we use something called QBQab, which is a semantics web application where a framework is developed in Python inside Logilab. You can think of it as an alternative to Django. It has an explicit data model and also a lot of components that can reuse from an application to another one. We call it Qubes. There is a lot of framework. Qubes is front agnostic. You can have your back end written in Qubes, but your front page is written inside the React application or whatever you want. Our text tag is composed of HTML, JavaScript, CSS. For the front, front end, Python for the back end with Qubes. Postgres called for database service. And eventually, everything is deployed with Docker. Inside Logilab, we have a lot of repository. We are using Mercurial, which is an alternative to Git written in Python. In order to use Mercurial, we can't use Mercurial with GitLab. We use Eptapad, which is a friendly product as I stated earlier. We have a multi-repository approach. We have one repo for Qubes, around 200 repository for public Qubes, some private Qubes for the client project, some importers projects that are not related to Qubes and also some internal repository. So we have a lot of repository to take care of. And all of them are hosted on Eptapad. If you have only one repository, you could think that keeping the repo clean and updated is simple and having several hundred repository is hard to have everything clean and updated. But I tend to disagree with that. I think that both situations are hard, because the only difference is that the problem occurs faster when you have a lot of repository. And the problem that I'm describing, I'm facing within Logilab is the first one is easy having a CI. So test and link, link, run every on every commit. Having a reviewer on every request, and so you don't have a request lying around for years, have a Korean code base so that you have a high standard code everywhere. And having your CI configured the right way across all the repository, having everything released properly and tagged on Pipeye for cases, because we are mainly on Python. But also as we use Docker, having everything correctly tagged, updated and properly set up. If you come from GitHub, with GitHub Action and Probot, you can have auto assign, the pandabot, release the drifter to do a lot of things. If you come from GitLab, you have the danger bots. You can do some of the work, such as the reviewer who let to have someone assign as a reviewer, or some information of your merge request. But that didn't fit our use case well, and we made our own tools. And what I will do now is present you, rely on a use case example, so when a new feature is introduced inside Kubiquab, and how all the tools we designed help us to review the merge request, make sure the tests are passed, the dependencies are updated, and everything is published correctly. So for example, you have a merge request on the project, so on Kubiquab. A schedule job of assign bots will assign a reviewer based on user preference. In contrast to reviewer who let our assign bot from GitHub, you assign our assign bot, rely on group membership, but also on some user preference. So that if I can say, okay, I want to focus on reviewing a lot of works this week, I can say that I will review only like 15 merge requests during the week and three per day, and then change those values in time. And so that all every person does not have the same workload on merge request reviewing. Also, assign bot will take care of kindly remind you to do your work on the merge request and put in a comment if the merge request is inactive for a week. Then when you have a reviewer, the first thing that has to do is make sure the CI is green before anything else. And having a right job is hard to keep it up to date. So what we do is have a GitLab CI template. GitLab CI template is a project, an app.tox project inside of our app.tapod instance, and it defines a lot of jobs. And within a project, we will use those jobs to declare the stage and the jobs that we need. And this will help us reduce the CI load, because all the jobs will be customized. And so we make sure to have the right job definition. So here there is an example of GitLab CI. So we have Pi 3 and some Docker. We'll build some Docker image, but also we can have some extensions. So even though we have some shared job definition, we can always customize a job or create a new state or create a new job. And here is an example of the Pi 3 job. There are a few things to notice. First, it shows a customized Docker image with all the dependency already installed. So we don't waste CI time to install everything. It also stores some artifacts. In our case, all the deprecation running that occurs during the test. Among those things. When you have your test screen, one thing that you may want is to test your application. And what you can do is build Docker image. So when you have your magic rest accepted, we define another job inside GitLab CI template that builds Docker images. And what's present here is inside the image build latest job, we are using some specific tags or latest and also the hash of the commit. And we do this only if we are on the default branch. So if you are in GitLab, it should be master. But if the CI is running on a tag inside the repository, it's not the same tag to apply to the Docker image. So here we are using the CI commit tag. And we do this only if we are on a tag. Then when the magic rest is accepted, everything is published. At some point, you want to release everything. And in our case, to pipy. So that you are using release new. Release new is a small example of how it behaves when you run it. It detects a new version number that you will use for the next version and updates the code. And we do this by using the semantic versioning of all the commits between this version and the last one. And we generate a change log from the commit message. Always let you modify it if you want. Update the packaging information. So in Python, the manifest. And after all that, it try to commit and tag it correctly. And as we are using GitLab, the only thing you have to do is push everything to your repo. Because we have another job from GitLab, saying, hey, if you are on a tag, something you want to publish, then run this specific job that will itself publish to PyPy. Now that you have your, and it's everything released, you want to update all the dependencies. And for that, we use kube.doctor. kube.doctor can update the repository for various reasons. The first one is pretty simple. It just rebays all the made requests in a project to make sure that we can safely review the work and manage it. And we know if we have some conflict, there is some conflict, and we have to do some manual rebays. But also, it creates a made request to update the package version. So here on the right part, you have an example of a made request created by kube.doctor to update kube.doctor to the next version. Because at some point, we release a new version, and inside this repo, it updates the code to update the dependencies automatically. So as a reviewer, as a maintainer of a repo, we have made requests to update everything. And this here will be green, and I will just have to click on the on the made button, and everything will be updated. But also, kube.doctor will take care of some to create a made request for some linked configuration. And also, once you can also create some rules to automatically refactor all your base on the repo. So for example, as you saw earlier, we take care to collect all the deprecation warning from the test. We collect them, and we can analyze it to understand what are the deprecation warning occurring, writing a new rule inside kube.doctor to update the code, and then having kube.doctor creating all the made request needed to fix the deprecation warning. And with that, let me conclude. So the main part is within Lojla, we are using Eptapod, and this is a great tool with a lot of features. The main one such as the schedule job to have something run every hour, every week, from a thing about to kube.doctor to everything. We are using the registry a lot. So, the image registry with the code is currently tagged, but also some package, Python package registry, and we rely a lot on shared job definition. Having a good CI helps a lot to keep the clean update. However, having a good CI needs a lot of manual effort, at least in our case. And we end up writing some tools, so the tools that I presented you. So, I think I have some reviewer assigned automatically for a project, and make sure to not fluid someone with tons of magic requests every week. We use our own version of GitLab CI so we have one place, one single source of truth to create our jobs, and we can update it to have everything, have all to handcraft all the jobs and making sure to take full advantages of the CI. So, having custom images, artifacts, everything. We rely on release new to easily create a new version on the repository. So, having always the same commit message to on the new version, creating a change log, making sure the packaging is good, is right, and then GitLab compiles again to actually do the work to release to the Internet. And then when we have to update all the repository to update the code itself, we use Cubector with some rules that we write ourselves. And that helps us to have all our repository, several hundred of repository, always clean and that thank you for your attention and see you in the question phase. Thank you for your talk. I'm looking if we have any questions in the channel. Seems there are no questions here in the channel. But after looking on your presentation, I was thinking how you keep track of all the merge requests, I mean, because you automated pretty well everything, and how you keep track to see that the merge requests are not piling up or if everything works fine. So we did have a small period of time when we were having a lot of merge requests and we're not making sure everything was merged and reviewed. And we ended up having custom dashboard, so the dashboard, small static pages made with pages, features inside GitLab. So in GitLab you can have on every commit, rebuild the dashboard and see all the merge requests that are open, closed, ready to be merged because the CI is green. So we have this small web page that gather all the information. It's a central web page or is it for each merge request? No, it's a global one. So we have a project dedicated to gather all the information. So every hour I think it runs on schedule jobs and it poke around with the API, the GitLab API to see how many merge requests there are if they're open, closed, and everything. Cool. I'm looking at the channel if we have any questions. No questions at all. Then let me think, after representation you said you have GitLab templates. And those templates are like, what type of templates do you have even? I guess you have a library of templates, right? Yeah, we have several templates, mainly of three kind of templates. One based on the LinkedIn problem, making sure that we have the link correctly configured for each project, for Python, we could have some for JavaScript project, some to have the test correctly configured. So in Python 3, making sure the test could run concurrently, stores the artifact of the test. And the one related to release everything, so release to bypy, release to Docker, the image registry inside the GitLab also on Docker directly. Okay. We have one question in the chat. I was also wondering how you keep track, I mean, you mentioned you forked GitLab. I mean, it's a big tool. And how you managed to keep upstream? How you managed the... So Eptapod, the friendly fork of GitLab is not managed by us. It's a small company called Octobus. I have checked, I will send you the link just after. So it's a dedicated company that does this for us. So it has... We send money to them and say, hey, please make sure that you follow GitLab upstream and do not wait too long, wait just before updating anything.
 Hi, I'm Moigu and I will present you how to improve the developer experience in GitLab  and how to automate the do-it-works to focus on development.  This presentation is more a use case presentation of how we use Eptapod within Logilab.  Eptapod is a friendly fork of GitLab with mercariable support.  During this presentation, I will first present Logilab and how our code is organized  and what are the problems we are facing within Logilab.  What are the existing solutions inside GitLab and GitLab?  The main part will be on the tools that we design and are open sourced.  We use internally to have some reviewer and some short definition.  It really is something on the internet and how to update dependencies.  First, Logilab is a small IT company, around 25 people in France.  It's focused on scientific computing, web semantics and Python training.  We do a lot of custom development for clients.  We work almost only with open source software and we contribute with code or money  on the project that we are using. Here are some examples.  On the left are some associations in France.  On the right, we contribute with money and also some examples that we contribute with code.  As we are developing applications for our clients, we use something called QBQab,  which is a semantics web application where a framework is developed in Python inside Logilab.  You can think of it as an alternative to Django.  It has an explicit data model and also a lot of components that can reuse  from an application to another one. We call it Qubes.  There is a lot of framework. Qubes is front agnostic.  You can have your back end written in Qubes, but your front page is written  inside the React application or whatever you want.  Our text tag is composed of HTML, JavaScript, CSS.  For the front, front end, Python for the back end with Qubes.  Postgres called for database service.  And eventually, everything is deployed with Docker.  Inside Logilab, we have a lot of repository.  We are using Mercurial, which is an alternative to Git written in Python.  In order to use Mercurial, we can't use Mercurial with GitLab.  We use Eptapad, which is a friendly product as I stated earlier.  We have a multi-repository approach. We have one repo for Qubes,  around 200 repository for public Qubes, some private Qubes for the client project,  some importers projects that are not related to Qubes and also some internal repository.  So we have a lot of repository to take care of.  And all of them are hosted on Eptapad.  If you have only one repository, you could think that keeping the repo clean and updated  is simple and having several hundred repository is hard to have everything clean and updated.  But I tend to disagree with that. I think that both situations are hard,  because the only difference is that the problem occurs faster when you have a lot of repository.  And the problem that I'm describing, I'm facing within Logilab is the first one is easy having a CI.  So test and link, link, run every on every commit.  Having a reviewer on every request, and so you don't have a request lying around for years,  have a Korean code base so that you have a high standard code everywhere.  And having your CI configured the right way across all the repository,  having everything released properly and tagged on Pipeye for cases, because we are mainly on Python.  But also as we use Docker, having everything correctly tagged, updated and properly set up.  If you come from GitHub, with GitHub Action and Probot, you can have auto assign,  the pandabot, release the drifter to do a lot of things.  If you come from GitLab, you have the danger bots. You can do some of the work, such as the  reviewer who let to have someone assign as a reviewer, or some information of your  merge request. But that didn't fit our use case well, and we made our own tools.  And what I will do now is present you, rely on a use case example, so when a new feature is  introduced inside Kubiquab, and how all the tools we designed help us to  review the merge request, make sure the tests are passed, the dependencies are updated,  and everything is published correctly. So for example, you have a merge request  on the project, so on Kubiquab. A schedule job of assign bots will assign a reviewer based on  user preference. In contrast to reviewer who let our assign bot from GitHub, you assign our assign  bot, rely on group membership, but also on some user preference. So that if I can say, okay,  I want to focus on reviewing a lot of works this week, I can say that I will review only like  15 merge requests during the week and three per day, and then change those values in time.  And so that all every person does not have the same workload on merge request reviewing.  Also, assign bot will take care of kindly remind you to do your work on the merge request and  put in a comment if the merge request is inactive for a week.  Then when you have a reviewer, the first thing that  has to do is make sure the CI is green before anything else. And having a right job is hard  to keep it up to date. So what we do is have a GitLab CI template. GitLab CI template is a project,  an app.tox project inside of our app.tapod instance, and it defines a lot of jobs.  And within a project, we will use those jobs to declare the stage and the jobs that we need.  And this will help us reduce the CI load, because all the jobs will be customized.  And so we make sure to have the right job definition. So here there is an example of GitLab CI.  So we have Pi 3 and some Docker. We'll build some Docker image, but also we can have some  extensions. So even though we have some shared job definition, we can always customize a job  or create a new state or create a new job. And here is an example of the Pi 3 job.  There are a few things to notice. First, it shows a customized Docker image with all the dependency  already installed. So we don't waste CI time to install everything. It also stores some artifacts.  In our case, all the deprecation running that occurs during the test.  Among those things. When you have your test screen, one thing that you may want is to test  your application. And what you can do is build Docker image. So when you have your magic rest  accepted, we define another job inside GitLab CI template that builds Docker images.  And what's present here is inside the image build latest job, we are using some specific tags or  latest and also the hash of the commit. And we do this only if we are on the default branch. So if  you are in GitLab, it should be master. But if the CI is running on a tag inside the repository,  it's not the same tag to apply to the Docker image. So here we are using the CI commit tag. And we do  this only if we are on a tag. Then when the magic rest is accepted, everything is published.  At some point, you want to release everything. And in our case, to pipy. So that you are using  release new. Release new is a small example of how it behaves when you run it. It detects a new  version number that you will use for the next version and updates the code. And we do this by  using the semantic versioning of all the commits between this version and the last one. And we  generate a change log from the commit message. Always let you modify it if you want. Update the  packaging information. So in Python, the manifest. And after all that, it try to commit and tag it  correctly. And as we are using GitLab, the only thing you have to do is push everything to your  repo. Because we have another job from GitLab, saying, hey, if you are on a tag, something  you want to publish, then run this specific job that will itself publish to PyPy. Now that you  have your, and it's everything released, you want to update all the dependencies. And for that, we  use kube.doctor. kube.doctor can update the repository for various reasons. The first one is  pretty simple. It just rebays all the made requests in a project to make sure that we can  safely review the work and manage it. And we know if we have some conflict, there is some  conflict, and we have to do some manual rebays. But also, it creates a made request to update  the package version. So here on the right part, you have an example of a made request created by  kube.doctor to update kube.doctor to the next version. Because at some point, we release a new  version, and inside this repo, it updates the code to update the dependencies automatically. So  as a reviewer, as a maintainer of a repo, we have made requests to update everything. And this here  will be green, and I will just have to click on the on the made button, and everything will be  updated. But also, kube.doctor will take care of some to create a made request for some linked  configuration. And also, once you can also create some rules to automatically refactor all your  base on the repo. So for example, as you saw earlier, we take care to collect all the deprecation  warning from the test. We collect them, and we can analyze it to understand what are the  deprecation warning occurring, writing a new rule inside kube.doctor to update the code, and then  having kube.doctor creating all the made request needed to fix the deprecation warning. And with  that, let me conclude. So the main part is within Lojla, we are using Eptapod, and this is a great  tool with a lot of features. The main one such as the schedule job to have something run every  hour, every week, from a thing about to kube.doctor to everything. We are using the registry a  lot. So, the image registry with the code is currently tagged, but also some package,  Python package registry, and we rely a lot on shared job definition. Having a good CI  helps a lot to keep the clean update. However, having a good CI needs a lot of manual  effort, at least in our case. And we end up writing some tools, so the tools that I presented  you. So, I think I have some reviewer assigned automatically for a project, and make sure to not  fluid someone with tons of magic requests every week. We use our own version of GitLab CI  so we have one place, one single source of truth to create our jobs, and we can update it to have  everything, have all to handcraft all the jobs and making sure to take full advantages of the CI.  So, having custom images, artifacts, everything. We rely on release new to easily create a new  version on the repository. So, having always the same commit message to on the new version,  creating a change log, making sure the packaging is good, is right, and then GitLab  compiles again to actually do the work to release to the Internet. And then when we have to update  all the repository to update the code itself, we use Cubector with some rules that we write  ourselves. And that helps us to have all our repository, several hundred of repository, always clean  and that thank you for your attention and see you in the question phase.  Thank you for your talk. I'm looking if we have any questions in the channel. Seems there are no  questions here in the channel. But after looking on your presentation, I was thinking how you keep  track of all the merge requests, I mean, because you automated pretty well everything, and how you  keep track to see that the merge requests are not piling up or if everything works fine.  So we did have a small period of time when we were having a lot of merge requests and we're not making  sure everything was merged and reviewed. And we ended up having custom dashboard, so the dashboard,  small static pages made with pages, features inside GitLab. So in GitLab you can have on every  commit, rebuild the dashboard and see all the merge requests that are open, closed, ready to be  merged because the CI is green. So we have this small web page that gather all the information.  It's a central web page or is it for each merge request?  No, it's a global one. So we have a project dedicated to gather all the information. So every  hour I think it runs on schedule jobs and it poke around with the API, the GitLab API to see how many  merge requests there are if they're open, closed, and everything.  Cool. I'm looking at the channel if we have any questions. No questions at all.  Then let me think, after representation you said you have GitLab templates. And those templates are  like, what type of templates do you have even? I guess you have a library of templates, right?  Yeah, we have several templates, mainly of three kind of templates. One based on the  LinkedIn problem, making sure that we have the link correctly configured for each project,  for Python, we could have some for JavaScript project, some to have the test correctly configured.  So in Python 3, making sure the test could run concurrently, stores the artifact of the test.  And the one related to release everything, so release to bypy, release to Docker, the image registry  inside the GitLab also on Docker directly. Okay. We have one question in the chat. I was also  wondering how you keep track, I mean, you mentioned you forked GitLab. I mean, it's a big tool.  And how you managed to keep upstream? How you managed the...  So Eptapod, the friendly fork of GitLab is not managed by us. It's a small company called Octobus.  I have checked, I will send you the link just after. So it's a dedicated company that does this for us.  So it has... We send money to them and say, hey, please make sure that you follow GitLab upstream and do not wait  too long, wait just before updating anything.
how_to_improve_the_developer_experience_in_heptapod_gitlab_0_143.png how_to_improve_the_developer_experience_in_heptapod_gitlab_144_863.png how_to_improve_the_developer_experience_in_heptapod_gitlab_864_1895.png how_to_improve_the_developer_experience_in_heptapod_gitlab_1896_4931.png how_to_improve_the_developer_experience_in_heptapod_gitlab_4932_6191.png how_to_improve_the_developer_experience_in_heptapod_gitlab_6192_8759.png how_to_improve_the_developer_experience_in_heptapod_gitlab_8760_17951.png how_to_improve_the_developer_experience_in_heptapod_gitlab_17952_20015.png how_to_improve_the_developer_experience_in_heptapod_gitlab_20016_20243.png how_to_improve_the_developer_experience_in_heptapod_gitlab_20244_20879.png how_to_improve_the_developer_experience_in_heptapod_gitlab_20880_24683.png how_to_improve_the_developer_experience_in_heptapod_gitlab_24684_29975.png how_to_improve_the_developer_experience_in_heptapod_gitlab_29976_30167.png how_to_improve_the_developer_experience_in_heptapod_gitlab_30168_30215.png how_to_improve_the_developer_experience_in_heptapod_gitlab_30216_30539.png how_to_improve_the_developer_experience_in_heptapod_gitlab_30540_30635.png how_to_improve_the_developer_experience_in_heptapod_gitlab_30636_30683.png how_to_improve_the_developer_experience_in_heptapod_gitlab_30684_31823.png how_to_improve_the_developer_experience_in_heptapod_gitlab_31824_31871.png how_to_improve_the_developer_experience_in_heptapod_gitlab_31872_31955.png how_to_improve_the_developer_experience_in_heptapod_gitlab_31956_32591.png how_to_improve_the_developer_experience_in_heptapod_gitlab_32592_32639.png how_to_improve_the_developer_experience_in_heptapod_gitlab_32640_32723.png how_to_improve_the_developer_experience_in_heptapod_gitlab_32724_32783.png how_to_improve_the_developer_experience_in_heptapod_gitlab_32784_32879.png how_to_improve_the_developer_experience_in_heptapod_gitlab_32880_32963.png how_to_improve_the_developer_experience_in_heptapod_gitlab_32964_33023.png how_to_improve_the_developer_experience_in_heptapod_gitlab_33024_33299.png how_to_improve_the_developer_experience_in_heptapod_gitlab_33300_34643.png how_to_improve_the_developer_experience_in_heptapod_gitlab_34644_34859.png how_to_improve_the_developer_experience_in_heptapod_gitlab_34860_34967.png how_to_improve_the_developer_experience_in_heptapod_gitlab_34968_35015.png how_to_improve_the_developer_experience_in_heptapod_gitlab_35016_35843.png how_to_improve_the_developer_experience_in_heptapod_gitlab_35844_35958.png
Hi, I'm Moigu and I will present you how to improve the developer experience in GitLab and how to automate the do-it-works to focus on development. This presentation is more a use case presentation of how we use Eptapod within Logilab. Eptapod is a friendly fork of GitLab with mercariable support. During this presentation, I will first present Logilab and how our code is organized and what are the problems we are facing within Logilab. What are the existing solutions inside GitLab and GitLab? The main part will be on the tools that we design and are open sourced. We use internally to have some reviewer and some short definition. It really is something on the internet and how to update dependencies. First, Logilab is a small IT company, around 25 people in France. It's focused on scientific computing, web semantics and Python training. We do a lot of custom development for clients. We work almost only with open source software and we contribute with code or money on the project that we are using. Here are some examples. On the left are some associations in France. On the right, we contribute with money and also some examples that we contribute with code. As we are developing applications for our clients, we use something called QBQab, which is a semantics web application where a framework is developed in Python inside Logilab. You can think of it as an alternative to Django. It has an explicit data model and also a lot of components that can reuse from an application to another one. We call it Qubes. There is a lot of framework. Qubes is front agnostic. You can have your back end written in Qubes, but your front page is written inside the React application or whatever you want. Our text tag is composed of HTML, JavaScript, CSS. For the front, front end, Python for the back end with Qubes. Postgres called for database service. And eventually, everything is deployed with Docker. Inside Logilab, we have a lot of repository. We are using Mercurial, which is an alternative to Git written in Python. In order to use Mercurial, we can't use Mercurial with GitLab. We use Eptapad, which is a friendly product as I stated earlier. We have a multi-repository approach. We have one repo for Qubes, around 200 repository for public Qubes, some private Qubes for the client project, some importers projects that are not related to Qubes and also some internal repository. So we have a lot of repository to take care of. And all of them are hosted on Eptapad. If you have only one repository, you could think that keeping the repo clean and updated is simple and having several hundred repository is hard to have everything clean and updated. But I tend to disagree with that. I think that both situations are hard, because the only difference is that the problem occurs faster when you have a lot of repository. And the problem that I'm describing, I'm facing within Logilab is the first one is easy having a CI. So test and link, link, run every on every commit. Having a reviewer on every request, and so you don't have a request lying around for years, have a Korean code base so that you have a high standard code everywhere. And having your CI configured the right way across all the repository, having everything released properly and tagged on Pipeye for cases, because we are mainly on Python. But also as we use Docker, having everything correctly tagged, updated and properly set up. If you come from GitHub, with GitHub Action and Probot, you can have auto assign, the pandabot, release the drifter to do a lot of things. If you come from GitLab, you have the danger bots. You can do some of the work, such as the reviewer who let to have someone assign as a reviewer, or some information of your merge request. But that didn't fit our use case well, and we made our own tools. And what I will do now is present you, rely on a use case example, so when a new feature is introduced inside Kubiquab, and how all the tools we designed help us to review the merge request, make sure the tests are passed, the dependencies are updated, and everything is published correctly. So for example, you have a merge request on the project, so on Kubiquab. A schedule job of assign bots will assign a reviewer based on user preference. In contrast to reviewer who let our assign bot from GitHub, you assign our assign bot, rely on group membership, but also on some user preference. So that if I can say, okay, I want to focus on reviewing a lot of works this week, I can say that I will review only like 15 merge requests during the week and three per day, and then change those values in time. And so that all every person does not have the same workload on merge request reviewing. Also, assign bot will take care of kindly remind you to do your work on the merge request and put in a comment if the merge request is inactive for a week. Then when you have a reviewer, the first thing that has to do is make sure the CI is green before anything else. And having a right job is hard to keep it up to date. So what we do is have a GitLab CI template. GitLab CI template is a project, an app.tox project inside of our app.tapod instance, and it defines a lot of jobs. And within a project, we will use those jobs to declare the stage and the jobs that we need. And this will help us reduce the CI load, because all the jobs will be customized. And so we make sure to have the right job definition. So here there is an example of GitLab CI. So we have Pi 3 and some Docker. We'll build some Docker image, but also we can have some extensions. So even though we have some shared job definition, we can always customize a job or create a new state or create a new job. And here is an example of the Pi 3 job. There are a few things to notice. First, it shows a customized Docker image with all the dependency already installed. So we don't waste CI time to install everything. It also stores some artifacts. In our case, all the deprecation running that occurs during the test. Among those things. When you have your test screen, one thing that you may want is to test your application. And what you can do is build Docker image. So when you have your magic rest accepted, we define another job inside GitLab CI template that builds Docker images. And what's present here is inside the image build latest job, we are using some specific tags or latest and also the hash of the commit. And we do this only if we are on the default branch. So if you are in GitLab, it should be master. But if the CI is running on a tag inside the repository, it's not the same tag to apply to the Docker image. So here we are using the CI commit tag. And we do this only if we are on a tag. Then when the magic rest is accepted, everything is published. At some point, you want to release everything. And in our case, to pipy. So that you are using release new. Release new is a small example of how it behaves when you run it. It detects a new version number that you will use for the next version and updates the code. And we do this by using the semantic versioning of all the commits between this version and the last one. And we generate a change log from the commit message. Always let you modify it if you want. Update the packaging information. So in Python, the manifest. And after all that, it try to commit and tag it correctly. And as we are using GitLab, the only thing you have to do is push everything to your repo. Because we have another job from GitLab, saying, hey, if you are on a tag, something you want to publish, then run this specific job that will itself publish to PyPy. Now that you have your, and it's everything released, you want to update all the dependencies. And for that, we use kube.doctor. kube.doctor can update the repository for various reasons. The first one is pretty simple. It just rebays all the made requests in a project to make sure that we can safely review the work and manage it. And we know if we have some conflict, there is some conflict, and we have to do some manual rebays. But also, it creates a made request to update the package version. So here on the right part, you have an example of a made request created by kube.doctor to update kube.doctor to the next version. Because at some point, we release a new version, and inside this repo, it updates the code to update the dependencies automatically. So as a reviewer, as a maintainer of a repo, we have made requests to update everything. And this here will be green, and I will just have to click on the on the made button, and everything will be updated. But also, kube.doctor will take care of some to create a made request for some linked configuration. And also, once you can also create some rules to automatically refactor all your base on the repo. So for example, as you saw earlier, we take care to collect all the deprecation warning from the test. We collect them, and we can analyze it to understand what are the deprecation warning occurring, writing a new rule inside kube.doctor to update the code, and then having kube.doctor creating all the made request needed to fix the deprecation warning. And with that, let me conclude. So the main part is within Lojla, we are using Eptapod, and this is a great tool with a lot of features. The main one such as the schedule job to have something run every hour, every week, from a thing about to kube.doctor to everything. We are using the registry a lot. So, the image registry with the code is currently tagged, but also some package, Python package registry, and we rely a lot on shared job definition. Having a good CI helps a lot to keep the clean update. However, having a good CI needs a lot of manual effort, at least in our case. And we end up writing some tools, so the tools that I presented you. So, I think I have some reviewer assigned automatically for a project, and make sure to not fluid someone with tons of magic requests every week. We use our own version of GitLab CI so we have one place, one single source of truth to create our jobs, and we can update it to have everything, have all to handcraft all the jobs and making sure to take full advantages of the CI. So, having custom images, artifacts, everything. We rely on release new to easily create a new version on the repository. So, having always the same commit message to on the new version, creating a change log, making sure the packaging is good, is right, and then GitLab compiles again to actually do the work to release to the Internet. And then when we have to update all the repository to update the code itself, we use Cubector with some rules that we write ourselves. And that helps us to have all our repository, several hundred of repository, always clean and that thank you for your attention and see you in the question phase. Thank you for your talk. I'm looking if we have any questions in the channel. Seems there are no questions here in the channel. But after looking on your presentation, I was thinking how you keep track of all the merge requests, I mean, because you automated pretty well everything, and how you keep track to see that the merge requests are not piling up or if everything works fine. So we did have a small period of time when we were having a lot of merge requests and we're not making sure everything was merged and reviewed. And we ended up having custom dashboard, so the dashboard, small static pages made with pages, features inside GitLab. So in GitLab you can have on every commit, rebuild the dashboard and see all the merge requests that are open, closed, ready to be merged because the CI is green. So we have this small web page that gather all the information. It's a central web page or is it for each merge request? No, it's a global one. So we have a project dedicated to gather all the information. So every hour I think it runs on schedule jobs and it poke around with the API, the GitLab API to see how many merge requests there are if they're open, closed, and everything. Cool. I'm looking at the channel if we have any questions. No questions at all. Then let me think, after representation you said you have GitLab templates. And those templates are like, what type of templates do you have even? I guess you have a library of templates, right? Yeah, we have several templates, mainly of three kind of templates. One based on the LinkedIn problem, making sure that we have the link correctly configured for each project, for Python, we could have some for JavaScript project, some to have the test correctly configured. So in Python 3, making sure the test could run concurrently, stores the artifact of the test. And the one related to release everything, so release to bypy, release to Docker, the image registry inside the GitLab also on Docker directly. Okay. We have one question in the chat. I was also wondering how you keep track, I mean, you mentioned you forked GitLab. I mean, it's a big tool. And how you managed to keep upstream? How you managed the... So Eptapod, the friendly fork of GitLab is not managed by us. It's a small company called Octobus. I have checked, I will send you the link just after. So it's a dedicated company that does this for us. So it has... We send money to them and say, hey, please make sure that you follow GitLab upstream and do not wait too long, wait just before updating anything.
improve the developer experience in GitLab and The main part will be on the tools that we design clients. We work almost only with open source software and we contribute with code or money on Logilab, we have a lot of repository. We are of them are hosted on Eptapad. If you have only several hundred repository is hard to have what I will do now is present you, rely on a use reviewer based on user preference. In contrast to but also on some user preference. So that if I a week. Then when you have a reviewer, the first a GitLab CI template. GitLab CI template is a artifacts. In our case, all the deprecation using the CI commit tag. And we do this only if want to publish, then run this specific job that your, and it's everything released, you want to requests in a project to make sure that we can some rules to automatically refactor all your one such as the schedule job to have something new to easily create a new version on the have to update all the repository to update the company that does this for us. So it has... We