Skip to content

Commit 9ef0d37

Browse files
committed
Add nuget-publish.md maintainer guide; manual publish workflow run
1 parent 9a362c2 commit 9ef0d37

3 files changed

Lines changed: 153 additions & 4 deletions

File tree

‎.github/workflows/publish.yml‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
name: publish
22

3-
# Publishes to nuget.org on tags like v1.2.0. Needs the repository secret NUGET_API_KEY (glob Code4mk.*).
3+
# Publishes to nuget.org on tags like v1.2.0, or manually (Actions → publish → Run workflow → version).
4+
# Needs the repository secret NUGET_API_KEY (Push scope, glob Code4mk.*). See nuget-publish.md.
45
on:
56
push:
67
tags: ["v*.*.*"]
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: "Package version, e.g. 1.1.0"
12+
required: true
713

814
permissions:
915
contents: read
@@ -17,8 +23,13 @@ jobs:
1723
with:
1824
dotnet-version: 10.0.x
1925
- name: Pack
26+
env:
27+
INPUT_VERSION: ${{ inputs.version }}
2028
run: |
21-
VERSION="${GITHUB_REF_NAME#v}"
29+
VERSION="${INPUT_VERSION:-${GITHUB_REF_NAME#v}}"
30+
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
31+
echo "::error::'$VERSION' is not a version like 1.2.0 or 1.2.0-preview.1"; exit 1
32+
fi
2233
dotnet pack TemplatePack.csproj -c Release -o artifacts -p:PackageVersion=$VERSION
2334
- name: Package contains no local-only files
2435
run: |

