Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
97 changes: 93 additions & 4 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ jobs:
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install dependencies
run: pip install Jinja2
run: pip install Jinja2 PyYAML

- name: Check scaffold syntax
run: python3 -m py_compile scaffold/create-tool.py
Expand All @@ -114,12 +114,101 @@ jobs:

test -f /tmp/scaffold-test/ci-test-plugin/.cursor-plugin/plugin.json
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/validate.yml
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/release.yml
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/pages.yml
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/stale.yml
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/drift-check.yml
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/label-sync.yml
test -f /tmp/scaffold-test/ci-test-plugin/.github/dependabot.yml
test -f /tmp/scaffold-test/ci-test-plugin/site.json
test -f /tmp/scaffold-test/ci-test-plugin/mcp-tools.json
test -f /tmp/scaffold-test/ci-test-plugin/mcp-server/server.py
echo "Scaffold test passed"

- name: Scaffold YAML well-formed
run: |
# Catches Jinja2 trim_blocks bugs that collapse adjacent expression lines.
python3 -c "
import yaml, sys
paths = [
'/tmp/scaffold-test/ci-test-plugin/.github/workflows/validate.yml',
'/tmp/scaffold-test/ci-test-plugin/.github/workflows/release.yml',
'/tmp/scaffold-test/ci-test-plugin/.github/workflows/pages.yml',
'/tmp/scaffold-test/ci-test-plugin/.github/workflows/stale.yml',
'/tmp/scaffold-test/ci-test-plugin/.github/workflows/drift-check.yml',
'/tmp/scaffold-test/ci-test-plugin/.github/workflows/label-sync.yml',
'/tmp/scaffold-test/ci-test-plugin/.github/dependabot.yml',
]
fail = False
for p in paths:
try:
with open(p) as f:
yaml.safe_load(f)
print(f'OK {p}')
except yaml.YAMLError as e:
print(f'FAIL {p}: {e}', file=sys.stderr)
fail = True
sys.exit(1 if fail else 0)
"

- name: Scaffold regression checks for DTD#41 patterns
run: |
# validate-counts job present
grep -q 'validate-counts' /tmp/scaffold-test/ci-test-plugin/.github/workflows/validate.yml \
|| { echo "::error::validate.yml missing validate-counts job"; exit 1; }

# drift-check pinned to @v1.9
grep -q 'drift-check@v1.9' /tmp/scaffold-test/ci-test-plugin/.github/workflows/drift-check.yml \
|| { echo "::error::drift-check.yml not pinned to @v1.9"; exit 1; }

# release.yml consumes release-doc-sync@v1
grep -q 'release-doc-sync@v1' /tmp/scaffold-test/ci-test-plugin/.github/workflows/release.yml \
|| { echo "::error::release.yml does not consume release-doc-sync@v1"; exit 1; }

# release.yml has the initial-release version-handling branch
grep -q 'Initial release' /tmp/scaffold-test/ci-test-plugin/.github/workflows/release.yml \
|| { echo "::error::release.yml missing initial-release branch"; exit 1; }

# release.yml does floating tag automation
grep -q 'tag -f "v\$major"' /tmp/scaffold-test/ci-test-plugin/.github/workflows/release.yml \
|| { echo "::error::release.yml missing floating major tag automation"; exit 1; }

# label-sync uses self-healing per-label gh label create --force
grep -q 'gh label create.*--force' /tmp/scaffold-test/ci-test-plugin/.github/workflows/label-sync.yml \
|| { echo "::error::label-sync.yml missing self-healing label create"; exit 1; }

# dependabot has github-actions ecosystem
grep -q 'package-ecosystem: "github-actions"' /tmp/scaffold-test/ci-test-plugin/.github/dependabot.yml \
|| { echo "::error::dependabot.yml missing github-actions ecosystem"; exit 1; }

# CLAUDE.md has **Version:** line so release-doc-sync can update it
grep -q '^\*\*Version:\*\* 0\.1\.0' /tmp/scaffold-test/ci-test-plugin/CLAUDE.md \
|| { echo "::error::CLAUDE.md missing **Version:** 0.1.0 line"; exit 1; }

# ROADMAP.md has standards-version marker and **Current:** line
grep -q '<!-- standards-version:' /tmp/scaffold-test/ci-test-plugin/ROADMAP.md \
|| { echo "::error::ROADMAP.md missing standards-version marker"; exit 1; }
grep -q '^\*\*Current:\*\* v0\.1\.0' /tmp/scaffold-test/ci-test-plugin/ROADMAP.md \
|| { echo "::error::ROADMAP.md missing **Current:** v0.1.0 line"; exit 1; }

