Log in to watch

Log in or create a free account to watch this video.

Log in
Virtual US 2022
Share

Meet GitHub Enterprise

Recently the GitHub Enterprise Advocates attended DevOps Enterprise Summit in Las Vegas.


This provided an amazing opportunity to have conversations with developers, managers, and leaders, all looking to improve their DevOps skills and processes.


At DevOps Enterprise Summit we noticed a common conversation topic was how to improve developer velocity. There are numerous ways to do this, through streamlining processes, providing good tooling, and removing barriers and tedious tasks.


Watch our session with GitHub's Senior Enterprise Advocate, Christopher Harrison, who talks through GitHub Enterprise and how to break through these common barriers.


This session is presented by GitHub.

Chapters

Full transcript

The complete talk, organized by section.

Christopher Harrison

Hi there, I'm Christopher Harrison. I'm a Senior Enterprise Advocate at GitHub. Recently we were at DevOps Enterprise Summit in Las Vegas, where we had a bunch of great conversations, highlighted and demonstrated a bunch of tools, and generally had a really good time. What I want to do here is explore a couple of the big tools that we were able to highlight there, in particular with Codespaces and Copilot.

Both these tools are here to help enhance your development experience by both streamlining the setup and streamlining the actual coding process itself. So let's get on into it.

The first tool that we want to take a look at is Codespaces. Traditionally, the way that we develop software is we write everything locally. This is problematic because to write software, to write code locally, what I need to do is go grab a whole bunch of different libraries. I need to make sure that all my versions are correct. I need to do a lot of setup.

This process could be hours. It could potentially even be days. This is not only going to introduce a lot of lost productivity as my developers are having to focus in on this, but it also winds up serving as a barrier for InnerSource or for contributing to other repositories. If there's a shared repository that we're all using, and I maybe want to create a PR for a bug fix or to introduce a new feature, I now need to get everything set up in order to just start writing some bit of code. If that's going to take me three, four, or five hours, that's time that I'm going to lose, and it can really wind up being a blocker. It can be a barrier.

What we want to do instead is streamline that process. We want to basically just not have our developers do that. What we can see, based on some different input from Airbnb, from Facebook, et cetera, is that that quick access is going to help enhance collaboration, and it's going to make our developers' lives better. This is what Codespaces is all about.

Codespaces, in a nutshell, is a container that's going to run in the cloud that I'll be able to connect to using a couple of different IDEs, maybe Visual Studio, Visual Studio Code, JetBrains coming soon, or even just through the browser, which actually then enables me to be able to write code from literally any type of machine in the world. As long as I have access to a browser, I'm going to be able to connect up to my codespace.

This will all reduce that setup, because now I can define all of that once. I'll be able to go in and just simply say, hey, give me this codespace, and then away I go from there. Let's actually get in and take a look at this.

What you're going to notice is I have a repository here called pets-walkthrough. This is a Next.js application that's also using Mongo. When we think about what would be needed for local dev, I would need to have Mongo set up. I would need to have Node installed. I would need to have all the appropriate libraries, et cetera.

What I'm going to do instead is create a devcontainer folder. My dev container is built on top of Docker. It's built on top of normal containers. You'll notice that I've got my Docker Compose, and here what we're going to do is bring together two images. I've got the one that's going to be defined in my Dockerfile, more on that in just a moment, and I've got the one that's going to be pulling from Mongo. It's going to pull both of those images and allow me access to those so I'll be able to use that environment for my development.

The Dockerfile is going to be pulling a Node image from Microsoft. I created this actually just by using Visual Studio Code. There's a great extension for dev containers that has a whole bunch of prebuilt options. That's exactly what I grabbed here. I just grabbed one of the prebuilt options, and then I customized it. I also added in a setup to install a little bit of tooling that's going to be needed for my Cypress testing. I've got all of this set up inside of here.

That's going to handle all of my libraries, all of the services that I'm going to need. But what about the IDE itself? Well, if I open up my devcontainer, what you're going to notice is we'll be able to identify different extensions that my developer will now have access to. When we think about writing code, we're always going to need some set of extensions, so I can list them all off right here.

