Around the time of Microsoft Build 2025, the new GitHub Copilot Coding Agent was unveiled and made widely available across GitHub. With AI evolving at a dizzying pace in recent months, we imagined a “dream scenario”:
- A GitHub issue is filed.
- The problem looks to have a straightforward solution.
- A team member assigns the issue to Copilot, giving it a few tips.
- Copilot generates a pull request with the fix (and tests).
- CI runs, tests pass, and the pull request is merged!
This would dramatically reduce time and effort, freeing human developers to focus on higher-value, complex problems–while Copilot takes care of the repetitive work.
But would this dream be a reality? In this post, we aim to share a balanced perspective: highlighting both where Copilot has been genuinely helpful, and when it completely missed the mark.
In many ways, it already is. The .NET MAUI team has been actively using Copilot to boost our productivity, and we’re excited to share some practical tips for getting the most out of it.
At the time of writing, Copilot has risen to be the #64 contributor all time in dotnet/maui, which we expect to grow in the coming months:
Step 1: .github/copilot-instructions.md
To start with the basics, we provide GitHub Copilot with some general context and guidance for our repository by including a copilot-instructions.md
file. By convention this file should be kept in the .github
folder at the root of your repository or workspace. This works both locally when using Copilot in Visual Studio or VS Code and when using the GitHub Copilot Coding Agent on GitHub.
The types of useful instructions we keep in this file include:
- Project Context: What is this repo? Provide an overview of the project and relevant background information.
- Repository Structure: Describe the structure of the repository, what types of files go where, how to write tests, etc.
- Coding Standards: If you are using non-default code formatting, give specific examples of how you want your code to look.
A great way to start is to simply ask the Copilot Coding Agent to generate this file for you.
An example GitHub issue would be:
Go through this repo, review structure of project, source code, etc.
Additional docs to review about the product: https://learn.microsoft.com/dotnet/maui
Update `.github/copilot-instructions.md` to make Copilot more helpful going forward.
Include a note to update `copilot-instructions.md` with new instructions as the project evolves.
See: https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot
Assign to Copilot and see what it comes up with. You can review and remove any instructions that are not relevant.
See examples of copilot-instructions.md
files on GitHub at:
Step 2: Firewall Rules
When the GitHub Copilot Coding Agent completes your first assigned issue, you may notice a warning on the pull request description, such as:
This warning is actually a key security feature:
-
Imagine you’re working on a “top secret” private repository.
-
Copilot decides to make a web request to a public website to retrieve some data.
-
Copilot could have inadvertently leaked your private code to the public website!
While this is less of a concern in public repositories, this could still happen with GitHub secrets or other credentials.
If you want Copilot to be able to make web requests, you can review each firewall warning and configure rules to allow specific domains.
-
Go to the
Settings > Environments > copilot
page on your GitHub repository. -
Scroll to the bottom,
Environment variables
section. -
Add a new
COPILOT_AGENT_FIREWALL_ALLOW_LIST
variable with a comma-separated list of domains you want to allow.
Some useful domains to allow include:
learn.microsoft.com
– for Microsoft and .NET documentation.nuget.org
– to add new NuGet packages.developer.apple.com
– for iOS and Apple-specific documentation.developer.android.com
– for Android-specific documentation.
Note
$COPILOT_AGENT_FIREWALL_ALLOW_LIST
should not have a trailing comma. See copilot-coding-agent/user-feedback#41 for more details.Step 3: .github/workflows/copilot-setup-steps.yml
Building upon GitHub (a platform), the Copilot Coding Agent literally runs within GitHub actions. You have complete control over the environment in which it runs, giving you the ability to run steps before the firewall restrictions are applied:
-
Download and install additional tools or dependencies.
-
Restore NuGet packages or other steps that require network access.
-
Do an inital (working) build of the project.
This way Copilot has a working source tree, can make changes, build again (incrementally), run tests, etc.
As with the previous step, you can file a GitHub issue and let Copilot
generate the copilot-setup-steps.yml
file. Here’s an example:
# Setup copilot development environment
Setup a `.github/workflows/copilot-setup-steps.yml` file, such as:
name: "Copilot Setup Steps"
on: workflow_dispatch
jobs:
copilot-setup-steps:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.x'
# TODO: Build the project
See `.github/DEVELOPMENT.md` for more details on how to build this project.
See: https://docs.github.com/en/copilot/customizing-copilot/customizing-the-development-environment-for-copilot-coding-agent
Note that Copilot currently only supports ubuntu-latest
as its
runtime OS. If your project needs Windows or macOS builds, Copilot may
be somewhat restricted in what it can do. See (or upvote!)
copilot-coding-agent/user-feedback#40 for more details.
One important detail: make sure that copilot-setup-steps.yml
is
configured to always complete, even if your build fails. This is
done using continue-on-error: true
.
- name: Run dotnet build
id: copilot-build
continue-on-error: true
run: dotnet build -bl
- name: Upload logs
uses: actions/upload-artifact@v4
if: steps.copilot-build.outcome == 'failure'
with:
name: copilot-artifacts
path: '**/*.binlog'
Copilot (or a human) might push a commit that breaks the build. If you
leave a comment like @copilot fix error XYZ
, it needs to be able get
past its setup steps and actually fix the problem. Having a copy of
the failed logs can also be useful for humans troubleshooting in the
future.
Step 4: Setup MCP Servers (Optional)
A Model Context Protocol (MCP) server provides “tools” that Copilot can draw from to accomplish specific goals. In our experience, the Microsoft Learn Docs MCP Server is one of the most powerful tools available. This gives Copilot important context on many topics before modifying your code.
To set this up, go to your repository Settings > Copilot > Coding Agent > MCP Configuration
:
{
"mcpServers": {
"microsoft-docs-mcp": {
"type": "http",
"url": "https://learn.microsoft.com/api/mcp",
"tools": [ "*" ]
}
}
}
It is also a good idea to add the following guidance at the top of
copilot-instructions.md
:
## Development Guidelines
**Always search Microsoft documentation (MS Learn) when working with .NET, Windows, or Microsoft features, or APIs.** Use the `microsoft_docs_search` tool to find the most current information about capabilities, best practices, and implementation patterns before making changes.
Security Note
Just like the firewall allow list, the MCP server configuration is a potential security risk. Be sure to review any MCP server’s source code and/or documentation to decide if it is safe to use.To setup GitHub Copilot Coding Agent end-to-end:
Note that much of this is optional, but Copilot can complete tasks faster and more reliably with a complete setup.
Storytime: AI’s Little White Lies
As a fun experiment, I used the Copilot Coding Agent to create a new .NET MAUI app called CatSwipe. It displays cat images from thecatapi.com, and lets you swipe left/no or right/yes (similar to a popular a dating app).
The trouble began, when I asked Copilot to take a screenshot of the running Android app. I was hoping it would do something like:
- Boot emulator:
emulator -avd Pixel_7_API_35
- Install and run the app.
adb shell screencap /sdcard/screenshot.png
adb pull /sdcard/screenshot.png
Unfortunately, due to a configuration issue, it couldn’t start the Android emulator, and things quickly went off the rails! It instead decided to:
- Write a C# console app.
- Use
System.Drawing
to generate an image of an Android emulator and what it imagined the app would look like. - Check in the screenshot to the repository, as if it was a real screenshot!
This experience led us to come up with strategies for keeping Copilot on track:
-
When assigning issues, always add links to documentation. Write the issue in a way that a junior engineer (human) could pick up the task.
-
Be terse and direct but not necessarily rude. Mention how you’d like something done and don’t expect Copilot to discover novel solutions on its own.
-
Anticipate what might go wrong for Copilot. Tell it to “give up” if it cannot complete a task and report the error message.
-
Write scripts for common tasks and put examples in
copilot-instructions.md
that Copilot can use as a reference.
When Copilot does the wrong thing, it likely needs more context or
more instructions. Think of this as “debugging” your
copilot-instructions.md
file. Keep this in mind as you review pull
requests from Copilot, ask it to update copilot-instructions.md
during code review.
Conclusion
The GitHub Copilot Coding Agent is already showing strong potential in our day-to-day development. We’ve found it particularly effective for handling well-scoped, low-risk tasks. By leveraging Copilot for these “easy” issues, we save valuable engineering time and keep our team focused on more complex, high-impact work.
Copilot has been most successful in the dotnet/android repository, where we’ve specifically assigned it simpler refactoring-related tasks. In the past 28 days we’ve seen the following results with pull requests:
Author | Count | Merge % | P50 time to merge |
---|---|---|---|
@copilot | 17 | 82.4% | 10:15:34 |
All others | 49 | 87.8% | 11:36:35 |
P50 is 50th percentile, or what you might think of as the most common time a PR could be merged. In dotnet/android, Copilot has been pretty successful compared to all other PRs.
In dotnet/maui, we’ve been more optimistic: assigning PRs we knew might be too tough for Copilot to complete:
Author | Count | Merge % | P50 time to merge |
---|---|---|---|
@copilot | 54 | 16.7% | 10:15:22 |
All others | 255 | 52.9% | 14:36:47 |
Take these numbers with a grain of salt, as we have certainly been focusing a decent amount of time on Copilot. We could easily be giving Copilot PRs more attention as a result! Over the next several months, we should have a better picture of Copilot Coding Agent’s full impact on the product.
A few things that GitHub Copilot Coding Agent doesn’t do yet:
-
Comment
@copilot do this
on an existing PR opened by a human: This would be beneficial to fix tiny “nitpicks” instead of waiting for one of our contributors (potentially a customer) to make the change. -
Support running on Windows or macOS: This is unfortunately a big need for .NET MAUI, as the product targets Windows and iOS. Ideally, we could detect the issue or pull request is specific to a platform, and programmatically choose which OS to run on.
As the tool improves, we expect to expand its role in our development process.
0 comments
Be the first to start the discussion.