# AGENTS.md keeps standards-version marker
grep -q '<!-- standards-version:' /tmp/scaffold-test/ci-test-plugin/AGENTS.md \
|| { echo "::error::AGENTS.md missing standards-version marker"; exit 1; }

# LICENSE has correct CC-BY-NC-ND-4.0 copyright (TM Hospitality Strategies, not TMHSDigital)
grep -q 'Copyright (c) 2026 TM Hospitality Strategies' /tmp/scaffold-test/ci-test-plugin/LICENSE \
|| { echo "::error::LICENSE missing canonical 'TM Hospitality Strategies' copyright line"; exit 1; }
grep -q 'SPDX-License-Identifier: CC-BY-NC-ND-4.0' /tmp/scaffold-test/ci-test-plugin/LICENSE \
|| { echo "::error::LICENSE missing SPDX-License-Identifier"; exit 1; }

# CONTRIBUTING.md has DCO inbound grant section
grep -q 'Developer Certificate of Origin' /tmp/scaffold-test/ci-test-plugin/CONTRIBUTING.md \
|| { echo "::error::CONTRIBUTING.md missing DCO section"; exit 1; }
grep -q 'Signed-off-by' /tmp/scaffold-test/ci-test-plugin/CONTRIBUTING.md \
|| { echo "::error::CONTRIBUTING.md missing Signed-off-by guidance"; exit 1; }

echo "All DTD#41 scaffold regression checks passed"

- name: Scaffold leak scan
run: |
if grep -rnE "tmhospitalitystrateg[i]es" /tmp/scaffold-test; then
Expand All @@ -133,7 +222,7 @@ jobs:
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
- uses: actions/setup-python@v5
with:
python-version: "3.12"

Expand Down Expand Up @@ -184,7 +273,7 @@ jobs:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
fetch-depth: 0

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.9.2
1.9.3
5 changes: 5 additions & 0 deletions scaffold/create-tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ def main():
write_file(output_dir, ".github/workflows/release.yml", render_template(env, "release.yml.j2", ctx))
write_file(output_dir, ".github/workflows/pages.yml", render_template(env, "pages.yml.j2", ctx))
write_file(output_dir, ".github/workflows/stale.yml", render_template(env, "stale.yml.j2", ctx))
write_file(output_dir, ".github/workflows/drift-check.yml", render_template(env, "drift-check.yml.j2", ctx))
write_file(output_dir, ".github/workflows/label-sync.yml", render_template(env, "label-sync.yml.j2", ctx))

# Dependabot config (github-actions ecosystem standard, optional pip for MCP)
write_file(output_dir, ".github/dependabot.yml", render_template(env, "dependabot.yml.j2", ctx))

# Documentation files
write_file(output_dir, "README.md", render_template(env, "README.md.j2", ctx))
Expand Down
4 changes: 4 additions & 0 deletions scaffold/templates/CLAUDE.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ This file provides guidance for Claude Code when working in this repository.

{{ name }} -- {{ description }}

**Version:** 0.1.0
**License:** {{ license_spdx }}
**Author:** {{ author_name }}

## Key paths

