|
| 1 | +## Scenario |
| 2 | + |
| 3 | +As any good dev shop, Tailspin Toys has a set of guidelines and requirements for development practices. These include: |
| 4 | + |
| 5 | +- API always needs unit tests. |
| 6 | +- UI should be in dark mode and have a modern feel. |
| 7 | +- Documentation should be added to code in the form of docstrings. |
| 8 | +- A block of comments should be added to the head of each file describing what the file does. |
| 9 | + |
| 10 | +Through the use of instruction files you'll ensure Copilot has the right information to perform the tasks in alignment with the practices highlighted. |
| 11 | + |
| 12 | +## Custom instructions |
| 13 | + |
| 14 | +Custom instructions allow you to provide context and preferences to Copilot chat, so that it can better understand your coding style and requirements. This is a powerful feature that can help you steer Copilot to get more relevant suggestions and code snippets. You can specify your preferred coding conventions, libraries, and even the types of comments you like to include in your code. You can create instructions for your entire repository, or for specific types of files for task-level context. |
| 15 | + |
| 16 | +There are two types of instructions files: |
| 17 | + |
| 18 | +- **.github/copilot-instructions.md**, a single instruction file sent to Copilot for **every** chat prompt for the repository. This file should contain project-level information, context which is relevant for most chat requests sent to Copilot. This could include the tech stack being used, an overview of what's being built and best practices, and other global guidance for Copilot. |
| 19 | +- **\*.instructions.md** files can be created for specific tasks or file types. You can use **\*.instructions.md** files to provide guidelines for particular languages (like Python or TypeScript), or for tasks like creating a Flask blueprint or a new set of unit tests. |
| 20 | + |
| 21 | +> [!NOTE] |
| 22 | +> When working in your IDE, instructions files are only used for code generation in Copilot Chat, and not used for code completions or next edit suggestions. |
| 23 | +> |
| 24 | +> Copilot coding agent will utilize both repository level and \*.instructions with `applyTo` header matter when generating code. |
| 25 | +
|
| 26 | +## Best practices for managing instructions files |
| 27 | + |
| 28 | +A full conversation about creating instructions files is beyond the scope of the workshop. However, the examples provided in the sample project provide a representative example of how to approach their management. At a high level: |
| 29 | + |
| 30 | +- Keep instructions in **copilot-instructions.md** focused on project-level guidance, such as a description of what's being built, the structure of the project, and global coding standards. |
| 31 | +- Use **\*.instructions.md** files to provide specific instructions for file types (unit tests, Flask blueprints, API endpoints), or for specific tasks. |
| 32 | +- Use natural language in your instructions files. Keep guidance clear. Provide examples of how code should (and shouldn't) look. |
| 33 | + |
| 34 | +There isn't one specific way to create instructions files, just as there isn't one specific way to use AI. You will find through experimentation what works best for your project. The guidance provided here and the [resources](#resources) below should help you get started. |
| 35 | + |
| 36 | +> [!TIP] |
| 37 | +> Every project using GitHub Copilot should have a robust collection of instructions files to provide context and best guide code generation. As you explore the instructions files in the project, you may notice there are ones for numerous types of files and tasks, including [UI updates](../.github/instructions/ui.instructions.md) and [Astro](../.github/instructions/astro.instructions.md). The investment made in instructions files will greatly enhance the quality of code suggestion from Copilot, ensuring it better matches the style and requirements your organization has. |
| 38 | +> |
| 39 | +> You can even have Copilot aid in generating instructions files by selecting the gear icon for **Configure Chat** in Copilot chat and selecting **Generate Agent Instructions**. |
| 40 | +> |
| 41 | +>  |
| 42 | +
|
| 43 | +## Use GitHub Copilot Chat before updating custom instructions |
| 44 | + |
| 45 | +To see the impact of custom instructions, you'll start by sending a prompt with the current version of the files. You'll then make some updates, send the same prompt again, and note the difference. |
| 46 | + |
| 47 | +1. Return to your codespace. |
| 48 | +2. Close any open files in your codespace from the previous exercises. This will ensure Copilot has the context you want it to have. |
| 49 | +3. Open `server/routes/publishers.py`, an empty file. |
| 50 | +4. If **Copilot chat** is not already open, open it by selecting the Copilot icon towards the top of your codespace. |
| 51 | +5. Create a new chat session by typing `/clear` into the chat window and selecting <kbd>Enter</kbd> (or <kbd>return</kbd> on a Mac). |
| 52 | +6. Select **Ask** from the modes dropdown. |
| 53 | + |
| 54 | +  |
| 55 | + |
| 56 | +7. Send the following prompt to create a new endpoint to return all publishers: |
| 57 | + |
| 58 | + ```plaintext |
| 59 | + Create a new endpoint to return a list of all publishers. It should return the name and id for all publishers. |
| 60 | + ``` |
| 61 | + |
| 62 | +8. Copilot explores the project to learn how best to implement the code, and generates a list of suggestions, which may include code for `publishers.py`, `app.py`, and tests to ensure the new code runs correctly. |
| 63 | +9. Explore the code, noticing the generated code includes [type hints][python-type-hints] because, as you'll see, the custom instructions includes the directive to include them. |
| 64 | +10. Notice the generated code **is missing** either a docstring or a comment header - or both! |
| 65 | + |
| 66 | +> [!IMPORTANT] |
| 67 | +> As highlighted previously, GitHub Copilot and LLM tools are probabilistic, not deterministic. As a result, the exact code generated may vary, and there's even a chance it'll abide by your rules without you spelling it out! But to aid consistency in code you should always document anything you want to ensure Copilot should understand about how you want your code generated. |
| 68 | +
|
| 69 | +## Add new repository standards to copilot-instructions.md |
| 70 | + |
| 71 | +As highlighted previously, `copilot-instructions.md` is designed to provide project-level information to Copilot. Let's ensure repository coding standards are documented to improve code suggestions from Copilot chat. |
| 72 | + |
| 73 | +1. Return to your codespace. |
| 74 | +2. Open `.github/copilot-instructions.md`. |
| 75 | +3. Explore the file, noting the brief description of the project and sections for **Code standards**, **Scripts** and **GitHub Actions Workflows**. These are applicable to any interactions you'd have with Copilot, are robust, and provide clear guidance on what you're doing and how you want to accomplish it. |
| 76 | +4. Locate the **Code formatting requirements** section, which should be near line 27. Note how it contains a note to use type hints. That's why you saw those in the code generated previously. |
| 77 | +5. Add the following lines of markdown right below the note about type hints to instruct Copilot to add comment headers to files and docstrings (which should be near line 27): |
| 78 | + |
| 79 | + ```markdown |
| 80 | + - Every function should have docstrings or the language equivalent. |
| 81 | + - Before imports or any code, add a comment block to the file that explains its purpose. |
| 82 | + ``` |
| 83 | + |
| 84 | +6. Close **copilot-instructions.md**. |
| 85 | +7. Select **New Chat** in Copilot chat to clear the buffer and start a new conversation. |
| 86 | +8. Return to **server/routes/publishers.py** to ensure focus is set correctly. |
| 87 | +9. Send the same prompt as before to create the endpoint. |
| 88 | + |
| 89 | + ```plaintext |
| 90 | + Create a new endpoint to return a list of all publishers. It should return the name and id for all publishers. |
| 91 | + ``` |
| 92 | + |
| 93 | +10. Notice how the newly generated code includes a comment header at the top of the file which resembles the following: |
| 94 | + |
| 95 | + ```python |
| 96 | + """ |
| 97 | + Publisher API routes for the Tailspin Toys Crowd Funding platform. |
| 98 | + This module provides endpoints to retrieve publisher information. |
| 99 | + """ |
| 100 | + ``` |
| 101 | + |
| 102 | +11. Notice how the newly generated code includes a docstring inside the function which resembles the following: |
| 103 | + |
| 104 | + ```python |
| 105 | + """ |
| 106 | + Returns a list of all publishers with their id and name. |
| 107 | + |
| 108 | + Returns: |
| 109 | + Response: JSON response containing an array of publisher objects |
| 110 | + """ |
| 111 | + ``` |
| 112 | + |
| 113 | +12. Notice the generated code now includes a docstring as well as a comment block at the top! |
| 114 | +13. Also note how the existing code isn't updated, but of course you could ask Copilot to perform that operation if you so desired! |
| 115 | +14. **Don't implement the suggested changes**, as you'll be doing that in the next section. |
| 116 | + |
| 117 | +> [!NOTE] |
| 118 | +> If you accepted the changes, you can always select the **Undo** button towards the top right of the Copilot chat window. |
| 119 | +
|
| 120 | +From this section, you explored how the custom instructions file has provided Copilot with the context it needs to generate code that follows the established guidelines. |
| 121 | + |
| 122 | +## Explore a task-specific custom instructions file |
| 123 | + |
| 124 | +You want to create a new endpoint to list all publishers, and to follow the same pattern used for the existing [games endpoints][games-endpoints], and to create tests which follow the same pattern as the existing [games endpoints tests][games-tests]. An instruction file has already been created; let's explore it and see the difference in code it generates. |
| 125 | + |
| 126 | +1. Open `.github/instructions/python-tests.instructions.md`. |
| 127 | +2. Note the `applyTo:` section at the top, which contains a filter for all files in the `server/tests` directory which start with `test_` and have a `.py` extension. Whenever Copilot Chat interacts with a file which matches this pattern it will automatically use the guidance provided in this file. |
| 128 | +3. Note the file contains guidance about how tests should be created, and how to utilize SQLite when testing database functionality. |
| 129 | +4. Open `.github/instructions/flask-endpoint.instructions.md`. |
| 130 | +5. Review the following entries inside the instruction file, which includes: |
| 131 | + |
| 132 | + - an overview of requirements, including that tests must be created, and endpoints are created in Flask using blueprints. |
| 133 | + - a link to another the previously mentioned `python-tests.instructions.md` file. |
| 134 | + - links to two existing files which follow the patterns you want - both the games blueprint and tests. Notice how these are setup as normal markdown links, allowing an instruction file to incorporate additional files for context. |
| 135 | + |
| 136 | +6. Return to `server/routes/publishers.py` to ensure focus is set correctly. |
| 137 | +7. Return to Copilot Chat and select **New Chat** to start a new session. |
| 138 | +8. Select **Edit** from the mode dropdown, which will allow Copilot to update multiple files. |
| 139 | + |
| 140 | +  |
| 141 | + |
| 142 | +> [!NOTE] |
| 143 | +> If you have any issues running the tests in this part of the exercise, please undo your changes and retry from the above step using **Agent** mode instead. |
| 144 | +
|
| 145 | +9. Select the **Add Context** button to open the context dialog |
| 146 | +10. If prompted to allow the codespace to see text and images copied to the clipboard, select **Allow**. |
| 147 | +11. Select **Instructions** from the dropdown at the top of your codespace. |
| 148 | + |
| 149 | +> [!TIP] |
| 150 | +> If the list of options is long, you can type **instructions** to filter to the Instructions option then select **Instructions**. |
| 151 | +
|
| 152 | +12. Select **flask-endpoint .github/instructions** to add the instruction file to the context. |
| 153 | + |
| 154 | +  |
| 155 | + |
| 156 | +13. Send the same prompt as before to generate the desired endpoint: |
| 157 | + |
| 158 | + ```plaintext |
| 159 | + Create a new endpoint to return a list of all publishers. It should return the name and id for all publishers. |
| 160 | + ``` |
| 161 | + |
| 162 | +> [!NOTE] |
| 163 | +> While the up-arrow shortcut to resend a prior command is handy, it will reset any context you might add as well. If you added in the instructions file as context, then use the up arrow, it will remove the instructions file. For this particular step, make sure you copy/paste (or type) the command to avoid accidentally removing context. |
| 164 | +
|
| 165 | +14. Note the **References** section and how it uses the **flask-endpoint.instructions.md** file to provide context. If you use instructions files with Copilot agent mode, you will notice that Copilot explores and reads the files referenced in the instructions file. |
| 166 | + |
| 167 | +  |
| 168 | + |
| 169 | +15. Copilot generates the files. Notice how it generates updates across multiple files, like **publishers.py** and **test_publishers.py** |
| 170 | + |
| 171 | +> [!NOTE] |
| 172 | +> Note that the code generated may diverge from some of the standards we set. AI tools like Copilot are non-deterministic, and may not always provide the same result. The other files in our codebase do not contain docstrings or comment headers, which could lead Copilot in another direction. Consistency is key, so making sure that your code follows the established patterns is important. You can always follow-up in chat and ask Copilot to follow your coding standards, which will help guide it in the right direction. |
| 173 | +
|
| 174 | +16. After reviewing the code, select **Keep** in Copilot Chat to accept the changes. |
| 175 | +17. Open a terminal window by selecting <kbd>Ctl</kbd>+<kbd>`</kbd>. |
| 176 | +18. Run the tests by running the script with the following command: |
| 177 | + |
| 178 | + ```sh |
| 179 | + ./scripts/run-server-tests.sh |
| 180 | + ``` |
| 181 | + |
| 182 | +19. Once the code is correct, and all tests pass, open the **Source Control** panel on the left of the Codespace and review the changes made by Copilot. |
| 183 | +20. Stage the changes by selecting the **+** icon in the **Source Control** panel. |
| 184 | +21. Generate a commit message using the **Sparkle** button. |
| 185 | + |
| 186 | +  |
| 187 | + |
| 188 | +22. Commit the changes to your repository by selecting **Commit**. |
| 189 | + |
| 190 | +## Resources |
| 191 | + |
| 192 | +- [Instruction files for GitHub Copilot customization][instruction-files] |
| 193 | +- [5 tips for writing better custom instructions for Copilot][copilot-instructions-five-tips] |
| 194 | +- [Best practices for creating custom instructions][instructions-best-practices] |
| 195 | +- [Personal custom instructions for GitHub Copilot][personal-instructions] |
| 196 | +- [Awesome Copilot - a collection of instructions files and other resources][awesome-copilot] |
| 197 | + |
| 198 | +--- |
| 199 | + |
| 200 | +| [← Previous lesson: Model Context Protocol (MCP)][previous-lesson] | [Next lesson: Copilot agent mode →][next-lesson] | |
| 201 | +|:--|--:| |
| 202 | + |
| 203 | +[previous-lesson]: ./1-mcp.md |
| 204 | +[next-lesson]: ./3-copilot-agent-mode-vscode.md |
| 205 | +[instruction-files]: https://code.visualstudio.com/docs/copilot/copilot-customization |
| 206 | +[python-type-hints]: https://docs.python.org/3/library/typing.html |
| 207 | +[games-endpoints]: ../server/routes/games.py |
| 208 | +[games-tests]: ../server/tests/test_games.py |
| 209 | +[instructions-best-practices]: https://docs.github.com/enterprise-cloud@latest/copilot/using-github-copilot/coding-agent/best-practices-for-using-copilot-to-work-on-tasks#adding-custom-instructions-to-your-repository |
| 210 | +[personal-instructions]: https://docs.github.com/copilot/customizing-copilot/adding-personal-custom-instructions-for-github-copilot |
| 211 | +[copilot-instructions-five-tips]: https://github.blog/ai-and-ml/github-copilot/5-tips-for-writing-better-custom-instructions-for-copilot/ |
| 212 | +[awesome-copilot]: https://github.com/github/awesome-copilot |
| 213 | +[repository-custom-instructions]: https://docs.github.com/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot |
0 commit comments