## File: README.md

# Mapperly

[](https://www.nuget.org/packages/Riok.Mapperly/)
[](https://www.nuget.org/packages/Riok.Mapperly/)
[](https://github.com/riok/mapperly/blob/main/LICENSE)
[](https://www.nuget.org/packages/Riok.Mapperly/)
[](https://github.com/sponsors/riok)
[](https://github.com/riok/mapperly)


Mapperly is a .NET source generator for generating object mappings.

Because Mapperly creates the mapping code at build time, there is minimal overhead at runtime.
Even better, the generated code is perfectly readable, allowing you to verify the generated mapping code easily.

## Documentation

The documentation is available [here](https://mapperly.riok.app/docs/getting-started/installation).

## Quickstart

### Installation

Add the NuGet Package to your project:
```bash
dotnet add package Riok.Mapperly
```

### Create your first mapper

Create a mapper declaration as a partial class
and apply the `Riok.Mapperly.Abstractions.MapperAttribute` attribute.
Mapperly generates mapping method implementations for the defined mapping methods in the mapper.

```c#
// Mapper declaration
[Mapper]
public partial class CarMapper
{
    public partial CarDto CarToCarDto(Car car);
}

// Mapper usage
var mapper = new CarMapper();
var car = new Car { NumberOfSeats = 10, ... };
var dto = mapper.CarToCarDto(car);
dto.NumberOfSeats.ShouldBe(10);
```

[Read the docs](https://mapperly.riok.app/docs/getting-started/installation) for any further information.

### Release Channels

Mapperly is distributed through two release channels:

- [**Stable Channel**](https://mapperly.riok.app): Production-ready releases with full support for the latest release. Install the latest stable version for production use. Subject to semantic versioning (breaking changes only in major version bumps).
- [**Next Channel**](https://next.mapperly.riok.app): Preview releases with upcoming features and improvements. These versions may contain breaking changes and are not subject to semantic versioning. Use for testing and early access to new features.

## Support Policy

Only the latest version released on the stable channel is fully supported.
We strive to support all .NET versions that are currently supported by Microsoft.

## Upgrading

Find a list of breaking changes for each major version and upgrade guides [here](https://mapperly.riok.app/docs/category/upgrading/).

## Support

Need assistance with Mapperly or looking for consulting services? The riok team is available to help with:

- Enterprise support and training
- Architecture consultation
- Custom feature development and integration support
- Performance optimization and code reviews

Reach out through [GitHub Discussions](https://github.com/riok/mapperly/discussions) for questions, or contact the riok team directly for professional consulting services at [hello@riok.ch](mailto:hello@riok.ch).
You can also support the project and get priority support through [GitHub Sponsors](https://github.com/sponsors/riok).

## How To Contribute

We would love for you to contribute to Mapperly and help make it even better than it is today!
Find information on how to contribute [in the docs](https://mapperly.riok.app/docs/contributing/).

## License

Mapperly is [Apache 2.0](https://github.com/riok/mapperly/blob/main/LICENSE) licensed.

---

## File: docs/docs/getting-started/faq.md

---
sidebar_position: 4
title: FAQ
---



# Frequently asked questions and answers {#faq}

Here you can find answers to frequently asked questions and common problems about Mapperly.

## Mapperly does not work when I use source generator X.

Chaining source generators is not supported by Roslyn.

## I updated the Mapperly version, but the generated code still looks the same.

Restart the IDE to make it load the new version of Mapperly. This is a bug of the IDE.

## Everything is configured correctly and dotnet build works, but the IDE shows the error "[Mapper method] must have an implementation part because it has accessibility modifiers"

Make sure your project meets the [requirements](../intro.md#requirements).
Try rebuilding the solution or restarting the IDE. This is a bug in the IDE.

## My advanced use case isn't supported by Mapperly or needs lots of configuration. What should I do?

Write the mapping for that class manually. You can mix automatically generated mappings and [user implemented mappings](../configuration/user-implemented-methods.mdx) without problems.

## My code throws `FileNotFoundException` with `Riok.Mapperly.Abstractions`. What should I do?

Are you using [reference handling](../configuration/reference-handling.md)
or have you enabled the [preservation of Mapperly attributes at runtime](installation.mdx#preserving-the-attributes-at-runtime)?
Make sure `ExcludeAssets` on the `PackageReference` does not include `runtime` as these features require runtime assets.

## Can I get professional help or consulting for Mapperly?

Yes! The riok team offers professional consulting and support services for Mapperly.
Whether you need help with architecture consultation, implementation support, custom feature development the team is here to assist. Reach out through [hello@riok.ch](mailto:hello@riok.ch) for professional services. You can also support the project through [GitHub Sponsors](https://github.com/sponsors/riok) to get priority support.

---

## File: docs/docs/getting-started/first-mapper.md

---
sidebar_position: 1
---

# Create your first mapper

Create a mapper declaration as a partial class
and apply the `Riok.Mapperly.Abstractions.MapperAttribute` attribute.
Mapperly generates mapping method implementations for the defined mapping methods in the mapper.

```csharp title="Mapper declaration"
[Mapper]
public partial class CarMapper
{
    public partial CarDto CarToCarDto(Car car);
}
```

```csharp title="Mapper usage"
var mapper = new CarMapper();
var car = new Car { NumberOfSeats = 10, ... };
var dto = mapper.CarToCarDto(car);
dto.NumberOfSeats.ShouldBe(10);
```

---

## File: docs/docs/getting-started/generated-mapper-example.mdx

---
sidebar_position: 2
---

import CodeBlock from '@theme/CodeBlock';
import CarSource from '!!raw-loader!../../src/data/generated/samples/Car.cs';
import CarDtoSource from '!!raw-loader!../../src/data/generated/samples/CarDto.cs';
import CarMapperSource from '!!raw-loader!../../src/data/generated/samples/CarMapper.cs';
import GeneratedCarMapperSource from '!!raw-loader!../../src/data/generated/samples/CarMapper.g.cs';

# Generated mapper example

This example will show you what kind of code Mapperly generates.
It is based on the [Mapperly sample](https://github.com/riok/mapperly/tree/main/samples/Riok.Mapperly.Sample).
To view the generated code of your own mapper, refer to the [generated source configuration](../configuration/generated-source.mdx).

## The source classes

In this example, we have a car class with some general information.

<CodeBlock language="csharp">{CarSource}</CodeBlock>

## The target classes

Our sample target classes are mostly the same as the source classes.
For demonstration purposes, we named the manufacturer property differently to show how Mapperly can handle this use case.

<CodeBlock language="csharp">{CarDtoSource}</CodeBlock>

## The mapper

The actual mapper is pretty simple. We use a static mapper class in this example.
As usual, we need to mark the mapper with the `[Mapper]` attribute, so that the source generator is able to recognize it.
Because the manufacturer/producer properties are named differently, we also need to configure that via an attribute.
In addition, because the `CarColor` and `CarColorDto` entries have different numeric values, we need to configure Mapperly to map them by their name.

<CodeBlock language="csharp">{CarMapperSource}</CodeBlock>

## The generated code

<CodeBlock language="csharp">{GeneratedCarMapperSource}</CodeBlock>

---

## File: docs/docs/getting-started/installation.mdx

---
sidebar_position: 0
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
import Conditional from '@site/src/components/Conditional';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';

# Installation

## Requirements

- .NET 8+ or .NET Framework 4.x.
- C# language version 9 or later
- Roslyn 4.8 or later

## Add the NuGet Package to your project

All you need to do, to install Mapperly is to add a NuGet reference pointing to the package [`Riok.Mapperly`](https://www.nuget.org/packages/Riok.Mapperly).

<Tabs>
  <TabItem value="csproj" label="PackageReference" default>
      <CodeBlock language="xml">{``}</CodeBlock>
  </TabItem>
<TabItem value="dotnet-cli" label=".NET CLI">

```bash
dotnet add package Riok.Mapperly
```

:::info
To remove the runtime dependency of Mapperly add
`ExcludeAssets="runtime"` and `PrivateAssets="all"`
to the resulting `PackageReference`.
:::

</TabItem>
<TabItem value="pkg-manager" label="Package Manager">

```powershell
Install-Package Riok.Mapperly
```

:::info
To remove the runtime dependency of Mapperly add
`ExcludeAssets="runtime"` and `PrivateAssets="all"`
to the resulting `PackageReference`.
:::

</TabItem>
</Tabs>

<Conditional condition={!useDocusaurusContext().siteConfig.customFields.environment.stable}>

:::warning
This is a prerelease version of Mapperly and is not subject to semantic release.
The API may break in any prerelease.
Checkout the latest stable version [here](https://mapperly.riok.app).
:::

</Conditional>

### Release Channels

Mapperly is distributed through two release channels:

- [**Stable Channel**](https://mapperly.riok.app): Production-ready releases with full support for latest release. Install the latest stable version for production use. Subject to semantic versioning (breaking changes only in major version bumps).
- [**Next Channel**](https://next.mapperly.riok.app): Preview releases with upcoming features and improvements. These versions may contain breaking changes and are not subject to semantic versioning. Use for testing and early access to new features.

## Support policy

Only the latest version released on the stable channel is fully supported.
We strive to support all .NET versions that are currently supported by Microsoft.

### Preserving the attributes at runtime

Mapperly removes the attribute references at compile time by default (they have the `ConditionalAttribute`).
If you want to preserve the attribute references at runtime
you can set the MSBuild variable `MapperlyAbstractionsScope` to `runtime`.

```xml

  <MapperlyAbstractionsScope>runtime</MapperlyAbstractionsScope>

```

:::info
When preserving the attribute usages, the Mapperly package reference needs to include the runtime assets.  
Make sure `ExcludeAssets` on the `PackageReference` does not include `runtime`.
:::

:::info
`MapperlyAbstractionsScope` only works in projects referencing `Riok.Mapperly` directly.
Alternatively you can set a constant `MAPPERLY_ABSTRACTIONS_SCOPE_RUNTIME`:

```xml

  <DefineConstants>$(DefineConstants);MAPPERLY_ABSTRACTIONS_SCOPE_RUNTIME</DefineConstants>

```

:::

---

## File: docs/docs/contributing/architecture.md

---
sidebar_position: 1
---

# Architecture

Mapperly is an incremental .NET source generator implementation.
Source generators are explained [here](https://github.com/dotnet/roslyn/blob/main/docs/features/source-generators.cookbook.md)
and [here](https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.md).

## Solution

- `benchmarks` Benchmarks to analyze the performance of the generated code and the source generator itself
- `build` Build scripts
- `docs` Documentation of Mapperly
- `samples` Sample implementations of Mappers using Mapperly
- `src` Source code of Mapperly
  - `Riok.Mapperly` The source generator implementation
  - `Riok.Mapperly.Abstractions` Abstractions and attributes to be used by the application code to configure Mapperly.
    This is referenced by the source generator but is not needed at runtime
    (except for some features, e.g., reference handling).
- `test` Unit- and integration tests of Mapperly

## Flow

This describes the process implemented by Mapperly on a higher level.
For each discovered `MapperAttribute` a new `DescriptorBuilder` is created.
The `DescriptorBuilder` is responsible to build a `MapperDescriptor` which holds all the mappings.
The `DescriptorBuilder` does this by following this process:

1. Extracting the configuration from the attributes
2. Extracting user implemented and user defined mapping methods.
   It instantiates a `User*Mapping` (eg. `UserDefinedNewInstanceMethodMapping`) for each discovered mapping method and adds it to the queue of mappings to work on.
3. Extracting user implemented object factories
4. Extracting user implemented format providers
5. Extracting external mappings
6. For each mapping in the queue the `DescriptorBuilder` tries to build its implementation bodies.
   This is done by a so called `*MappingBodyBuilder`.
   A mapping body builder tries to map each property from the source to the target.
   To do this, it asks the `DescriptorBuilder` to create mappings for the according types.
   To create a mapping from one type to another, the `DescriptorBuilder` loops through a set of `*MappingBuilder`s.
   Each of the mapping builders try to create a mapping (an `ITypeMapping` implementation) for the asked type mapping by using
   one approach on how to map types (eg. an explicit cast is implemented by the `ExplicitCastMappingBuilder`).
   These mappings are queued in the queue of mappings which need the body to be built.
7. The `SourceEmitter` emits the code described by the `MapperDescriptor` and all its mappings.
   The syntax objects are created by using `SyntaxFactory` and `SyntaxFactoryHelper`.
   The `SyntaxFactoryHelper` tries to simplify creating formatted syntax trees.
   If indentation is needed,
   the `SyntaxFactoryHelper` instance of the `SourceEmitterContext`/`TypeMappingBuildContext` can be used.

## Roslyn multi targeting

Mapperly targets multiple Roslyn versions by building multiple NuGet packages
and merging them together into a single one.
Multi-targeting is needed to support new language features,
such as required members introduced in C# 11,
while still supporting older compiler versions.

See `build/package.sh` for details.

To introduce support for a new roslyn version see [common tasks](./common-tasks.md#add-support-for-a-new-roslyn-version).

## C# language features

The Mapperly source generator targets `.netstandard2.0` but uses the latest C# language version
and polyfills generated by [`Meziantou.Polyfill`](https://github.com/meziantou/Meziantou.Polyfill).
Some newer C# language features require new runtime features and therefore cannot be used in Mapperly.
A good C# language features requirements overview is available [here](https://sergeyteplyakov.github.io/Blog/c%23/2024/03/06/CSharp_Language_Features_vs_Target_Frameworks.html).

---

## File: docs/docs/contributing/common-tasks.md

---
sidebar_position: 5
---

# Common tasks

This page provides todo lists for some common tasks one may encounter while contributing to Mapperly.

## New diagnostic

To introduce a new diagnostic follow these steps:

1. Ensure no existing diagnostic in `Riok.Mapperly.Diagnostics.DiagnosticDescriptors.cs` matches the new use case.
2. Create a new public static readonly entry following the existing naming and formatting style,
   as ID use `RMG<NUMBER>` with `<NUMBER>` being the highest already used number plus one.
   The highest used number can be found in `AnalyzerReleases.Shipped.md` as there may be removed diagnostics which are not present in `DiagnosticDescriptors` anymore
   but which should still not be used for new diagnostics.
3. Add the new diagnostic to `AnalyzerReleases.Shipped.md` (Mapperly does not use the `Unshipped` file).
4. Add a new documentation file at `docs/docs/configuration/analyzer-diagnostics/{id}.mdx` (as needed)
5. Add a unit test generating and asserting the added diagnostic (use `TestHelperOptions.AllowDiagnostics` and `Should().HaveDiagnostic(...).HaveAssertedAllDiagnostics()`.

It is not necessary to update the `analyzer-diagnostics/index.mdx` documentation file manually,
as it is generated automatically on the basis of the `AnalyzerReleases.Shipped.md` file.

## New public API

If new public API surface is introduced in `Riok.Mapperly.Abstractions` or existing API surface is modified,
the `PublicApiTest` snapshot test needs to be updated.  
See also [VerifyTests](./tests.md#verifytests).

## Add support for a new roslyn version

To support a new roslyn version via multi targeting follow these steps (see also [architecture/roslyn multi targeting](./architecture.md#roslyn-multi-targeting)):

1. Include the new version in `roslyn_versions` in `build/package.sh`.
2. Create a new file `Riok.Mapperly.Roslyn$(Version).props` in `src/Riok.Mapperly` similar to the existing ones
   and define constants and include dependencies as needed.
3. Update the default `ROSLYN_VERSION` in `src/Riok.Mapperly/Riok.Mapperly.csproj`.
4. Update the `Microsoft.CodeAnalysis.CSharp` dependency version.
5. Adjust the .NET version matrix of the `integration-test` GitHub Actions job (defined in `.github/workflows/test.yml`)
   to include a dotnet version which is based on the added Roslyn version.
6. Adjust the .NET version in the `global.json` file as needed.
7. Add the new version in `Riok.Mapperly.IntegrationTests.Helpers.Versions` and `Riok.Mapperly.IntegrationTests.BaseMapperTest.GetCurrentVersion`.
8. If generated code changes based on the new Roslyn version,
   adjust the `VersionedSnapshotAttribute`s as needed.
9. Adjust the documentation as needed.
10. Add new preprocessor constants to `.csharpierrc.yaml`.
11. Add new GitHub required checks as needed (needs to be done by a maintainer).

## Mapping syntax

Mapperly Mappings use Roslyn syntax trees.
[RoslynQuoter](https://roslynquoter.azurewebsites.net/) and [SharpLab](https://sharplab.io/)
are fantastic tools to understand and work with Roslyn syntax trees.
The `Riok.Mapperly.Emit.Syntax.SyntaxFactoryHelper` and `Microsoft.CodeAnalysis.CSharp.SyntaxFactory` classes help building these syntax trees.

---

## File: docs/docs/contributing/debugging.md

---
sidebar_position: 3
---

# Debugging

## Generated code

To debug the code generated by Mapperly just set a breakpoint in the generated code and you are ready to go.
Check [here](../configuration/generated-source.mdx) on how to inspect the generated code.

## Unit tests

To debug the Mapperly in unit tests, set a breakpoint
in the code of Mapperly which you want to debug and run the tests in debug mode.

## Integration tests

If your IDE supports the `DebugRoslynComponent` launch configuration command,
you can set your breakpoints and debug the preconfigured `IntegrationTests` profile which will debug Mapperly
in the context of the integration tests.
JetBrains Rider and Visual Studio both support `DebugRoslynComponent`.
Visual Studio requires the [Roslyn SDK](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/) to be installed.

If your IDE does not support `DebugRoslynComponent`,
debugging the integration tests requires some more effort.
Mapperly uses a compile constant `DEBUG_SOURCE_GENERATOR` to determine whether to attach a debugger.
If it is set, it tries to attach a debugger
(it uses `Debugger.Launch()` on windows, on other operating systems it tries to launch JetBrains Rider)
and waits for the connection of the debugger (for up to 30 seconds).
If the automatic debugger attachment fails you can use these 30 seconds to attach the debugger manually
(for Visual Studio see [attach to running processes](https://docs.microsoft.com/en-us/visualstudio/debugger/attach-to-running-processes-with-the-visual-studio-debugger?view=vs-2022)).
You can use the `DefineConstants` dotnet build or csproj parameter to define the `DEBUG_SOURCE_GENERATOR` constant.

For the debugger attachment with JetBrains Rider to work correctly,
`Generate Shell Scripts` needs to be enabled in the JetBrains ToolBox
and the generated shell scripts need to be on the path (Mapperly calls `rider attach-to-process {pid} {Mapperly-Sln-File}`).

## CSC warning CS8785 stack trace

If you see the compiler warning `CS8785: Generator 'MapperlyGenerator' failed to generate source`,
you can get a stack trace from the C# compiler by emitting a compiler error log. The stack trace is included in the SARIF output.

Add the following MSBuild property when you build:

- `/p:ErrorLog=compiler-diagnostics.sarif`

Then open the SARIF file to inspect the generator exception and stack trace.

---

## File: docs/docs/contributing/docs.md

---
sidebar_position: 4
---

# Documentation

The Mapperly documentation is built using [Docusaurus](https://docusaurus.io/)
and is located in the `docs` directory.

## Dependencies

Docusaurus is based on the node ecosystem.
A `.node-version` file provides the node version number to be used.
This file can be interpreted by several node version managers (eg. [fnm](https://github.com/Schniz/fnm) or [nvm](https://github.com/nvm-sh/nvm)).
Make sure you use a node version matching the version in `.node-version` for all following commands.

To install documentation dependencies run:

```bash
npm i
```

### Update generated documentation

To build the generated parts of the documentation
(eg. the API documentation (located in `docs/99-api`), the table of analyzer rules, the samples, ...)
ensure the dotnet solution is built or run `dotnet build` in the solutions root directory.
Then run the prebuild script:

```bash
npm run prebuild
```

To reflect changes, this command needs to be re-run each time the source of the generated output changes.

## Local Development

```bash
npm run start
```

This command starts a local development server and opens up a browser window.
Most changes are reflected live without having to restart the server.
The documentation search does not work when using the local development server,
as it depends on the statically built content (see [build](#build)).

## Linting

To run the linters locally run:

```bash
npm run lint
```

To fix detected issues automatically run:

```bash
npm run fix
```

## Build

```bash
npm run build
```

This command generates static content into the `build` directory
and can be served using any static contents hosting service or locally using `npm run serve`.

---

## File: docs/docs/contributing/index.md

---
sidebar_position: 0
---

# Contributing

We would love for you to contribute to Mapperly and help make it even better than it is today!
As a contributor, here are the guidelines we would like you to follow.

## Code of Conduct

Help us keep Mapperly open and inclusive. Please read and follow our [code of conduct](https://github.com/riok/mapperly/blob/main/CODE_OF_CONDUCT.md).

## Got a question or problem?

If you have a question or a problem create a new [GitHub Discussion](https://github.com/riok/mapperly/discussions/new/choose).

## Found a Bug?

If you find a bug in the source code, you can help us by [submitting a GitHub Issue](https://github.com/riok/mapperly/issues/new).
Even better, you can [submit a Pull Request](#submit-pr) with a fix.

## Missing a Feature?

You can _request_ a new feature by [submitting an issue](#submit-issue) to our GitHub repository.
If you would like to _implement_ a new feature, please consider the size of the change in order to determine the right steps to proceed:

- For a **major feature**, first [open an issue](https://github.com/riok/mapperly/issues/new) and outline your proposal so that it can be discussed.
  Getting early feedback will help ensure your implementation work is accepted by the maintainers.
  This will also allow us to better coordinate our efforts and minimize duplicated effort.

  Note: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.

- **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).

## Using AI tools

You are welcome to use AI tools to help you contribute to Mapperly.
However, you are responsible for every line of code you submit.
Before opening a pull request, please make sure that you did not use AI tools to generate the PR,
or that you have manually verified that you understand the code, that it is correct, optimal, and follows the project guidelines and architecture.

Low-quality, AI-generated pull requests that have not been reviewed and understood by their author
will be closed immediately without further explanation.

## Submission Guidelines

### <a name="submit-issue"></a> Submitting an issue

Before you submit an issue, please search the issue tracker and discussions.
An issue for your problem might already exist and the discussion might inform you of workarounds readily available.

You can file new issues by filling out the new issue template.

### <a name="submit-pr"></a> Submitting a pull request (PR)

Before you submit your Pull Request (PR) consider the following guidelines:

1. Search [GitHub](https://github.com/riok/mapperly/pulls) for an open or closed PR that relates to your submission.
   You don't want to duplicate existing efforts.

2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
   Discussing the design upfront helps to ensure that we're ready to accept your work.

3. Get an overview on how Mapperly works by reading this contributing documentation, the [architectural overview](./architecture) and related documentation.

4. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the riok/mapperly repository.

5. In your forked repository, make your changes in a new Git branch:

   ```shell
   git checkout -b my-fix-branch main
   ```

6. Create your patch, including appropriate [test](./tests) cases and [documentation](./docs) updates.

7. Commit your changes using a descriptive commit message.
   Adherence to these conventions is necessary because release notes are automatically generated from these messages.
   [Husky](https://alirezanet.github.io/Husky.Net/) and [csharpier](https://csharpier.com/) automatically format changed files when commited.

   ```shell
   git commit --all
   ```

   Note: the optional commit `-a` command-line option will automatically "add" and "rm" edited files.

8. If any commits have been made to the upstream main branch,
   you should rebase your development branch so that merging it will be a simple fast-forward that won't require any conflict resolution work.

9. ```shell
   git checkout main
   git pull upstream main
   git checkout my-fix-branch
   git rebase main
   ```

10. Now, it may be desirable to squash some of your smaller commits down into a small number of larger more cohesive commits. You can do this with an interactive rebase:

    ```bash
    # Rebase all commits on your development branch
    git checkout
    git rebase -i main
    ```

11. Push your branch to GitHub:

    ```shell
    git push origin my-fix-branch
    ```

12. In GitHub, send a pull request to `riok:main` and request a review from a maintainer.

#### Checks failure

Once you've submitted a pull request, all continuous-integration checks are triggered.
If some of these checks fail, it could be either problems with the pull request or a failure of some test cases.
For more information on the failure, check the output logs of the jobs.

#### Reviewing a pull request

The reviewers will provide you feedback and approve your changes as soon as they are satisfied.
If we ask you for changes in the code, you can follow the [GitHub Guide](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request) to incorporate feedback in your pull request.