How do I access that container? How do I set up Codespaces? All that I have to do is simply hit Code, and then now I can hit a brand new codespace by hitting that plus. I happen to already have one, which is what I'm going to use, but I want to highlight the fact that if I create a brand new codespace here, this might take it a few minutes because it's now going to have to go grab all of those containers and do all of that setup.

Fortunately, I can prebuild all of this by going into my settings, going into Codespaces, and then setting up a prebuild. Now every time that, say, my main branch, or whichever branches it is that I want to set this up for, are updated, this can now set up a codespace that's going to be all set and ready to go, so that way my developers will literally be able to open this up inside of seconds.

While I'm in the settings for the repository, the other one that I want to highlight here: I'll scroll down, go under Secrets and variables, and hit Codespaces. You're going to notice I'm going to be able to create some environment variables as well. Again, thinking about development, it's not just going to be about those libraries. It's also going to be about that configuration. Since this is going to be using MongoDB, typically that's going to be set up through an environment variable, and I can define that right inside of here, which is pretty slick.

By the way, this does wind up being write-only inside of here. If I go in and I say edit, what you're going to notice is that I'm not able to read the value from inside of here. I'm still going to need to have permissions set up for my codespace to be able to read those variables.

Let's go to my code. My codespace here is called cuddly-memory. I kind of like that name, and we'll give this just a moment to set up.

Cool. Now, I did have a couple of files open, which is why it's giving me that little error message. I'm not going to worry too much about that. Here is my codespace. This is Visual Studio Code. A couple of things that I want to highlight here. First of all, over on my extensions, what you're going to notice is that there's a whole host of extensions in here, and this includes the ones that were listed inside of the devcontainer and the ones that I have configured as well. I like an awful lot of extensions, and so that's why you see all of them right there.

You'll also notice my settings are saved. I really like this workbench over here on the right-hand side, and so it's going to have that setting as well. All of this is now inside of my browser. I didn't need any local install. If I wanted to connect to this through Visual Studio, Visual Studio Code, JetBrains, I'm going to have that opportunity as well. For my demo, I'm going to stick to doing it inside the browser, and we'll see how we can start writing code here.

When we think about how my developers write code, they're almost always going to be using a framework. What's great about frameworks is that they help limit the amount of code that I have to create, because they're going to have a whole bunch of great tooling installed and set up for me.

The challenge, though, is that even though there's going to be this great library that's going to make my life easier, you can only abstract away so much. I'm still going to need to create my data models. I'm still going to need to add in the code to create a React component. I'm still going to need to set up a new model inside of Django, if that's what I happen to be using. A lot of times that winds up being boilerplate code, where you wind up just copying and pasting, or you wind up using snippets, or you wind up having to go out to Stack Overflow or out to the documentation to go look all of that up. That's not a great experience for my developers.

How can we help our developers be able to write more code by writing less code? This is where Copilot comes into play.

Typically, my developers are going to rely on different processes to generate code. It might be that they're going to copy and paste. Maybe they're copying and pasting. Copy and paste is a great way to just duplicate bugs across your project, and every time I copy and paste I then need to remember to make the little updates, and quite frequently you wind up forgetting those. So copy and paste isn't a great tool.

Sure, we can go to Stack Overflow. Looking things up on Stack Overflow has become so much of a meme that the meme itself is a meme. But now that's going to take me out of the flow, because now I'm having to go off to this other website rather than just writing code inside of Visual Studio. There's a lot of cycles that wind up being lost by having to open up those different tools, or just simply trying to remember how to do something in a framework that maybe you don't do on a regular basis.

This is where Copilot really shines. What Copilot will do is it will automatically generate code based on what it sees me doing. When I add in a comment, it will be able to read that comment and create code based on that. When I'm creating functions, when I'm making different calls, it will then start to predict and create the code based on what it sees.

Now when we're talking about maybe having to go look something up inside of Stack Overflow, I can just let Copilot do that for me. Or when I'm having to copy and paste, I don't have to do that. I can just simply say, hey, this is what I want, and let Copilot generate that code for me.

