Skip to content

Commit eee9654

Browse files
hubwriterCopilotheiskrvgrl
authored
Add new tutorial on burning down tech debt (#58552)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Kevin Heis <heiskr@users.noreply.github.com> Co-authored-by: Vanessa <vgrl@github.com>
1 parent f0ce922 commit eee9654

File tree

5 files changed

+438
-25
lines changed

5 files changed

+438
-25
lines changed

content/copilot/tutorials/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ children:
2121
- /explore-pull-requests
2222
- /write-tests
2323
- /refactor-code
24+
- /reduce-technical-debt
2425
- /review-ai-generated-code
2526
- /learn-a-new-language
2627
- /modernize-legacy-code
Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
---
2+
title: Using GitHub Copilot to reduce technical debt
3+
shortTitle: Reduce technical debt
4+
intro: 'Use {% data variables.product.prodname_copilot_short %} to automate refactoring and maintenance tasks, freeing your team to focus on feature development.'
5+
versions:
6+
feature: copilot
7+
topics:
8+
- Copilot
9+
contentType: tutorials
10+
category:
11+
- Burn down tech debt
12+
- Author and optimize with Copilot
13+
---
14+
15+
## Introduction
16+
17+
Technical debt accumulates in every codebase: duplicate code, missing tests, outdated dependencies, and inconsistent patterns. These issues can accumulate because feature development is typically given a higher priority. This tutorial explains how you can use {% data variables.product.prodname_copilot %} to tackle technical debt systematically, without sacrificing feature velocity.
18+
19+
### Who this tutorial is for
20+
21+
This tutorial is designed to help engineering teams and technical leads reduce technical debt while maintaining the pace at which new features are delivered. You should have:
22+
23+
* A {% data variables.product.prodname_copilot_short %} subscription with access to {% data variables.copilot.copilot_coding_agent %}
24+
* Admin access to at least one repository
25+
* Familiarity with your team's development workflow
26+
27+
### What you'll accomplish
28+
29+
By the end of this tutorial, you'll have learned about:
30+
31+
* Using {% data variables.product.prodname_copilot_short %} to implement in-the-moment fixes
32+
* Leveraging {% data variables.copilot.copilot_coding_agent %} for large-scale cleanup tasks
33+
* Creating custom instructions to align {% data variables.product.prodname_copilot_short %} with your team's standards
34+
* Measuring the impact of {% data variables.product.prodname_copilot_short %} on your technical debt
35+
36+
## Understanding the technical debt problem
37+
38+
Before starting to reduce the technical debt in a codebase, you should take some time to identify the types of technical debt your team faces most often.
39+
40+
Common types of technical debt include:
41+
42+
* **Code duplication** - The same logic implemented in multiple places
43+
* **Missing tests** - Features without adequate test coverage
44+
* **Outdated dependencies** - Libraries several versions behind current releases
45+
* **Inconsistent patterns** - Different approaches to the same problem across your codebase
46+
* **Legacy code** - Old code that works but doesn't follow current standards
47+
48+
The cost of technical debt compounds over time:
49+
50+
* Senior engineers spend time on routine updates instead of architecture design
51+
* Code reviews become longer as reviewers debate inconsistent patterns
52+
* New developers take longer to onboard due to confusing code organization
53+
* Deployment risk increases as outdated dependencies accumulate vulnerabilities
54+
55+
## Using {% data variables.product.prodname_copilot_short %} in your IDE for in-the-moment fixes
56+
57+
The best way to avoid technical debt accumulating in your codebase is to prevent it getting into the codebase in the first place.
58+
59+
When you encounter technical debt during development, fix it immediately using {% data variables.product.prodname_copilot_short %} in your IDE.
60+
61+
### Quick refactoring workflow
62+
63+
1. While working in your IDE, highlight code that needs improvement.
64+
1. Open {% data variables.copilot.copilot_chat_short %} in the IDE.
65+
1. Ask {% data variables.product.prodname_copilot_short %} to refactor the code. For example:
66+
67+
* `Extract this into a reusable helper and add error handling`
68+
* `Standardize this logging format to match our pattern`
69+
* `Add null checks for all optional parameters`
70+
* `Replace this deprecated API call with the current version` <!-- markdownlint-disable-line GHD046 -->
71+
72+
1. Review the suggested changes.
73+
1. Accept the changes or ask {% data variables.product.prodname_copilot_short %} to modify its approach.
74+
1. Run your tests to verify the changes work correctly.
75+
76+
### Example: Standardizing error handling
77+
78+
If you find inconsistent error handling—for example:
79+
80+
```javascript id="err-handling"
81+
// Highlight this code
82+
try {
83+
await fetchData();
84+
} catch (e) {
85+
console.log(e);
86+
}
87+
```
88+
89+
Ask {% data variables.product.prodname_copilot_short %} to improve the code—for example:
90+
91+
```copilot prompt copy ref="err-handling"
92+
Refactor this to use structured logging and proper error handling
93+
```
94+
95+
{% data variables.product.prodname_copilot_short %} might suggest:
96+
97+
```javascript
98+
try {
99+
await fetchData();
100+
} catch (error) {
101+
logger.error('Failed to fetch data', {
102+
error: error.message,
103+
stack: error.stack,
104+
timestamp: new Date().toISOString()
105+
});
106+
throw error;
107+
}
108+
```
109+
110+
> [!NOTE] This response is an example. {% data variables.copilot.copilot_chat_short %} responses are non-deterministic, so you may get a different response if you run the same prompt against the same code.
111+
112+
By adopting the in-the-moment fix approach, you help to ensure that substandard code does not get added to your codebase, and you avoid the creation of a backlog issue that may never be addressed.
113+
114+
For more details on using {% data variables.product.prodname_copilot_short %} in your IDE, see [AUTOTITLE](/copilot/using-github-copilot/asking-github-copilot-questions-in-your-ide).
115+
116+
## Using {% data variables.copilot.copilot_coding_agent %} for large-scale refactoring
117+
118+
Some refactoring tasks are just too big to complete while everyone on the team is busy developing new features. In this situation you can use {% data variables.copilot.copilot_coding_agent %} to handle these tasks autonomously. Human effort will still be required—at a minimum for reviewing the changes {% data variables.copilot.copilot_coding_agent %} proposes—but getting {% data variables.product.prodname_copilot_short %} to do the bulk of the work can allow you to carry out large-scale refactoring with much less impact on your team's productivity.
119+
120+
### When to use {% data variables.copilot.copilot_coding_agent %}
121+
122+
Use {% data variables.copilot.copilot_coding_agent %} for tasks that:
123+
124+
* Touch many files across your codebase
125+
* Require systematic changes (like removing old feature flags)
126+
* Need careful testing but are straightforward to implement
127+
* Would interrupt feature development if done manually
128+
129+
Examples include:
130+
131+
* Framework upgrades that affect 50+ files
132+
* Removing deprecated feature flags <!-- markdownlint-disable-line GHD046 -->
133+
* Migrating to strict TypeScript
134+
* Updating dependency versions
135+
* Standardizing import patterns
136+
137+
### Workflow for {% data variables.copilot.copilot_coding_agent %}
138+
139+
1. Create a {% data variables.product.prodname_dotcom %} issue describing the refactoring task.
140+
141+
Be specific about what needs to change. For example:
142+
143+
```markdown
144+
Remove all feature flags marked for cleanup in Q2.
145+
146+
These flags are:
147+
- `enable_new_dashboard`
148+
- `beta_export_feature`
149+
- `experimental_search`
150+
151+
All three flags are enabled by default in production.
152+
153+
Remove the flag checks and keep the "enabled" code path.
154+
```
155+
156+
1. Assign the issue to the **Copilot** user.
157+
1. {% data variables.copilot.copilot_coding_agent %} will:
158+
159+
* Set up a development environment
160+
* Open a draft pull request
161+
* Make the required changes to the code
162+
* Run your tests
163+
* Finalize the pull request for review
164+
* Request your review of the pull request
165+
166+
1. Review the pull request just as you would a pull request raised by a human.
167+
1. Leave comments if changes are needed—{% data variables.copilot.copilot_coding_agent %} will update the pull request based on your feedback.
168+
1. Iterate in this way until the work is completed correctly.
169+
1. Approve and merge the pull request.
170+
171+
For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) and [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/review-copilot-prs).
172+
173+
### Safety guardrails
174+
175+
{% data variables.copilot.copilot_coding_agent %} operates with built-in safety measures:
176+
177+
* It can only push to its own `copilot/*` branches
178+
* It cannot merge pull requests—requires your approval
179+
* All commits are logged and auditable
180+
* Your existing branch protections remain active
181+
* CI/CD checks run before any code is merged
182+
183+
## Creating custom instructions for your team
184+
185+
Custom instructions help {% data variables.product.prodname_copilot_short %} understand your team's coding standards and patterns. This ensures suggestions match your expectations from the start.
186+
187+
### Setting up custom instructions
188+
189+
1. In your repository, create a file named `.github/copilot-instructions.md`.
190+
1. Add your team's coding standards in clear, straightforward statements—for example, using bulleted lists.
191+
1. Commit the file to your repository.
192+
193+
### Example custom instructions
194+
195+
Here's an example of effective custom instructions:
196+
197+
```markdown
198+
## Our Standards
199+
200+
- Use structured logging, not console.log
201+
- Sanitize user input before database queries
202+
- Check for null/undefined on all optional parameters
203+
- Keep functions under 50 lines (extract helpers if needed)
204+
- Every public function needs a test
205+
- Flag any loops that might trigger N+1 queries
206+
207+
## Error Handling
208+
209+
- Always use try-catch blocks for async operations
210+
- Log errors with context (user ID, request ID, timestamp)
211+
- Never swallow errors silently
212+
- Return appropriate HTTP status codes
213+
214+
## Testing Requirements
215+
216+
- Unit tests for all business logic
217+
- Integration tests for API endpoints
218+
- Mock external services in tests
219+
- Test both success and failure paths
220+
```
221+
222+
For detailed guidance on writing custom instructions, see [AUTOTITLE](/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot).
223+
224+
### Benefits of custom instructions
225+
226+
With custom instructions in place:
227+
228+
* {% data variables.product.prodname_copilot_short %} suggests code following your patterns
229+
* Code reviews become faster, with fewer discussions about style changes
230+
* New team members learn your standards through {% data variables.product.prodname_copilot_short %} suggestions
231+
* Consistency improves across your codebase
232+
233+
## Running a pilot program
234+
235+
Start small to validate {% data variables.product.prodname_copilot_short %}'s impact on your technical debt before rolling it out widely.
236+
237+
### Week 1: Set up and establish baselines
238+
239+
1. Ensure all pilot participants have {% data variables.product.prodname_copilot_short %} access with {% data variables.copilot.copilot_coding_agent %} enabled.
240+
1. Count the technical debt items in your backlog:
241+
242+
* Number of "tech debt", "chore", or similar labeled issues
243+
* Number of outdated dependencies
244+
* Number of files failing linter checks
245+
246+
1. Track current metrics:
247+
248+
* Average time from pull request creation to merge for refactoring PRs
249+
* Average number of review rounds per refactoring PR
250+
251+
1. Create your first `.github/copilot-instructions.md` file with 3–5 of your most important standards.
252+
253+
### Weeks 2–4: Run the pilot
254+
255+
1. Select 5–10 repositories for your pilot.
256+
1. Choose 1–2 specific problems to address. For example:
257+
258+
* Code duplication in a particular area
259+
* Missing tests on frequently changed files
260+
* Outdated dependencies
261+
262+
1. Use {% data variables.product.prodname_copilot_short %} in your IDE for quick fixes as you encounter issues.
263+
1. Assign larger cleanup tasks to {% data variables.copilot.copilot_coding_agent %}.
264+
1. Review all {% data variables.product.prodname_copilot_short %}-generated PRs carefully.
265+
1. Provide feedback on suggestions to help {% data variables.product.prodname_copilot_short %} learn your preferences.
266+
267+
### Week 5: Evaluate results
268+
269+
After the pilot, measure your results:
270+
271+
* How much faster are refactoring pull requests getting merged?
272+
* How many review rounds do they require now?
273+
* Which types of code change suggestions, made by {% data variables.copilot.copilot_coding_agent %} in pull requests, did developers accept most often?
274+
* Which suggestions needed the most revision?
275+
* Are your technical debt metrics improving?
276+
277+
* Linter warnings decreasing?
278+
* Test coverage increasing?
279+
* Dependency versions more current?
280+
281+
Update your custom instructions based on what you learned about which guidance helped {% data variables.product.prodname_copilot_short %} most.
282+
283+
## Measuring success
284+
285+
Track specific metrics to understand {% data variables.product.prodname_copilot_short %}'s impact on your technical debt.
286+
287+
### Velocity metrics
288+
289+
Monitor how {% data variables.product.prodname_copilot_short %} affects development speed:
290+
291+
* Time to close technical debt issues (target: 30–50% reduction)
292+
* Number of technical debt pull requests merged per week (target: 2–3x increase)
293+
* Average number of review cycles per refactoring pull request (assess whether this increased or decreased)
294+
295+
### Quality metrics
296+
297+
Ensure quality improves alongside velocity:
298+
299+
* Linter warning count (this should trend downward)
300+
* Test coverage percentage (this should trend upward)
301+
* Number of production incidents related to refactored code (assess whether this changed)
302+
303+
### Engineer satisfaction
304+
305+
Survey your team regularly:
306+
307+
* Are engineers spending less time on routine maintenance?
308+
* Are code reviews focusing more on architecture and less on style?
309+
* Is onboarding faster for new team members?
310+
311+
## Troubleshooting
312+
313+
### {% data variables.product.prodname_copilot_short %} suggests incorrect changes
314+
315+
If {% data variables.product.prodname_copilot_short %} consistently suggests code that doesn't match your needs:
316+
317+
* Review your custom instructions—they may be too vague or contradictory
318+
* Provide more specific context in your prompts
319+
* Add examples of good code to your custom instructions
320+
* Leave detailed feedback in pull request reviews to allow {% data variables.copilot.copilot_coding_agent %} to fix the problems
321+
322+
### Pull requests are too large to review
323+
324+
If {% data variables.copilot.copilot_coding_agent %} creates pull requests that are difficult to review:
325+
326+
* Break large tasks into smaller, focused issues
327+
* Ask {% data variables.copilot.copilot_coding_agent %} to handle one file or directory at a time
328+
* Use more specific issue descriptions
329+
330+
### Changes break tests
331+
332+
If refactoring introduces test failures:
333+
334+
* Ensure your test suite runs reliably before using {% data variables.copilot.copilot_coding_agent %}
335+
* Review {% data variables.product.prodname_copilot_short %} changes carefully before merging
336+
* Ask {% data variables.product.prodname_copilot_short %} to update tests along with the code changes
337+
338+
### Team adoption is slow
339+
340+
If your team isn't using {% data variables.product.prodname_copilot_short %} for technical debt:
341+
342+
* Share success stories from early adopters
343+
* Demonstrate time savings in team meetings
344+
* Start with the most annoying technical debt items
345+
* Make creating custom instructions a team activity
346+
347+
## Conclusion
348+
349+
In this tutorial, you learned how to use {% data variables.product.prodname_copilot_short %} to systematically reduce technical debt. You now know how to:
350+
351+
* Fix technical debt immediately using {% data variables.product.prodname_copilot_short %} in your IDE
352+
* Assign large refactoring tasks to {% data variables.copilot.copilot_coding_agent %}
353+
* Create custom instructions that align {% data variables.product.prodname_copilot_short %} with your team's standards
354+
* Run a pilot program to validate the approach
355+
* Measure {% data variables.product.prodname_copilot_short %}'s impact on technical debt
356+
357+
By automating routine refactoring and maintenance tasks, {% data variables.product.prodname_copilot_short %} frees you to focus on architecture, feature development, and other high-value work.
358+
359+
### Quick survey
360+
361+
{% note %}
362+
363+
After reading this tutorial, do you feel confident you can use {% data variables.product.prodname_copilot_short %} to reduce the technical debt in a codebase?
364+
365+
<a href="https://docs.github.io/success-test/yes.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>Yes</span></a> <a href="https://docs.github.io/success-test/no.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>No</span></a>
366+
367+
{% endnote %}
368+
369+
## Next steps
370+
371+
* **Expand your pilot**: Roll out to more repositories based on your pilot results.
372+
* **Automate dependency updates**: Create recurring issues for {% data variables.copilot.copilot_coding_agent %} to handle dependency updates.
373+
* **Build a refactoring queue**: Label issues in your backlog as good for {% data variables.product.prodname_copilot_short %} then regularly assign a batch of these to {% data variables.product.prodname_copilot_short %} to work on.
374+
* **Share best practices**: Document successful prompts and custom instructions for your team.
375+
376+
## Further reading
377+
378+
* [AUTOTITLE](/copilot/using-github-copilot/coding-agent)
379+
* [AUTOTITLE](/copilot/tutorials/refactoring-code-with-github-copilot)
380+
* [How to use GitHub Copilot in your IDE: Tips, tricks, and best practices](https://github.blog/developer-skills/github/how-to-use-github-copilot-in-your-ide-tips-tricks-and-best-practices/) in the {% data variables.product.company_short %} blog
381+
* [5 ways to integrate GitHub Copilot coding agent into your workflow](https://github.blog/ai-and-ml/github-copilot/5-ways-to-integrate-github-copilot-coding-agent-into-your-workflow/) in the {% data variables.product.company_short %} blog

data/reusables/contributing/content-linter-rules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
| GHD058 | journey-tracks-liquid | Journey track properties must use valid Liquid syntax | error | frontmatter, journey-tracks, liquid |
6363
| GHD059 | journey-tracks-guide-path-exists | Journey track guide paths must reference existing content files | error | frontmatter, journey-tracks |
6464
| GHD060 | journey-tracks-unique-ids | Journey track IDs must be unique within a page | error | frontmatter, journey-tracks, unique-ids |
65-
| GHD061 | frontmatter-hero-image | Hero image paths must be absolute and point to valid images in /assets/images/banner-images/ | error | frontmatter, images |
65+
| GHD061 | frontmatter-hero-image | Hero image paths must be absolute, extensionless, and point to valid images in /assets/images/banner-images/ | error | frontmatter, images |
6666
| GHD062 | frontmatter-intro-links | introLinks keys must be valid keys defined in data/ui.yml under product_landing | error | frontmatter, single-source |
6767
| [search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) | deprecated liquid syntax: octicon-<icon-name> | The octicon liquid syntax used is deprecated. Use this format instead `octicon "<octicon-name>" aria-label="<Octicon aria label>"` | error | |
6868
| [search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) | deprecated liquid syntax: site.data | Catch occurrences of deprecated liquid data syntax. | error | |

0 commit comments

Comments
 (0)