{% if type == 'cursor-plugin' %}
Expand Down
20 changes: 18 additions & 2 deletions scaffold/templates/CONTRIBUTING.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ Use [Conventional Commits](https://www.conventionalcommits.org/):
2. Update `CHANGELOG.md` if the change is user-facing
3. Use a descriptive PR title following conventional commit format

## License
## Inbound license grant and DCO

By contributing, you agree that your contributions will be licensed under the project's {{ license_spdx }} license.
This project's outbound license is {{ license_spdx }}. Contributions are accepted inbound under a broader grant via the Developer Certificate of Origin (DCO). Both pieces are required because {{ license_spdx }} alone cannot cleanly accept third-party derivatives.

### Required grant

By submitting a contribution to this repository, you certify that you have the right to do so under the Developer Certificate of Origin (DCO) 1.1, and you grant TMHSDigital a perpetual, worldwide, non-exclusive, royalty-free, irrevocable license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your contribution under the project's current license ({{ license_spdx }}) or any successor license chosen by the project.

### DCO sign-off

Every commit in a pull request must carry a `Signed-off-by:` trailer matching the commit author. Sign at commit time with the `-s` flag:

```bash
git commit -s -m "feat: add new skill"
```

This appends a line like `Signed-off-by: Jane Developer <jane@example.com>` to the commit message. The GitHub DCO App enforces this on every PR.

For the full inbound/outbound model and rationale, see [`standards/licensing.md`](https://github.com/TMHSDigital/Developer-Tools-Directory/blob/main/standards/licensing.md) in the Developer-Tools-Directory meta-repo.
26 changes: 19 additions & 7 deletions scaffold/templates/LICENSE.j2
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,36 @@ limitations under the License.
{% else %}
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International

Copyright (c) 2026 {{ author_name }}
Copyright (c) 2026 TM Hospitality Strategies

This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
This work is licensed under the Creative Commons
Attribution-NonCommercial-NoDerivatives 4.0 International License.

You are free to:
Share - copy and redistribute the material in any medium or format

Share - copy and redistribute the material in any medium or format.

The licensor cannot revoke these freedoms as long as you follow the
license terms.

Under the following terms:

Attribution - You must give appropriate credit, provide a link to the
license, and indicate if changes were made.
license, and indicate if changes were made. You may do so in any
reasonable manner, but not in any way that suggests the licensor
endorses you or your use.

NonCommercial - You may not use the material for commercial purposes.

NoDerivatives - If you remix, transform, or build upon the material,
you may not distribute the modified material.

No additional restrictions - You may not apply legal terms or technological
measures that legally restrict others from doing anything the license permits.
No additional restrictions - You may not apply legal terms or
technological measures that legally restrict others from doing
anything the license permits.

Full license text:
https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode

Full license text: https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode
SPDX-License-Identifier: CC-BY-NC-ND-4.0
{% endif %}
4 changes: 4 additions & 0 deletions scaffold/templates/ROADMAP.md.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<!-- standards-version: {{ standards_version }} -->

# Roadmap

**Current:** v0.1.0

## {{ name }}

### v0.1.x -- Foundation
Expand Down
12 changes: 12 additions & 0 deletions scaffold/templates/dependabot.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
{% if has_mcp %}
- package-ecosystem: "pip"
directory: "/mcp-server"
schedule:
interval: "weekly"
{% endif %}
21 changes: 21 additions & 0 deletions scaffold/templates/drift-check.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Ecosystem drift check

on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:

jobs:
drift-check:
name: Ecosystem drift check
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- uses: TMHSDigital/Developer-Tools-Directory/.github/actions/drift-check@v1.9
with:
mode: self
format: gh-summary
68 changes: 68 additions & 0 deletions scaffold/templates/label-sync.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Label PRs

on:
pull_request:
types: [opened, synchronize]

permissions:
contents: read
pull-requests: write

jobs:
label:
name: Auto-label by path
runs-on: ubuntu-latest
steps:
{% raw %}
- uses: actions/checkout@v4

- name: Get changed files
id: changed
run: |
FILES=$(gh pr diff ${{ github.event.pull_request.number }} --name-only)
echo "files<<EOF" >> "$GITHUB_OUTPUT"
echo "$FILES" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Apply labels
run: |
LABELS=""

if echo "$FILES" | grep -q "^skills/"; then
LABELS="$LABELS skills"
fi

if echo "$FILES" | grep -q "^rules/"; then
LABELS="$LABELS rules"
fi
{% endraw %}
{% if has_mcp %}

if echo "$FILES" | grep -q "^mcp-server/"; then
LABELS="$LABELS mcp-server"
fi
{% endif %}
{% raw %}
if echo "$FILES" | grep -q "^docs/"; then
LABELS="$LABELS documentation"
fi

if echo "$FILES" | grep -q "^\.github/"; then
LABELS="$LABELS ci"
fi

if [ -n "$LABELS" ]; then
for label in $LABELS; do
gh label create "$label" --force --color "ededed" 2>/dev/null || true
gh pr edit ${{ github.event.pull_request.number }} --add-label "$label"
done
echo "Applied labels:$LABELS"
else
echo "No labels to apply"
fi
env:
FILES: ${{ steps.changed.outputs.files }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
{% endraw %}
4 changes: 3 additions & 1 deletion scaffold/templates/pages.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ concurrency:

jobs:
build-and-deploy:
{% raw %}
environment:
name: github-pages
url: {% raw %}${{ steps.deployment.outputs.page_url }}{% endraw %}
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
{% endraw %}
steps:
- uses: actions/checkout@v4

Expand Down
Loading
Loading