How does Copilot do all of this? Well, it's been trained on public code, publicly available text, so it not only understands how to write code, but it also understands language as well. As I'm writing my code, some context is going to be sent over to Copilot, and then Copilot will be able to make suggestions based on what it sees. This is going to include the code that I'm creating. It's going to include the frameworks that I'm using, so it will be able to make suggestions based on what I'm doing.

That last little item there about improving suggestions, I want to make sure that I highlight that only publicly available code is going to be used to retrain and to update Copilot. If you're working on local code, you're working on an internal or private repository, it's not going to be reused by Copilot. I also want to make sure that I highlight the fact that any of the code that you're creating, any of the code that Copilot is going to be creating, is not stored by Copilot. That is your code there.

There are extensions, plugins, for a whole bunch of popular editors, including Visual Studio Code, JetBrains, Visual Studio, and Neovim.

What do we get out of Copilot? A couple of very big things. Our telemetry shows that when Copilot is enabled, 25 to up to 40% of the committed code has actually been written by Copilot.

Developers also report 75% higher fulfillment. The reason for that is because Copilot is going to handle a lot of the different things that my developers just don't like to have to deal with. Nobody likes having to write boilerplate code. Nobody likes having to run over to Stack Overflow to look things up. By being able to let Copilot do those things, it frees my developers up to now focus on introducing business logic, on solving the actual problems that I want my developers to focus in on.

Additionally, we did a nice little study where we brought in 95 developers, split them into two groups, and gave them a task of writing a web server in JavaScript. What you're going to notice is that 78% of those with Copilot finished; 70% of those who didn't have access to Copilot finished. You can argue that with the relatively small numbers that we have there, that 8% is within the margin of error, and I would be inclined to agree with that.

But that bottom number there is huge. For those who had access to Copilot, it was an hour and 11 minutes to finish. For those who didn't have access to Copilot, two hours 41 minutes. That's a big difference, more than half. That's pretty remarkable. So when we're thinking about Copilot, we're thinking about this investment, there's certainly a lot to be gained out of improving the velocity of my developers through the use of Copilot.

Now I think the best way to do this is to actually see it. So let's go ahead and write a little bit of code here.

What I'm going to do is create a brand new component here. Let's call this pets.jsx. What I want to do is create a component that's going to go load data from an API and display all of that out as a list. That's what I want to do here. I'm going to let Copilot basically write as much as it can.

Let's start by importing in the library. So, import React library, and there it is. It's at this point that I want to highlight the fact that I'm not a huge React person. I prefer a different framework. I prefer Svelte over React. The vast majority of the web developer world really seems to prefer React. Okay, fine. So I typically go along with that for a lot of my demos and so forth. If you're not a React person, don't @ me. It's really to highlight how this works, how this behaves, especially inside of a framework that maybe you aren't overly familiar with.

What I know I'm going to need is a component here, and I know that in React that's typically done by creating a function. So let's just ask Copilot to do that for me. I'll say, create function component Pets. There we go. You'll notice that gray italicized text here. That is my bit of Copilot right here.

What I can do is, once that's there, I can hit tab to accept whatever it gives to me. If I want to see what's going on behind the scenes, I can hit Open GitHub Copilot, where what you're going to see is up to 10 different solutions that it thinks might be helpful. By default, it's going to show me the ones that it is very certain are going to be what I'm looking for. This allows me to see what's going on behind the scenes.

This gives me an opportunity to highlight a couple of very important things. Number one is that Copilot is not necessarily going to write perfect code. So I might have to tweak some things. I might have to talk a little bit more to Copilot to get exactly what it is that I'm looking for out of it.

The next thing, and this is a question that I get asked quite frequently, is how long does it take to get used to working with Copilot? My answer there is, at least for me, it took maybe about a half hour or an hour. What I find is if I'm not getting exactly what I want out of Copilot, if I just get a little bit more specific, Copilot will quite frequently give me exactly what I want.

You'll notice that I've created that component, that little function, and so now it's going to give me the export down at the very bottom because it knows that that's how React usually works here.

