Skip to content

Commit 96039d3

Browse files
mnriemCopilot
andauthored
Require preset-usage README with Spec Kit CLI syntax in preset submissions (#3104)
* Require preset-usage README with Spec Kit CLI syntax in submissions Tighten the community preset submission workflow so it validates the README referenced by the documentation field rather than merely checking for a root README. The workflow now fails submissions whose linked README lacks a valid 'specify preset add ...' command and flags monorepo submissions that point documentation at a generic root README. - Add a required Documentation URL field to the preset issue template - Add validation step 2d (documentation README + CLI-syntax check) to .github/workflows/add-community-preset.md and recompile the lock file - Document the stricter usage-README requirement and reviewer content check in presets/PUBLISHING.md Closes #3103 Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align preset README docs with workflow's actual enforcement Address PR review feedback on #3104: - PUBLISHING.md: clarify that only README resolution + a valid 'specify preset add ...' command are mechanically enforced; the preset-scoped-README and minimum-structure items are reviewer expectations, not automated checks. - PUBLISHING.md: state that a missing 'specify preset add ...' command is a hard validation failure (check 2d), not just 'flagged for changes'. - preset_submission.yml: require 'specify preset add ...' (not the looser 'specify preset ...') to match the workflow validation. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Tighten preset README validation and docs per PR review Address PR review feedback on #3104: - Workflow Step 2c: drop the generic repo-root README.md check so the README requirement is enforced exactly once, in Step 2d, against the file the documentation field points to (avoids monorepo false-positive). - Workflow Step 2d: restrict the documentation URL to GitHub-hosted README URLs (github.com/.../blob/... or raw.githubusercontent.com/...) before fetching user-provided input. - PUBLISHING.md: add the required 'id' field to the example catalog entry. - preset_submission.yml: fix the Documentation URL placeholder to match the recommended monorepo presets/<id>/README.md pattern. - Recompile add-community-preset.lock.yml (body hash only). Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Refine preset README validation rules per PR review Address PR review feedback on #3104: - Workflow Step 2d: broaden the documentation URL allowlist to also accept github.com/.../raw/... URLs; strip any fragment/query before fetching so the target is deterministic; clarify that a 'specify preset add --from <url>' command only counts when its URL matches the submitted Download URL (a different --from URL does not satisfy the requirement, though other accepted forms still can). - PUBLISHING.md: show both accepted download URL shapes (tag archive and release asset) in the README install example instead of implying only the releases/download form. - preset_submission.yml: remove the ambiguous generic 'README.md with description and usage instructions' checkbox; the linked-README requirement is the single source of truth. - Recompile add-community-preset.lock.yml (body hash only). Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify install-command requirement wording per PR review Address PR review feedback on #3104: the previous 'matching the download URL' wording overstated the requirement. Only the 'specify preset add --from <url>' form needs an exact download-URL match; other accepted forms ('specify preset add <id>' / '--dev <path>') don't reference the download URL at all. - preset_submission.yml: reword the Documentation URL description and the Submission Requirements checkbox to reflect what's enforced vs preferred. - PUBLISHING.md: clarify the reviewer note so the exact-match rule is scoped to the --from form. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Require README.md target and fix release-ZIP wording per PR review Address PR review feedback on #3104: - Workflow Step 2d: add an explicit check that the documentation URL path ends with README.md (case-insensitive) after stripping fragment/query, so a non-README markdown file is rejected before fetching. - PUBLISHING.md: reword the release-ZIP note, which conflicted with the earlier preset structure guidance. The real requirement is that the README is reachable at the documentation URL before download; it's fine for the same file to also ship inside the release ZIP. - Recompile add-community-preset.lock.yml (body hash only). Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use stable unnumbered anchor for Usage README Requirements Address PR review feedback on #3104: drop the '6.' prefix from the 'Usage README Requirements' heading so its GitHub anchor isn't tied to a section number (brittle under renumbering, and avoids confusion with the top-level 'Best Practices' TOC item). Update the Prerequisites cross-link to the new #usage-readme-requirements anchor. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align README requirement wording with enforced checks per PR review Address PR review feedback on #3104: - PUBLISHING.md: the 'mechanically enforces' summary now lists all Step 2d checks (GitHub-hosted URL, path ends with README.md, resolves, contains a valid 'specify preset add ...' command), instead of only two. - PUBLISHING.md: reword the PR checklist item so a usage README + install command is the requirement, with preset-scoped README recommended for monorepos (matches the workflow's flag-not-fail behavior). - preset_submission.yml: include the full 'specify preset add' prefix on the --dev and --from forms in the field description and checklist so submitters copy the exact syntax. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix grammar in Usage README Requirements intro Address PR review feedback on #3104: remove the incorrect colon after 'the linked README' so the sentence reads naturally. Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Avoid lossy raw URL rewrite for slash-containing refs per PR review Address PR review feedback on #3104: rewriting documentation URLs into the raw.githubusercontent.com/<owner>/<repo>/<ref>/<path> form can't reliably represent refs that contain slashes (e.g. a feature/foo branch). Step 2d now fetches github.com blob URLs by swapping only /blob/ -> /raw/, and fetches github.com/.../raw/... and raw.githubusercontent.com/... URLs as-is, instead of reconstructing the raw host form. Recompile add-community-preset.lock.yml (body hash only). Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d6cddd4 commit 96039d3

4 files changed

Lines changed: 125 additions & 9 deletions

File tree

.github/ISSUE_TEMPLATE/preset_submission.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ body:
7777
validations:
7878
required: true
7979

80+
- type: input
81+
id: documentation
82+
attributes:
83+
label: Documentation URL
84+
description: |
85+
Link to the README that explains how to use **this preset** (not a general product/framework pitch).
86+
Prefer the preset-scoped README (e.g. `presets/<id>/README.md` in a monorepo) over the repository root README.
87+
It must contain at least one valid `specify preset add ...` install command — ideally `specify preset add --from <download-url>` using the exact Download URL above (other forms such as `specify preset add <preset-id>` or `specify preset add --dev <path>` are also accepted).
88+
placeholder: "https://github.com/your-org/spec-kit-presets/blob/main/presets/your-preset/README.md"
89+
validations:
90+
required: true
91+
8092
- type: input
8193
id: license
8294
attributes:
@@ -175,7 +187,7 @@ body:
175187
options:
176188
- label: Valid `preset.yml` manifest included
177189
required: true
178-
- label: README.md with description and usage instructions
190+
- label: Linked README (Documentation URL) explains how to use this preset and includes a valid `specify preset add ...` command (preferably `specify preset add --from <download-url>` using the exact download URL)
179191
required: true
180192
- label: LICENSE file included
181193
required: true

.github/workflows/add-community-preset.lock.yml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/add-community-preset.md

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ fields):
7373
| Author | `author` | Yes |
7474
| Repository URL | `repository` | Yes |
7575
| Download URL | `download-url` | Yes |
76+
| Documentation URL | `documentation` | Yes |
7677
| License | `license` | Yes |
7778
| Required Spec Kit Version | `speckit-version` | Yes |
7879
| Required Extensions | `required-extensions` | No |
@@ -100,17 +101,70 @@ deciding pass/fail:
100101
### 2c. Repository validation
101102
- Fetch the repository URL — confirm it exists and is publicly accessible
102103
- Confirm the repository contains a `preset.yml` file
103-
- Confirm the repository contains a `README.md` file
104104
- Confirm the repository contains a `LICENSE` file
105105

