diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..8a7fce7 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,84 @@ +## General + +- Make only high confidence suggestions when reviewing code changes. +- Always use the latest version C#, currently C# 13 features. +- Write code that is clean, maintainable, and easy to understand. +- Only add comments rarely to explain why a non-intuitive solution was used. The code should be self-explanatory otherwise. +- Don't add the UTF-8 BOM to files unless they have non-ASCII characters. +- Never change global.json unless explicitly asked to. +- Never change package.json or package-lock.json files unless explicitly asked to. +- Never change NuGet.config files unless explicitly asked to. + +## Code Style + +### Formatting + +- Apply code-formatting style defined in `.editorconfig`. +- Use primary constructors where applicable. +- Prefer file-scoped namespace declarations and single-line using directives. +- Insert a newline before the opening curly brace of any code block (e.g., after `if`, `for`, `while`, `foreach`, `using`, `try`, etc.). +- Ensure that the final return statement of a method is on its own line. +- Use pattern matching and switch expressions wherever possible. +- Prefer using collection expressions when possible +- Use `is` pattern matching instead of `as` and null checks +- Use `nameof` instead of string literals when referring to member names. +- Prefer `?.` if applicable (e.g. `scope?.Dispose()`). +- Use `ObjectDisposedException.ThrowIf` where applicable. +- Use `ArgumentNullException.ThrowIfNull` to validate input paramters. +- If you add new code files, ensure they are listed in the csproj file (if other files in that folder are listed there) so they build. + +### Nullable Reference Types + +- Declare variables non-nullable, and check for `null` at entry points. +- Always use `is null` or `is not null` instead of `== null` or `!= null`. +- Trust the C# null annotations and don't add null checks when the type system says a value cannot be null. + +## Architecture and Design Patterns + +### Asynchronous Programming + +- Provide both synchronous and asynchronous versions of methods where appropriate. +- Use the `Async` suffix for asynchronous methods. +- Return `Task` or `ValueTask` from asynchronous methods. +- Use `CancellationToken` parameters to support cancellation. +- Avoid async void methods except for event handlers. +- Call `ConfigureAwait(false)` on awaited calls to avoid deadlocks. + +### Error Handling + +- Use appropriate exception types. +- Include helpful error messages. +- Avoid catching exceptions without rethrowing them. + +### Performance Considerations + +- Be mindful of performance implications, especially for database operations. +- Avoid unnecessary allocations. +- Consider using more efficient code that is expected to be on the hot path, even if it is less readable. + +### Implementation Guidelines + +- Write code that is secure by default. Avoid exposing potentially private or sensitive data. +- Make code NativeAOT compatible when possible. This means avoiding dynamic code generation, reflection, and other features that are not compatible. with NativeAOT. If not possible, mark the code with an appropriate annotation or throw an exception. + +## Documentation + +- Include XML documentation for all public APIs. Mention the purpose, intent, and 'the why' of the code, so developers unfamiliar with the project can better understand it. If comments already exist, update them to meet the before mentioned criteria if needed. Use the full syntax of XML Doc Comments to make them as awesome as possible including references to types. Don't add any documentation that is obvious for even novice developers by reading the code. +- Add proper `` tags with links to relevant documentation where helpful. +- For keywords like `null`, `true` or `false` use `` tags. +- Include code examples in documentation where appropriate. +- Overriding members should inherit the XML documentation from the base type via `/// `. + +## Markdown +- Use Markdown for documentation files (e.g., README.md). +- Use triple backticks for code blocks, JSON snippets and bash commands, specifying the language (e.g., ```csharp, ```json and ```bash). + +## Testing + +- When adding new unit tests, strongly prefer to add them to existing test code files rather than creating new code files. +- We use xUnit SDK v3 for tests. +- Do not emit "Act", "Arrange" or "Assert" comments. +- Use NSubstitute for mocking in tests. +- Copy existing style in nearby files for test method names and capitalization. +- When running tests, if possible use filters and check test run counts, or look at test logs, to ensure they actually ran. +- Do not finish work with any tests commented out or disabled that were not previously commented out or disabled. \ No newline at end of file diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 65b3c8a..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: CodeQL - -on: - push: - branches-ignore: [ master ] - paths: [ 'src/**' ] - pull_request: - branches: [ master, develop] - paths: [ 'src/**' ] - workflow_dispatch: - schedule: - - cron: '0 0 1,15 * *' - -env: - NET_VERSION: '9.x' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'csharp' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - - name: Setup .NET SDK ${{ env.NET_VERSION }} - uses: actions/setup-dotnet@v3 - with: - dotnet-version: ${{ env.NET_VERSION }} - dotnet-quality: 'ga' - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - # ?? Command-line programs to run using the OS shell. - # ?? See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 44119ae..f9f7421 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,5 +1,8 @@ name: Lint Code Base +permissions: + contents: read + ############################# # Start the job on all push # ############################# @@ -31,7 +34,7 @@ jobs: # Checkout the code base # ########################## - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # Full git history is needed to get a proper list of changed files within `super-linter` fetch-depth: 0 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cb56783..cb27af8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,9 @@ name: Publish SimpleAuthentication on NuGet + +permissions: + contents: read + packages: write + actions: write on: push: @@ -19,12 +24,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: Setup .NET SDK ${{ env.NET_VERSION }} - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.NET_VERSION }} dotnet-quality: 'ga' diff --git a/.github/workflows/publish_abstractions.yml b/.github/workflows/publish_abstractions.yml index 1a0eace..927b149 100644 --- a/.github/workflows/publish_abstractions.yml +++ b/.github/workflows/publish_abstractions.yml @@ -1,4 +1,9 @@ name: Publish Abstractions on NuGet + +permissions: + contents: read + packages: write + actions: write on: push: @@ -20,12 +25,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: Setup .NET SDK ${{ env.NET_VERSION }} - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.NET_VERSION }} dotnet-quality: 'ga' diff --git a/.github/workflows/publish_swashbuckle.yml b/.github/workflows/publish_swashbuckle.yml index 2dac52d..a600e2a 100644 --- a/.github/workflows/publish_swashbuckle.yml +++ b/.github/workflows/publish_swashbuckle.yml @@ -1,4 +1,9 @@ name: Publish Swashbuckle for Simple Authentication on NuGet + +permissions: + contents: read + packages: write + actions: write on: push: @@ -20,12 +25,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: Setup .NET SDK ${{ env.NET_VERSION }} - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.NET_VERSION }} dotnet-quality: 'ga' diff --git a/SimpleAuthentication.sln b/SimpleAuthentication.sln index c594173..b2bede1 100644 --- a/SimpleAuthentication.sln +++ b/SimpleAuthentication.sln @@ -8,6 +8,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A025126A-3557-4B63-AC19-C8851FB3B88C}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + .github\copilot-instructions.md = .github\copilot-instructions.md src\Directory.Build.props = src\Directory.Build.props EndProjectSection EndProject diff --git a/samples/Controllers/ApiKeySample/ApiKeySample.csproj b/samples/Controllers/ApiKeySample/ApiKeySample.csproj index fad3a53..b316ba7 100644 --- a/samples/Controllers/ApiKeySample/ApiKeySample.csproj +++ b/samples/Controllers/ApiKeySample/ApiKeySample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/Controllers/BasicAuthenticationSample/BasicAuthenticationSample.csproj b/samples/Controllers/BasicAuthenticationSample/BasicAuthenticationSample.csproj index fad3a53..b316ba7 100644 --- a/samples/Controllers/BasicAuthenticationSample/BasicAuthenticationSample.csproj +++ b/samples/Controllers/BasicAuthenticationSample/BasicAuthenticationSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/Controllers/JwtBearerSample/JwtBearerSample.csproj b/samples/Controllers/JwtBearerSample/JwtBearerSample.csproj index 0ea4a86..3268a60 100644 --- a/samples/Controllers/JwtBearerSample/JwtBearerSample.csproj +++ b/samples/Controllers/JwtBearerSample/JwtBearerSample.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/samples/MinimalApis/ApiKeySample/ApiKeySample.csproj b/samples/MinimalApis/ApiKeySample/ApiKeySample.csproj index 17c2130..f448ae1 100644 --- a/samples/MinimalApis/ApiKeySample/ApiKeySample.csproj +++ b/samples/MinimalApis/ApiKeySample/ApiKeySample.csproj @@ -8,7 +8,7 @@ - + diff --git a/samples/MinimalApis/BasicAuthenticationSample/BasicAuthenticationSample.csproj b/samples/MinimalApis/BasicAuthenticationSample/BasicAuthenticationSample.csproj index 17c2130..f448ae1 100644 --- a/samples/MinimalApis/BasicAuthenticationSample/BasicAuthenticationSample.csproj +++ b/samples/MinimalApis/BasicAuthenticationSample/BasicAuthenticationSample.csproj @@ -8,7 +8,7 @@ - + diff --git a/samples/MinimalApis/JwtBearerSample/JwtBearerSample.csproj b/samples/MinimalApis/JwtBearerSample/JwtBearerSample.csproj index 0ce9caf..86d0d92 100644 --- a/samples/MinimalApis/JwtBearerSample/JwtBearerSample.csproj +++ b/samples/MinimalApis/JwtBearerSample/JwtBearerSample.csproj @@ -8,7 +8,7 @@ - + diff --git a/samples/MinimalApis/Net8JwtBearerSample/Net8JwtBearerSample.csproj b/samples/MinimalApis/Net8JwtBearerSample/Net8JwtBearerSample.csproj index 88f9619..220c8a0 100644 --- a/samples/MinimalApis/Net8JwtBearerSample/Net8JwtBearerSample.csproj +++ b/samples/MinimalApis/Net8JwtBearerSample/Net8JwtBearerSample.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/SimpleAuthentication.Abstractions/SimpleAuthentication.Abstractions.csproj b/src/SimpleAuthentication.Abstractions/SimpleAuthentication.Abstractions.csproj index 71c4de5..0148894 100644 --- a/src/SimpleAuthentication.Abstractions/SimpleAuthentication.Abstractions.csproj +++ b/src/SimpleAuthentication.Abstractions/SimpleAuthentication.Abstractions.csproj @@ -28,11 +28,11 @@ - + - +