Post

Instructions and prompts

It is no secret that I am using GitHub Copilot as my personal coding assistant. To optimize the quality of Copilot’s answers (and code), I recently started to use custom instructions and reusable prompts.

What are instructions?

Instructions are a set of customization commands we can give Copilot to specify our preferences. There are two main kinds of instructions:

Repository-wide instructions

These are valid in the context of the repo itself (like formatting, folder structure, commit preferences). These instructions live in the copilot-instructions.md file directly within the .github folder. A sample could look like this:

1
2
3
4
5
# C# Coding Standards
- Use PascalCase for public members
- Use async/await for I/O operations
- Follow SOLID principles
- Write XML documentation for public APIs

Path-specific instructions

These are valid in the context of a specific file path (like class files, XAML files, HTML files, etc.) and live in multiple NAME.instructions.md markdown files within the instructions subfolder. A sample could look like this:

1
2
3
4
# *.xaml.cs Instructions
- Follow MVVM pattern for code-behind
- Keep code-behind minimal, delegate to ViewModels
- Use data binding instead of direct property access

Both VS Code and Rider support both of these instruction types.

What are prompts?

Prompts are reusable instructions for specific use cases, such as refactoring code or generating tests. Like manual prompts, saved prompts follow the repository’s instructions. They are stored in markdown files within the .github/prompts folder.

A sample prompt file (e.g., generate-unit-tests.prompt.md) could look like this:

1
2
3
4
5
6
7
# Generate Unit Tests

Generate comprehensive unit tests for the selected code using xUnit.
- Ensure 80% code coverage minimum
- Use descriptive test names following the Given-When-Then pattern
- Mock external dependencies
- Include both positive and negative test cases

We can then trigger these prompts via Copilot’s Chat / menu for quick access.

Getting Started with Awesome Copilot

To jumpstart your Copilot setup, I recommend using a personal fork of the ‘Awesome Copilot’ repository. The repository provides a curated collection of ready-to-use instructions and prompts that you can adapt to your team’s needs.

You can either:

  • Fork the repository and customize the files for your project
  • Copy specific instructions/prompts that match your tech stack
  • Use their browser-based installer for quick setup

How to structure your solution

The instructions and prompts are saved in subfolders within the .github folder, which is created automatically when you clone a GitHub repo. If you are using Copilot but another source control system like Bitbucket, you will need to create this folder manually. The .github folder should always live at the root of the repository’s folder.

Once you have the .github folder, create both an instructions and a prompt folder, so your repo’s folder structure looks like this:

1
2
3
4
5
6
7
8
9
your-repo/
├── .github/
│   ├── copilot-instructions.md  
│   ├── instructions/
│   │   └── *.instructions.md
│   └── prompts/
│       └── *.prompt.md
├── YourSolution.sln
└── src/

Tip: If you can’t see the .github folder in finder or file explorer, you need to activate hidden files and folders. Hit Command+Shift+. on macOS to show them. On Windows, you need to go to the file explorer options, select View and find the Show hidden files, folders and drives option in the Advanced settings section.

Why this structure is important

VSCode and Rider are opening .NET solutions differently. While VS Code always uses the folder approach and just adds a Solution Explorer view, but stays in the context of the folder, Rider needs to open the solution directly to work with it, even if you are choosing a folder. Because of this behavior, it is important to keep the .sln file always at the same level as the .github folder - which should ideally be the root folder of the repository.

Only then you will be able to use both VS Code and Rider for your repository while keeping the instructions and prompts at hand. This interoperability is especially important if multiple persons work on the same repo as a team.

Conclusion

As you can see, we can keep interoperability of our .NET solutions easily just by following some easy conventions. If you follow this structure, you can make both VS Code and Rider following your instructions or use your prompts in the / menu of Copilot’s Chat. As always, I hope this post is helpful for some of you.

Until the next post, happy coding, everyone!

This post is licensed under CC BY 4.0 by the author.