{"id":16323507,"url":"https://github.com/you54f/pact-plugin-template-dotnet","last_synced_at":"2025-05-14T14:34:57.652Z","repository":{"id":64693645,"uuid":"577519929","full_name":"YOU54F/pact-plugin-template-dotnet","owner":"YOU54F","description":"Pact 🔗 Plugin 🔌 template for the .NET/C# 🥅  language = 🫶","archived":false,"fork":false,"pushed_at":"2023-03-12T09:33:34.000Z","size":1141,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-17T04:22:31.486Z","etag":null,"topics":["contract-testing","csharp","dotnet","grpc","grpc-server","pact","pact-plugin","template"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/YOU54F.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-12T23:16:20.000Z","updated_at":"2023-03-08T20:01:46.000Z","dependencies_parsed_at":"2024-12-25T22:32:55.856Z","dependency_job_id":null,"html_url":"https://github.com/YOU54F/pact-plugin-template-dotnet","commit_stats":null,"previous_names":[],"tags_count":3,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YOU54F%2Fpact-plugin-template-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YOU54F%2Fpact-plugin-template-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YOU54F%2Fpact-plugin-template-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YOU54F%2Fpact-plugin-template-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YOU54F","download_url":"https://codeload.github.com/YOU54F/pact-plugin-template-dotnet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254160647,"owners_count":22024574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contract-testing","csharp","dotnet","grpc","grpc-server","pact","pact-plugin","template"],"created_at":"2024-10-10T22:54:59.376Z","updated_at":"2025-05-14T14:34:57.587Z","avatar_url":"https://github.com/YOU54F.png","language":"C#","readme":"# Pact Plugin Template\n\n\u003cimg src=\"https://user-images.githubusercontent.com/19932401/206557102-f5141b7d-a4f4-441b-84f6-ede3552c4696.png\" height=\"3.5%\" width=\"3.5%\"\u003e\u003cimg src=\"https://dotnet.microsoft.com/static/images/redesign/social/square.png\" height=\"3.5%\" width=\"3.5%\"\u003e\n\n\nTemplate project to help bootstrap a new Pact [Plugin](https://github.com/pact-foundation/pact-plugins) for the [Pact](http://docs.pact.io) framework. \n\n**Features:**\n\n* Stubbed gRPC methods ready to implement\n* Automated release procedure\n* Support for recommended common platform/targets\n* Levelled logging for observability\n\n**TODO**\n\n- [ ] Support Matchers and Generators (requires FFI package support)\n\n## Repository Structure\n\n\n```\n\n├── README.md                # This file!\n├── Makefile                 # Build configuration            (✅ fill me in!)\n├── Program.cs               # The gRPC server handler            \n├── Services\n│   └── PactPluginService.cs # The gRPC server implementation (✅ fill me in!)\n├── Protos                   # Plugin configuration file - set to use the binary distributable\n│   └── plugin.proto         # Location of protobuf for the Pact Plugin Framework\n├── pact-plugin.json\n├── build                    # This is where your binary distributions will be output\n├── GrpcPactPlugin           # This is will be the name of the plugin, yours will change\n├── GrpcPactPlugin.csproj    # The project config file\n├── Properties\n│   └── launchSettings.json  # The project dependencies file\n├── appsettings.json         # The project settings file\n├── evans.sh                 # A quick tool to help you test your plugin\n└── test\n    └── pact-js              # A test with Pact-JS to exercise the plugin\n└── .github/workflows        # This holds your CI build and release configuration\n├── RELEASING.md             # Instructions on how to release 🚀\n```\n\n## Developing the plugin\n\n### Prerequsites\n\nThe protoc compiler must be installed for this plugin \n\nSee .NET specific instructions [here](https://github.com/grpc/grpc-dotnet#to-start-using-grpc-for-net)\nand the official Microsoft docs [page](https://learn.microsoft.com/en-us/aspnet/core/grpc/protobuf?view=aspnetcore-7.0) for knowledge about construction Protobuf messages in .NET\n\n### Create your new repository\n\n1. Clone this repository \n2. Create a new repository in GitHub. The name of the plugin should be `pact-\u003cPROJECT\u003e-plugin` e.g. `pact-protobuf-plugin`\n3. Push this code to your new repository\n\n### Install the project dependencies\n\nRun:\n\n```\nmake build\n```\n\nwhich is an alias for \n\n```\ndotnet build\n```\n\nTo ensure the dependencies and vendoring are correct.\n\n### Set the name and version\n\nIn the top of the [`Makefile`](./Makefile) set `PROJECT` to your plugin's name.\n\n`PROJECT` should map to `\u003cPROJECT\u003e` in your GitHub repository.\n\n*NOTE: It's important that the name of your GitHub project and the `PROJECT` variable must align, to create artifacts discoverable to the CLI tooling, such as the [Plugin CLI](https://docs.pact.io/implementation_guides/pact_plugins/cli).*\n\n### Design the consumer interface\n\nThis is how the users of your plugin will write the plugin specific interaction details. \n\nFor example, take the following HTTP interaction:\n\n```js\nawait pact\n  .addInteraction()\n  .given('the Matt protocol exists')\n  .uponReceiving('an HTTP request to /matt')\n  .usingPlugin({\n    plugin: 'matt',\n    version: '0.0.4',\n  })\n  .withRequest('POST', '/matt', (builder) =\u003e {\n    builder.pluginContents('application/matt', mattRequest); // \u003c- request\n  })\n  .willRespondWith(200, (builder) =\u003e {\n    builder.pluginContents('application/matt', mattResponse); // \u003c- response\n  })\n  .executeTest((mockserver) =\u003e {\n          ...\n```          \n\nThe user needs to specify the request and response body portion of the request.\n\nBecause the use cases for plugins are so wide and varied, the framework does not impose limits\non this data structure and is something you need to design.\n\nThis being said, most plugins have opted to use a JSON structure. \n\nThis structure is represented in our GoLang template in [`configuration.go`](https://github.com/pact-foundation/pact-plugin-template-golang/blob/main/configuration.go)\n\nThink about how you would like your user to specify the interaction details for the various interaction types. \n\nHere is an example for a TCP plugin with a custom text protocol:\n\n#### Synchronous Messages\n\nSet the expected response from the API:\n\n```go\nmattMessage := `{\"response\": {\"body\": \"hellotcp\"}}`\n```\n\n#### Asynchronous Messages\n\nSet the request/response all in one go:\n\n```go\nmattMessage := `{\"request\": {\"body\": \"hellotcp\"}, \"response\":{\"body\":\"tcpworld\"}}`\n```\n\n#### HTTP\n\nSeparate out the body on the request/response part of the interaction:\n\n```go\nmattRequest := `{\"request\": {\"body\": \"hello\"}}`\nmattResponse := `{\"response\":{\"body\":\"world\"}}`\n```\n\n### Write the Plugin!\n\n#### Implement the relevant RPC functions\n\nOpen [`PactPluginService.cs`](./Services/PactPluginService.cs) and update the relevant RPC functions. \n\nDepending on your use case, some of the RPC calls won't be required, each method is well signposted to help you along.\n\n#### Logging\n\nYou should log regularly. Debugging gRPC calls from the framework can be challenging, as the plugin is started asynchronously by the Plugin Driver behind the scenes.\n\nThere are two ways to log:\n\n1. Stdout - all stdout (e.g. `print`) is pulled into the general Pact logs for the framework you're running\n2. To file. All calls to `log` will be written to a file\n\nThe log setup has three main features:\n\n1. [X] It works with the native `C#` package\n2. [ ] It logs to a file relative to plugin execution in `log/plugin.log`\n3. [ ] It is levelled, at the direction of the plugin driver (that is, the log level will pass in from the driver which will restrict the levels logged in this plugin)\n\n\u003c!-- To write something to the log file, you simply call the `log` method, with the level prefixed as per below: --\u003e\nTo write something to stdout, you simply call the `Console.WriteLine` method\n\n`log(message)`\n\n\u003c!-- ```golang\nlog.Println(\"[TRACE] ...\")\nlog.Println(\"[DEBUG] ...\")\nlog.Println(\"[INFO] ...\")\nlog.Println(\"[WARN] ...\")\nlog.Println(\"[ERROR] ...\")\n``` --\u003e\n\n### Publish your plugin\n\nFollow the steps in [Releasing](./RELEASING.md) to publish a new version of your Plugin.\n\n## Local Development\n\nThe following command will build the plugin, and install into the correct plugin directory for local development:\n\n```\nmake install_local\n```\n\nYou can then reference your plugin in local tests to try it out.\n\n### Regenerating the plugin protobuf definitions\n\nIf a new protobuf definition is required (e.g. to support a new feature), copy it into the `Protos` folder and run the following Make task:\n\n\u003e Need to add annotation in the protofile `option csharp_namespace = \"GrpcPactPlugin\"` for an idiomatic naming convention for C#\n\n```\nmake proto\n```\n\nIt will update the definitions in the `./obj/Debug/net6.0` packages. Note this may result in a breaking change, depending on the version. So upgrade carefully and ensure you have appropriate tests\n\n## Supported targets\n\nThis code base should automatically create artifacts for the following OS/Architecture combiations:\n\n| OS      | Architecture | Supported |\n| ------- | ------------ | --------- |\n| OSX     | x86_64       | ✅         |\n| OSX     | arm          | ✅         |\n| Linux   | x86_64       | ✅         |\n| Linux   | arm          | ✅         |\n| Windows | x86_64       | ✅         |\n| Windows | arm          | ✅         |\n\n## .NET Development notes\n\n1. Install .NET 6+\n2. Open the Project.\n3. Run `dotnet run`\n4. Build with `dotnet build`\n   1. Different options for different archs `https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build`\n   2. For full list see https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyou54f%2Fpact-plugin-template-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyou54f%2Fpact-plugin-template-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyou54f%2Fpact-plugin-template-dotnet/lists"}