Submind YouTube summaries
Thumbnail for GitLab CI - A Template for Reusability

GitLab CI - A Template for Reusability

Watch on YouTube

Video summary

The video introduces GitLab CI as a powerful tool for achieving reusability and efficiency in software development, hosted by Francis and Nick from Cold Front Labs. The speakers begin by defining continuous integration (CI) as the practice of frequently merging code changes into a central repository to trigger automated builds and tests. This approach offers significant benefits such as rapid bug detection, reduced integration conflicts due to smaller incremental changes, and increased transparency for all team members. The presentation then distinguishes between CI, which focuses on testing, and continuous delivery or deployment, which extends this process by automating the release of code to production environments. To utilize GitLab CI effectively, the video explains its core architecture involving runners, pipelines, stages, and jobs. Runners are machines that execute the tasks defined in a project's `.gitlab-ci.yml` file, while pipelines orchestrate a series of automated tasks organized into sequential stages. Within these stages, individual jobs run in parallel to perform specific functions like linting, building, or deploying. The configuration is managed through the CI file placed at the root of the repository, where scripts define exactly what actions to take. Features like artifacts allow teams to save build outputs for later inspection, and the interface provides visibility into pipeline status, including detailed logs for debugging failures. A major focus of the presentation is on reducing code duplication through templates and variables. The speakers demonstrate how to create generic job templates that can be extended by specific jobs using the `extends` parameter, allowing teams to share common logic across multiple projects. Variables are used to inject dynamic values, such as target server addresses, into these templates without hard-coding them. Furthermore, the `include` parameter enables teams to embed external YAML files directly into their CI configurations, serving as a single source of truth for reusable scripts. This strategy drastically reduces file size and maintenance effort, ensuring that updates to standard procedures automatically propagate across all dependent projects. The video concludes with a practical demonstration of deploying Drupal sites using these templating strategies. The team showcases how they structure complex workflows involving initial database creation, configuration imports, permission fixes, and automated backups using custom scripts. By leveraging variables for SSH keys and site aliases, they manage multiple environments like development, QA, and production from a unified set of templates. The final takeaway emphasizes that while the initial setup requires understanding these concepts, the resulting system saves considerable time by eliminating repetitive coding, ensuring consistency across projects, and providing confidence in the build process through rigorous automated testing and deployment pipelines.
Read the full video transcript
so welcome to galaxy on a template for usability I'm Francis and I'm a project specialist at cold front labs I work on a lot of mating tests and we're closed right and I'm Nick I do a lot of like front-end JavaScript stuff that cold front labs as well as Drupal theming and a little bit of module development so today we're going to talk about get lab CI and before we get into get lab and what you can do all the amazing things you can do with it we're gonna quickly go and talk about continuous integration and what it is just a note on terminology I'm going to use the words merge and merge quest quite a bit today these are similar to the terms pull and pull requests in other systems but even get lab you say merge so just so I don't lose you on the terminology it has to do with the practice of integrating code into a repository or yeah the act of integrating code into a repository so at its most basic continuous integration is the practice of merging changes into a central repository on a regular basis and running automated processes builds tests etc to verify that the build is functional instead of keeping code on individual computers developers merge their code into a shared repository frequently generally on a daily basis or more often so that everyone has access to the latest version of the code depending on who you ask there are anywhere between like 33 and 30 mils of CI today we're going to keep things simple and highlight just a few that everyone pretty much agrees on the main tenets I guess would be that code is stored maintained and updated in a single central repository this doesn't mean on your production web to it this means by changes to the code should be small and modular and merged in on a regular basis and every commit should be tested automated self testing builds should be run to ensure that the build is working so some of the benefits of CI have to do in reducing time spent tracking down bugs speeding up code integration and increasing visibility and transparency because you're constantly running tests on your code bugs are found quickly it's also generally easy to isolate about be cut or the positive about because code changes are kept small and in small manageable chunks another benefit of making incremental changes is that there's less likelihood of integration conflicts when coding honk let's do our eyes they're generally pretty easy to deal with because you're only dealing with a small number of changes that displeases the chance of making mistakes when dealing with conflicts and also avoids compounding issues memorizing food since the code is stored in a single place everyone always has access to the latest version and could tell the status of the build at any time without having to track down individuals and ask him like how features doing or where bottom is at or all of that stuff so the major takeaway about CI is that it saves you time having everything in well-tested manual manageable chunks speeds up the development process and here automated CI processes give you confidence in your code because it is being built and tested with each commit [Music] so the workflow for the CI Pasha's is simple you have your central repository where your code is saved and this might be your master branch if you're using git and Jesus to this code are made by making copies of the code and merging in small changes back to the main repository on a regular basis in our project we follow a feature branch workflow for CI we create branches of code for building and testing and then of these branches are merged back into our main master branch finally processes such as code code checks tests and builds are automated so that they are run on every commit every change you make to your code is tested and verified some examples of automated tasks include running a linter it to checks your coding syntax and standards running compilers to ensure your code is building and running validation tests to ensure that functionality is working and everything is we're going to check for regressions - whether using feature branches or committing directly to the master branch it's important to remember the continuous in continuous integration to realize the benefits of CI you have to commit often and keep changes to a reasonable size for example it's much easier to read something like this in which a dependency a single dependency has been added to the project then to read something like this where there are many many changes like images being added dependencies added components created and configurations changed all in a single change so sure you can read through large volumes of changes but it's much quicker to deal with things in those small chunks that we talked about previously okay so Nick told me I shouldn't spring pop quizzes and presentations but does anyone know what CDs dancer does Yellin oh okay continues delivery so actually it was a bit of a trick question but I guess it actually gave more people the opportunity to get it right can this continuous deployment or continuous delivery basically have is following the CI process but then tacking on automated deployments to your automated processes these deployments might be triggered automatically which would be continuous deployment or continuous delivery in which case you are manually trigger your deployments but they're still part of your automated processes in our examples today we're going to include automated deployments as part of our CI okay all right so now that you all are masters of the CI seedy lifestyle we're going to get into our main topic here get lab CI so before we go into the nitty gritty good lab CI stuff we're going to tell you why and how we use it so the first the most obvious reason is that gitlab we host a lot of our projects on get lab be it for internal use sort of personal projects or clients and get leb ci is built in to get lab and it's free to use the next one is it's really easy to configure we'll get into this a little bit later but essentially all you have to do is add your get lab CI file into the root of your repository and you're done it'll run every time you push next it offers really good process control you could run individual pipelines without necessarily having to make code changes so if you just needed to run a test again you could go through the gate lab you I go into pipelines and run your your stuff manually without having it to pick up on changes and go and you can also save artifacts to your build and what this is basically when we run a production deployment get lab CI saves a compiled code version of our build which is the artifact so that we can go and download it later if we need to we need to figure out what went wrong or was it broken when we built it kind of stuff and for those of you who know our boss he also told us to use it and so we had to so at copán we use get web CI for a lot of different things we run a lot of code checks and linting on our PHP in our sass and our JavaScript code we use it to build and deploy our Drupal seven and eight sites UJS projects and even popular images and we run validation like backstop Code section acts and a couple other things on our sites and we run security audits using dress composer and again so now that we told you what we use why we use it and what we use it for let's start things off with some basic terminology get the home people exit process are kind of broken down into four main things runners pipelines stages and jobs so a runner it's basically a machine typically a virtual machine that takes all of your code from your repository all destructions in your CI file and if we execute any tasks it runs things get lab provides a set of free runners for you to use if you're going to get lab comm there are some usage limits they're pretty high though I think you are allowed to run 1000 pipelines per month is it typically you would create your own runner so you don't run into any limitations and you can optimize it for your own processes runners are what makes your CI process go they run your pipelines pipeline is a pretty generic they like it's the wrapper term for your jobs that you're running it will basically just contains all your series of automated tasks that you run on your code and they contain multiple stages a stage is a category within your pipeline you may have a little stage or at the chlorine stage probably all of those things and the order in which you declare the stages or the order in which they are run they run consecutively which means basically one stage must complete before the stages after it can begin to run so like the lint stage must finish before the build stage begins and the deploy stage has to wait for the builds to finish before it can also run an important thing to know about your stages though is that while they define the general order of your pipeline they don't actually execute anything that's what jobs are for so a job is an individual task contained within the stage it's where the functionality of all your CI processes are written you can have multiple jobs contained within the same stage so for example when you're linting something you probably maybe have JavaScript and SAS so you're gonna want to run tests on your es lint or JavaScript style int for your SAS code it doesn't make a whole lot of sense to run es lint and styling in the exact same job yes they're both linking processes but they're for two different languages they should be separated into two different jobs so within your lint stage you could have a es lint job and a style lint job another important thing to remember about jobs is that unlike the stages that they're contained in they run in parallel so when your lint stage begins both your es lint and your style and jobs will start running at the exact same time once the third matters as long as there is once all your jobs in a stage have completed that stage is then completed itself and then the next stage is all of the jobs inside of it can start running so let's visualize so here you can see we have some groupings of tasks all of these tasks are what makes up your pipeline within our Python we have three categories lint build and deploy these are our stages within each stage we can see some individual tasks these are jobs we have es lint or silent in the lint stage we have a job called build in the build stage in the job called the deploy in the deploy stage so when a pipeline begins all the code and instructions are sent to your runner and all the jobs within the first stage will begin to run but now just because all the jobs started at the same time does not mean that they will finish at the same time fortunately before the build stage can begin all of the jobs in Billund stage must succeed once all the lint jobs have succeeded our build can go and this process basically just repeats throughout the whole pipeline each stage must finish before the next stage can begin all right so let's take a look at configuring so Nick mentioned the CI file which is used to control your pipelines right I forgot a slide which I always do here we go to create a pipeline so Gill at CI is controlled by file called the gitlab CI yellow file this as I mentioned is used to tell get lab what to do it defines the pipeline and get lab will automatically detect this file when you place it at the root of your repository so let's go have a look at that file so you can see at the top of this file I have defined the stages in this case we have a super simple example we have three stages lint buildin boy down here you can see the jobs I have an es link job in the lint stage a build prod in the product state or the build stage and deploying the deploy section now can any to see how well you've been listening and he wouldn't tell me why we would have three stages when we only have three jobs and you know we could just have them in a single stage why would we have these jobs in individual status so you guys exactly so you need them to run one after another so in in this case you can see that we have very simple scripts the scripts are what tells the run are exactly what to do during the job we just run a linter to check syntax run a build and then deploy that build out to a server you'll notice that in the build stage we create an artifact and that's what is used grabbed by our deploy stage to copy over to our to our web server let's go take a look at this in the gate lab UI that's a little oh and something I didn't mention here you can control by an artifact size expire so you probably don't want these you know if you're if you're building as much as we are you probably don't want those artifacts sticking around too long so you can control when how long you want get loud to hold on to those for you all right so you can see that the latest on the pipeline's page of the gate lab UI you can see that I have my demo branch here and I've actually had all the stages succeed um you can click on a stage to see the builds that were run within that stage and you can see here that my linting task actually failed earlier so let's go have a look at the terminal output for that job here you can see that it ran the npm install just fine but it did fail on the engine from linked because of syntax error on in my main J's file if we go back to the pipeline after fixing the linting error let's go have a look at that build that we that we ran you can see here that those job artifacts can be accessed downloaded or you can browse to the files that were that were saved in that artifact we specified in the file you can also a kind of a handy feature that I like is if you create merge requests you can go and see the stat the most recent status of the pipeline that was run against that branch with a merge request another handy little tip you you can also run jobs again which is something they can mention and you can also run whole pipe lines if you if you have a reason to to want to run a specific branch at a later point okay so going back to our gate lab CI file I'm going to go to version 2 there we go so some of you might have picked up on in the last version of the file I'm not sure if anyone was paying that much attention but we had some repetition going on in our job skirts because I had npm install written in every script parameter in this version I've moved that up to the before script which is a special keyword in github CI which will just run all of those commands you list in the before script array prior to every job in the file there are also a series of other keywords such as after script so that you can kind of reduce redundancy in this CI file as you can imagine as we add jobs things easily get you'd have a lot of repetition going on in this version of the file I've also added two new deploy jobs I've added a deploy dev and deploy QA because I didn't always want to be deploying to my production server once we introduced jobs like this I don't actually want to run all three of those jobs every time I run the pipeline so we've added these only and accept parameters to make sure that we deploy to dev when for a commit as made to a branch except in cases where we commit to the master branch and then the deploy to QA will happen whenever we make a change to the master branch I've decided to trigger my deploying to prod manually because I don't want to accidentally have that happen anymore so the taking a look at these scripts you can see that actually there's a lot of duplicated code here because pretty much everything is the same between my deploy jobs except for the location where I'm actually copying that build to this gets especially troublesome when you imagine adding multiple validation jobs to all of your cert or to test code on all of your servers and adding like we we get to the point where we have you know nine stages and probably 20 to 30 jobs yeah and so if you're you know it it adds a lot of bulk to your CI file if you're repeating code so what's the answer to this problem of dilute 10 please okay so templates the reason you probably have come to this presentation okay so get lab see our templates are pretty much exactly what they sound like they're pre-made jobs that you have created that you can extend to fit the needs of your of all your stages and these do you can have script stages only accepts dependencies anything that another job could have that's what a template can also have all these parameters are inherited by the job that's extending the template and you can customize and override each parameter whenever you need just in case you need something a little different in a previous example they had three different jobs for deploying to three different servers we could easily create a generic deploy template to handle all of these so let's take a look at how we would do that so here we have our production deployment job I've taken the liberty of removing some of the functional the screen went away yes yes so it is essentially yes I'll let you attach to the dog and so they're accessible by the other runners it just makes the next I'll be able to has like a storage it has some temporary storage that you can use typically you would make your own caching server not ours for the most part we also have our own good lab instance so we control the whole server yes we sure do yeah so I actually just had a build issue and I was like trying to make the demo and I wasn't gonna troubleshoot it so I just went back to recording it's because fun fact your NPM walks like the package - lock JSON file is read first and then the package.json file is read to install any updates so your log file does squat all unless you use okay carrying on so we have our deployment job here for Prague so I've replaced some of the functional code with comments because you guys get we don't need to see all of the code so we know by looking on a previous examples that this job looks pretty much identical to our deployment jobs for dev and QA except for the server so they're all part of the deploy stage that although the SSH key they all are sync like they're all basically the same so the first step in to turn is into a template is to rename our job so we've named it deploy template and so we're just telling everyone what it is so you'll note the period before the name this is a handy little tool that tells gitlab that this is not just an ordinary job it won't run it because it's hidden from the CIE process so next we'll get rid of our only and accept parameters you could have default values for them if you wanted which is totally cool to do but for our purposes right now we won't worry about that so now looking at the script parameter the only thing we have left is the big problem the server is hard-coded right into the script to solve this we will take advantage of variables so variables allow us to really harness the power of getting leb CGI templates just like any other language variables or data storage key value pairs you're good you can declare variables in a few different methods and levels which we won't go too far into but essentially you can declare them per job per pipeline per project and even per group inside of gitlab itself so you can use variables pretty much anywhere you want within your builds except for a few small exceptions and those exceptions can be found in the gate lab see I documentation about variables so yes so depending on where you would declare them that's where its scope is when the CI process begins on your runner all of the variables in your various scopes are loaded as environment variables just into your terminal so you would access them like you would any other command line environment variable so let's see how we can use variables to finish off this template so Clare a variable in a template we use the variables parameter which is a basic Hamel array so now that we have the target server variable available to us we can simply remove the hard-coded server and plug in our variable so now as you can clearly see our slides are using bash so we access our variable through the dollar sign and then the variable name obviously if you're using what does match your PowerShell or something there'll be a slightly different syntax but you get the gist so the next step is to actually use our template to allow drops to pull from this newly created template we use the extend its functionality we use the extends parameter this basically tells get lab that when it gets to our job it needs to go look at our template first I use that as the base job then look at our new job and make any overrides or customizations based on that you know like like a template so let's look how we can use this template in our deployment job the first step is to tell get lab that we are extending our new template using the extends parameter next we need to make use of our target server variable and give it a value for this job so in this case just drop 4.com finally we'll add our only except rameters back because they're specific to our job to make sure that we don't accidentally have a dev build deploy to queue at production that would be unfortunate so following these steps we could upgrade our dev and QA stages as well there were jobs as well so here you can see we've extended our template declared our variables and made our own lean except rules pretend the real only accept so while these templates help reduce duplicate code it may not seem so important in this situation we only have a few jobs to execute the same code but when you have multiple types of builds multiple types of deploys a whole bunch of tests that run before and after those deployments they the repetition can add up really quick okay so extends and variables is great they're all very nice to use but what if you have multiple projects on git lab that needs these templates so you start off with one project with a pipeline in a template then you add another and another one and more templates more projects more pipelines more bills it's just getting ridiculous so you may be like our good friend Leo here and think that that's just way too much work to support all those projects with their CI bills and all their templates and you're right it is way too much work we would know we used to do it we would have all of our clients projects and all of our projects with their own CI build files all using these sort of templates we've made in our files all extending them and then if we updated one of the projects we would then have to make sure to go through all of our other projects and update those as well to make sure that all of our builds are on the same on the same stage there and this is where the final key feature of templating comes into play the include parameter the include parameter is a global parameter just like when you're declaring your stages it goes like right at the top of your gitlab CI file it functions as a basic list of URLs all pointing to different Gambel files when you add a gamma file within the includes parameter get much the IVA basically look at the URL go to that URL and embed all of that ammo as if it were written in your CI file itself this allows you to have a single source for template files all of which can be included extended and customized throughout all of your without having to update constantly so as an example these two slides are exactly the same as far as get lassie is concerned so not only does this allow you to include templates across multiple projects but it also drastically reduces the amount of code you have in your CI files so we'll end our official slide presentation with some important notes to keep in mind when you're working with templates all the parameters like script and stage and all that they're unique this means that if you have if your template declares a stage and your job declares a different stage when the gitlab CI runs your job stage will be the only one that's respected will not look at both of them a really important example for this is your scripts you may have a lot of default scripts written in a template if your job has a scripts parameter all of your default code in your template crushed is gone you cannot have two scripts so if you need to customize the script for this one job even by like just ever so slightly you would have to rewrite all of the scripts for that job unless you can somehow work it into variables like we do the exception to this rule is when a parameter is basically just a list of key value pairs like variables in that case get lab will merge those two parameters so let's say you had your target server variable in your template and then you added a site alias variable in your job itself your target server will be respected building into a list another important note is that jobs are limited to one template you can't combine multiple templates into one which is only a temporary limitation coming and get lab 12 they're changing the extends parameter to take a list of templates so you could have multiple templates combined into one job where that could be useful is like for us we have our basic set of like only and accept rules for deploying to different environments that we just caught and throughout everything all of our projects follow the same tagging and branch naming standards it would be nice for us to have a template that is just be dead deployment categories and extend that with another template so that when we make a dev deploy we can say take the deploy take the dev deploy and then we're good so we do have I believe we have some time left so we can do questions although we had a couple however we can also show you how we deploy Drupal with git lab CI and it's going to be very technical because we're basically going to show you how we template it all out okay I actually have it oh yeah here okay so it's big enough you guys want a little bit bigger good okay so essentially when we're making a build we have our template for building Drupal which essentially is just making sure composer is run and NPM is run and we add some default artifacts just naming our artifact and how the artifact will be saved and then we kind of customize it what we do with our templates is we kind of make templates from our templates to import into our jobs because basically our dev Bill is going to be the same pretty much every project we do our Drupal dev wants to build the exact same way so we have our build template then we have just a job that is the dev build and then we include that throughout all of our projects so that if we change the dev build once anywhere all of them will update and make sure they all deploy the same way so here you can kind of see some examples of the artifacts here is a good example of where parameters that are key value pairs are merged and not crushed so in our template we declare the name of our artifact and what pads it needs to save as the artifact and then in our dev build we have artifacts again and we're adding a new key to tell it that our dev field should expire in one day scroll that up a little bit so in this case artifacts in both the template and the build are kept there just merged into one so then we have a slightly different process for our release builds where we get into a lot of crazy templating is our deployment stage so we have two different kinds of deployments I won't go into initial deployment just because it's a weird use case and we have to deal a lot with drush which i don't want to talk about dealing with rush so essentially how we deploy to Drupal is we build it all through through composer and then just used rush site aliases to arsenic everything where it needs to go so the whole site aside from the database is built on our runner and then we just copy it all over so you can see a lot of like this is where variables come into play because you see like we have site aliases options ssh options our alias group our alias their alias type and then we SSH everything and then we run a bunch of other commands to get dress up to date we even wrote our own backup script because drush 9 took out the ability to then backups on your site because why not don't work yeah so we made our own little PHP script that is essentially Drescher so we do a whole lot of things we run the Drupal fix permissions script that you can get on drupal.org with a little customization by us and essentially it's all automatic we can go from no dev site on the server at all to a completely functioning dev site with just clicking the CI build run so it depends on which one we're running we have our initial Drupal deploy this actually creates a database and gives it all that with the MySQL URL our normal deploy we just update the data then move on and then after we've deployed everything we actually run a bunch of updates so we automatically run like brush-up dB we import all of our config and we do some more permission fixing just because we've noticed that get lab CI can sometimes screw up some of the permissions I did consider showing you a full demo of it like running but sometimes it can take upwards of our entire presentation time to fully deploy like a functional Drupal site so that didn't really make a whole lot of sense unless I hit play at the beginning and then showed you the end result yeah and so then we have it split out so we have our update template which has our basic stuff and then we extend this template further so that we update our future environments specifically we update our dev environments and update our QA environments our product buyers and most of these are just taking from the template with the small exception of like we changed the dress alias type variable just so when we run rush it knows what server to go to what to do another example are we on we are we are yeah are we okay so our SSH key is loaded I can actually show you we have we've done like all out in this template essentially for all of our projects we just have a list of imported files and that's all our CI consists of for the most part so when we load SSH keys they are variable stored on a project level so within gitlab you can go into the UI and actually make variables and those are inserted into every pipeline in that project which is where we the actual keys yeah well they're as they're not committed to the repo so they're they're stored as like secure variables that only maintain errs and owners can actually access and then basically we have this before script run and all it does is it looks for our variable and just loads it in and that way all of our jobs can access our Devon and prod servers as needed and another cool thing although if you want to talk to me like after this you can come find me because we also have stuff that like when our lint fails it actually runs a fix and gives you that artifact so that you can download that apply those changes and commit them back up it is technically public I'm just going over with Matt our boss just if we are actually going to like give it out fully we will yeah when the slides become available you'll you'll get there okay thank you [Applause]