‎README.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ dotnet new code4mk-mcp -n Sample.Mcp -o ../sample-mcp # always create projec
135135
- `DotnetMcpTemplate` (and `dotnetmcptemplate-slug`) are placeholders; keep them. Package versions live in
136136
`templates/DotnetMcpTemplate/Directory.Packages.props`.
137137
- CI creates a project from the template, builds and tests it, checks the UI bundles, and packs the template.
138-
- Release: update `CHANGELOG.md`, then `git tag v1.1.0 && git push origin v1.1.0`; the publish workflow pushes to
139-
nuget.org (secret `NUGET_API_KEY`).
138+
- Changing, testing and publishing the template: [nuget-publish.md](https://github.com/code4mk/dotnet-mcp-server-template/blob/main/nuget-publish.md).
140139

141140
## License
142141

‎nuget-publish.md‎

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Maintaining and publishing
2+
3+
Notes for template maintainers: how to change, test and publish the template. This file isn't part of the NuGet
4+
package.
5+
6+
## Repository layout
7+
8+
```text
9+
dotnet-mcp-server-template/
10+
├── README.md public readme (also shown on nuget.org)
11+
├── CHANGELOG.md template version history
12+
├── nuget-publish.md this guide
13+
├── LICENSE
14+
├── TemplatePack.csproj packs the template into a NuGet package
15+
├── assets/ README screenshots (loaded from GitHub, not packed)
16+
├── .github/workflows/
17+
│ ├── template-ci.yml creates a sample project, builds, tests, packs; checks UI bundles (push, PR)
18+
│ └── publish.yml publishes to nuget.org (version tags or manual run)
19+
└── templates/
20+
└── DotnetMcpTemplate/ the template itself (everything a new project gets)
21+
├── .template.config/template.json
22+
├── DotnetMcpTemplate.sln
23+
└── src/ tests/ ui/ docker/ docs/ .github/ ...
24+
```
25+
26+
The `.github/workflows` inside `templates/DotnetMcpTemplate` belong to generated projects. They don't run in this
27+
repository.
28+
29+
## Rules
30+
31+
- Keep `DotnetMcpTemplate` as the placeholder name everywhere (`sourceName`). Never rename it.
32+
- Keep `dotnetmcptemplate-slug` where a lowercase, dash-only name is needed (Docker image, Compose, `ui/package.json`).
33+
- Set NuGet package versions only in `templates/DotnetMcpTemplate/Directory.Packages.props`.
34+
- After changing anything in `templates/DotnetMcpTemplate/ui/`, run `pnpm run build` there and commit the updated
35+
bundles in `src/DotnetMcpTemplate/ui_dist/`. CI fails when they are stale.
36+
- Never commit or pack `.env`. It's git-ignored and excluded in `TemplatePack.csproj`, and CI and `publish` fail if a
37+
`.env` ends up in the package. `.env.example` is the committed one.
38+
- Never create projects inside this repository.
39+
40+
## Install from source
41+
42+
```bash
43+
dotnet new install ./templates/DotnetMcpTemplate # first time
44+
dotnet new install ./templates/DotnetMcpTemplate --force # after changes
45+
dotnet new uninstall ./templates/DotnetMcpTemplate # remove
46+
dotnet new list code4mk-mcp # check
47+
```
48+
49+
## Workflow for a change
50+
51+
1. Create a branch and edit files under `templates/DotnetMcpTemplate`.
52+
2. Test the template in place (it builds and runs as a normal solution):
53+
54+
```bash
55+
cd templates/DotnetMcpTemplate
56+
dotnet build && dotnet test
57+
cd ui && pnpm install && pnpm run build # when ui/ changed
58+
```
59+
60+
3. Test a generated project, outside the repository:
61+
62+
```bash
63+
dotnet new install ./templates/DotnetMcpTemplate --force
64+
cd ..
65+
dotnet new code4mk-mcp -n Test.Mcp -o test-mcp
66+
cd test-mcp && dotnet build && dotnet test
67+
grep -rIi --exclude-dir=bin --exclude-dir=obj --exclude-dir=node_modules dotnetmcptemplate . || echo "no placeholders left"
68+
cd .. && rm -rf test-mcp
69+
```
70+
71+
4. Add an entry to `CHANGELOG.md` under a new version.
72+
5. Open a pull request. `template-ci` runs automatically.
73+
6. After merging, publish the new version.
74+
75+
## Publishing to nuget.org
76+
77+
Packages are published under the nuget.org account **Code4mk** as `Code4mk.McpServer.Template`.
78+
79+
Before every publish:
80+
81+
1. `main` is pushed. The README's screenshots and CI badge load from GitHub, so they break on nuget.org otherwise.
82+
2. `CHANGELOG.md` has the new version and date.
83+
3. `template-ci` is green on `main`.
84+
85+
### From your machine
86+
87+
```bash
88+
dotnet pack TemplatePack.csproj -c Release -o artifacts -p:PackageVersion=1.0.0
89+
90+
# check the contents: only .env.example, no .env, bin/, obj/ or node_modules/
91+
unzip -l artifacts/Code4mk.McpServer.Template.1.0.0.nupkg | grep -E "\.env|/bin/|/obj/|node_modules"
92+
93+
# macOS / Linux
94+
export NUGET_API_KEY="your-key"
95+
dotnet nuget push artifacts/Code4mk.McpServer.Template.1.0.0.nupkg \
96+
--source https://api.nuget.org/v3/index.json --api-key $NUGET_API_KEY
97+
98+
# Windows PowerShell
99+
$env:NUGET_API_KEY = "your-key"
100+
dotnet nuget push artifacts\Code4mk.McpServer.Template.1.0.0.nupkg `
101+
--source https://api.nuget.org/v3/index.json --api-key $env:NUGET_API_KEY
102+
```
103+
104+
Then tag the release so the repository matches the package: `git tag v1.0.0 && git push origin v1.0.0`.
105+
If `NUGET_API_KEY` is also set as a repository secret, that tag starts `publish` too; it skips the version that
106+
already exists (`--skip-duplicate`), so this is harmless.
107+
108+
### From GitHub Actions
109+
110+
1. Add the nuget.org API key as the repository secret `NUGET_API_KEY` (Settings → Secrets and variables → Actions).
111+
2. Either push a version tag: `git tag v1.1.0 && git push origin v1.1.0`,
112+
or open Actions → `publish` → **Run workflow** and enter the version (e.g. `1.1.0`).
113+
114+
The workflow validates the version, packs the template with it, checks the package for `.env` files and pushes it.
115+
116+
### Notes
117+
118+
- Create the API key on nuget.org (username → API Keys) with the **Push** scope and glob pattern `Code4mk.*`.
119+
Give it an expiry and don't paste it into files or commits.
120+
- New versions appear on nuget.org after validation and indexing, usually within 15 to 30 minutes.
121+
- Every publish needs a new version number. A broken version can be unlisted but never deleted or replaced.
122+
- Pre-releases use a suffix (`1.1.0-preview.1`); `dotnet new install` only picks them when asked for explicitly.
123+
- `README.md` is packed into the package and shown on nuget.org: keep its links and images absolute (GitHub URLs,
124+
images from `raw.githubusercontent.com` or `img.shields.io`).
125+
- Users update with `dotnet new install Code4mk.McpServer.Template` (installs the latest) or
126+
`dotnet new update`.
127+
128+
## Troubleshooting
129+
130+
| Problem | Fix |
131+
| --- | --- |
132+
| `No templates found matching: 'code4mk-mcp'` | Install the template and check `dotnet new list code4mk-mcp` |
133+
| Namespaces like `my_app.Mcp` | Dashes were used in `-n`. Use PascalCase in `-n` and dashes only in `-o` |
134+
| New project contains another project | `dotnet new` ran inside the template repo. Delete it and run from another folder |
135+
| `template-ci` fails on "Committed bundles match the source" | Run `pnpm run build` in `templates/DotnetMcpTemplate/ui` and commit `ui_dist/` |
136+
| `publish` fails on "Package contains no local-only files" | A `.env` got into the package: check the excludes in `TemplatePack.csproj` |
137+
| README images missing on nuget.org | Push `main` (images load from GitHub); nuget.org caches the README per version |
138+
| `409 Conflict` on push | That version already exists on nuget.org: bump the version |
139+
| `403 Forbidden` on push | The API key expired, lacks the Push scope, or its glob doesn't match `Code4mk.*` |

0 commit comments

Comments
 (0)