This past week I got access to the preview of GitHub Copilot X aka the one with Chat.
I've been heads down delivering my next Pluralsight course on React debugging and between ChatGPT and GitHub Copilot, I can tell you first-hand that AI copilots will change the way developers use your product.
Here's a small but significant example and I figured I'd write it up as it just happened since I have a tendency to write a lot when I shouldn't, like when it's midnight.
GitHub has a new way to configure codespaces called Dev Containers. I've never used them before tonight.
For my Pluralsight course, I have a full-on learning experience companion app with code challenges, it looks like this:
It's what I use to do all the debugging demos in the course. It's designed to be played with, poked at, and cattle-prodded by learners – even ones outside Pluralsight. It's a learning experiment I wanted to do to try and practice what I preach – gamification, hands-on learning, storytelling – ya know? We'll see how it goes.
Anyway, what I wanted to enable was a "one-click" developer experience so learners could click a button and get this up and running. No local machine shenanigans. No wrestling with config. I want a frictionless DX. Again, that's kinda my thing.
Well, I was able to achieve it using GitHub Codespaces and Dev Containers.
But not right away. You see, the repository itself has a folder structure like this, with materials for the course:
The learning app is all within the demo
folder.
By default, the dev container configuration will launch the Codespaces at the root of your repo which most people will want.
But in my case, I needed to launch it so VS Code is displaying the demo
folder contents, not the root, because I use different VS Code configurations and, well, it's just confusing. That's not frictionless.
I read the initial getting started documentation and had the following JSON configuration file:
{
"name": "Node.js",
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18",
"forwardPorts": [3000],
"postCreateCommand": "npm install"
}
This was easy enough because the file it generated contained code comments with helpful suggestions:
This worked right away, and I could launch my codespace.
But then my next question was, of course, how do I get this to show the right folder in the browser?
At first, because old habits die hard, I went to the docs.
GitHub has great comprehensive documentation of this feature but OF COURSE, the actual reference docs for this JSON file are hosted elsewhere and not linked anywhere that I could easily parse in the Great Wall of Docs.
Thankfully, the JSON file itself linked to it.
Once I got to the right spot, I spotted two settings that looked promising: workspaceFolder
and workspaceMount
. However, it was a bit confusing which one did what, and the mount expression was unfamiliar to me.
The docs, in this case, didn't go into further detail.
Alarm bell. If a developer gets stuck, there's a decision point. I could soldier on and try to figure it out through trial and error. Or abandon ship.
It's hard to know what goes on in a developer's mind so I'll just tell you what went on in mine:
Dang it. What do I do? These HAVE to be it... there must be some magic value I can pass to one of these or both of them to make it work. Ugggh, it should have been simple why is this so hard. I really want this to work.
I felt like this was the right direction, and I wanted it to work, so I continued. That's me though, I have been on enough support calls in my life to know that many devs (and people, for that matter) will throw up their hands at any sign of resistance – that's when they'll seek help instead of trying to debug the issue. I took on the React Debugging course for a reason, dangit, I AM The Debugger.
In fact, I had an idea 💡
I certainly have no idea what to do, what if GitHub Copilot can tell me what to do? This would put its hype to the test. I'll be honest, I didn't think it could help me, despite me using it just the other day to write a duration formatting function that I hooted for joy in the dead of night in my basement when it worked and I didn't even need to Google anything. Despite the fact that earlier today it uncovered a bug in my sample code I didn't intend (shh, you didn't hear that!).
No – I remained skeptical.
On the right side of my editor, I opened up the Copilot Chat and started to tell it what I wanted.
I began... a conversation. I'll reproduce it formatted below, emojis representing my reactions:
workspaceFolder
property in the devcontainer.json
file to /demo
as it is already set in the provided excerpt. This will make the demo subfolder the root folder of the workspace.
Here is an example of what your
settings.json
file could look like:[example]
workspaceFolder
set to /demo
but the browser is still loading VS Code at the root of the repo instead of the demo
subfolderworkspaceFolder
property in the devcontainer.json
file to /demo
, but the browser is still loading VS Code at the root of the repo instead of the demo
subfolder, you can try setting the workspacePath
property in the .devcontainer/devcontainer.json
file to /demo
. This will set the workspace path to the demo
subfolder.Here is an example of what your
devcontainer.json
file could look like:[example]
In the meantime, you can try setting the
workspaceFolder
property to "./demo"
instead of "/demo"
. This will set the workspace folder to the demo
subfolder relative to the root of the repository.Here is an example of what your
devcontainer.json
file could look like:[example]
workspacePath
it says the property is not allowed according to the JSON schema. I tried the ./demo
for workspaceFolder
but it still doesn't work when the container rebuilds. Is there a different way to configure the codespaces editor?workspacePath
property is not allowed in the devcontainer.json
file.If setting the
workspaceFolder
property to "./demo"
did not work for you, you can try setting the workspaceMount
property to mount the demo
subfolder as the root of the workspace. This will ensure that the demo
subfolder is the root folder of the workspace, and the browser editor will open in that folder.Here is an example of what your
devcontainer.json
file could look like:[example]
This will mount the
demo
subfolder as the root of the workspace, and the workspaceFolder
property is set to "."
to ensure that the workspace is not nested within the demo
subfolder..
shows me the root of the container filesystem"."
as the workspaceFolder
property shows you the root of the container filesystem, you can try setting the workspaceFolder
property to "./demo"
instead. This will set the workspace folder to the demo
subfolder relative to the root of the repository.Here is an example of what your
devcontainer.json
file could look like:[example]
This will mount the
demo
subfolder as the root of the workspace, and the workspaceFolder
property is set to "./demo"
to ensure that the workspace is not nested within the demo
subfolder.demo
subfolder, but the workspace itself still seems to be rooted at the root of the container, not /workspace
/workspace
, you can try setting the workspaceFolder
property to /workspace
in the devcontainer.json
file. This will set the workspace folder to the /workspace
directory.Here is an example of what your
devcontainer.json
file could look like:[example]
This will mount the
demo
subfolder as the demo
subdirectory of the /workspace
directory, and the workspaceFolder
property is set to /workspace
to ensure that the workspace is rooted at the /workspace
directory.workspaceFolder
property to /workspace
and mounting the demo
subfolder as the demo
subdirectory of the /workspace
directory worked for you! If you have any other questions or issues, feel free to ask.OK. A few things.
At the start, like I feared, the answer wasn't helpful – I already had the config setting it said to try.
Then, it got worse – it hallucinated.
Because workspacePath
is a non-existent JSON property. I could see this in the editor because VS Code was also saying it wasn't an allowed property.
Luckily, it understood when I gave it some more context. As as last ditch effort, I asked if there was another way. I was thinking perhaps some other JSON file or configuration hidden somewhere.
That's when it got interesting.
When it asked me to modify the workspaceFolder
to .
it changed what I was seeing in the browser. Suddenly, something happened.
I could see that maybe this was on the right path, because all we needed to do, me and my new best robo friend, was change the folder from the root of the container to /workspace
which did have the contents of the demo
folder now.
I perked up.
It only took one more try, actually reverting back to the default value of /workspace
(which the docs never mention, btw).
This gave us:
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "Node.js",
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18",
"workspaceFolder": "/workspace",
"workspaceMount": "source=${localWorkspaceFolder}/demo,target=/workspace,type=bind,consistency=cached",
"forwardPorts": [3000],
"postCreateCommand": "npm install"
}
The magic was really the source=${localWorkspaceFolder}/demo
bit. That, plus having the right value for workspaceFolder
.
When this worked, I was ecstatic. This whole conversation probably took 15 minutes since I had to push each change and test it.
The story could end there but as I wrote this up, I realized something. Maybe you did too, if you paid close enough attention (I bet you didn't).
The answer was in the docs.
Here, let me highlight it for you:
WHY DIDN'T I SEE IT?
Well, why didn't you see it?
I think it's a combination of things.
- We scan, we don't read unless there's something we decide warrants attention.
- The code is all inline instead of formatted nicely in a code block
- It doesn't explain the example, so there was no call to pay attention
- The
workspaceFolder
setting doesn't mention the default value either - I was trying to comprehend what I was reading, I didn't know yet what the code block might be communicating because I had never seen it before
So let's take a step back now.
What does this all mean? Besides being a gripping story between man and machine where machine helps man triumph and cause him to stay up late (again) writing a longform blog post.
What does it mean, besides that?
It means: the way developers will interact with your product, your education, your... experience, is going to change.
Even though the answer was in plain sight, as a human being, I didn't see it. The machine did. Actually, I have no idea if it did, but it eventually led to the right answer with enough back-and-forth context narrowing, like a funnel where the ping-pong ball has no choice but to end up at the end.
Now it was possible the answer was "You can't do that," but that's a sufficient answer. At least I wouldn't wonder – I'd need to find an alternative way. But as the expert developer, based on my experience, I reasoned it was possible – just that I didn't know the exact details of how to make it work.
So anyway, GitHub Copilot is the real deal.
Look for my new React Debugging course in a few weeks, you can follow me on Pluralsight directly and of course, I'll announce it through the list.
Have a lovely day,
Kamran