Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,18 @@ Available VS Code tasks (use via `run_task` tool):
</ItemGroup>
```

5. **Directory.Build.props**: Common MSBuild properties shared across all projects
(`TargetFramework`, `Nullable`, `ImplicitUsings`, `AnalysisLevel`, `AnalysisMode`,
`EnableNETAnalyzers`, `ArtifactsPath`, `IsPackable`, `ManagePackageVersionsCentrally`)
live here at the solution root. Only add a property to a `.csproj` when it is
specific to that project or requires an explicit override of the shared default.

6. **Directory.Packages.props**: All NuGet package versions are centralised here via
`PackageVersion` items. Individual `.csproj` files use `PackageReference Include="..."`
with no `Version` attribute. Asset metadata (`PrivateAssets`, `IncludeAssets`) stays
in the `.csproj` `PackageReference` element. Use `VersionOverride` only when a project
genuinely requires a different version from the central default.

### Code Formatting Tools

1. **CSharpier**: Primary code formatter
Expand Down Expand Up @@ -309,6 +321,15 @@ The project includes comprehensive `.editorconfig` settings that enforce:

**Always respect the .editorconfig settings** - these are verified by the build process.

## Git and Commit Rules

**These rules are absolute — no exceptions:**

- **Never make git commits.** All commits must be cryptographically signed (SSH/GPG). AI coding agents cannot produce signed commits. Stage changes with `git add` and leave `git commit` to the developer, who must run it in their own environment where signing keys are available.
- **Never force push.** Do not run `git push --force` or `git push --force-with-lease`. Force pushing rewrites shared branch history and is blocked by branch protection rules.
- **Never run destructive git commands** (`git reset --hard`, `git checkout .`, `git restore .`, `git clean -f`) without explicit developer instruction.
- **Staging is the limit.** Prepare changes and stage files; the developer handles all commits and pushes.

## Workflow

1. **Before coding**: Run `dotnet tool restore` to ensure tools are installed
Expand Down
38 changes: 36 additions & 2 deletions .github/workflows/merge-bot-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ jobs:
merge-dependabot:
name: Merge dependabot pull request job
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]' && github.event.pull_request.head.repo.full_name == github.repository
# Must come from dependabot, and the PR must be from the same repository to prevent abuse
if: >-
github.actor == 'dependabot[bot]' &&
github.event.pull_request.head.repo.full_name == github.repository
permissions:
contents: write
pull-requests: write
Expand All @@ -36,7 +39,38 @@ jobs:
merge-codegen:
name: Merge codegen pull request job
runs-on: ubuntu-latest
if: github.event.pull_request.user.login == 'github-actions[bot]' && github.event.pull_request.head.ref == 'codegen' && github.event.pull_request.base.ref == 'main' && github.event.pull_request.head.repo.full_name == github.repository && ((github.event.action == 'reopened' && github.actor == 'ptr727') || (github.event.action != 'reopened' && github.actor == 'github-actions[bot]'))
# Must come from the codegen workflow, and the PR must be from the same repository to prevent abuse
if: >-
github.event.pull_request.user.login == 'github-actions[bot]' &&
github.event.pull_request.head.ref == 'codegen' &&
github.event.pull_request.base.ref == 'main' &&
github.event.pull_request.head.repo.full_name == github.repository &&
(
(github.event.action == 'reopened' && github.actor == github.repository_owner) ||
(github.event.action != 'reopened' && github.actor == 'github-actions[bot]')
)
permissions:
contents: write
pull-requests: write

steps:

- name: Merge pull request step
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}

merge-codegen-app:
name: Merge codegen app pull request job
runs-on: ubuntu-latest
# Must come from the codegen app workflow, and the PR must be from the same repository to prevent abuse
if: >-
github.actor == 'ptr727-codegen[bot]' &&
github.event.pull_request.user.login == 'ptr727-codegen[bot]' &&
github.event.pull_request.head.ref == 'codegen' &&
github.event.pull_request.base.ref == 'main' &&
github.event.pull_request.head.repo.full_name == github.repository
permissions:
contents: write
pull-requests: write
Expand Down
65 changes: 65 additions & 0 deletions .github/workflows/run-codegen-app-pull-request-task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Run codegen app and pull request task

on:
workflow_call:
secrets:
# GitHub App credentials to generate an installation token
CODEGEN_APP_ID:
required: true
CODEGEN_APP_PRIVATE_KEY:
required: true

jobs:

codegen:
name: Run codegen app and pull request job
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

steps:

- name: Generate GitHub App token step
uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.CODEGEN_APP_ID }}
private-key: ${{ secrets.CODEGEN_APP_PRIVATE_KEY }}

- name: Setup .NET SDK step
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.x

- name: Checkout code step
uses: actions/checkout@v6
with:
ref: main
token: ${{ steps.app-token.outputs.token }}

- name: Run codegen step
run: |
dotnet run --project ./CodeGen/CodeGen.csproj -- \
--codepath ./CodeGen

- name: Format code step
run: |
dotnet tool restore
dotnet husky install
dotnet csharpier format --log-level=debug .
git status

- name: Create pull request step
uses: peter-evans/create-pull-request@v8
id: cpr
with:
# Use app token: triggers pull_request workflow events directly, creates verified commits as the app
token: ${{ steps.app-token.outputs.token }}
base: main
branch: codegen
title: 'Update codegen files'
body: 'This PR updates the codegen files.'
commit-message: 'Update codegen files'
delete-branch: true
sign-commits: true
3 changes: 3 additions & 0 deletions .github/workflows/run-codegen-pull-request-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: Run codegen and pull request task
on:
workflow_call:
secrets:
# Use PAT to trigger workflows
WORKFLOW_PAT:
required: true

Expand Down Expand Up @@ -43,6 +44,7 @@ jobs:
uses: peter-evans/create-pull-request@v8
id: cpr
with:
# Use GITHUB_TOKEN to sign the commit, but will not trigger workflows
token: ${{ secrets.GITHUB_TOKEN }}
base: main
branch: codegen
Expand All @@ -59,4 +61,5 @@ jobs:
gh pr close "$PR"
gh pr reopen "$PR"
env:
# Use PAT to trigger workflows
GH_TOKEN: ${{ secrets.WORKFLOW_PAT }}
24 changes: 24 additions & 0 deletions .github/workflows/run-periodic-codegen-app-pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Run weekly CodeGen App and Pull Request action

on:
workflow_dispatch:
schedule:
# Run weekly on Thursdays at 02:00 UTC (PAT workflow runs on Mondays)
- cron: '0 2 * * THU'

concurrency:
# Workflow always checks out and targets main/codegen
group: codegen-main
cancel-in-progress: true

jobs:

run-codegen-app:
name: Run codegen app and pull request job
uses: ./.github/workflows/run-codegen-app-pull-request-task.yml
secrets:
CODEGEN_APP_ID: ${{ secrets.CODEGEN_APP_ID }}
CODEGEN_APP_PRIVATE_KEY: ${{ secrets.CODEGEN_APP_PRIVATE_KEY }}
permissions:
contents: write
pull-requests: write
5 changes: 3 additions & 2 deletions .github/workflows/run-periodic-codegen-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ name: Run weekly CodeGen and Pull Request action
on:
workflow_dispatch:
schedule:
# Run weekly on Mondays at 02:00 UTC
# Run weekly on Mondays at 02:00 UTC (PAT workflow; app workflow runs on Thursdays)
- cron: '0 2 * * MON'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# Workflow always checks out and targets main/codegen
group: codegen-main
cancel-in-progress: true

jobs:
Expand Down
102 changes: 51 additions & 51 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Console Root",
"type": "coreclr",
"request": "launch",
"preLaunchTask": ".Net Build",
"program": "${workspaceFolder}/Console/bin/Debug/net10.0/Console.dll",
"args": [
"--loglevel=Debug",
"--logfile=console.log",
"--logfile-clear=true"
],
"cwd": "${workspaceFolder}/Console/bin/Debug/net10.0",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "Console Test",
"type": "coreclr",
"request": "launch",
"preLaunchTask": ".Net Build",
"program": "${workspaceFolder}/Console/bin/Debug/net10.0/Console.dll",
"args": [
"--loglevel=Debug",
"--logfile=console.log",
"--logfile-clear=true",
"test",
"--test=test"
],
"cwd": "${workspaceFolder}/Console/bin/Debug/net10.0",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "CodeGen",
"type": "coreclr",
"request": "launch",
"preLaunchTask": ".Net Build",
"program": "${workspaceFolder}/CodeGen/bin/Debug/net10.0/CodeGen.dll",
"args": [
"--codepath",
"${workspaceFolder}/CodeGen"
],
"cwd": "${workspaceFolder}/CodeGen/bin/Debug/net10.0",
"console": "internalConsole",
"stopAtEntry": false
}
]
}
{
"version": "0.2.0",
"configurations": [
{
"name": "Console Root",
"type": "coreclr",
"request": "launch",
"preLaunchTask": ".Net Build",
"program": "${workspaceFolder}/.artifacts/bin/Console/Debug/Console.dll",
"args": [
"--loglevel=Debug",
"--logfile=console.log",
"--logfile-clear=true"
],
"cwd": "${workspaceFolder}/.artifacts/bin/Console/Debug",
"console": "internalConsole",
Comment thread
ptr727 marked this conversation as resolved.
"stopAtEntry": false
},
{
"name": "Console Test",
"type": "coreclr",
"request": "launch",
"preLaunchTask": ".Net Build",
"program": "${workspaceFolder}/.artifacts/bin/Console/Debug/Console.dll",
"args": [
"--loglevel=Debug",
"--logfile=console.log",
"--logfile-clear=true",
"test",
"--test=test"
],
"cwd": "${workspaceFolder}/.artifacts/bin/Console/Debug",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "CodeGen",
"type": "coreclr",
"request": "launch",
"preLaunchTask": ".Net Build",
"program": "${workspaceFolder}/.artifacts/bin/CodeGen/Debug/CodeGen.dll",
"args": [
"--codepath",
"${workspaceFolder}/CodeGen"
],
"cwd": "${workspaceFolder}/.artifacts/bin/CodeGen/Debug",
"console": "internalConsole",
"stopAtEntry": false
}
]
}
22 changes: 22 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,28 @@
"clear": false
}
},
{
"label": ".Net Benchmark",
"type": "process",
"command": "dotnet",
"args": [
"run",
"--project",
"${workspaceFolder}/Benchmarks/Benchmarks.csproj",
"-c",
"Release",
"--",
"--artifacts",
"${workspaceFolder}/.artifacts/benchmarks"
],
"problemMatcher": [
"$msCompile"
],
"presentation": {
"showReuseMessage": false,
"clear": false
}
},
{
"label": ".Net Outdated Upgrade",
"type": "process",
Expand Down
18 changes: 18 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

For comprehensive coding standards and detailed conventions, refer to [`.github/copilot-instructions.md`](./.github/copilot-instructions.md) and [`CODESTYLE.md`](./CODESTYLE.md).

## Git and Commit Rules

**These rules are absolute — no exceptions:**

- **Never make git commits.** AI coding agents cannot produce cryptographically signed commits. All commits must be signed (SSH/GPG) and must be made by the developer. Stage changes with `git add` and leave the commit to the developer.
- **Never force push.** Do not run `git push --force` or `git push --force-with-lease` under any circumstances. Force pushing rewrites shared history and can cause data loss.
- **Never run destructive git commands** (`git reset --hard`, `git checkout .`, `git restore .`, `git clean -f`) without explicit developer instruction.
- **Staging is the limit.** Prepare and stage file changes; the developer runs `git commit` in their own environment where signing keys are available.

## Key Requirements for All Projects Derived from This Template

### Build & Quality Standards
Expand All @@ -15,6 +24,15 @@ For comprehensive coding standards and detailed conventions, refer to [`.github/
- `<EnableNETAnalyzers>true</EnableNETAnalyzers>`
- `<AnalysisLevel>latest-all</AnalysisLevel>`

### Project Configuration

- Common MSBuild properties (`TargetFramework`, `Nullable`, `ImplicitUsings`, `AnalysisLevel`, etc.)
live in `Directory.Build.props` at the solution root. Do not duplicate these in individual `.csproj`
files — only add a property to a `.csproj` when it is project-specific or overrides the shared default.
- All NuGet package versions are centralised in `Directory.Packages.props`. `PackageReference` elements
in `.csproj` files must not include a `Version` attribute. Asset metadata (`PrivateAssets`,
`IncludeAssets`) stays in the `.csproj` `PackageReference` element.

### Development Environment

- Target latest .NET SDK (currently .NET 10 with C# 14)
Expand Down
7 changes: 1 addition & 6 deletions Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AnalysisLevel>latest-all</AnalysisLevel>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RootNamespace>ptr727.ProjectTemplate.Benchmarks</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
<PackageReference Include="BenchmarkDotNet" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Library\Library.csproj" />
Expand Down
1 change: 0 additions & 1 deletion Benchmarks/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
global using System;
global using BenchmarkDotNet.Attributes;
global using BenchmarkDotNet.Running;
Loading
Loading