Let's start creating my list of pets here. That's going to be inside of a state object. Again, I'm going to let Copilot do this for me. So I'm going to create a state object named pets. There we go. Let's go ahead and just accept that. What this is doing is using the proper useState from React, and it's setting up my pets and my setPets. Pets is going to be the variable that will actually have my data. setPets is what we would use to now update that list of pets inside of React.

That's the first thing. The next thing is now I want to fetch this from an API, and you'll notice it's kind of trying to figure this out automatically for me. Let's just go ahead and tell it. I'm going to say, fetch pets from the API of /api/pets. Cool. Now let me just let it generate the code here, and then I'm going to talk my way through it.

What this is doing is it's using this hook inside of React called useEffect. What useEffect allows you to do is keep an eye on some piece of data, and if that changes, if something modifies, to run some code in response to that. Quite typically this is going to be performing some sort of a refresh, some form of an update.

There's one little catch when it comes to React and loading data. If I'm going to be making an asynchronous call, I can't do that directly inside of the component. What I wind up having to do is use this little useEffect. Right here is the filter. This is going to be what it's going to look for for data changes, and by giving it this empty array, that's effectively saying do this on load or when the component is ready. This is something, especially for a novice React developer, that they frequently have to go look up. I know when I was first learning React this really confused me in trying to find that, so that's now just right there. This does that inherently for me, which is pretty slick.

You'll also notice that now it's going to use fetch. If I was maybe using Axios or if I was using a different library to go get my data, then I could have imported that in and told it to use that, or probably it would have detected that on its own as well. In my case, I'm using fetch. You'll also notice that it's got a couple of little then statements here to do the next thing. It's going to go grab the JSON from my response object, and then it's going to grab the data and put that into my setPets right there.

If I wanted to tell this to do it with async/await instead of using then, which honestly is my personal preference, but I'm not going to worry about updating the code, I could have told it to do that inside of the comment. This is again going back to what I was talking about previously: if it's ever not quite doing what you want, what you can do is just update the comment or update the bit of code, and it will start to figure out what it is that you're trying to tell it.

All right, let's finish this out here. Let's go ahead and return out my data. We'll let it return out my JSX and see what it does. There is my pets. It's going to give me an unordered list, and now it's going to map all of them out and display it out just like that.

Let's close out my return. Copilot did all of that for me. Now, you'll notice that it's giving me an ID, a name, and a type. It's just inferring those properties based on what it thinks a pet might have. It's using that English word. I do want to highlight that this does support other languages. If I was maybe writing this in Spanish or a different language, it would give me different property names based on the language that I'm using. But since I'm using English, it's going to give me everything here in English.

There's a real quick side note. If I was using TypeScript, what I would normally do is just create an interface, and then it would use the interface. But since I'm using JavaScript, that's what I have.

There is Copilot. This was able to generate all of that code for me with me just going in and creating a couple of little comments. Maybe at this point I would need to modify the output. Maybe I need to add in some different CSS classes that I need to have used here or whatever. But the core of my code has been generated by Copilot, again allowing me to focus in on the more important challenges that we wind up having.

This also then leads me into a blog post that I want to make sure that I highlight. You can find it in the description down below. It lists off a handful of different pitfalls, and one of the biggest is when it comes to tooling. If we're using a whole bunch of different tools, it can become very challenging. You might be thinking, well, wait a minute, isn't Codespaces and Copilot now just another tool that my developers have to learn? I suppose the answer to that would be yes, but there's a very big caveat on that: this very much meets my developers where they're at.

I didn't have to really do anything when it came to using Copilot. I have to make sure the extension is installed, but after that I'm just writing code and it's doing its thing. When it comes time to use Codespaces, all that I had to do was just go to the repository, and it was right there. So very much meeting my developers where they're at.

Where do we go from here? I definitely recommend checking out Copilot. There is a free demo that is available. I believe it's for 30 days on Copilot that you can go check out. Definitely explore Codespaces. The best place to start would be on those shared repositories, on those libraries that your entire team, that your entire organization uses. That way you're going to start to get the most bang for your buck there and start to see how Codespaces can really help your team there.

With that, I want to thank you for checking all of this out. Hopefully you learned a little bit about Copilot. Hopefully you learned a little bit about Codespaces. You can always come find me. I am @geektrainer. Thanks.