Transcript
Speaker: Hello, hello!
Speaker: It's Artistry of Code again, this time back in a group of three.
Speaker: And the hosts for today are Artur Wolny, Marek Kurbanowicz and Grzegorz Godlewski.
Speaker: So today we gathered to talk about my personal favorite topic of all, which is continuous integration.
Speaker: We'll go a little bit into the DevOps pit, talk about the processes and how they are modeled, executed over our code.
Speaker: Before we start, please make sure that you follow us on Spotify, Google Podcast, Apple Podcast, and you subscribe to our channel on YouTube.
Speaker: So without further ado, just like Grzegorz likes to say, let's start.
Speaker: Welcome to the Artistry of Code podcast, where we, together with our guests, are seeking ways of doing things right and having fun with it.
Speaker: Software, architecture, soft skills, teamwork and other crazy buzzwords.
Speaker: Are you ready?
Speaker: Let's bring more value to the business.
Speaker: Okay, gentlemen, first things first.
Speaker: So let's start from the definition.
Speaker: What is continuous integration?
Speaker: And I will let myself to start this divagation.
Speaker: So for me, the continuous integration is first of all, the process of integrating the code that we are working on to the main branch of the application.
Speaker: So this leads to a conclusion that there is no continuous integration without a versioning system.
Speaker: So it is always coming together.
Speaker: And the continuous integration process is meant to
Speaker: make the integration process safer.
Speaker: So it's a set of scripts run on every code change that is propagated to the versioning server that are about to verify if our code that we would like to integrate is meeting all the requirements that we have put on our cell phone on the source code that we produce.
Speaker: So those scripts can do things like testing, like linting, checking things that we usually or previously a few years ago did manually or in code reviews.
Speaker: So it's a matter of automation and saving our precious time.
Speaker: So this is my definition.
Speaker: Do you guys feel that I missed something?
Speaker: I don't think you have missed something.
Speaker: I wouldn't have courage to say so to the master of CI.
Speaker: But I would add on top that to me, the continuous integration can be somehow equal, at least in some aspects to quality assurance, because this is for me the quality assurance tool.
Speaker: Don't mix it with QA people, let's say, because it's everyone's responsibility.
Speaker: But without having the CI, I wouldn't say that we care about the quality at all because it has to be there.
Speaker: It really is much better than any kind of Git hooks or whatever we could use because, as we already mentioned many times in this podcast, we cannot trust the developers.
Speaker: even if someone is skipping the GitHub, not intentionally even because sometimes the GitHub maybe can fail for some stupid reason because of some setup and maybe GitHub were set up for Windows in some
Speaker: and they don't work on Linux as expected, and they fail successfully.
Speaker: So they don't break the git push or git commit commands.
Speaker: To me, the CI must have for the quality assurance thing in the team.
Speaker: For me, the continuous integration is very close because it's one of the most emphasized things about extreme programming.
Speaker: And personally, I'm a big fan of that approach.
Speaker: And when it comes to defining what CI is,
Speaker: First of all, I would say that that's a set of principles and practices which are allowing you to build up CI implementation.
Speaker: You guys covered the parts like tools, the responsibilities of it.
Speaker: I would just extend this by encouraging everybody to
Speaker: have a read about the list of practices which are very specific for a successful STI implementation.
Speaker: We're going to talk about them on the episode today.
Speaker: But if I were to define, for me, CI in only a couple of sentences, that would be a setup.
Speaker: in which the code being built by the developers or edited by the developers is frequently integrated even multiple times a day.
Speaker: So one manifestation of it would be the case where everybody's working on a single branch.
Speaker: And when I'm doing a commit, I'm having all the tests passing.
Speaker: I'm just going to push it so that Marek and Artur can have it in a matter of minutes.
Speaker: And then on their end,
Speaker: They are practicing continuous integration by downloading that commit and then instantly integrating, merging, resolving conflicts so that on each and every interval of not to be so strict, like an hour, two hours, but multiple times a day, we exchange code and we integrate that code.
Speaker: And in order for this to be stable, there's that set of principles and practices which come along.
Speaker: So we already know what the continuous integration is.
Speaker: And I feel like we fluently went to the next point, which is what are the benefits of CI?
Speaker: Because there are many, I believe so, even though it might be costful to introduce it into your organization, especially when you have like a big project with complicated process of working.
Speaker: But still, let's mention once again, what are benefits of using continuous integration?
Speaker: So to me, the main benefit is being sure as a team, not a single developer, the change which we are going to merge because we will usually use some kind of PR or MR, depending on the platform we use.
Speaker: The change which we are reviewing, for example, is really working because as
Speaker: pull request reviewer, you are not really going to check out the branch and run all the tests, all the linting locally because it's wasting of time.
Speaker: So you want to, first of all, see that the CI is green.
Speaker: This is the first thing I always do when I look at the PR as a reviewer.
Speaker: Is CI green or if it's red for some reason?
Speaker: Maybe there is already some comment from the developer.
Speaker: Why is it red?
Speaker: Because sometimes we may have some issues with the CI, unfortunately, but maybe there is a reason for that.
Speaker: So this is a key benefit for me of having CI.
Speaker: Another thing is that there is a lot of time being saved on CI, even if the CI can be expensive to some degree, because especially when we don't have like super fast CI for multiple reasons, it's still saving time of developers and the time of developers these days.
Speaker: is much, much more expensive than the time of the machines.
Speaker: So this is another big benefit of the CI for me.
Speaker: And yeah, I will probably stop talking now to not say everything and let you guys say something important.
Speaker: So as I'm the next in line, then I would say, I would start actually with a very small clarification here, because when it comes to the definition, and I kind of feel that when Madak you were explaining, that might also pop up there.
Speaker: CI is frequently understood by people in two ways, either as the set of practices as we define this, or as a continuous integration server.
Speaker: So things like Team City, Atlassian Bamboo, stuff like that.
Speaker: So it's very important to
Speaker: separate that in terms of, you know, when you're talking with somebody, you need to redefine whether we're going to talk about the practices which the developers do or the tools in terms of the CI server, stuff like that.
Speaker: But then again, and that's just, you know, like for the purity of the discussion.
Speaker: But when it comes to the key benefits, what I would emphasize is the following.
Speaker: So first of all, continuous integration helps to deal with integration bugs.
Speaker: So if we are having that two developers or a team of developers which are coding all the time, sometimes there are some ideas which are contradicting in the code.
Speaker: And if we exchange the code frequently, we shorten that feedback loop where we can detect that there's an integration issue or there's an
Speaker: issue with the idea, right?
Speaker: So that's a very valuable thing.
Speaker: The second thing is that this kind of enforces and really grounds the practice of any kind of unit testing, integration testing, end-to-end testing, because that's kind of like a prerequisite for having a successful CI implementation.
Speaker: So the mere fact that it requires it, it's a benefit on its own.
Speaker: So you're going to get a quality increase only by having that.
Speaker: And the last one, which I would like to emphasize, it's not that obvious, but when you have multiple developers working on the same code base,
Speaker: continuous integration has a side effect of modularizing the code.
Speaker: So if you have people coding on the same code base, in order to avoid conflicts, this actually will require a more modular design so that those people who are coding different modules in that application, they won't stop on each other's toes.
Speaker: really.
Speaker: So this also is a nice side effect of having the CI because it kind of leads you to a modular design just to manage the complexity of the integration.
Speaker: Yeah, these were really great points.
Speaker: I have a few to add.
Speaker: So for me, first of all, is that having a continuous integration as a server, as an execution environment to all the checks that we want to run over the code.
Speaker: First, it's unified.
Speaker: So we have like a certainty that
Speaker: Anyone who is working on the code will go through the same testing, checking routine, regardless if they have Windows, Linux, macOS, whatever, just like you, Marek, said.
Speaker: Second, it's usually coming nowadays with some kind of registry.
Speaker: so you can track how it was performing.
Speaker: If you have integrated, there are some important metrics about the quality of code, like for example, test coverage or some kind of performance testing that you do artificially.
Speaker: It's some kind of record that you can take like two commits from the master over which the CI has been executed and compare the results.
Speaker: If we're going into the good direction,
Speaker: direction or bad.
Speaker: And another thing that is also about this record and the tooling that we have is I want to say that what I remember from the book about continuous integration, I unfortunately don't remember the name, so we will try to put it into the description.
Speaker: But I remember the example that one team just implemented the check failed on the integration to master.
Speaker: they installed some kind of alarm light, red light that was going round and round and notifying everyone with the beeper.
Speaker: And they were just raising alarm that the code on the master is not deployable.
Speaker: So everyone knew that something is going on and the whole team could react and try to fix it immediately.
Speaker: So it reduces the risk of leaving the code problematic on the main branch, which we don't want to have.
Speaker: And it even calls out to fix it immediately, right?
Speaker: So that alarm set up in the office is just a cherry on the top, really.
Speaker: But one of the core principles is that whenever you find the build is failing,
Speaker: that has to be dealt with immediately.
Speaker: I mean, you drop anything else, everybody drops anything else, and this is getting fixed.
Speaker: Either by unmerging, you're reverting your changes.
Speaker: That's one of the easiest ways.
Speaker: Been there, so that had to do that.
Speaker: So this works effectively, I would say.
Speaker: But then again, yeah, that's a very important part of it.
Speaker: You really always have to take care that the pipeline is green.
Speaker: Yeah, that's true.
Speaker: I also wanted to mention that the benefit of having CI is a possibility to make your process of delivering software easier.
Speaker: So with this one, you can even go to the extreme, which is having only trunk or only master branch and committing there.
Speaker: So this is a way of working that...
Speaker: Dave Farley is trying to promote over the internet on his channel.
Speaker: I feel it's truly the easiest in the well-organized team.
Speaker: And without the CI, I don't believe that it might be possible.
Speaker: What you guys said brought me to one more thing here, or even two things.
Speaker: The one thing about like, it's regarding the ensuring that everyone is going through the very same pipeline of checks, etc.
Speaker: And it also reminds me about some issues which were caught in the past, thanks to the CI, when some tests were passing locally for the developer, and it was all good.
Speaker: But it was caused by the fact that he was on the higher node version than we had in the production.
Speaker: And this is like one tip, always remember to align all the versions on the CI with the production.
Speaker: And then it started to failing on the CI.
Speaker: And at first he was completely confused why it's passing locally and not on the CI.
Speaker: And then we found that this was the issue.
Speaker: So this is one other benefit.
Speaker: And the other benefit is that, like, this is just a small addition to what you, Grzegorz, said about the modularity, is that I found really many times from my experience that issues which are exposed by CI, like maybe because of long-running jobs or something, or random failures, et cetera, et cetera, they are like...
Speaker: pushing the team and punching us from the back to improve some stuff.
Speaker: So this is another thing which is really helping the team to improve the code, improve the quality, improve the tooling and everything, which is automated.
Speaker: So it's almost free, let's say.
Speaker: There is no cost of someone looking for improvements.
Speaker: It's just there and hitting us with some results.
Speaker: Let's do it, guys.
Speaker: Do something with this stupid thing.
Speaker: So yeah, a lot of benefits.
Speaker: Yeah, that's a lot of benefits, but it's not that easy to get to that point when we can benefit from running CI.
Speaker: So now let's go to another point, which is what are the challenges and requirements that we need to meet to have this continuous integration running smoothly.
Speaker: So I will start with my point.
Speaker: So first of all, we said that it's a set of scripts and checks executed to control the quality of code.
Speaker: So first of all, we need to have them.
Speaker: So yeah, just like Grzegorz said, it's putting the pressure on us to have those tests.
Speaker: So if we don't have them, we need to...
Speaker: start doing them.
Speaker: We need to prepare at least this minimal set of checks that will control over code.
Speaker: Why I believe it's important because the CI is the last resort that decides if the code will be integrated into the main branch or not.
Speaker: So we need to trust it.
Speaker: And all those checks that we will implement in the process
Speaker: needs to be reliable, needs to be deterministic.
Speaker: So every time we will run it, we will know that if it passed, then it's fine.
Speaker: If it fails, then it means that something in the code is wrong.
Speaker: And this is an interesting thing.
Speaker: Also a quote from Dave Farley from his last episode about CI is that we can't really trust that our tests will fail
Speaker: give us 100% certainty that everything is working fine.
Speaker: They rather say that things that we tested are working fine, but we are never sure that we covered everything, every flow in the code, even with those test coverage statistics.
Speaker: Yeah, OK, so I will try to not take all the points from this section.
Speaker: So guys, what do you think are the challenges?
Speaker: So for me, I would just emphasize two.
Speaker: First of all, it's the required mindset change.
Speaker: So if you're working on a team
Speaker: which didn't practice such way of integrating.
Speaker: That's definitely a groundbreaking change which requires employing a lot of those practices.
Speaker: And our people, you might always have people on the team who are not going to get along too well with it.
Speaker: So there is an education part, some mind shifting part involved there.
Speaker: which will take some time and they really have to be considerable about this.
Speaker: We have to have the empathy for those people because they need a little bit more time to get to this.
Speaker: And why this is hard?
Speaker: Because it kind of calls you to embrace conflict in a way that if you're going to integrate
Speaker: your code with others, you're going to be exposed for way much more communication just to settle things up.
Speaker: And sometimes, you know, when the code is conflicted, that's way much easier to deal when people have conflicting ideas.
Speaker: Now,
Speaker: Now, there's way much more to work on.
Speaker: The other challenge which I see with CI is the scalability of the CI because it's easy to start when you just have some unit tests.
Speaker: But later on, the code base and the test base is growing and growing and growing.
Speaker: The amount of people on the team also is growing.
Speaker: and the whole thing tends to get slow.
Speaker: And one of the requirements for CI is to have very fast builds.
Speaker: So this is also an area where you will have to do some engineering at some point, because if you're going to have those tens of thousands tests running, and if you flipped the test pyramid and you have more end-to-end tests, then I kind of say you're screwed with CI because...
Speaker: the most of the tests of the slowest ones will be there.
Speaker: So we're getting back to the test pyramid examples here.
Speaker: So my general recommendation would be that if you're starting a greenfield project, so you're going to create a repository today, in the initial comment, you put the readme file,
Speaker: And on the second commit, you define the CI tools already.
Speaker: So you already have things like Jest, you have the Bitbucket pipeline or the GitHub actions defined, the linter is in place, stuff like that, so that in the second commit, the base of CI is already there so that when you're going to add the things, you're going to have most of the work done.
Speaker: But when you're working on an existing code base, so you have a team which you're working on and the practices are not there,
Speaker: Make sure that you know what are the requirements.
Speaker: Make sure that you know what are the practices.
Speaker: Talk with your team and define which of them in what order you're going to employ.
Speaker: Because they're just jumping on everybody and saying, hey, guys, this is the list of 10 practices which we're going to start using from now.
Speaker: It ain't going to work.
Speaker: You're going to have a nice pushback and the whole idea might change.
Speaker: fail.
Speaker: So that would be my recommendations for some of the challenges which you may face while implementing CI.
Speaker: Okay, you guys said almost everything.
Speaker: It's really hard to say something now, but I have one more thing here in terms of challenges.
Speaker: And I think this is like the change of mindset sometimes when it comes to the tooling run, let's say.
Speaker: to explain more like
Speaker: It's some stuff is like super easy to run locally for multiple reasons.
Speaker: But when it comes to set up the stuff to run automatically on the CI and like grab the results as expected to get the step failing when it should fail, when, for example, some tools are not exiting with non-zero code, even if they are failing, because that's the way how they work for some reason.
Speaker: It comes with the challenges in this area.
Speaker: So you have to start thinking how to do that on the CI.
Speaker: Sometimes when we are doing something locally, it's really good to already start thinking about how can I run it on the CI.
Speaker: Is it possible to set it up on the CI if I do that this way?
Speaker: So it's like a complete change of way of thinking about what we do.
Speaker: Like I say, I like your points, especially the one about changing the mindset.
Speaker: I remember that it was once quite a challenging thing to make our stakeholders trust us into going with the continuous integration.
Speaker: So first of all, I would also say make team ready for it, make team trustworthy, then try to go with automatization.
Speaker: So last but not least, the part with tooling for the CI.
Speaker: So what we can use in the pipelines, where the pipelines can be executed.
Speaker: So what CI mechanism we have.
Speaker: So Grzegorz, would you like to tell us your perfect or at least minimal set of tools that you... Yeah, sure.
Speaker: So the bare minimum, which I always have, is the code formatting checker.
Speaker: So it's prettier.
Speaker: The SLint will configure it for TypeScript.
Speaker: We're talking about the Node.js environment here, and that's just for testing.
Speaker: For backend development, that's most of the time all I need.
Speaker: Right now, I'm using Big Bucket pipelines because I'm just using some free repositories over there.
Speaker: That's my CI of choice.
Speaker: But while I would be switching to GitHub, that probably would be GitHub Actions.
Speaker: And for me, that little set here is like covering 99% of my needs when it comes to day-to-day coding.
Speaker: How about you guys?
Speaker: So for me, the Docker is the tool that I like to use in the CI.
Speaker: in those checks, usually because using Docker compatible containers and for example, Docker Compose, I can reuse some parts of those checks also locally.
Speaker: I can integrate it into local scripts kept in the repository.
Speaker: So I can, for example, start some artificial virtual volatile environment for my
Speaker: local integration tests easily and reuse them next in the CI.
Speaker: So it's also important for me to make use of the CI engine that allows to use the Docker.
Speaker: And the second point for using the Docker compatible solutions is that
Speaker: We haven't said it previously.
Speaker: We should have done it because continuous integration, at least in my eyes, should end with some kind of artifact that will be deployable to the production.
Speaker: So we integrated our code.
Speaker: We should have something that we can deploy.
Speaker: And Docker is a very cool, or in general, containers are very cool artifacts to have because nowadays we have a cloud which based on the containers mostly.
Speaker: So yeah, this is my favorite tool.
Speaker: Marek, what would you add to that?
Speaker: One thing which I would add to the Docker is that it has a catch there, which is the DIN thing, which is the Docker in Docker challenge, which can sometimes really either slow down the CI, which is
Speaker: still the less difficult issue with that.
Speaker: But sometimes it can bring some issues with running the Docker at all in the Docker because some stuff will not work or will need massive workarounds to work.
Speaker: So while I'm a big fan of running the Docker on the CI, I always like to try to encourage to not use the Docker in Docker if it's the way how it will work on your CI of choice.
Speaker: and maybe look at the services or whatever it is called on the CI provider you use, which will take the Docker in Docker to run it really like Docker without the intermediate container which you are running your main CI processor because that's the way how most CI will work.
Speaker: So they will spawn the Docker container for you.
Speaker: So that's one thing.
Speaker: Another thing which is super important to me and I always try to push it wherever I am as developer is to find the way in your tool which you are using because it's now available, I think, in most CI tools in one way or another, but to run your CI
Speaker: on the merge result or whatever we will call it.
Speaker: So this is the challenge which comes a lot in the way of the teams using the CI.
Speaker: So to explain it is that imagine having like two PRs which are not directly conflicting
Speaker: because they are not touching the same files, but they are touching the same functionalities or side effects, maybe crashing.
Speaker: And one PR is both are green on the CI, but the first one getting merged,
Speaker: And the CI should fail on the second one, but it will not because it's running on the branch itself.
Speaker: So, for example, GitLab has amazing thing, which is called merge trains.
Speaker: So every PR will get rebuilt after the main branch got changed.
Speaker: with running the tests against the synthetic merge commits of this branch against the main branch.
Speaker: And this is super cool because it can save a lot of issues.
Speaker: And I can say that I've seen already code crashing after merging two green PRs because of this issue.
Speaker: So always try to push to get the CR running on the merge result.
Speaker: This is super important.
Speaker: Okay, thanks, Marek.
Speaker: So we're going slowly into the end of this episode.
Speaker: We mentioned a lot of cool stuff about continuous integration, but I'm sure there's plenty of them to add by you, our dear listeners.
Speaker: So feel free to share with us all your insights, all your experiences about the continuous integration.
Speaker: I personally would really love to hear what you do better than us.
Speaker: So remember also to follow us on the podcast platforms, Spotify, Apple Podcasts, Google Podcasts, like us on Facebook.
Speaker: And remember to subscribe on YouTube and see you in the next episode.
Speaker: Thank you very much.
Speaker: Thank you.
Speaker: Bye-bye.
Speaker: Take care.
Speaker: Bye-bye.
Speaker: That's all for today.
Speaker: Thanks for spending your time with us.
Speaker: Visit our page on Facebook and Twitter, leave us a comment under the episode, subscribe to the updates and share it with others.
Speaker: We would like to hear your feedback so that we can prepare more interesting content for you to enjoy.
Speaker: Hear you next time!