106-
### 2d. Release and download URL validation
106+
> The README requirement is enforced once, in **Step 2d**, against the specific file the
107+
> `documentation` field points to — not a generic repository-root `README.md`. This avoids
108+
> the monorepo false-positive where a root README exists but isn't the preset-usage doc.
109+
110+
### 2d. Documentation README validation
111+
112+
The `documentation` field must point to the README that explains **how to use this
113+
preset** — not just any file named `README.md`, and not a product/framework pitch.
114+
115+
- **Restrict the URL to GitHub before fetching.** The `documentation` value is
116+
user-provided input. Only accept GitHub-hosted README URLs:
117+
- `https://github.com/<owner>/<repo>/blob/<ref>/<path>`
118+
- `https://github.com/<owner>/<repo>/raw/<ref>/<path>`
119+
- `https://raw.githubusercontent.com/<owner>/<repo>/<ref>/<path>`
120+
121+
If the URL points anywhere else (or isn't a URL), **fail this check** and do not fetch it.
122+
- **Require the URL to point at a README file.** After stripping any fragment/query (see
123+
below), the URL path must end with `README.md` (case-insensitive). If it points at some
124+
other Markdown file, **fail this check** and ask the submitter to link the preset's README.
125+
- Fetch the **exact URL** in the `documentation` field. First strip any fragment (`#...`)
126+
or query string (`?...`) — these are common when copying from the browser UI and must be
127+
ignored so the fetch target is deterministic. Then resolve the raw content to fetch:
128+
- For a `github.com/<owner>/<repo>/blob/<ref>/<path>` URL, fetch the equivalent
129+
`github.com/<owner>/<repo>/raw/<ref>/<path>` URL (only swap `/blob/``/raw/`).
130+
- Fetch `github.com/.../raw/...` and `raw.githubusercontent.com/...` URLs as-is.
131+
132+
Do **not** rewrite into `raw.githubusercontent.com/<owner>/<repo>/<ref>/<path>` form — that
133+
format can't reliably represent refs containing slashes (e.g. a `feature/foo` branch).
134+
Confirm the fetched URL resolves to a readable Markdown file.
135+
- **Validate that the README contains a valid Spec Kit CLI install command.** The fetched
136+
README must contain at least one `specify preset add ...` invocation. The strongest
137+
signal is the catalog-install form whose URL matches the submitted **Download URL**:
138+
- `specify preset add --from <download-url>` (preferred), or
139+
- `specify preset add <preset-id>`, or
140+
- `specify preset add --dev <path>`
141+
142+
A `specify preset add --from <url>` command only counts when its `<url>` **matches the
143+
submitted Download URL exactly**. A `--from` command pointing at a *different* URL does
144+
**not** satisfy the install-command requirement (treat it as if absent) — but the README
145+
may still pass on one of the other accepted forms (`specify preset add <preset-id>` or
146+
`specify preset add --dev <path>`).
147+
148+
If **no** accepted `specify preset add ...` command is present, the README is treated as a
149+
generic description/pitch rather than preset-usage documentation — **fail this check** and
150+
tell the submitter to add a valid install command (ideally
151+
`specify preset add --from <download-url>`).
152+
- **Prefer a preset-scoped README in monorepos.** If `documentation` resolves to a generic
153+
repository-root README in a monorepo (the preset lives in a subdirectory such as
154+
`presets/<id>/` and a preset-scoped README exists there), **flag it** in your comment and
155+
recommend the submitter point `documentation` at the preset-scoped README
156+
(e.g. `presets/<id>/README.md`) so the catalog surfaces usage instead of marketing. Treat
157+
this as a flag rather than a hard failure **only if** the root README still contains a valid
158+
`specify preset add ...` command for this preset; otherwise it fails check 2d above.
159+
160+
### 2e. Release and download URL validation
107161
- The download URL should follow the pattern
108162
`https://github.com/<owner>/<repo>/archive/refs/tags/v<version>.zip`
109163
or
110164
`https://github.com/<owner>/<repo>/releases/download/<tag>/<asset>.zip`
111165
- Verify a GitHub release exists matching the submitted version
112166

113-
### 2e. Submission checklists
167+
### 2f. Submission checklists
114168
- Confirm that all required checkboxes in the Testing Checklist and Submission
115169
Requirements sections are checked (`[x]`)
116170

@@ -154,7 +208,7 @@ Insert the entry in **alphabetical order by preset ID** within the
154208
"repository": "<repository>",
155209
"download_url": "<download_url>",
156210
"homepage": "<homepage or repository>",
157-
"documentation": "<documentation or repository README>",
211+
"documentation": "<documentation URL — the validated preset-usage README>",
158212
"license": "<license>",
159213
"requires": {
160214
"speckit_version": "<speckit_version>"

presets/PUBLISHING.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Before publishing a preset, ensure you have:
1919

2020
1. **Valid Preset**: A working preset with a valid `preset.yml` manifest
2121
2. **Git Repository**: Preset hosted on GitHub (or other public git hosting)
22-
3. **Documentation**: README.md with description and usage instructions
22+
3. **Documentation**: A preset-scoped README.md that explains how to use **this preset**, including a valid `specify preset add ...` install command (see [Usage README Requirements](#usage-readme-requirements))
2323
4. **License**: Open source license file (MIT, Apache 2.0, etc.)
2424
5. **Versioning**: Semantic versioning (e.g., 1.0.0)
2525
6. **Testing**: Preset tested on real projects with `specify preset add --dev`
@@ -147,6 +147,46 @@ https://github.com/your-org/spec-kit-preset-your-preset/archive/refs/tags/v1.0.0
147147
specify preset add --from https://github.com/your-org/spec-kit-preset-your-preset/archive/refs/tags/v1.0.0.zip
148148
```
149149

150+
### Usage README Requirements
151+
152+
The catalog `documentation` field must point at a README that explains how to use
153+
**this preset** — not a product pitch for a broader framework or a separate CLI.
154+
155+
The submission workflow **mechanically enforces** that the linked README is a GitHub-hosted
156+
URL whose path ends with `README.md`, resolves to a readable file, and contains at least one
157+
valid `specify preset add ...` command. The remaining items (preferring a preset-scoped README
158+
in monorepos, covering the minimum structure) are expectations a human reviewer checks —
159+
follow them so your submission isn't sent back for changes.
160+
161+
- **Point `documentation` at the preset-scoped README.** In a monorepo where the preset
162+
lives in a subdirectory (e.g. `presets/<id>/`), link the README inside that directory
163+
(`presets/<id>/README.md`) rather than the repository-root README. The root README is
164+
often a marketing/overview page; the catalog should surface preset usage instead. The key
165+
requirement is that this README is reachable at the `documentation` URL so users can read
166+
it *before* downloading the release artifact — it's fine for the same file to also ship
167+
inside the release ZIP.
168+
- **Include a valid Spec Kit CLI install command** *(enforced)*. The linked README must
169+
contain at least one `specify preset add ...` invocation. Preferably use the
170+
catalog-install form whose URL matches your Download URL:
171+
172+
```bash
173+
# <download-url> is the same URL you submit as the catalog Download URL —
174+
# either the tag archive or a release asset, e.g.:
175+
specify preset add --from https://github.com/<org>/<repo>/archive/refs/tags/vX.Y.Z.zip
176+
specify preset add --from https://github.com/<org>/<repo>/releases/download/vX.Y.Z/<id>-X.Y.Z.zip
177+
```
178+
179+
`specify preset add <id>` and `specify preset add --dev <path>` are also accepted, but the
180+
`--from <download-url>` form is the clearest signal that the README documents this exact
181+
preset release.
182+
- **Cover the minimum structure** so a reader can decide whether the preset fits:
183+
- What the preset does / what it provides
184+
- The install command using Spec Kit CLI syntax (above)
185+
- When to use it / when not to use it
186+
187+
A submission whose linked README lacks a valid `specify preset add ...` command **fails
188+
validation** (workflow check 2d) and will not be added until corrected.
189+
150190
---
151191

152192
## Submit to Catalog
@@ -181,12 +221,14 @@ Edit `presets/catalog.community.json` and add your preset.
181221
"presets": {
182222
"your-preset": {
183223
"name": "Your Preset Name",
224+
"id": "your-preset",
184225
"description": "Brief description of what your preset provides",
185226
"author": "Your Name",
186227
"version": "1.0.0",
187228
"download_url": "https://github.com/your-org/spec-kit-preset-your-preset/archive/refs/tags/v1.0.0.zip",
188229
"sha256": "OPTIONAL: SHA-256 hex digest of the archive above; verified before install",
189230
"repository": "https://github.com/your-org/spec-kit-preset-your-preset",
231+
"documentation": "https://github.com/your-org/spec-kit-preset-your-preset/blob/main/README.md",
190232
"license": "MIT",
191233
"requires": {
192234
"speckit_version": ">=0.1.0"
@@ -243,7 +285,7 @@ git push origin add-your-preset
243285
244286
### Checklist
245287
- [ ] Valid preset.yml manifest
246-
- [ ] README.md with description and usage
288+
- [ ] Usage README with a valid `specify preset add ...` command, linked from `documentation` (preset-scoped README recommended for monorepos)
247289
- [ ] LICENSE file included
248290
- [ ] GitHub release created
249291
- [ ] Preset tested with `specify preset add --dev`
@@ -264,7 +306,15 @@ After submission, maintainers will review:
264306
2. **Template quality** — templates are useful and well-structured
265307
3. **Command coherence** — commands reference sections that exist in templates
266308
4. **Security** — no malicious content, safe file operations
267-
5. **Documentation** — clear README explaining what the preset does
309+
5. **Documentation** — the README linked from `documentation` explains how to use *this* preset and contains a valid `specify preset add ...` command
310+
311+
> **Reviewer note:** the workflow can mechanically check *structure* (the linked README
312+
> resolves and contains a valid `specify preset add ...` snippet; when that snippet uses the
313+
> `--from <url>` form, its URL must match the submitted download URL exactly — other accepted
314+
> forms like `specify preset add <id>` don't reference the download URL at all). Whether the
315+
> README genuinely documents *this* preset is partly a content judgment, so a human reviewer
316+
> should still confirm the linked doc isn't just a funnel to a separate product or CLI before
317+
> approving.
268318

269319
Once verified, `verified: true` is set and the preset appears in `specify preset search`.
270320

0 commit comments

Comments
 (0)