From 262ab79a12dbb9b93fabc61b4e183d1080609baa Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 22 Nov 2024 15:31:27 -0500 Subject: [PATCH] [DO NOT MERGE] Official megabranch of "Copilot Chat Cookbook" with new map topic structure (#53046) Co-authored-by: hubwriter Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> Co-authored-by: Tiago Pascoal Co-authored-by: Christopher Harrison Co-authored-by: Sophie <29382425+sophietheking@users.noreply.github.com> Co-authored-by: Sunbrye Ly <56200261+sunbrye@users.noreply.github.com> Co-authored-by: sunbrye Co-authored-by: Hector Alfaro Co-authored-by: Siara <108543037+SiaraMist@users.noreply.github.com> --- .../debugging-invalid-json.md | 78 +++++ .../handling-api-rate-limits.md | 98 +++++++ .../debugging-errors/index.md | 11 + .../documenting-legacy-code.md | 147 ++++++++++ .../explaining-complex-algorithms-or-logic.md | 169 +++++++++++ .../explaining-legacy-code.md | 115 ++++++++ .../documenting-code/index.md | 13 + ...syncing-documentation-with-code-changes.md | 85 ++++++ .../index.md | 16 + ...pling-business-logic-from-ui-components.md | 149 ++++++++++ .../refactoring-code/fixing-lint-errors.md | 67 +++++ ...ng-code-readability-and-maintainability.md | 275 ++++++++++++++++++ .../refactoring-code/index.md | 15 + .../refactoring-data-access-layers.md | 127 ++++++++ ...efactoring-for-performance-optimization.md | 93 ++++++ ...factoring-to-implement-a-design-pattern.md | 115 ++++++++ ...inding-existing-vulnerabilities-in-code.md | 51 ++++ .../security-analysis/index.md | 10 + .../create-end-to-end-tests-for-a-webpage.md | 148 ++++++++++ .../create-mock-objects-to-abstract-layers.md | 91 ++++++ .../testing-code/generate-unit-tests.md | 79 +++++ .../testing-code/index.md | 12 + content/copilot/index.md | 1 + ...ng-github-copilot-questions-in-your-ide.md | 8 +- .../example-use-cases/index.md | 13 - ...-started-with-prompts-for-copilot-chat.md} | 8 +- .../guides-on-using-github-copilot/index.md | 15 + .../refactoring-code-with-github-copilot.md | 2 + .../writing-tests-with-github-copilot.md | 2 + content/copilot/using-github-copilot/index.md | 2 +- content/index.md | 2 +- .../example-prompts/further-reading-items.md | 2 + .../example-prompts/response-is-an-example.md | 1 + .../example-prompts/responses-are-examples.md | 1 + 34 files changed, 1999 insertions(+), 22 deletions(-) create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/debugging-invalid-json.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/handling-api-rate-limits.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/index.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/documenting-code/documenting-legacy-code.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-complex-algorithms-or-logic.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-legacy-code.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/documenting-code/index.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/documenting-code/syncing-documentation-with-code-changes.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/index.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/decoupling-business-logic-from-ui-components.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/fixing-lint-errors.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/improving-code-readability-and-maintainability.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/index.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-data-access-layers.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-for-performance-optimization.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-to-implement-a-design-pattern.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/security-analysis/finding-existing-vulnerabilities-in-code.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/security-analysis/index.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-end-to-end-tests-for-a-webpage.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-mock-objects-to-abstract-layers.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/testing-code/generate-unit-tests.md create mode 100644 content/copilot/example-prompts-for-github-copilot-chat/testing-code/index.md delete mode 100644 content/copilot/using-github-copilot/example-use-cases/index.md rename content/copilot/using-github-copilot/{example-use-cases/example-prompts-for-copilot-chat.md => guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat.md} (97%) create mode 100644 content/copilot/using-github-copilot/guides-on-using-github-copilot/index.md rename content/copilot/using-github-copilot/{example-use-cases => guides-on-using-github-copilot}/refactoring-code-with-github-copilot.md (99%) rename content/copilot/using-github-copilot/{example-use-cases => guides-on-using-github-copilot}/writing-tests-with-github-copilot.md (99%) create mode 100644 data/reusables/copilot/example-prompts/further-reading-items.md create mode 100644 data/reusables/copilot/example-prompts/response-is-an-example.md create mode 100644 data/reusables/copilot/example-prompts/responses-are-examples.md diff --git a/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/debugging-invalid-json.md b/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/debugging-invalid-json.md new file mode 100644 index 000000000000..2563572f64ea --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/debugging-invalid-json.md @@ -0,0 +1,78 @@ +--- +title: Debugging invalid JSON +shortTitle: Debug invalid JSON +intro: '{% data variables.product.prodname_copilot_chat_short %} can identify and resolve syntax errors or structural issues in JSON data.' +versions: + feature: copilot +category: + - 'Debugging code' +complexity: + - Intermediate +octicon: bug +topics: + - Copilot +--- + +When working with JSON data, you may encounter issues such as trailing commas, mismatched braces, or incorrect data types that make the JSON invalid. {% data variables.product.prodname_copilot_chat %} can help you debug and fix these errors by suggesting corrections to fix invalid JSON. + +## Example scenario + +Consider a scenario where an application consumes JSON data from an API, but the response fails to parse due to invalid formatting. You receive the error message: + +```bash +Error: Parse error +----------------------^ +Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined' +``` + +Below is the JSON data that caused the error: + +```json +{ + "location": "San Francisco", + "current_weather": { + "temperature": 18, + "unit": "Celsius", + "conditions": "Cloudy + }, + "forecast": { + "day": "Monday", + "high": 22, + "low": 15, + "precipitation": 10 + } +} +``` + +## Example prompt + +```Why is my JSON object invalid and how can I fix it?``` + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} might suggest that your JSON is invalid because it is missing a closing quote for the `conditions` value. Here is the corrected JSON: + +```json +{ + "location": "San Francisco", + "current_weather": { + "temperature": 18, + "unit": "Celsius", + "conditions": "Cloudy" + }, + "forecast": { + "day": "Monday", + "high": 22, + "low": 15, + "precipitation": 10 + } +} +``` + +In this example response, {% data variables.product.prodname_copilot_short %}'s suggestions include fixing the closing quote for the `conditions` value, which resolves the JSON parsing error. + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/handling-api-rate-limits.md b/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/handling-api-rate-limits.md new file mode 100644 index 000000000000..325b6347a0c4 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/handling-api-rate-limits.md @@ -0,0 +1,98 @@ +--- +title: Handling API rate limits +shortTitle: Handle API rate limits +intro: '{% data variables.product.prodname_copilot_chat_short %} can help handle API rate limits by suggesting code that detects implements retry logic.' +versions: + feature: copilot +category: + - 'Debugging code' +complexity: + - Intermediate +octicon: bug +topics: + - Copilot +--- + +When making requests to APIs, it's common to encounter rate limits that restrict the number of calls you can make within a certain time frame. {% data variables.product.prodname_copilot_chat %} can help you handle these limits by suggesting code to detect rate limit responses and automatically retry requests after a delay. + +## Example scenario + +The following Python code fetches weather data from an external API. If the API has rate limits, requests may fail when limits are exceeded, and your app may need a way to handle these responses gracefully by implementing retry logic. + +```python +from flask import Flask, request +import requests + +app = Flask(__name__) + +WEATHER_API_URL = "https://api.example.com/weather" + +@app.route('/get_weather', methods=['GET']) +def get_weather(): + city = request.args.get('city') + # Simulate an API request to the external weather service + response = requests.get(WEATHER_API_URL, params={"city": city}) + weather_data = response.json() + + return weather_data +``` + +## Example prompt + +`How can I handle API rate limits within get_weather().` + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} might suggest code that implements a retry mechanism with exponential backoff to limit the frequency of retry attempts. + +For example: + +```python +import requests +from flask import Flask, request +from requests.adapters import HTTPAdapter +from requests.packages.urllib3.util.retry import Retry + +app = Flask(__name__) + +WEATHER_API_URL = "https://api.example.com/weather" + +def requests_retry_session( + retries=3, + backoff_factor=0.3, + status_forcelist=(500, 502, 504), + session=None, +): + session = session or requests.Session() + retry = Retry( + total=retries, + read=retries, + connect=retries, + backoff_factor=backoff_factor, + status_forcelist=status_forcelist, + ) + adapter = HTTPAdapter(max_retries=retry) + session.mount("http://", adapter) + session.mount("https://", adapter) + return session + +@app.route('/get_weather', methods=['GET']) +def get_weather(): + city = request.args.get('city') + try: + response = requests_retry_session().get(WEATHER_API_URL, params={"city": city}) + response.raise_for_status() + weather_data = response.json() + except requests.exceptions.RequestException as e: + return {"error": str(e)}, 500 + + return weather_data +``` + +In this example, {% data variables.product.prodname_copilot_short %}'s suggestions include setting up a retry session that allows the code to automatically retry requests if they fail due to specific status codes (500, 502, 504). The `backoff_factor` gradually increases the delay between retries, helping avoid exceeding the API's rate limit further. + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/index.md b/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/index.md new file mode 100644 index 000000000000..9aa2cba614a3 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/debugging-errors/index.md @@ -0,0 +1,11 @@ +--- +title: Debugging errors +intro: 'Discover ways that you can use {% data variables.product.prodname_copilot %} to debug errors during development.' +versions: + feature: copilot +topics: + - Copilot +children: + - /debugging-invalid-json + - /handling-api-rate-limits +--- diff --git a/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/documenting-legacy-code.md b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/documenting-legacy-code.md new file mode 100644 index 000000000000..19d291ea5c97 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/documenting-legacy-code.md @@ -0,0 +1,147 @@ +--- +title: 'Documenting legacy code' +shortTitle: Document legacy code +intro: '{% data variables.product.prodname_copilot_chat_short %} can help with documenting legacy code.' +versions: + feature: copilot +category: + - 'Documenting code' +complexity: + - Simple +octicon: book +topics: + - Copilot +--- +Working with legacy code can be challenging for developers, especially when the code is complex or not well-documented. In such cases, it can be helpful to use Copilot Chat to explain unclear or complex code to other developers or to document it for future reference. + +## Example scenario + +The block of COBOL below connects to a database and inserts a record. The code lacks documentation, which makes it difficult to understand what it does and how it works. + +```text +IDENTIFICATION DIVISION. +PROGRAM-ID. INSERT-RECORD. + +ENVIRONMENT DIVISION. + +DATA DIVISION. +WORKING-STORAGE SECTION. +01 WS-STATUS-FLAGS. + 05 WS-DB-STATUS PIC X(2). + 88 WS-SUCCESS VALUE "00". + 05 WS-SQLCODE PIC S9(9) COMP. + 05 WS-ERROR-MSG PIC X(50). + +LINKAGE SECTION. +01 LS-PARAMETERS. + 05 LS-PERSON-RECORD. + 10 PERSON-ID PIC 9(6). + 10 PERSON-NAME PIC X(50). + 10 PERSON-AGE PIC 9(3). + 05 LS-RESULT PIC X. + 88 SUCCESS VALUE 'T'. + 88 FAILED VALUE 'F'. + +PROCEDURE DIVISION USING LS-PARAMETERS. + PERFORM INSERT-AND-VALIDATE + GOBACK + . + +INSERT-AND-VALIDATE. + EXEC SQL + INSERT INTO persons (id, name, age) + VALUES (:PERSON-ID, :PERSON-NAME, :PERSON-AGE) + END-EXEC + + IF SQLCODE = 0 + EXEC SQL COMMIT END-EXEC + SET SUCCESS TO TRUE + ELSE + EXEC SQL ROLLBACK END-EXEC + SET FAILED TO TRUE + STRING "DB Error: " SQLCODE + DELIMITED BY SIZE + INTO WS-ERROR-MSG + DISPLAY WS-ERROR-MSG + END-IF + . +``` + +## Example prompt + +We can use a simple prompt to ask {% data variables.product.prodname_copilot_chat_short %} to document the code. + +`Document this code` + +> [!NOTE] If you want the documentation generated in another format like Markdown, you can specify the desired output format in the prompt. For example: `Document this code in Markdown`. + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +Copilot will provide a text overview of the code block, and an updated version with comments explaining the logic and purpose of each section. + +For example: + +```text +***************************************************************** +* Program: INSERT-RECORD +* Purpose: Inserts a person record into the database with +* transaction management and error handling +***************************************************************** + IDENTIFICATION DIVISION. + PROGRAM-ID. INSERT-RECORD. + + ENVIRONMENT DIVISION. + + DATA DIVISION. + WORKING-STORAGE SECTION. +* Status flags and error handling variables + 01 WS-STATUS-FLAGS. + 05 WS-DB-STATUS PIC X(2). *> Database status + 88 WS-SUCCESS VALUE "00". *> Success flag + 05 WS-SQLCODE PIC S9(9) COMP. *> SQL return code + 05 WS-ERROR-MSG PIC X(50). *> Error message + + LINKAGE SECTION. +* Input/Output parameters + 01 LS-PARAMETERS. + 05 LS-PERSON-RECORD. + 10 PERSON-ID PIC 9(6). *> Person ID + 10 PERSON-NAME PIC X(50). *> Person name + 10 PERSON-AGE PIC 9(3). *> Person age + 05 LS-RESULT PIC X. *> Operation result + 88 SUCCESS VALUE 'T'. *> Success flag + 88 FAILED VALUE 'F'. *> Failure flag + + PROCEDURE DIVISION USING LS-PARAMETERS. + PERFORM INSERT-AND-VALIDATE + GOBACK + . + +***************************************************************** +* Handles database insertion with transaction management +***************************************************************** + INSERT-AND-VALIDATE. + EXEC SQL + INSERT INTO persons (id, name, age) + VALUES (:PERSON-ID, :PERSON-NAME, :PERSON-AGE) + END-EXEC + + IF SQLCODE = 0 + EXEC SQL COMMIT END-EXEC *> Commit if successful + SET SUCCESS TO TRUE + ELSE + EXEC SQL ROLLBACK END-EXEC *> Rollback if failed + SET FAILED TO TRUE + STRING "DB Error: " SQLCODE + DELIMITED BY SIZE + INTO WS-ERROR-MSG + DISPLAY WS-ERROR-MSG + END-IF + . +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-complex-algorithms-or-logic.md b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-complex-algorithms-or-logic.md new file mode 100644 index 000000000000..47f451334bcc --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-complex-algorithms-or-logic.md @@ -0,0 +1,169 @@ +--- +title: 'Explaining complex algorithms or logic' +shortTitle: Explain complex logic +intro: '{% data variables.product.prodname_copilot_chat_short %} can help add clear and concise documentation on complex algorithms or logic.' +versions: + feature: copilot +category: + - 'Documenting code' +complexity: + - Intermediate +octicon: book +topics: + - Copilot +--- + +There may be times where you need to explain complex algorithms or logic in your code. This can be challenging, especially when you're trying to make it understandable to others. {% data variables.product.prodname_copilot_chat_short %} can help you with this task by providing you with suggestions on how to explain the algorithm or logic in a clear and concise manner. + +## Example scenario + +In the C# code below, we have a method which fetches data, retries if there's an error, and updates a status label. You might want to explain, in comments in the code, how the method works and how it handles retries and cancellations. + +```csharp +private static readonly HttpClient _client = new HttpClient(); + +public async Task FetchDataFromApiWithRetryAsync(string apiUrl, CancellationToken cancellationToken, int maxRetries, int cancellationDelay, Label statusLabel) +{ + var retryCount = 0; + using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + + while (retryCount < maxRetries) + { + try + { + cts.CancelAfter(cancellationDelay); + return await FetchDataFromApiAsync(cts.Token, statusLabel); + } + catch (Exception ex) when (!(ex is OperationCanceledException)) + { + if (retryCount < maxRetries - 1) { + retryCount++; + int delay = (int)Math.Pow(2, retryCount) * 1000; + await Task.Delay(delay, cancellationToken); + UpdateStatusLabel($"Retrying ({retryCount}/{maxRetries})...", statusLabel); + } else { + throw new Exception($"Failed to fetch data after {maxRetries} retries: {ex.Message}", ex); + } + } + } + + throw new OperationCanceledException("The operation was cancelled.", cts.Token); +} + +private async Task FetchDataFromApiAsync(string apiUrl, CancellationToken cancellationToken, Label statusLabel) +{ + UpdateStatusLabel("Fetching data...", statusLabel); + + HttpResponseMessage response = await _client.GetAsync(apiUrl, cancellationToken); + response.EnsureSuccessStatusCode(); + string data = await response.Content.ReadAsStringAsync(); + + UpdateStatusLabel("Data fetched.", statusLabel); + return data; +} + +private void UpdateStatusLabel(string message, Label statusLabel) +{ + if (statusLabel.InvokeRequired) { + statusLabel.BeginInvoke(new Action(UpdateStatusLabel), message, statusLabel); + } else { + statusLabel.Text = message; + } +} +``` + +## Example prompt + +We can ask {% data variables.product.prodname_copilot_chat_short %} to make this code easier to understand using comments. + +`Add comments to this code to make it more understandable` + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} responds with an overview of the update it suggests, and the code snippet with the comments added: + +```csharp +// Shared HttpClient instance for making HTTP requests (best practice for reuse) +private static readonly HttpClient _client = new HttpClient(); + +/// +/// Fetches data from an API with retry mechanism and timeout functionality +/// +/// The URL to fetch data from +/// Token to cancel the operation +/// Maximum number of retry attempts +/// Timeout duration in milliseconds +/// UI label to show status updates +public async Task FetchDataFromApiWithRetryAsync(string apiUrl, CancellationToken cancellationToken, int maxRetries, int cancellationDelay, Label statusLabel) +{ + var retryCount = 0; + // Create a linked cancellation token that combines user cancellation and timeout + using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + + while (retryCount < maxRetries) + { + try + { + // Set timeout for this attempt + cts.CancelAfter(cancellationDelay); + return await FetchDataFromApiAsync(cts.Token, statusLabel); + } + catch (Exception ex) when (!(ex is OperationCanceledException)) + { + // If not the last retry attempt, implement exponential backoff + if (retryCount < maxRetries - 1) { + retryCount++; + // Exponential backoff: 2^retryCount seconds (1s, 2s, 4s, 8s, etc.) + int delay = (int)Math.Pow(2, retryCount) * 1000; + await Task.Delay(delay, cancellationToken); + UpdateStatusLabel($"Retrying ({retryCount}/{maxRetries})...", statusLabel); + } else { + // If all retries failed, throw exception with details + throw new Exception($"Failed to fetch data after {maxRetries} retries: {ex.Message}", ex); + } + } + } + + // This is reached if maxRetries is 0 or some other unexpected case + throw new OperationCanceledException("The operation was cancelled.", cts.Token); +} + +/// +/// Makes the actual API call to fetch data +/// +private async Task FetchDataFromApiAsync(string apiUrl, CancellationToken cancellationToken, Label statusLabel) +{ + UpdateStatusLabel("Fetching data...", statusLabel); + + // Perform HTTP GET request with cancellation support + HttpResponseMessage response = await _client.GetAsync(apiUrl, cancellationToken); + response.EnsureSuccessStatusCode(); // Throws if response is not successful + string data = await response.Content.ReadAsStringAsync(); + + UpdateStatusLabel("Data fetched.", statusLabel); + return data; +} + +/// +/// Updates UI label text safely across threads +/// +/// The message to display +/// The label control to update +private void UpdateStatusLabel(string message, Label statusLabel) +{ + // Check if we need to invoke on UI thread + if (statusLabel.InvokeRequired) { + // Use BeginInvoke to update label on UI thread + statusLabel.BeginInvoke(new Action(UpdateStatusLabel), message, statusLabel); + } else { + // Direct update if already on UI thread + statusLabel.Text = message; + } +} +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-legacy-code.md b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-legacy-code.md new file mode 100644 index 000000000000..d4ca8fabc467 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/explaining-legacy-code.md @@ -0,0 +1,115 @@ +--- +title: 'Explaining legacy code' +shortTitle: Explain legacy code +intro: '{% data variables.product.prodname_copilot_chat_short %} can help with explaining unfamiliar code.' +versions: + feature: copilot +category: + - 'Documenting code' +complexity: + - Simple +octicon: book +topics: + - Copilot +--- + +One of the biggest challenges with legacy code is helping developers understand it who aren't familiar with the languages or frameworks. With {% data variables.product.prodname_copilot_chat_short %}, you can explain the background you have and ask for an explanation. + +## Example scenario + +Consider the following COBOL code. If you're a Python developer (as an example), you might not be familiar with COBOL, so you could ask {% data variables.product.prodname_copilot_chat_short %} to explain the code to you. + +```text +IDENTIFICATION DIVISION. +PROGRAM-ID. INSERT-RECORD. + +ENVIRONMENT DIVISION. + +DATA DIVISION. +WORKING-STORAGE SECTION. +01 WS-STATUS-FLAGS. + 05 WS-DB-STATUS PIC X(2). + 88 WS-SUCCESS VALUE "00". + 05 WS-SQLCODE PIC S9(9) COMP. + 05 WS-ERROR-MSG PIC X(50). + +LINKAGE SECTION. +01 LS-PARAMETERS. + 05 LS-PERSON-RECORD. + 10 PERSON-ID PIC 9(6). + 10 PERSON-NAME PIC X(50). + 10 PERSON-AGE PIC 9(3). + 05 LS-RESULT PIC X. + 88 SUCCESS VALUE 'T'. + 88 FAILED VALUE 'F'. + +PROCEDURE DIVISION USING LS-PARAMETERS. + PERFORM INSERT-AND-VALIDATE + GOBACK + . + +INSERT-AND-VALIDATE. + EXEC SQL + INSERT INTO persons (id, name, age) + VALUES (:PERSON-ID, :PERSON-NAME, :PERSON-AGE) + END-EXEC + + IF SQLCODE = 0 + EXEC SQL COMMIT END-EXEC + SET SUCCESS TO TRUE + ELSE + EXEC SQL ROLLBACK END-EXEC + SET FAILED TO TRUE + STRING "DB Error: " SQLCODE + DELIMITED BY SIZE + INTO WS-ERROR-MSG + DISPLAY WS-ERROR-MSG + END-IF + . +``` + +## Example prompt + +You can ask for an explanation of the COBOL code from the point of view of a Python developer. + +`I'm a Python developer. Help me better understand this code. Please provide analogies.` + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} provides a high-level overview of the code, before walking through the various operations and explaining them in a way that Python developers can understand. It uses analogies to make the explanation more accessible. The response might start with the following: + +```text +Let me explain this COBOL code using Python analogies: + +High-Level Overview +This is similar to a Python function that inserts a person's record into a database with error handling. +``` + +```python +# In Python, the COBOL divisions would be like: + +# IDENTIFICATION DIVISION = module/file name +# PROGRAM-ID = function name +def insert_record(): + pass + +# DATA DIVISION would be like declaring these variables: +class WorkingStorage: + db_status = "" # WS-DB-STATUS + sqlcode = 0 # WS-SQLCODE + error_msg = "" # WS-ERROR-MSG + +# LINKAGE SECTION is like function parameters +class PersonRecord: + def __init__(self, person_id: int, person_name: str, person_age: int): + self.person_id = person_id # PERSON-ID + self.person_name = person_name # PERSON-NAME + self.person_age = person_age # PERSON-AGE + self.success = False # LS-RESULT +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/index.md b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/index.md new file mode 100644 index 000000000000..4420dd0af31b --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/index.md @@ -0,0 +1,13 @@ +--- +title: Documenting code +intro: 'Discover ways that you can use {% data variables.product.prodname_copilot_chat %} to document your code.' +versions: + feature: copilot +topics: + - Copilot +children: + - /documenting-legacy-code + - /explaining-legacy-code + - /explaining-complex-algorithms-or-logic + - /syncing-documentation-with-code-changes +--- diff --git a/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/syncing-documentation-with-code-changes.md b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/syncing-documentation-with-code-changes.md new file mode 100644 index 000000000000..41b35af800fb --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/documenting-code/syncing-documentation-with-code-changes.md @@ -0,0 +1,85 @@ +--- +title: 'Syncing documentation with code changes' +shortTitle: Sync documentation +intro: '{% data variables.product.prodname_copilot_chat_short %} can help with keeping code documentation up-to-date.' +versions: + feature: copilot +category: + - 'Documenting code' +complexity: + - Intermediate +octicon: book +topics: + - Copilot +--- + +It can be difficult to keep documentation up to date with changes to code. However, good documentation is essential for maintaining codebases and ensuring that developers can work effectively with the code. {% data variables.product.prodname_copilot_chat_short %} can assist in updating existing code documentation. + +## Example scenario + + Imagine a scenario where you have a TypeScript function that retrieves products by category name, but the documentation is out of date. + +```typescript +/** + * Retrieves all products belonging to a specific category. + * + * @param categoryId - The unique identifier of the product category + * @returns Promise that resolves to an array of Product objects + * + * @example + * const products = await getByCategoryName(5); + * // Returns: [{id: 1, name: "Product 1", categoryId: 5}, ...] + * + * @throws {PrismaClientKnownRequestError} If database query fails + * @see {@link https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#findmany} + */ +async getByCategoryName(categoryId: number, page = 1, pageSize = 10): Promise { + return await prisma.products.findMany({ + where: { categoryId }, + skip: (page - 1) * pageSize, + take: pageSize, + include: { + reviews: { + orderBy: { date: 'desc' }, + take: 5, + }, + }, + }); +} +``` + +## Example prompt + +You can ask {% data variables.product.prodname_copilot_chat_short %} to update the documentation according to the current code. + +`Update the existing documentation for the getByCategoryName function to reflect the current implementation.` + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} explains it will create the updated documentation for the `getByCategoryName` function. It then provides the updated documentation, which now includes the `page` and `pageSize` parameters, as well as the `PrismaClientKnownRequestError` error that can be thrown. + +For example: + +```typescript +/** + * Retrieves all products belonging to a specific category with pagination and recent reviews. + * + * @param categoryId - The unique identifier of the product category + * @param page - The page number for pagination (default: 1) + * @param pageSize - Number of products per page (default: 10) + * @returns Promise that resolves to an array of Product objects with their 5 most recent reviews + * + * @example + * const products = await getByCategoryName(5, 2, 20); + * // Returns: [{id: 1, name: "Product 1", categoryId: 5, reviews: [...5 recent reviews]}, ...] + * + * @throws {PrismaClientKnownRequestError} If database query fails + * @see {@link https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#findmany} + */ +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/index.md b/content/copilot/example-prompts-for-github-copilot-chat/index.md new file mode 100644 index 000000000000..b488e211d8dd --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/index.md @@ -0,0 +1,16 @@ +--- +title: Example prompts for GitHub Copilot Chat +shortTitle: Example prompts +intro: 'Find examples of prompts to use with {% data variables.product.prodname_copilot_chat %}.' +versions: + feature: copilot +topics: + - Copilot +layout: category-landing +children: + - /debugging-errors + - /refactoring-code + - /documenting-code + - /testing-code + - /security-analysis +--- diff --git a/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/decoupling-business-logic-from-ui-components.md b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/decoupling-business-logic-from-ui-components.md new file mode 100644 index 000000000000..c74b38a08192 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/decoupling-business-logic-from-ui-components.md @@ -0,0 +1,149 @@ +--- +title: Decoupling business logic from UI components +shortTitle: Decoupling business logic +intro: '{% data variables.product.prodname_copilot_chat_short %} can help you separate your business logic from your user interface code, making it easier to maintain and scale your application.' +versions: + feature: copilot +category: + - 'Refactoring code' +complexity: + - Advanced +octicon: rocket +topics: + - Copilot +--- + +In many front-end frameworks, business logic can become embedded within user interface (UI) components, making the code hard to maintain or extend, especially as the application grows. + +{% data variables.product.prodname_copilot_chat_short %} can help you refactor your code to extract business logic into separate services or state management solutions. This allows the business logic to be reused across different UI components. It also makes the code easier to scale by separating concerns and reducing interdependencies, and it simplifies unit testing by allowing business logic to be tested independently from UI components. + +## Example scenario + +In this JavaScript code, the `Counter` component configures the business logic for the component and also defines UI code for using the component in a web page. + +```javascript +import React, { useState } from 'react'; + +const Counter = () => { + const [count, setCount] = useState(0); + + const increment = () => { + if (count >= 10) { + alert('Count cannot exceed 10'); + return; + } + setCount(count + 1); + }; + + return ( +
+

Count: {count}

+ +
+ ); +}; + +export default Counter; +``` + +## Example prompt + +`Use Redux to separate the UI code from the Counter component in this code.` + +## Example response + +{% data variables.product.prodname_copilot_short %} provides step-by-step instructions for refactoring the code. + +The suggested changes refactor the `Counter` component to use Redux for state management. This includes setting up a Redux store with an initial state and a reducer, defining an increment action, and modifying the `Counter` component to connect to the Redux store. Finally, the application is wrapped with a `Provider` component to make the Redux store available to the `Counter` component. This separates the UI logic from state management. + +The proposed changes separate the code into five separate files. + +> [!NOTE] {% data variables.product.prodname_copilot_chat_short %} responses are non-deterministic, so you may get a different response from the one described here. + +### actions.js + +```javascript +export const increment = () => ({ + type: 'INCREMENT' +}); +``` + +### reducer.js + +```javascript +const initialState = { + count: 0 +}; + +const counterReducer = (state = initialState, action) => { + switch (action.type) { + case 'INCREMENT': + if (state.count >= 10) { + alert('Count cannot exceed 10'); + return state; + } + return { + ...state, + count: state.count + 1 + }; + default: + return state; + } +}; + +export default counterReducer; +``` + +### store.js + +```javascript +import { createStore } from 'redux'; +import counterReducer from './reducer'; + +const store = createStore(counterReducer); + +export default store; +``` + +### counter.js + +```javascript +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { increment } from './actions'; + +const Counter = () => { + const count = useSelector(state => state.count); + const dispatch = useDispatch(); + + return ( +
+

Count: {count}

+ +
+ ); +}; + +export default Counter; +``` + +### index.js + +```javascript +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Provider } from 'react-redux'; +import store from './store'; +import Counter from './counter'; + +ReactDOM.render( + + + , + document.getElementById('root') +); +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/fixing-lint-errors.md b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/fixing-lint-errors.md new file mode 100644 index 000000000000..3058ba0ac0fb --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/fixing-lint-errors.md @@ -0,0 +1,67 @@ +--- +title: Fixing lint errors +shortTitle: Lint errors +intro: '{% data variables.product.prodname_copilot_chat_short %} can suggest ways to fix issues identified by a code linter.' +versions: + feature: copilot +category: + - 'Refactoring code' +complexity: + - Intermediate +octicon: rocket +topics: + - Copilot +--- + +It's good practice to use a linter to check your code for potential errors, style violations, or deviations from best practices. Linters can help you to catch bugs early, improve the readability of your code, and ensure that your code is consistent and maintainable. + +## Example scenario + +You have run a linter on your code and it has identified some issues that need to be fixed. Rather than fixing these manually, you can ask {% data variables.product.prodname_copilot_chat_short %} to fix them for you. + +## Example prompts + +* Select all of the code in the editor, then type: + + `Fix the lint errors` + +* You can specify a particular set of coding guidelines for a language, such as PEP8 for Python: + + `Use PEP8 to fix the lint errors` + +* If you have a local file that defines your coding conventions and rules, you can drag the file into the chat window to add it as an attachment, then type: + + `Use the attached style guide to fix the lint errors` + +* Alternatively, you can ask {% data variables.product.prodname_copilot_chat_short %} to fix only a specific type of lint error: + + `Make sure all functions use snake_case naming style` + +## Example response + +{% data variables.product.prodname_copilot_short %} tells you what needs to be changed, and then gives you the corrected code. You should review the suggested code thoroughly before using it. The code that {% data variables.product.prodname_copilot_short %} suggests may not fix all of the issues identified by your linter, so you should always run the linter again if you choose to use the suggested code. + +Linting issues that {% data variables.product.prodname_copilot_short %} can help you fix include: + +* Adding necessary imports that are missing. +* Removing imports that are not used in the code. +* Splitting import statements into separate lines. +* Using method and function names that follow style guidelines. +* Adding spaces around operators. +* Ensuring consistent indentation. +* Removing trailing whitespace. +* Splitting multiple statements that are on a single line into separate lines. +* Breaking long line into multiple lines. +* Removing unused variables. +* Adding or removing blank lines to adhere to style guidelines. +* Adding docstrings to functions, classes, and modules. +* Removing code that will never be executed. +* Ensuring that all return statements in a function either return a value or none. +* Reducing or eliminating the use of global variables. +* Ensuring that functions are called with the correct number and type of arguments. +* Ensuring that comments are placed correctly and are meaningful. +* Replacing print statements with proper logging. + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/improving-code-readability-and-maintainability.md b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/improving-code-readability-and-maintainability.md new file mode 100644 index 000000000000..14ab97316032 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/improving-code-readability-and-maintainability.md @@ -0,0 +1,275 @@ +--- +title: 'Improving code readability and maintainability' +shortTitle: Improve code readability +intro: '{% data variables.product.prodname_copilot_chat_short %} can suggest ways to make your code easier to understand and maintain.' +versions: + feature: copilot +category: + - 'Refactoring code' +complexity: + - Simple +octicon: rocket +topics: + - Copilot +--- + +Code with poor readability is difficult for other developers to maintain and extend. {% data variables.product.prodname_copilot_chat_short %} can help in a number of ways. For example, by: +* [Suggesting improvements to variable names](#improving-variable-names) +* [Avoiding sequential conditional checks](#avoiding-sequential-conditional-checks) +* [Reducing nested logic](#reducing-nested-logic) +* [Splitting large methods into smaller, more readable ones](#splitting-up-large-methods) + +Documenting your code is another way to improve the maintainability of your code. For information about using {% data variables.product.prodname_copilot_chat_short %} to help you add useful comments to your code, see the example prompts in "[Documenting code](/copilot/example-prompts-for-github-copilot-chat/documenting-code)." + +> [!NOTE] The responses shown in this article are examples. {% data variables.product.prodname_copilot_chat_short %} responses are non-deterministic, so you may get different responses from the ones shown here. + +## Improving variable names + +Descriptive variable names and parameter names make it easier to understand their purpose. + +### Example scenario + +This JavaScript code logs a message about a person's age to the console. The abstract parameter names make it difficult to understand the purpose of the code. + +```javascript +function logPersonsAge(a, b, c) { + if (c) { + console.log(a + " is " + b + " years old."); + } else { + console.log(a + " does not want to reveal their age."); + } +} +``` + +### Example prompt + +In the editor, select the function you want to change, then ask {% data variables.product.prodname_copilot_chat_short %}: + +`Improve the variable names in this function` + +### Example response + +{% data variables.product.prodname_copilot_short %} suggests descriptive variable names. + +```javascript +function logPersonAge(name, age, revealAge) { + if (revealAge) { + console.log(name + " is " + age + " years old."); + } else { + console.log(name + " does not want to reveal their age."); + } +} +``` + +## Avoiding sequential conditional checks + +`if...else` chains can be difficult to read, especially when they are long. + +### Example scenario + +This Python code prints the sound that various animals make, if defined, or "Unknown animal" if the animal type is not recognized. However, the chain of `if...else` statements makes the code inefficient and cumbersome. + +```python +class Animal: + def speak(self): + pass + +class Dog(Animal): + def speak(self): + return "Woof!" + +class Cat(Animal): + def speak(self): + return "Meow!" + +class Bird(Animal): + def speak(self): + return "Tweet!" + +def animal_sound(animal_type): + if animal_type == "dog": + return Dog().speak() + elif animal_type == "cat": + return Cat().speak() + elif animal_type == "bird": + return Bird().speak() + else: + return "Unknown animal" + +print(animal_sound("dog")) +print(animal_sound("cat")) +print(animal_sound("bird")) +print(animal_sound("fish")) +``` + +### Example prompt + +`Simplify this code. Avoid using if/else chains but retain all function return values.` + +### Example response + +{% data variables.product.prodname_copilot_short %} suggests using a dictionary to map the animal types to their corresponding classes. + +```python +class Animal: + def speak(self): + pass + +class Dog(Animal): + def speak(self): + return "Woof!" + +class Cat(Animal): + def speak(self): + return "Meow!" + +class Bird(Animal): + def speak(self): + return "Tweet!" + +def animal_sound(animal_type): + animals = { + "dog": Dog, + "cat": Cat, + "bird": Bird + } + animal_class = animals.get(animal_type, Animal) + return animal_class().speak() if animal_class != Animal else "Unknown animal" + +print(animal_sound("dog")) +print(animal_sound("cat")) +print(animal_sound("bird")) +print(animal_sound("fish")) +``` + +## Reducing nested logic + +Deeply nested structures can make the code hard to follow, making it difficult to modify or extend the logic of the code in future. + +### Example scenario + +This Ruby code prints information about a user account based on three parameters. The use of nested `if...else` statements makes the code unnecessarily complex. + +```ruby +def determine_access(user_role, has_permission, is_active) + if user_role == "admin" + if has_permission + if is_active + "Active admin account with full access." + else + "Inactive admin account." + end + else + "Admin account lacks necessary permissions." + end + else + "Access denied." + end +end + +puts determine_access("admin", true, true) +puts determine_access("admin", true, false) +puts determine_access("admin", false, true) +puts determine_access("user", true, true) +``` + +### Example prompt + +`Rewrite this code to avoid the nested if/else statements` + +### Example response + +{% data variables.product.prodname_copilot_short %} suggests using guard clauses to handle the conditions early and return the appropriate messages. + +```ruby +def determine_access(user_role, has_permission, is_active) + return "Access denied." unless user_role == "admin" + return "Admin account lacks necessary permissions." unless has_permission + return "Inactive admin account." unless is_active + + "Active admin account with full access." +end + +puts determine_access("admin", true, true) +puts determine_access("admin", true, false) +puts determine_access("admin", false, true) +puts determine_access("user", true, true) +``` + +## Splitting up large methods + +It can be difficult to grasp exactly what a method or function does if it is too long, making it difficult to maintain. Methods or functions that perform multiple tasks may not be reusable in other contexts. It may also be difficult to test each task in isolation. + +### Example scenario + +This Java method processes a customer order and prints a message. It performs multiple tasks in a single method. + +```java +public void processOrder(Order order) { + if (order == null || order.getItems().isEmpty()) { + throw new IllegalArgumentException("Order is invalid."); + } + + double totalPrice = 0.0; + for (Item item : order.getItems()) { + totalPrice += item.getPrice() * item.getQuantity(); + } + order.setTotalPrice(totalPrice); + + if (totalPrice > 0) { + order.setStatus("Processed"); + } else { + order.setStatus("Pending"); + } + + System.out.println("Order for customer " + order.getCustomerName() + " has been processed. Total price: " + totalPrice); +} +``` + +### Example prompt + +`How could the processOrder method be refactored to be more useful and easier to maintain` + +### Example response + +{% data variables.product.prodname_copilot_short %} suggests breaking this method down into smaller, more focused methods. + +```java +public void processOrder(Order order) { + validateOrder(order); + double totalPrice = calculateTotalPrice(order); + updateOrderStatus(order, totalPrice); + printOrderSummary(order, totalPrice); +} + +private void validateOrder(Order order) { + if (order == null || order.getItems().isEmpty()) { + throw new IllegalArgumentException("Order is invalid."); + } +} + +private double calculateTotalPrice(Order order) { + double totalPrice = 0.0; + for (Item item : order.getItems()) { + totalPrice += item.getPrice() * item.getQuantity(); + } + order.setTotalPrice(totalPrice); + return totalPrice; +} + +private void updateOrderStatus(Order order, double totalPrice) { + if (totalPrice > 0) { + order.setStatus("Processed"); + } else { + order.setStatus("Pending"); + } +} + +private void printOrderSummary(Order order, double totalPrice) { + System.out.println("Order for customer " + order.getCustomerName() + " has been processed. Total price: " + totalPrice); +} +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/index.md b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/index.md new file mode 100644 index 000000000000..58012a97226f --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/index.md @@ -0,0 +1,15 @@ +--- +title: Refactoring code +intro: 'Discover ways that you can use {% data variables.product.prodname_copilot %} to refactor your code.' +versions: + feature: copilot +topics: + - Copilot +children: + - /refactoring-data-access-layers + - /improving-code-readability-and-maintainability + - /decoupling-business-logic-from-ui-components + - /fixing-lint-errors + - /refactoring-to-implement-a-design-pattern + - /refactoring-for-performance-optimization +--- diff --git a/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-data-access-layers.md b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-data-access-layers.md new file mode 100644 index 000000000000..c33696d9d25b --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-data-access-layers.md @@ -0,0 +1,127 @@ +--- +title: Refactoring data access layers +shortTitle: Data access layers +intro: '{% data variables.product.prodname_copilot_chat_short %} can suggest ways to decouple your data access code from your business logic, making an application easier to maintain and scale.' +versions: + feature: copilot +category: + - 'Refactoring code' +complexity: + - Advanced +octicon: rocket +topics: + - Copilot +--- + +Hardcoded SQL queries and tightly coupled data access code can make it difficult to scale or switch databases, and they often lead to repeated logic. + +{% data variables.product.prodname_copilot_chat_short %} can recommend implementing a repository pattern or data access layer that abstracts database interactions, making the code more modular and reducing redundancy. It can also help refactor SQL queries into optimized versions, improving performance and maintainability. + +> [!NOTE] The responses described in this article are examples. {% data variables.product.prodname_copilot_chat_short %} responses are non-deterministic, so you may get different responses from the ones shown here. + +## Example scenario + +This Python code connects to a SQLite database, retrieves a user record, and returns the user data. However, it fails to abstract the database connection logic and uses a hardcoded query that's vulnerable to SQL injection. + +```python +import sqlite3 + +def get_user_by_id(user_id): + conn = sqlite3.connect('database.db') + cursor = conn.cursor() + cursor.execute(f"SELECT display_name FROM users WHERE id = {user_id}") + user = cursor.fetchone() + conn.close() + return user +``` + +## Example prompt 1 + +You can start by asking {% data variables.product.prodname_copilot_short %} a general question about how to improve the code. + +`How can I improve this code to make it safe and easier to update and expand? List possible improvements but don't show revised code.` + +## Example response 1 + +{% data variables.product.prodname_copilot_short %} makes several suggestions for improving the code: + +* Abstract the database connection details. +* Use parameterized queries to prevent SQL injection. +* Use a context manager to ensure that the database connection is properly closed if an error occurs. +* Add error handling. + +## Example prompt 2 + +You can use the response to your first prompt to write a more specific prompt. + +`Rewrite this code to make it more scalable and easier to maintain. Use a context manager. Avoid hardcoded SQL queries and tightly coupled data access code. Instead, use a repository pattern to abstract database interactions and make the code more modular and reusable. Where possible optimize the code to improve performance. Include error trapping, and make sure the code is not vulnerable to SQL injection.` + +## Example response 2 + +{% data variables.product.prodname_copilot_short %} suggests splitting the code into separate files, each with a specific purpose. It also provides example code for returning a user's details. + +The suggested changes implement a repository pattern and use parameterized queries to avoid SQL injection. + +```python +# database.py +import sqlite3 + +class Database: + def __init__(self, db_path): + self.db_path = db_path + + def __enter__(self): + self.conn = sqlite3.connect(self.db_path) + self.cursor = self.conn.cursor() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + if exc_type or exc_val or exc_tb: + self.conn.rollback() + else: + self.conn.commit() + self.conn.close() + +# user_repository.py +class UserRepository: + def __init__(self, db): + self.db = db + + def get_user_by_id(self, user_id): + try: + self.db.cursor.execute("SELECT display_name FROM users WHERE id = ?", (user_id,)) + user = self.db.cursor.fetchone() + return user + except sqlite3.Error as e: + print(f"An error occurred: {e}") + return None + +# main.py +from database import Database +from user_repository import UserRepository + +def get_user_by_id(user_id): + with Database('database.db') as db: + user_repo = UserRepository(db) + return user_repo.get_user_by_id(user_id) + +# Example usage +if __name__ == "__main__": + user = get_user_by_id(1) + if user: + print(user) + else: + print("User not found or an error occurred.") +``` + +The revised code improves on the original in several ways: + +* The code now implements a basic data access layer. +* The `Database` class handles the connection to the SQLite database, implementing the context manager protocol with the `__enter__` and `__exit__` methods. This ensures that the database connection is properly managed, including committing transactions and closing the connection. +* The `UserRepository` class encapsulates the logic for accessing user data. +* Values for the queries are parameterized to prevent SQL injection. +* Errors are caught, with details printed to the console. + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-for-performance-optimization.md b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-for-performance-optimization.md new file mode 100644 index 000000000000..540149310a63 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-for-performance-optimization.md @@ -0,0 +1,93 @@ +--- +title: Refactoring for performance optimization +shortTitle: Performance optimization +intro: '{% data variables.product.prodname_copilot_chat_short %} can suggest ways to speed up slow-running code.' +versions: + feature: copilot +category: + - 'Refactoring code' +complexity: + - Simple +octicon: rocket +topics: + - Copilot +--- + +Existing code may function correctly but be inefficient, leading to performance bottlenecks. Examples of coding that can adversely impact performance include inefficient loops, unnecessary computations, and excessive memory allocation. + +{% data variables.product.prodname_copilot_chat_short %} can identify performance hotspots and suggest refactoring strategies such as optimizing data structures (for example, using hashmaps instead of arrays), reducing redundant calculations, and improving algorithmic efficiency. It can also recommend caching mechanisms or parallelizing operations to improve performance. + +## Example scenario + +The following Python code prints every 1000th prime number up to the 10,000th prime. It includes a timer, and prints how long the code takes to run as the last line of the output. The program takes several seconds to complete. + +```python +import time + +def is_prime(n): + if n <= 1: + return False + for i in range(2, n): + if n % i == 0: + return False + return True + +def every_1000th_prime(): + primes = [] + num = 2 + while len(primes) < 10000: + if is_prime(num): + primes.append(num) + num += 1 + return [primes[i] for i in range(999, 10000, 1000)] + +if __name__ == "__main__": + start_time = time.time() + primes = every_1000th_prime() + for prime in primes: + print(prime) + end_time = time.time() + elapsed_time = end_time - start_time + print(f"Time taken: {elapsed_time:.10f} seconds") +``` + +## Example prompt + +`Optimize this code for performance` + +## Example response + +{% data variables.product.prodname_copilot_short %} suggests using a sieve function to generate the prime numbers much more efficiently. If you run this program it will complete in a fraction of a second. + +> [!NOTE] {% data variables.product.prodname_copilot_chat_short %} responses are non-deterministic, so you may get a different response from the one shown here. + +```python +import time + +def sieve_of_eratosthenes(limit): + sieve = [True] * (limit + 1) + sieve[0] = sieve[1] = False + for start in range(2, int(limit**0.5) + 1): + if sieve[start]: + for multiple in range(start*start, limit + 1, start): + sieve[multiple] = False + return [num for num, is_prime in enumerate(sieve) if is_prime] + +def every_1000th_prime(): + limit = 105000 # Higher than needed to ensure 10,000 primes + primes = sieve_of_eratosthenes(limit) + return [primes[i] for i in range(999, 10000, 1000)] + +if __name__ == "__main__": + start_time = time.time() + primes = every_1000th_prime() + for prime in primes: + print(prime) + end_time = time.time() + elapsed_time = end_time - start_time + print(f"Time taken: {elapsed_time:.10f} seconds") +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-to-implement-a-design-pattern.md b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-to-implement-a-design-pattern.md new file mode 100644 index 000000000000..1779d99d4cbd --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/refactoring-code/refactoring-to-implement-a-design-pattern.md @@ -0,0 +1,115 @@ +--- +title: Refactoring to implement a design pattern +shortTitle: Design patterns +intro: '{% data variables.product.prodname_copilot_chat_short %} can suggest design patterns that you can use to improve your code.' +versions: + feature: copilot +category: + - 'Refactoring code' +complexity: + - Intermediate +octicon: rocket +topics: + - Copilot +--- + +Code that doesn’t follow established design patterns (like Singleton, Factory, or Observer) can lead to issues like tight coupling, lack of flexibility, or duplicated code. + +{% data variables.product.prodname_copilot_chat_short %} can help you use appropriate design patterns to make your code more flexible and maintainable. For example, it can recommend converting repetitive instantiations into a Factory pattern, or using the Observer pattern to decouple tightly connected classes. + +> [!NOTE] The responses described in this article are examples. {% data variables.product.prodname_copilot_chat_short %} responses are non-deterministic, so you may get different responses from the ones shown here. + +## Example scenario + +This JavaScript code creates three `Person` objects, each with `name` and `age` properties. It then uses the name of a person to retrieve and print their age. + +```javascript +class Person { + constructor(name, age) { + this.name = name; + this.age = age; + } +} + +var people = {}; + +function addPerson(name, age) { + people[name] = new Person(name, age); +} + +function getAge(name) { + if (people[name]) { + console.log(name + " is " + people[name].age + " years old."); + } else { + console.log("Person not found."); + } +} + +addPerson("Ana", 30); +addPerson("Mario", 25); +addPerson("Louise", 40); + +getAge("Mario"); +``` + +## Example prompt 1 + +`What design patterns could improve this code? Don't show me code examples.` + +## Example response 1 + +{% data variables.product.prodname_copilot_short %} suggests the following patterns: + +* **Singleton pattern**: to ensure that there is only one instance of the `people` object. +* **Factory pattern**: to create a factory for creating `Person` objects. +* **Module pattern**: to encapsulate the `people` object and related functions within a module to avoid polluting the global namespace. + +## Example prompt 2 + +You can now ask {% data variables.product.prodname_copilot_short %} to implement the pattern that you feel is most appropriate. + +`Refactor this code using the module pattern` + +## Example response 2 + +```javascript +const PersonModule = (function() { + class Person { + constructor(name, age) { + this.name = name; + this.age = age; + } + } + + const people = {}; + + function addPerson(name, age) { + people[name] = new Person(name, age); + } + + function getAge(name) { + if (people[name]) { + console.log(name + " is " + people[name].age + " years old."); + } else { + console.log("Person not found."); + } + } + + return { + addPerson, + getAge + }; +})(); + +PersonModule.addPerson("Ana", 30); +PersonModule.addPerson("Mario", 25); +PersonModule.addPerson("Louise", 40); + +PersonModule.getAge("Mario"); +``` + +The module pattern improves code organization, enhances data privacy, and reduces the risk of naming conflicts, making the code more maintainable and scalable. + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/security-analysis/finding-existing-vulnerabilities-in-code.md b/content/copilot/example-prompts-for-github-copilot-chat/security-analysis/finding-existing-vulnerabilities-in-code.md new file mode 100644 index 000000000000..183a0b1d9834 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/security-analysis/finding-existing-vulnerabilities-in-code.md @@ -0,0 +1,51 @@ +--- +title: 'Finding existing vulnerabilities in code' +shortTitle: Finding vulnerabilities +intro: 'Copilot Chat can help find common vulnerabilities in your code and suggest fixes.' +versions: + feature: copilot +category: + - 'Security analysis' +complexity: + - Intermediate +octicon: code +topics: + - Copilot +--- + +While they may be considered "common knowledge" by many developers, the vast majority of newly introduced security weaknesses are due to vulnerabilities like cross-site scripting (XSS), SQL injection, and cross-site request forgery (CSRF). These vulnerabilities can be mitigated by following secure coding practices, such as using parameterized queries, input validation, and avoiding hard-coded sensitive data. GitHub Copilot can help detect and resolve these issues. + +> [!NOTE] While {% data variables.product.prodname_copilot_chat_short %} can help find some common security vulnerabilities and help you fix them, you should not rely on {% data variables.product.prodname_copilot_short %} for a comprehensive security analysis. Using security tools and features will more thoroughly ensure your code is secure. For more information on {% data variables.product.github %} security features, see "[AUTOTITLE](/code-security/getting-started/github-security-features)." + +## Example scenario + +The JavaScript code below has a potential XSS vulnerability that could be exploited if the `name` parameter is not properly sanitized before being displayed on the page. + +```javascript +function displayName(name) { + const nameElement = document.getElementById('name-display'); + nameElement.innerHTML = `Showing results for "${name}"` +``` + +## Example prompt + +You can ask {% data variables.product.prodname_copilot_chat_short %} to analyze code for common security vulnerabilities and provide explanations and fixes for the issues it finds. + +`Analyze this code for potential security vulnerabilities and suggest fixes.` + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} responds with an explanation of the vulnerability, and suggested changes to the code to fix it. + +```javascript +function displayName(name) { + const nameElement = document.getElementById('name-display'); + nameElement.textContent = `Showing results for "${name}"`; +} +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/security-analysis/index.md b/content/copilot/example-prompts-for-github-copilot-chat/security-analysis/index.md new file mode 100644 index 000000000000..3c9929805af4 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/security-analysis/index.md @@ -0,0 +1,10 @@ +--- +title: Security analysis +intro: 'Discover ways that you can use {% data variables.product.prodname_copilot %} to improve code security.' +versions: + feature: copilot +topics: + - Copilot +children: + - /finding-existing-vulnerabilities-in-code +--- diff --git a/content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-end-to-end-tests-for-a-webpage.md b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-end-to-end-tests-for-a-webpage.md new file mode 100644 index 000000000000..d589c71ba619 --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-end-to-end-tests-for-a-webpage.md @@ -0,0 +1,148 @@ +--- +title: 'Create end-to-end tests for a webpage' +shortTitle: Create end-to-end tests +intro: '{% data variables.product.prodname_copilot_chat_short %} can help with generating end-to-end tests.' +versions: + feature: copilot +category: + - 'Testing code' +complexity: + - Advanced +octicon: beaker +topics: + - Copilot +--- + +Creating end-to-end tests for a webpage can be time-consuming and complex as the HTML will be generated dynamically. {% data variables.product.prodname_copilot_chat_short %} can help you create end-to-end tests for a webpage by suggesting the necessary code to interact with the webpage and validate the expected results. + +## Example scenario + +Imagine a React application that displays product details on a webpage. You need to create end-to-end tests to ensure the product details are displayed correctly. You can ask {% data variables.product.prodname_copilot_chat_short %} to generate these tests for you. + +```javascript +import React, { useState, useEffect } from 'react'; +import PropTypes from 'prop-types'; + +const ProductDetails = ({ productId = '1' }) => { + const [product, setProduct] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchProduct = async () => { + try { + const response = await fetch(`/api/product/${productId}`); + if (!response.ok) { + throw new Error('Product not found'); + } + const data = await response.json(); + setProduct(data); + setLoading(false); + } catch (err) { + setError(err.message); + setLoading(false); + } + }; + + fetchProduct(); + return; + }, [productId]); // Add productId to dependency array + + if (loading) return
Loading...
; + if (error) return
Error: {error}
; + + return ( +
+ {product && ( +
+

{product.name}

+

{product.description}

+

Price: ${product.price}

+
+ )} +
+ ); +}; + +ProductDetails.propTypes = { + productId: PropTypes.string +}; + +export default ProductDetails; +``` + +## Example prompt + +> [!NOTE] This example uses Playwright for end-to-end testing, but you can use other frameworks like Selenium or Cypress. + +`Using Playwright, generate an e2e test to ensure the product displays correctly.` + +If you have an existing test you wish {% data variables.product.prodname_copilot_short %} to use as a model, you can use `#file: path/to/test-file.js` to provide the path to the file, and include this information in the prompt. + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} will respond with an end-to-end test that you can use for your application. + +```typescript +import { test, expect } from '@playwright/test'; + +test.describe('ProductDetails Component', () => { + test.beforeEach(async ({ page }) => { + // Set up API mocking + await page.route('/api/product/1', async (route) => { + await route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ + name: 'Test Product', + description: 'This is a test product', + price: 99.99 + }) + }); + }); + + // Mock error response for product ID 999 + await page.route('/api/product/999', async (route) => { + await route.fulfill({ + status: 404, + contentType: 'application/json', + body: JSON.stringify({ error: 'Product not found' }) + }); + }); + }); + + test('displays loading state initially', async ({ page }) => { + await page.goto('/product/1'); + const loadingElement = page.locator('text=Loading...'); + await expect(loadingElement).toBeVisible(); + }); + + test('displays product details correctly', async ({ page }) => { + await page.goto('/product/1'); + + // Wait for loading to disappear + await expect(page.getByText('Loading...')).toBeHidden(); + + // Check all product details + await expect(page.locator('h2')).toHaveText('Test Product'); + await expect(page.locator('text=This is a test product')).toBeVisible(); + await expect(page.locator('text=Price: $99.99')).toBeVisible(); + }); + + test('displays error message when product not found', async ({ page }) => { + await page.goto('/product/999'); + + // Wait for loading to disappear + await expect(page.getByText('Loading...')).toBeHidden(); + + // Check error message + await expect(page.locator('text=Error: Product not found')).toBeVisible(); + }); +}); +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-mock-objects-to-abstract-layers.md b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-mock-objects-to-abstract-layers.md new file mode 100644 index 000000000000..1af06410138a --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/create-mock-objects-to-abstract-layers.md @@ -0,0 +1,91 @@ +--- +title: 'Create mock objects to abstract layers' +shortTitle: Create mock objects +intro: '{% data variables.product.prodname_copilot_chat_short %} can help with creating mock objects that you can use for unit tests.' +versions: + feature: copilot +category: + - 'Testing code' +complexity: + - Intermediate +octicon: beaker +topics: + - Copilot +--- + +When creating unit tests, it's important to ensure they're isolated and not depending on external services. One way to achieve this is to create mock objects that abstract layers of your application. {% data variables.product.prodname_copilot_chat_short %} can help you generate the code you need to create these mock objects. + +## Example scenario + +Imagine a website built with TypeScript which displays a list of runners. You have a service which fetches the runners from a database, and the server-side code which uses this service. You want to test the server-side code, but you don't want to make a call to the database. You can ask {% data variables.product.prodname_copilot_chat_short %} to generate a mock object for the service. + +```typescript +// SvelteKit example at +page.server.ts +import service from './service'; + +export async function load({ params }) { + const runner = await service.getRunner(params.id); + + return { + runner + }; +} +``` + +## Example prompt + +This example assumes you are using [vitest](https://vitest.dev/) for your tests, but will work with other test runners. + +`/tests Create a unit test to ensure the service is called correctly. Mock the service object.` + +If you have an existing test you wish {% data variables.product.prodname_copilot_short %} to use as a model, you can use `#file: path/to/test-file.js` to provide the path to the file, and include this information in the prompt. + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +{% data variables.product.prodname_copilot_short %} provides the plan it will implement and the code text which includes the mocks. + +```typescript +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { load } from './+page.server.ts'; + +// Mock the entire service module +vi.mock('./service', () => ({ + default: { + getRunner: vi.fn() + } +})); + +// Import the mocked service +import service from './service'; + +describe('load function', () => { + const mockRunner = { + id: '123', + name: 'Test Runner', + status: 'active' + }; + + beforeEach(() => { + // Reset mock before each test + vi.resetAllMocks(); + + // Setup default mock implementation + (service.getRunner as any).mockResolvedValue(mockRunner); + }); + + it('should fetch runner with correct id', async () => { + const params = { id: '123' }; + const result = await load({ params }); + + expect(service.getRunner).toHaveBeenCalledWith('123'); + expect(service.getRunner).toHaveBeenCalledTimes(1); + expect(result).toEqual({ runner: mockRunner }); + }); +}); +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/testing-code/generate-unit-tests.md b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/generate-unit-tests.md new file mode 100644 index 000000000000..2879d26f9e7d --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/generate-unit-tests.md @@ -0,0 +1,79 @@ +--- +title: 'Generate unit tests' +shortTitle: Generate unit tests +intro: '{% data variables.product.prodname_copilot_chat_short %} can help with generating unit tests for a function.' +versions: + feature: copilot +category: + - 'Testing code' +complexity: + - Intermediate +octicon: beaker +topics: + - Copilot +--- + +A good suite of unit tests is critical to the success of any project. However, writing these tests can be time-consuming and are often neglected. {% data variables.product.prodname_copilot_chat_short %} can help generate these tests for you. + +## Example scenario + +Imagine you have a Python function which validates data before updating the database. You need to create unit tests to ensure the validation performs the way you expect. You can ask {% data variables.product.prodname_copilot_chat_short %} to generate these tests for you. + +```python +def validate_price(price: float): + if price <= 0: + raise ValueError("Price must be greater than 0") + if price > 1000: + raise ValueError("Price must be less than or equal to 1000") +``` + +## Example prompt + +`/tests Generate unit tests for this function. Validate both success and failure, and include edge cases.` + +## Example response + +{% data reusables.copilot.example-prompts.response-is-an-example %} + +If this is your first time asking {% data variables.product.prodname_copilot_chat_short %} to generate unit tests, it may ask you if you wish to configure unit tests for your project. For this example, we are assuming you decline this offer. + +{% data variables.product.prodname_copilot_short %} will provide a strategy for generating the tests, and then provide the tests themselves. + +```python +import unittest +from generate_unit_tests import validate_price + +class TestValidateProduct(unittest.TestCase): + def test_price_zero(self): + with self.assertRaises(ValueError) as context: + validate_price(0) + self.assertEqual(str(context.exception), "Price must be greater than 0") + + def test_price_negative(self): + with self.assertRaises(ValueError) as context: + validate_price(-10) + self.assertEqual(str(context.exception), "Price must be greater than 0") + + def test_price_above_limit(self): + with self.assertRaises(ValueError) as context: + validate_price(1500) + self.assertEqual(str(context.exception), "Price must be less than or equal to 1000") + + def test_price_edge_case_zero(self): + with self.assertRaises(ValueError) as context: + validate_price(0) + self.assertEqual(str(context.exception), "Price must be greater than 0") + + def test_price_edge_case_max(self): + try: + validate_price(1000) + except ValueError: + self.fail("validate_price() raised ValueError unexpectedly!") + +if __name__ == '__main__': + unittest.main() +``` + +## Further reading + +{% data reusables.copilot.example-prompts.further-reading-items %} diff --git a/content/copilot/example-prompts-for-github-copilot-chat/testing-code/index.md b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/index.md new file mode 100644 index 000000000000..00710ed0e25e --- /dev/null +++ b/content/copilot/example-prompts-for-github-copilot-chat/testing-code/index.md @@ -0,0 +1,12 @@ +--- +title: Testing code +intro: 'Discover ways that you can use {% data variables.product.prodname_copilot %} to test your code.' +versions: + feature: copilot +topics: + - Copilot +children: + - /generate-unit-tests + - /create-mock-objects-to-abstract-layers + - /create-end-to-end-tests-for-a-webpage +--- diff --git a/content/copilot/index.md b/content/copilot/index.md index 1e528d0baaf1..31c1d5decd5e 100644 --- a/content/copilot/index.md +++ b/content/copilot/index.md @@ -27,6 +27,7 @@ children: - /about-github-copilot - /setting-up-github-copilot - /using-github-copilot + - /example-prompts-for-github-copilot-chat - /managing-copilot - /customizing-copilot - /building-copilot-extensions diff --git a/content/copilot/using-github-copilot/asking-github-copilot-questions-in-your-ide.md b/content/copilot/using-github-copilot/asking-github-copilot-questions-in-your-ide.md index 942faaa5a291..376127e7b934 100644 --- a/content/copilot/using-github-copilot/asking-github-copilot-questions-in-your-ide.md +++ b/content/copilot/using-github-copilot/asking-github-copilot-questions-in-your-ide.md @@ -35,7 +35,7 @@ You can ask {% data variables.product.prodname_copilot_chat_short %} to give cod > > For additional ways to access {% data variables.product.prodname_copilot_chat_short %}, including inline with your code, see [Additional ways to access {% data variables.product.prodname_copilot_chat_short %}](#additional-ways-to-access-copilot-chat) below. -1. Enter a prompt in the prompt box, or click one of the suggested prompts. For example prompts, see "[AUTOTITLE](/copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat)." +1. Enter a prompt in the prompt box, or click one of the suggested prompts. For an introduction to the kinds of prompts you can use, see "[AUTOTITLE](/copilot/using-github-copilot/guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat)." 1. Evaluate {% data variables.product.prodname_copilot_short %}'s response, and make a follow up request if needed. @@ -45,7 +45,7 @@ You can ask {% data variables.product.prodname_copilot_chat_short %} to give cod ## Using keywords in your prompt -You can use special keywords to help {% data variables.product.prodname_copilot_short %} understand your prompt. For examples, see "[AUTOTITLE](/copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat)." +You can use special keywords to help {% data variables.product.prodname_copilot_short %} understand your prompt. For examples, see "[AUTOTITLE](/copilot/using-github-copilot/guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat)." ### Chat participants @@ -222,7 +222,7 @@ To leave feedback about the {% data variables.product.prodname_copilot_chat %} e You can ask {% data variables.product.prodname_copilot_chat_short %} to give code suggestions, explain code, generate unit tests, and suggest code fixes. 1. In the {% data variables.product.prodname_vs %} menu bar, click **View**, then click **{% data variables.product.prodname_copilot_chat %}**. -1. In the {% data variables.product.prodname_copilot_chat_short %} window, enter a prompt, then press **Enter**. For example prompts, see "[AUTOTITLE](/copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat)." +1. In the {% data variables.product.prodname_copilot_chat_short %} window, enter a prompt, then press **Enter**. For example prompts, see "[AUTOTITLE](/copilot/using-github-copilot/guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat)." 1. Evaluate {% data variables.product.prodname_copilot_short %}'s response, and submit a follow up prompt if needed. The response often includes interactive elements. For example, the response may include buttons to copy, insert, or preview the result of a code block. @@ -371,7 +371,7 @@ You can ask {% data variables.product.prodname_copilot_chat_short %} to give cod ![Screenshot of the {% data variables.product.prodname_copilot_chat_short %} icon in the Activity Bar.](/assets/images/help/copilot/jetbrains-copilot-chat-icon.png) -1. Enter a prompt in the prompt box. For example prompts, see "[AUTOTITLE](/copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat)." +1. Enter a prompt in the prompt box. For example prompts, see "[AUTOTITLE](/copilot/using-github-copilot/guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat)." 1. Evaluate {% data variables.product.prodname_copilot_short %}'s response, and submit a follow up prompt if needed. diff --git a/content/copilot/using-github-copilot/example-use-cases/index.md b/content/copilot/using-github-copilot/example-use-cases/index.md deleted file mode 100644 index 364e2b47a5e2..000000000000 --- a/content/copilot/using-github-copilot/example-use-cases/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Example use cases -shortTitle: Examples -intro: 'Learn about good use cases for {% data variables.product.prodname_copilot %}, and get example prompts.' -versions: - feature: copilot -topics: - - Copilot -children: - - /example-prompts-for-copilot-chat - - /refactoring-code-with-github-copilot - - /writing-tests-with-github-copilot ---- diff --git a/content/copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat.md b/content/copilot/using-github-copilot/guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat.md similarity index 97% rename from content/copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat.md rename to content/copilot/using-github-copilot/guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat.md index 873d672d818b..d110f8398c12 100644 --- a/content/copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat.md +++ b/content/copilot/using-github-copilot/guides-on-using-github-copilot/getting-started-with-prompts-for-copilot-chat.md @@ -1,12 +1,14 @@ --- -title: Example prompts for Copilot Chat -intro: 'Get example prompts and use cases for {% data variables.product.prodname_copilot_chat_short %}.' +title: Getting started with prompts for Copilot Chat +intro: 'Get an overview of ways to use {% data variables.product.prodname_copilot_chat_short %}.' topics: - Copilot defaultTool: vscode versions: feature: copilot -shortTitle: Example prompts for chat +redirect_from: + - /copilot/using-github-copilot/example-use-cases/example-prompts-for-copilot-chat +shortTitle: Getting started with chat --- You can ask {% data variables.product.prodname_copilot_chat_short %} specific questions about your project or general software questions. You can also ask {% data variables.product.prodname_copilot_chat_short %} to write code, fix errors, write tests, and document code. diff --git a/content/copilot/using-github-copilot/guides-on-using-github-copilot/index.md b/content/copilot/using-github-copilot/guides-on-using-github-copilot/index.md new file mode 100644 index 000000000000..ae9ea40d260e --- /dev/null +++ b/content/copilot/using-github-copilot/guides-on-using-github-copilot/index.md @@ -0,0 +1,15 @@ +--- +title: Guides on using GitHub Copilot +shortTitle: Guides +intro: 'Learn how to optimize your use of {% data variables.product.prodname_copilot %} for various use cases.' +versions: + feature: copilot +topics: + - Copilot +redirect_from: + - /copilot/using-github-copilot/example-use-cases +children: + - /getting-started-with-prompts-for-copilot-chat + - /refactoring-code-with-github-copilot + - /writing-tests-with-github-copilot +--- diff --git a/content/copilot/using-github-copilot/example-use-cases/refactoring-code-with-github-copilot.md b/content/copilot/using-github-copilot/guides-on-using-github-copilot/refactoring-code-with-github-copilot.md similarity index 99% rename from content/copilot/using-github-copilot/example-use-cases/refactoring-code-with-github-copilot.md rename to content/copilot/using-github-copilot/guides-on-using-github-copilot/refactoring-code-with-github-copilot.md index c8280ad9ed8e..04321af56fd3 100644 --- a/content/copilot/using-github-copilot/example-use-cases/refactoring-code-with-github-copilot.md +++ b/content/copilot/using-github-copilot/guides-on-using-github-copilot/refactoring-code-with-github-copilot.md @@ -5,6 +5,8 @@ topics: - Copilot versions: feature: copilot +redirect_from: + - /copilot/using-github-copilot/example-use-cases/refactoring-code-with-github-copilot shortTitle: Refactor code --- diff --git a/content/copilot/using-github-copilot/example-use-cases/writing-tests-with-github-copilot.md b/content/copilot/using-github-copilot/guides-on-using-github-copilot/writing-tests-with-github-copilot.md similarity index 99% rename from content/copilot/using-github-copilot/example-use-cases/writing-tests-with-github-copilot.md rename to content/copilot/using-github-copilot/guides-on-using-github-copilot/writing-tests-with-github-copilot.md index a7cd2ca04a69..56937d493500 100644 --- a/content/copilot/using-github-copilot/example-use-cases/writing-tests-with-github-copilot.md +++ b/content/copilot/using-github-copilot/guides-on-using-github-copilot/writing-tests-with-github-copilot.md @@ -5,6 +5,8 @@ topics: - Copilot versions: feature: copilot +redirect_from: + - /copilot/using-github-copilot/example-use-cases/writing-tests-with-github-copilot shortTitle: Write tests --- diff --git a/content/copilot/using-github-copilot/index.md b/content/copilot/using-github-copilot/index.md index abcf9f43add9..06f6cfa8a6fc 100644 --- a/content/copilot/using-github-copilot/index.md +++ b/content/copilot/using-github-copilot/index.md @@ -21,7 +21,7 @@ children: - /using-claude-sonnet-in-github-copilot - /finding-public-code-that-matches-github-copilot-suggestions - /using-github-copilot-for-pull-requests - - /example-use-cases + - /guides-on-using-github-copilot redirect_from: - /copilot/github-copilot-chat - /copilot/github-copilot-in-the-cli diff --git a/content/index.md b/content/index.md index 1e12a2121f46..cf517b1a055d 100644 --- a/content/index.md +++ b/content/index.md @@ -107,7 +107,7 @@ childGroups: - copilot/using-github-copilot/getting-code-suggestions-in-your-ide-with-github-copilot - copilot/using-github-copilot/prompt-engineering-for-github-copilot - copilot/using-github-copilot/asking-github-copilot-questions-in-github - - copilot/using-github-copilot/example-use-cases/refactoring-code-with-github-copilot + - copilot/using-github-copilot/guides-on-using-github-copilot/refactoring-code-with-github-copilot - name: CI/CD and DevOps octicon: GearIcon children: diff --git a/data/reusables/copilot/example-prompts/further-reading-items.md b/data/reusables/copilot/example-prompts/further-reading-items.md new file mode 100644 index 000000000000..2a30fafb4a3b --- /dev/null +++ b/data/reusables/copilot/example-prompts/further-reading-items.md @@ -0,0 +1,2 @@ +* "[AUTOTITLE](/copilot/using-github-copilot/prompt-engineering-for-github-copilot)" +* "[AUTOTITLE](/copilot/using-github-copilot/best-practices-for-using-github-copilot)" diff --git a/data/reusables/copilot/example-prompts/response-is-an-example.md b/data/reusables/copilot/example-prompts/response-is-an-example.md new file mode 100644 index 000000000000..5e9c5463c274 --- /dev/null +++ b/data/reusables/copilot/example-prompts/response-is-an-example.md @@ -0,0 +1 @@ +> [!NOTE] The following response is an example. {% data variables.product.prodname_copilot_chat_short %} responses are non-deterministic, so you may get a different response from the one shown here. diff --git a/data/reusables/copilot/example-prompts/responses-are-examples.md b/data/reusables/copilot/example-prompts/responses-are-examples.md new file mode 100644 index 000000000000..ae9cc39d2762 --- /dev/null +++ b/data/reusables/copilot/example-prompts/responses-are-examples.md @@ -0,0 +1 @@ +> [!NOTE] The following responses are examples. {% data variables.product.prodname_copilot_chat_short %} responses are non-deterministic, so you may get different responses from the ones shown here.