Rename Library project to NuGetLibrary - #62
Merged
Conversation
Disambiguate the .NET project name in preparation for adding a sibling Python PyPi project. The folder, csproj filename, RootNamespace, and namespace declarations move from `Library` to `NuGetLibrary`. The companion GitHub Actions reusable workflow `build-library-task.yml` is renamed to `build-nugetlibrary-task.yml` for the same reason; the artifact name and zip filename track the rename. The published NuGet package id is intentionally preserved as `ptr727.ProjectTemplate.Library` via an explicit `<PackageId>` element so existing consumers and the README NuGet badges continue to work without a new package or a 404 on the existing nuget.org URL. Class names `TemplateLibrary` and `StaticTemplateLibrary` are left alone — they describe the type, not the project, and are referenced by tests and benchmarks. dotnet build: 0 warnings, 0 errors. dotnet test: 15 passed, 0 failed. dotnet pack: produces ptr727.ProjectTemplate.Library.1.0.0-pre.nupkg as expected.
Contributor
There was a problem hiding this comment.
Pull request overview
Renames the .NET “Library” project to “NuGetLibrary” to avoid ambiguity with an upcoming Python sibling, while keeping the published NuGet package identity (ptr727.ProjectTemplate.Library) unchanged. This updates project paths, namespaces, and CI workflows so builds and releases continue to work under the new project name.
Changes:
- Renamed project references and solution/workspace entries from
LibrarytoNuGetLibrary. - Updated source namespaces and
RootNamespacetoptr727.ProjectTemplate.NuGetLibrary(plus addedGlobalUsings.csfor logging types). - Renamed the reusable build workflow and updated release workflow wiring/artifact naming accordingly.
Reviewed changes
Copilot reviewed 16 out of 18 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| Tests/Tests.csproj | Updates ProjectReference to the renamed NuGetLibrary project. |
| Tests/LoggingTests.cs | Updates using to the new ptr727.ProjectTemplate.NuGetLibrary namespace. |
| Console/Console.csproj | Updates ProjectReference to NuGetLibrary/NuGetLibrary.csproj. |
| Console/Program.cs | Updates using to the new library namespace. |
| Benchmarks/Benchmarks.csproj | Updates ProjectReference to the renamed library project. |
| NuGetLibrary/NuGetLibrary.csproj | Sets RootNamespace to the new namespace while preserving PackageId. |
| NuGetLibrary/Library.cs | Updates namespace declaration to ptr727.ProjectTemplate.NuGetLibrary. |
| NuGetLibrary/Options.cs | Updates namespace declaration to ptr727.ProjectTemplate.NuGetLibrary. |
| NuGetLibrary/LogOptions.cs | Updates namespace declaration to ptr727.ProjectTemplate.NuGetLibrary. |
| NuGetLibrary/Extensions.cs | Updates namespace declaration to ptr727.ProjectTemplate.NuGetLibrary. |
| NuGetLibrary/GlobalUsings.cs | Adds global usings to simplify logging-related references across the project. |
| NuGetLibrary/.editorconfig | Adds a project-scoped editorconfig (CS1591 suppression) for the renamed library folder. |
| .github/workflows/build-nugetlibrary-task.yml | Renames and retargets the reusable workflow to build/package NuGetLibrary. |
| .github/workflows/build-release-task.yml | Updates release workflow to call the renamed reusable build workflow and artifact references. |
| ProjectTemplate.slnx | Updates solution project paths and workflow file entry to the renamed files/paths. |
| ProjectTemplate.code-workspace | Adds nugetlibrary to cSpell to avoid spelling noise after the rename. |
| AGENTS.md | Updates project structure documentation to reflect NuGetLibrary naming and packaging identity. |
| .github/copilot-instructions.md | Updates project overview and namespace examples to reflect NuGetLibrary. |
This was referenced May 3, 2026
# Conflicts: # .github/workflows/build-release-task.yml
ptr727
added a commit
that referenced
this pull request
May 3, 2026
## Summary Adds a single unified [Dev Container](https://containers.dev/) hosting both the .NET 10 SDK and the upcoming Python `uv` toolchain, plus three focused docs files that decompose host setup, devcontainer setup, and SSH commit signing per-OS. On Windows, the **devcontainer flow** requires WSL2 (the bind-mounts use POSIX paths). The **host-install flow** in `README.md` supports native Windows via winget — see `docs/host-setup.md` for the per-flow scope. > **Stacked on [#62](#62) (NuGetLibrary rename)**. The diff against `develop` will show PR #62's changes until that PR merges; once it does, the diff here cleans up to just the devcontainer + docs work. ## Changes **New files**: - `.devcontainer/devcontainer.json` — base `mcr.microsoft.com/devcontainers/dotnet:1-10.0`, `gh` and `common-utils` features. Bind-mounts `~/.ssh/id_ed25519.pub` (read-only), `~/.config/git/allowed_signers` (read-only), `~/.config/gh` (read-write). `${localEnv:HOME}${localEnv:USERPROFILE}` form covers Linux/macOS and WSL2 hosts. Extension list mirrors `ProjectTemplate.code-workspace` `recommendations`. - `.devcontainer/post-create.sh` (executable, mode 100755) — installs `uv` from `astral.sh` (pinned to a specific version via the version-prefixed install URL; re-installs on version mismatch so the pin holds even when uv is already on PATH), runs `dotnet tool restore`, installs Husky.Net hooks, pre-syncs `PyPiLibrary` if it exists (guarded so this script works before PR 5 lands). - `docs/host-setup.md` — git identity, Ed25519 SSH key, `allowed_signers`, `gh auth login`, per-OS ssh-agent setup, verify checklist. - `docs/devcontainer.md` — bind-mount table, lifecycle commands, `gh` credential-store nuance (Keychain vs libsecret vs file), verify checklist, troubleshooting. - `docs/ssh-signing.md` — per-OS deltas (systemd ssh-agent on Linux, Apple Keychain on macOS, WSL2 caveats), `allowed_signers` format, devcontainer interaction, troubleshooting. **Modified**: - `README.md` — adds a "Recommended (devcontainer)" path to the Development Environment Setup section linking to the new docs; the existing host-install path stays. Template Project Setup section now points at the docs files for prerequisites instead of inlining them. - `ProjectTemplate.code-workspace` — adds `ms-python.python` and `charliermarsh.ruff` to `recommendations` (mirrors the devcontainer list); adds `unwantedRecommendations` for `ms-pyright.pyright` (deprecated; pyright is provided by Pylance which `ms-python.python` auto-installs), `ms-python.mypy-type-checker`, `ms-python.pylint`, `ms-python.flake8`, `ms-python.isort`, and `ms-python.black-formatter` so contributors aren't prompted to install tools that overlap with ruff + Pylance and would surface "could not find binary" connection errors against the venv. Also adds `astral`, `devcontainer`, `hatchling`, `Keychain`, `libsecret`, `onCreateCommand`, `postCreateCommand`, `pyproject`, `pypi`, `pypilibrary`, `pyright`, `ruff` to `cSpell.words`. ## Why a single unified container VS Code Dev Containers does not support per-folder containers in the same multi-root window — only a picker per session. A single image with both .NET and `uv` is the simplest mental model and lets downstream users delete the language they don't need by removing a feature line and a postCreateCommand step. See [VS Code Dev Containers docs](https://code.visualstudio.com/remote/advancedcontainers/connect-multiple-containers) for the limitation. ## Why bind-mount the public key, not the private key The private key never enters the container. Signing happens via the SSH agent socket forwarded by VS Code Dev Containers (`SSH_AUTH_SOCK`). The public key plus `allowed_signers` is enough for git to know which key to delegate signing to and to verify signatures in `git log --show-signature`. ## Why an `onCreateCommand` chown On macOS hosts the bind-mount surfaces `/home/vscode/.ssh` as root-owned inside the container, which would block `gh` from updating `known_hosts`. The chown is idempotent on Linux and WSL2 so it stays unconditional rather than gated on host detection. ## Test plan - [x] `gh pr create --base develop --head devcontainer-docs` succeeded - [ ] CI green on the PR (test-pull-request workflow) - [ ] Build the devcontainer on Linux, run `git -c gpg.format=ssh commit -S --allow-empty -m verify` inside, verify it signs - [ ] Build the devcontainer on macOS host, verify the `onCreateCommand` chown lets `gh auth status` work - [ ] Build on WSL2 host, verify behavior matches Linux - [ ] Confirm `recommendations` in `code-workspace` and `customizations.vscode.extensions` in `devcontainer.json` are identical - [ ] Markdown lint passes on the new docs files
ptr727
added a commit
that referenced
this pull request
May 3, 2026
## Summary Adds a Python PyPi template project alongside the .NET `NuGetLibrary`, completing the polyglot template. Modern 2026 stack: hatchling backend, `uv` for env/deps/publish, ruff for lint+format, pyright for typing, pytest for tests, PyPI Trusted Publishing via OIDC. > **Stacked on [#62](#62) (NuGetLibrary rename, merged) and [#63](#63) (devcontainer + docs)**. Once #63 merges this PR's diff cleans up to just the PyPiLibrary work. ## Naming - Folder: `PyPiLibrary/` — qualifier on disk to disambiguate from `NuGetLibrary/` - Published PyPI name: `ptr727-projecttemplate-library` — **no `pypi` qualifier**, mirrors the NuGet identity - Python import name: `ptr727_projecttemplate_library` ## New tree ```text PyPiLibrary/ pyproject.toml # hatchling backend, ruff/pyright/pytest config, PEP 735 [dependency-groups] README.md # what this PyPi template is + uv quickstart + Trusted Publisher setup uv.lock # committed for reproducible CI src/ ptr727_projecttemplate_library/ __init__.py _version.py # __version__ = "0.0.0" placeholder; see README.md "Template Adoption" for version-scheme options example.py # trivial greet() function tests/ test_example.py # 3 tests ``` ## Workflow plumbing The split-by-purpose layout was chosen so `id-token: write` (required by Trusted Publishing) only has to be granted on the entry-point job, not propagated through reusable-workflow chains: - **New** `.github/workflows/build-pypilibrary-task.yml` — reusable workflow that **only builds**: setup uv (pinned to `0.11.8` to match the devcontainer), sync, ruff check, ruff format --check, pyright, pytest, `uv build`, upload artifact. **No publish job here**, no `id-token: write`. - **Modified** `.github/workflows/build-release-task.yml` — adds a `build-pypilibrary` job calling the new reusable workflow, includes it in the `github-release` `needs:` list. Build runs unconditionally (matches the always-validate-on-PR semantic of the rest of the workflow). **No `pypi: bool` input** — would require id-token propagation through the test-pull-request chain (and triggered `startup_failure`, fixed in 4c939f6). - **Modified** `.github/workflows/publish-release.yml` — adds a top-level `publish-pypi` job that runs after `create-release`, downloads the `pypilibrary-build` artifact by name (artifacts uploaded by reusable workflows are accessible to sibling jobs in the same run), and publishes via Trusted Publishing. **`id-token: write` lives only here**, alongside the explicit `contents: read` and `actions: read` needed for `actions/download-artifact`. Uses `skip-existing: true` so the placeholder `0.0.0` version doesn't fail the workflow on repeated pushes. - **Modified** `.github/workflows/test-release-task.yml` — no PyPi-specific input needed; the build runs as part of the existing chain. ## Other plumbing - **`.github/dependabot.yml`** — adds `package-ecosystem: "uv"` targeting `/PyPiLibrary` with the `pypi-deps` group label. Existing `nuget` and `github-actions` blocks normalized to standard two-space indentation under `updates:`. - **`.husky/task-runner.json`** — adds `Ruff Format` and `Ruff Check` tasks scoped to `PyPiLibrary/**/*.py`. Both pass `${staged}` as positional args via `bash -c "..." -- ${staged}` so paths with spaces survive; both gate on `command -v uv` so a `.cs`-only commit on a contributor without uv installed doesn't fail. - **`ProjectTemplate.code-workspace`** — adds Python format-on-save with ruff, the `[python]` formatter binding, `python.terminal.activateEnvironment: false`. No hard-coded venv paths (those caused "could not find ruff binary" popups before `uv sync` ran). Adds `unwantedRecommendations` for mypy / pylint / flake8 / isort / black / standalone pyright so contributors aren't prompted to install tools that overlap with ruff and Pylance. - **`ProjectTemplate.slnx`** — adds `build-pypilibrary-task.yml` to the GitHub Actions folder. - **`.gitignore`** — adds `.venv/`, `dist/`, `__pycache__/`, `*.py[cod]`, `*.egg-info/`, `.pytest_cache/`, `.ruff_cache/`, `.pyright/`. - **`README.md`** — PyPI badge + link in the build/distribution and releases sections; template TODO list reminds the deriver to delete the unused language side. `gh` "pre-authenticated" wording softened to call out the Keychain/libsecret credential-store limitation. ## Trusted Publisher setup (one-time, on PyPI side) 1. PyPI → **Account settings** → **Publishing** → **Add a new pending publisher** - Project name: `ptr727-projecttemplate-library` - Owner: `ptr727` - Repo: `ProjectTemplate` - Workflow: `publish-release.yml` - Environment: `pypi` 2. GitHub repo → **Settings** → **Environments** → create `pypi` environment (optionally with required reviewers). The first successful release converts the pending publisher to a real publisher. ## Versioning gap `_version.py` ships with `__version__ = "0.0.0"`. Trusted Publishing with `skip-existing: true` means the workflow won't fail, but no new PyPI versions land until you wire `_version.py` to something that increments — see `PyPiLibrary/README.md` "Template Adoption" for the three usual options (hatch-vcs / version.json bridge / manual bumps). ## Test plan - [x] `uv sync` clean (host: uv 0.11.8) - [x] `uv run ruff check` — All checks passed - [x] `uv run ruff format --check` — clean - [x] `uv run pyright` — 0 errors, 0 warnings, 0 informations - [x] `uv run pytest` — 3 passed - [x] `uv build` — produces `ptr727_projecttemplate_library-0.0.0.tar.gz` and wheel - [x] `dotnet build` — 0 warnings, 0 errors - [x] `dotnet test` — 15 passed (no .NET regression) - [ ] CI green on the PR (test-release-task exercises ruff, pyright, pytest, uv build via the same reusable workflow that publish uses) - [ ] After Trusted Publisher is configured on PyPI and a real version scheme is wired in `_version.py`, next merge to `main` smoke-tests the publish path
5 tasks
ptr727
added a commit
that referenced
this pull request
May 4, 2026
## Summary
Disambiguates the .NET project name from the upcoming Python
`PyPiLibrary` sibling. Folder, csproj filename, `RootNamespace`, and
namespace declarations move from `Library` to `NuGetLibrary`. The
companion GitHub Actions reusable workflow `build-library-task.yml` is
renamed to `build-nugetlibrary-task.yml`; the produced artifact name and
7z filename track the rename.
## Preserved on purpose
- `<PackageId>ptr727.ProjectTemplate.Library</PackageId>` is **kept** so
the published nupkg keeps its identity. No orphaned package, no 404 on
existing consumers, no new badge URL needed.
- README NuGet badges (`nuget-link`, `nugetreleaseversion-shield`,
`nugetprereleaseversion-shield`) still point at
`ptr727.ProjectTemplate.Library` and continue to work.
- Class names `TemplateLibrary` and `StaticTemplateLibrary` are
unchanged — they describe types, not the project.
- `InternalsVisibleTo` declarations stay (`Console`, `Tests`,
`Benchmarks` assembly names are unchanged).
## Files touched
- `git mv Library/ NuGetLibrary/` (folder)
- `git mv NuGetLibrary/Library.csproj NuGetLibrary/NuGetLibrary.csproj`
- `git mv .github/workflows/build-library-task.yml
.github/workflows/build-nugetlibrary-task.yml` — paths, job key
`build-nugetlibrary`, artifact name `nugetlibrary-build`, zip
`NuGetLibrary.7z`
- `.github/workflows/build-release-task.yml` — caller updated: job key,
`uses:`, `needs:` array, artifact-id reference
- `Console/Console.csproj`, `Tests/Tests.csproj`,
`Benchmarks/Benchmarks.csproj` — `<ProjectReference>` paths
- `Console/Program.cs`, `Tests/LoggingTests.cs` — `using` statement
- `NuGetLibrary/{Library,Options,LogOptions,Extensions}.cs` — namespace
declaration
- `NuGetLibrary/NuGetLibrary.csproj` — `RootNamespace`
- `ProjectTemplate.slnx` — 4 project path entries + 1 GitHub Actions
folder entry
- `ProjectTemplate.code-workspace` — `cSpell.words` add `nugetlibrary`
- `AGENTS.md`, `.github/copilot-instructions.md` — project list,
namespace examples, structure section
## Test plan
- [x] `dotnet build` — 0 warnings, 0 errors locally
- [x] `dotnet test` — 15 passed, 0 failed
- [x] `dotnet pack ./NuGetLibrary/NuGetLibrary.csproj` — produces
`ptr727.ProjectTemplate.Library.1.0.0-pre.nupkg` (PackageId preserved)
- [x] Repo-wide grep for `Library/Library.csproj`, `build-library-task`
— zero remaining hits
- [ ] CI green on the PR (test-pull-request workflow invokes the renamed
reusable workflow)
- [ ] After merge, next prerelease produces `NuGetLibrary.7z` artifact
attached to the GitHub release
ptr727
added a commit
that referenced
this pull request
May 4, 2026
## Summary Adds a single unified [Dev Container](https://containers.dev/) hosting both the .NET 10 SDK and the upcoming Python `uv` toolchain, plus three focused docs files that decompose host setup, devcontainer setup, and SSH commit signing per-OS. On Windows, the **devcontainer flow** requires WSL2 (the bind-mounts use POSIX paths). The **host-install flow** in `README.md` supports native Windows via winget — see `docs/host-setup.md` for the per-flow scope. > **Stacked on [#62](#62) (NuGetLibrary rename)**. The diff against `develop` will show PR #62's changes until that PR merges; once it does, the diff here cleans up to just the devcontainer + docs work. ## Changes **New files**: - `.devcontainer/devcontainer.json` — base `mcr.microsoft.com/devcontainers/dotnet:1-10.0`, `gh` and `common-utils` features. Bind-mounts `~/.ssh/id_ed25519.pub` (read-only), `~/.config/git/allowed_signers` (read-only), `~/.config/gh` (read-write). `${localEnv:HOME}${localEnv:USERPROFILE}` form covers Linux/macOS and WSL2 hosts. Extension list mirrors `ProjectTemplate.code-workspace` `recommendations`. - `.devcontainer/post-create.sh` (executable, mode 100755) — installs `uv` from `astral.sh` (pinned to a specific version via the version-prefixed install URL; re-installs on version mismatch so the pin holds even when uv is already on PATH), runs `dotnet tool restore`, installs Husky.Net hooks, pre-syncs `PyPiLibrary` if it exists (guarded so this script works before PR 5 lands). - `docs/host-setup.md` — git identity, Ed25519 SSH key, `allowed_signers`, `gh auth login`, per-OS ssh-agent setup, verify checklist. - `docs/devcontainer.md` — bind-mount table, lifecycle commands, `gh` credential-store nuance (Keychain vs libsecret vs file), verify checklist, troubleshooting. - `docs/ssh-signing.md` — per-OS deltas (systemd ssh-agent on Linux, Apple Keychain on macOS, WSL2 caveats), `allowed_signers` format, devcontainer interaction, troubleshooting. **Modified**: - `README.md` — adds a "Recommended (devcontainer)" path to the Development Environment Setup section linking to the new docs; the existing host-install path stays. Template Project Setup section now points at the docs files for prerequisites instead of inlining them. - `ProjectTemplate.code-workspace` — adds `ms-python.python` and `charliermarsh.ruff` to `recommendations` (mirrors the devcontainer list); adds `unwantedRecommendations` for `ms-pyright.pyright` (deprecated; pyright is provided by Pylance which `ms-python.python` auto-installs), `ms-python.mypy-type-checker`, `ms-python.pylint`, `ms-python.flake8`, `ms-python.isort`, and `ms-python.black-formatter` so contributors aren't prompted to install tools that overlap with ruff + Pylance and would surface "could not find binary" connection errors against the venv. Also adds `astral`, `devcontainer`, `hatchling`, `Keychain`, `libsecret`, `onCreateCommand`, `postCreateCommand`, `pyproject`, `pypi`, `pypilibrary`, `pyright`, `ruff` to `cSpell.words`. ## Why a single unified container VS Code Dev Containers does not support per-folder containers in the same multi-root window — only a picker per session. A single image with both .NET and `uv` is the simplest mental model and lets downstream users delete the language they don't need by removing a feature line and a postCreateCommand step. See [VS Code Dev Containers docs](https://code.visualstudio.com/remote/advancedcontainers/connect-multiple-containers) for the limitation. ## Why bind-mount the public key, not the private key The private key never enters the container. Signing happens via the SSH agent socket forwarded by VS Code Dev Containers (`SSH_AUTH_SOCK`). The public key plus `allowed_signers` is enough for git to know which key to delegate signing to and to verify signatures in `git log --show-signature`. ## Why an `onCreateCommand` chown On macOS hosts the bind-mount surfaces `/home/vscode/.ssh` as root-owned inside the container, which would block `gh` from updating `known_hosts`. The chown is idempotent on Linux and WSL2 so it stays unconditional rather than gated on host detection. ## Test plan - [x] `gh pr create --base develop --head devcontainer-docs` succeeded - [ ] CI green on the PR (test-pull-request workflow) - [ ] Build the devcontainer on Linux, run `git -c gpg.format=ssh commit -S --allow-empty -m verify` inside, verify it signs - [ ] Build the devcontainer on macOS host, verify the `onCreateCommand` chown lets `gh auth status` work - [ ] Build on WSL2 host, verify behavior matches Linux - [ ] Confirm `recommendations` in `code-workspace` and `customizations.vscode.extensions` in `devcontainer.json` are identical - [ ] Markdown lint passes on the new docs files
ptr727
added a commit
that referenced
this pull request
May 4, 2026
## Summary Adds a Python PyPi template project alongside the .NET `NuGetLibrary`, completing the polyglot template. Modern 2026 stack: hatchling backend, `uv` for env/deps/publish, ruff for lint+format, pyright for typing, pytest for tests, PyPI Trusted Publishing via OIDC. > **Stacked on [#62](#62) (NuGetLibrary rename, merged) and [#63](#63) (devcontainer + docs)**. Once #63 merges this PR's diff cleans up to just the PyPiLibrary work. ## Naming - Folder: `PyPiLibrary/` — qualifier on disk to disambiguate from `NuGetLibrary/` - Published PyPI name: `ptr727-projecttemplate-library` — **no `pypi` qualifier**, mirrors the NuGet identity - Python import name: `ptr727_projecttemplate_library` ## New tree ```text PyPiLibrary/ pyproject.toml # hatchling backend, ruff/pyright/pytest config, PEP 735 [dependency-groups] README.md # what this PyPi template is + uv quickstart + Trusted Publisher setup uv.lock # committed for reproducible CI src/ ptr727_projecttemplate_library/ __init__.py _version.py # __version__ = "0.0.0" placeholder; see README.md "Template Adoption" for version-scheme options example.py # trivial greet() function tests/ test_example.py # 3 tests ``` ## Workflow plumbing The split-by-purpose layout was chosen so `id-token: write` (required by Trusted Publishing) only has to be granted on the entry-point job, not propagated through reusable-workflow chains: - **New** `.github/workflows/build-pypilibrary-task.yml` — reusable workflow that **only builds**: setup uv (pinned to `0.11.8` to match the devcontainer), sync, ruff check, ruff format --check, pyright, pytest, `uv build`, upload artifact. **No publish job here**, no `id-token: write`. - **Modified** `.github/workflows/build-release-task.yml` — adds a `build-pypilibrary` job calling the new reusable workflow, includes it in the `github-release` `needs:` list. Build runs unconditionally (matches the always-validate-on-PR semantic of the rest of the workflow). **No `pypi: bool` input** — would require id-token propagation through the test-pull-request chain (and triggered `startup_failure`, fixed in 4c939f6). - **Modified** `.github/workflows/publish-release.yml` — adds a top-level `publish-pypi` job that runs after `create-release`, downloads the `pypilibrary-build` artifact by name (artifacts uploaded by reusable workflows are accessible to sibling jobs in the same run), and publishes via Trusted Publishing. **`id-token: write` lives only here**, alongside the explicit `contents: read` and `actions: read` needed for `actions/download-artifact`. Uses `skip-existing: true` so the placeholder `0.0.0` version doesn't fail the workflow on repeated pushes. - **Modified** `.github/workflows/test-release-task.yml` — no PyPi-specific input needed; the build runs as part of the existing chain. ## Other plumbing - **`.github/dependabot.yml`** — adds `package-ecosystem: "uv"` targeting `/PyPiLibrary` with the `pypi-deps` group label. Existing `nuget` and `github-actions` blocks normalized to standard two-space indentation under `updates:`. - **`.husky/task-runner.json`** — adds `Ruff Format` and `Ruff Check` tasks scoped to `PyPiLibrary/**/*.py`. Both pass `${staged}` as positional args via `bash -c "..." -- ${staged}` so paths with spaces survive; both gate on `command -v uv` so a `.cs`-only commit on a contributor without uv installed doesn't fail. - **`ProjectTemplate.code-workspace`** — adds Python format-on-save with ruff, the `[python]` formatter binding, `python.terminal.activateEnvironment: false`. No hard-coded venv paths (those caused "could not find ruff binary" popups before `uv sync` ran). Adds `unwantedRecommendations` for mypy / pylint / flake8 / isort / black / standalone pyright so contributors aren't prompted to install tools that overlap with ruff and Pylance. - **`ProjectTemplate.slnx`** — adds `build-pypilibrary-task.yml` to the GitHub Actions folder. - **`.gitignore`** — adds `.venv/`, `dist/`, `__pycache__/`, `*.py[cod]`, `*.egg-info/`, `.pytest_cache/`, `.ruff_cache/`, `.pyright/`. - **`README.md`** — PyPI badge + link in the build/distribution and releases sections; template TODO list reminds the deriver to delete the unused language side. `gh` "pre-authenticated" wording softened to call out the Keychain/libsecret credential-store limitation. ## Trusted Publisher setup (one-time, on PyPI side) 1. PyPI → **Account settings** → **Publishing** → **Add a new pending publisher** - Project name: `ptr727-projecttemplate-library` - Owner: `ptr727` - Repo: `ProjectTemplate` - Workflow: `publish-release.yml` - Environment: `pypi` 2. GitHub repo → **Settings** → **Environments** → create `pypi` environment (optionally with required reviewers). The first successful release converts the pending publisher to a real publisher. ## Versioning gap `_version.py` ships with `__version__ = "0.0.0"`. Trusted Publishing with `skip-existing: true` means the workflow won't fail, but no new PyPI versions land until you wire `_version.py` to something that increments — see `PyPiLibrary/README.md` "Template Adoption" for the three usual options (hatch-vcs / version.json bridge / manual bumps). ## Test plan - [x] `uv sync` clean (host: uv 0.11.8) - [x] `uv run ruff check` — All checks passed - [x] `uv run ruff format --check` — clean - [x] `uv run pyright` — 0 errors, 0 warnings, 0 informations - [x] `uv run pytest` — 3 passed - [x] `uv build` — produces `ptr727_projecttemplate_library-0.0.0.tar.gz` and wheel - [x] `dotnet build` — 0 warnings, 0 errors - [x] `dotnet test` — 15 passed (no .NET regression) - [ ] CI green on the PR (test-release-task exercises ruff, pyright, pytest, uv build via the same reusable workflow that publish uses) - [ ] After Trusted Publisher is configured on PyPI and a real version scheme is wired in `_version.py`, next merge to `main` smoke-tests the publish path
ptr727
added a commit
that referenced
this pull request
May 11, 2026
…me (#66) Release merge: brings five squashed PRs from develop into main. ## Squashed PRs included - **#61 — Pin release action SHA, target_commitish, agent conventions.** `softprops/action-gh-release` pinned to a commit SHA with `target_commitish: ${{ github.sha }}` so the release tag lands on the artifact's commit, not the default branch. Updated `AGENTS.md` workflow YAML conventions. - **#62 — Rename Library project to NuGetLibrary.** Project + folder renamed; `.slnx`, `.csproj`, build workflow, and references updated. Disambiguates from the new Python sibling. - **#63 — Add devcontainer + per-OS host and SSH signing docs.** New `docs/host-setup.md`, `docs/ssh-signing.md`, `docs/devcontainer.md`. Devcontainer bind-mounts SSH public key, allowed_signers, and `gh` config so commits sign correctly inside the container. - **#64 — Add PyPiLibrary Python sibling project.** New `PyPiLibrary/` template under `src/`-layout: pyproject.toml + uv.lock + ruff/pyright/pytest config + sample module + tests + `build-pypilibrary-task.yml` workflow + `publish-pypi` job in `publish-release.yml`. - **#65 — Split Devcontainer and Workspace per Language and Drop Husky.** `.devcontainer/dotnet/` + `DotNet.code-workspace` and `.devcontainer/python/` + `Python.code-workspace`. Husky.Net removed (CI is the lint backstop). Optional opt-in hooks documented in README. All Husky references removed from workflows, AGENTS, CODESTYLE, and tasks. ## Notes - Merge method: **merge-commit** (per [AGENTS.md branching model](https://github.com/ptr727/ProjectTemplate/blob/develop/AGENTS.md#branching-model)). Squash and rebase are blocked by the main ruleset. - Main currently has 6 codegen-update commits that develop doesn't have (#58, #59, #60 etc.). The merge-commit re-anchors develop on top of those; the next develop cycle will start by merging main back into develop to absorb them. ## Test plan - [ ] CI passes on the merge commit (test-release-task workflow, all build matrix legs). - [ ] Confirm release tag lands on the merge commit (target_commitish from #61). - [ ] Spot-check the new `.devcontainer/dotnet/` and `.devcontainer/python/` open and build cleanly. - [ ] Spot-check `cd PyPiLibrary && uv sync && uv run pytest` passes. - [ ] Confirm `.git/hooks/pre-commit` is absent in a fresh clone (Husky removed).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Disambiguates the .NET project name from the upcoming Python
PyPiLibrarysibling. Folder, csproj filename,RootNamespace, and namespace declarations move fromLibrarytoNuGetLibrary. The companion GitHub Actions reusable workflowbuild-library-task.ymlis renamed tobuild-nugetlibrary-task.yml; the produced artifact name and 7z filename track the rename.Preserved on purpose
<PackageId>ptr727.ProjectTemplate.Library</PackageId>is kept so the published nupkg keeps its identity. No orphaned package, no 404 on existing consumers, no new badge URL needed.nuget-link,nugetreleaseversion-shield,nugetprereleaseversion-shield) still point atptr727.ProjectTemplate.Libraryand continue to work.TemplateLibraryandStaticTemplateLibraryare unchanged — they describe types, not the project.InternalsVisibleTodeclarations stay (Console,Tests,Benchmarksassembly names are unchanged).Files touched
git mv Library/ NuGetLibrary/(folder)git mv NuGetLibrary/Library.csproj NuGetLibrary/NuGetLibrary.csprojgit mv .github/workflows/build-library-task.yml .github/workflows/build-nugetlibrary-task.yml— paths, job keybuild-nugetlibrary, artifact namenugetlibrary-build, zipNuGetLibrary.7z.github/workflows/build-release-task.yml— caller updated: job key,uses:,needs:array, artifact-id referenceConsole/Console.csproj,Tests/Tests.csproj,Benchmarks/Benchmarks.csproj—<ProjectReference>pathsConsole/Program.cs,Tests/LoggingTests.cs—usingstatementNuGetLibrary/{Library,Options,LogOptions,Extensions}.cs— namespace declarationNuGetLibrary/NuGetLibrary.csproj—RootNamespaceProjectTemplate.slnx— 4 project path entries + 1 GitHub Actions folder entryProjectTemplate.code-workspace—cSpell.wordsaddnugetlibraryAGENTS.md,.github/copilot-instructions.md— project list, namespace examples, structure sectionTest plan
dotnet build— 0 warnings, 0 errors locallydotnet test— 15 passed, 0 faileddotnet pack ./NuGetLibrary/NuGetLibrary.csproj— producesptr727.ProjectTemplate.Library.1.0.0-pre.nupkg(PackageId preserved)Library/Library.csproj,build-library-task— zero remaining hitsNuGetLibrary.7zartifact attached to the GitHub release