Skip to content

Commit 4d124ca

Browse files
committed
feat: SHA-pin workflows, dynamic repo sync, org health files
- Convert workflow-templates to thin wrappers calling reusable workflows - Pin all workflow references by SHA (Renovate-only, no Dependabot) - Generate repo-sync target list dynamically from all non-archived repos - Add CODEOWNERS, CONTRIBUTING.md, and issue templates (bug/feature) - Expand compliance audit to check LICENSE and CODEOWNERS - Update README with dependency policy and community health docs
1 parent c62d0ee commit 4d124ca

14 files changed

Lines changed: 186 additions & 156 deletions

File tree

.github/sync.yml

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,12 @@
1-
# Repo file sync configuration
2-
# Syncs org-wide config files to target repositories.
3-
# Requires REPO_SYNC_TOKEN secret (PAT with repo scope).
4-
#
5-
# Add new repos here when created. The compliance-audit workflow
6-
# will flag repos missing from this list.
7-
# Exclude archived repos (they are read-only).
1+
# Repo file sync — file mappings only.
2+
# The repo list is resolved dynamically at runtime
3+
# (all non-archived h13 repos, excluding .github itself).
4+
# See .github/workflows/repo-sync.yml for details.
85

9-
h13/gtm-users:
10-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
11-
dest: .github/PULL_REQUEST_TEMPLATE.md
12-
13-
h13/constraint-engine:
14-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
15-
dest: .github/PULL_REQUEST_TEMPLATE.md
16-
17-
h13/contract-templates:
18-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
19-
dest: .github/PULL_REQUEST_TEMPLATE.md
20-
21-
h13/feed-pulse:
22-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
23-
dest: .github/PULL_REQUEST_TEMPLATE.md
24-
25-
h13/feed-pulse-ts:
26-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
27-
dest: .github/PULL_REQUEST_TEMPLATE.md
28-
29-
h13/smallbiz-suite:
30-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
31-
dest: .github/PULL_REQUEST_TEMPLATE.md
32-
33-
h13/fyi:
34-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
35-
dest: .github/PULL_REQUEST_TEMPLATE.md
36-
37-
h13/nps-platform:
38-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
39-
dest: .github/PULL_REQUEST_TEMPLATE.md
40-
41-
h13/autoreload.fish:
42-
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
43-
dest: .github/PULL_REQUEST_TEMPLATE.md
44-
45-
h13/anki-manual-ja:
6+
files:
467
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
478
dest: .github/PULL_REQUEST_TEMPLATE.md
9+
- source: sync/.github/ISSUE_TEMPLATE/bug_report.yml
10+
dest: .github/ISSUE_TEMPLATE/bug_report.yml
11+
- source: sync/.github/ISSUE_TEMPLATE/feature_request.yml
12+
dest: .github/ISSUE_TEMPLATE/feature_request.yml

.github/workflows/ci-markdown.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
steps:
1818
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
1919

20-
- uses: h13/.github/actions/apply-org-config@main
20+
- uses: h13/.github/actions/apply-org-config@c62d0eebefffc0d3ca156453f0fb7cd3dcb94f4c # main
2121
with:
2222
config-file: .markdownlint-cli2.yaml
2323

.github/workflows/compliance-audit.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
for repo in $REPOS; do
2828
FINDINGS=""
2929
30-
# Check renovate.json
30+
# Check renovate.json (Renovate-only policy — no Dependabot)
3131
if ! gh api "repos/h13/$repo/contents/renovate.json" --silent 2>/dev/null; then
3232
FINDINGS="${FINDINGS}\n - [ ] Missing \`renovate.json\`"
3333
fi
@@ -43,6 +43,23 @@ jobs:
4343
FINDINGS="${FINDINGS}\n - [ ] No branch protection on \`$DEFAULT_BRANCH\`"
4444
fi
4545
46+
# Check LICENSE
47+
if ! gh api "repos/h13/$repo/contents/LICENSE" --silent 2>/dev/null; then
48+
FINDINGS="${FINDINGS}\n - [ ] Missing \`LICENSE\`"
49+
fi
50+
51+
# Check CODEOWNERS
52+
HAS_CODEOWNERS=false
53+
for path in "CODEOWNERS" ".github/CODEOWNERS" "docs/CODEOWNERS"; do
54+
if gh api "repos/h13/$repo/contents/$path" --silent 2>/dev/null; then
55+
HAS_CODEOWNERS=true
56+
break
57+
fi
58+
done
59+
if [ "$HAS_CODEOWNERS" = "false" ]; then
60+
FINDINGS="${FINDINGS}\n - [ ] Missing \`CODEOWNERS\`"
61+
fi
62+
4663
if [ -n "$FINDINGS" ]; then
4764
REPORT="${REPORT}\n### $repo\n$FINDINGS\n"
4865
ISSUES_FOUND=$((ISSUES_FOUND + 1))

.github/workflows/repo-sync.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ on:
55
branches: [main]
66
paths:
77
- "sync/**"
8-
- ".github/sync.yml"
98
workflow_dispatch:
109

1110
permissions:
@@ -17,6 +16,31 @@ jobs:
1716
steps:
1817
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
1918

19+
- name: Generate sync config from all org repos
20+
env:
21+
GH_TOKEN: ${{ secrets.REPO_SYNC_TOKEN }}
22+
run: |
23+
set -euo pipefail
24+
25+
REPOS=$(gh repo list h13 --no-archived --json name -q '.[].name' \
26+
| grep -v '^\\.github$' \
27+
| sort \
28+
| awk '{printf " h13/%s\n", $0}')
29+
30+
cat > .github/sync.yml <<SYNC
31+
group:
32+
- repos: |
33+
${REPOS}
34+
files:
35+
- source: sync/.github/PULL_REQUEST_TEMPLATE.md
36+
dest: .github/PULL_REQUEST_TEMPLATE.md
37+
- source: sync/.github/ISSUE_TEMPLATE/bug_report.yml
38+
dest: .github/ISSUE_TEMPLATE/bug_report.yml
39+
- source: sync/.github/ISSUE_TEMPLATE/feature_request.yml
40+
dest: .github/ISSUE_TEMPLATE/feature_request.yml
41+
SYNC
42+
cat .github/sync.yml
43+
2044
- uses: BetaHuhn/repo-file-sync-action@8d7590ac8bf240686428959b8fd060a34d508b3f # v1.9.4
2145
with:
2246
GH_PAT: ${{ secrets.REPO_SYNC_TOKEN }}

CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Default owner for all files in h13 repositories.
2+
# Repos can override this by adding their own CODEOWNERS file.
3+
* @h13

CONTRIBUTING.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Contributing
2+
3+
Thanks for your interest in contributing to h13 projects.
4+
5+
## Getting Started
6+
7+
1. Fork the repository
8+
2. Create a feature branch from `main`
9+
3. Make your changes
10+
4. Run tests locally and ensure CI passes
11+
5. Open a pull request
12+
13+
## Guidelines
14+
15+
- Keep pull requests focused on a single change
16+
- Follow the existing code style and conventions
17+
- Add tests for new functionality
18+
- Update documentation if needed
19+
20+
## Dependency Management
21+
22+
All repositories use [Renovate](https://docs.renovatebot.com/) for automated dependency updates. Do not use Dependabot.
23+
24+
## Reporting Issues
25+
26+
- **Bugs**: Use the "Bug report" issue template
27+
- **Features**: Use the "Feature request" issue template
28+
- **Security**: See [SECURITY.md](SECURITY.md) — do not open a public issue

README.md

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ Default community health files, reusable workflows, and shared config for h13 re
77

88
## Reusable Workflows
99

10-
Call from any repo via `uses: h13/.github/.github/workflows/<name>@v1`:
10+
Call from any repo via `uses: h13/.github/.github/workflows/<name>@<sha>`:
1111

12-
| Workflow | Stack | Inputs | Steps |
13-
|---|---|---|---|
14-
| `ci-node.yml` | Node.js | `node-version` | npm ci (cached) → npm test |
15-
| `ci-go.yml` | Go || go test -race → golangci-lint |
16-
| `ci-php.yml` | PHP | `php-version`, `php-extensions`, `working-directory`, `composer-args`, `test-command` | composer install (cached) → composer test |
17-
| `ci-terraform.yml` | Terraform | `terraform-version` | terraform fmt/init/validate → tflint |
18-
| `ci-markdown.yml` | Markdown | `glob` | markdownlint-cli2 (org config auto-applied) |
12+
| Workflow | Stack | Inputs | Steps |
13+
| ------------------ | --------- | ------------------------------------------------------------------------------------- | ------------------------------------------- |
14+
| `ci-node.yml` | Node.js | `node-version` | npm ci (cached) → npm run lint → npm test |
15+
| `ci-go.yml` | Go | | go test -race → golangci-lint |
16+
| `ci-php.yml` | PHP | `php-version`, `php-extensions`, `working-directory`, `composer-args`, `test-command` | composer install (cached) → composer test |
17+
| `ci-terraform.yml` | Terraform | `terraform-version` | terraform fmt/init/validate → tflint |
18+
| `ci-markdown.yml` | Markdown | `glob` | markdownlint-cli2 (org config auto-applied) |
1919

2020
All workflows enforce `permissions: { contents: read }` (least-privilege).
2121

@@ -29,41 +29,56 @@ on:
2929
pull_request:
3030
jobs:
3131
ci:
32-
uses: h13/.github/.github/workflows/ci-node.yml@v1
32+
uses: h13/.github/.github/workflows/ci-node.yml@c62d0eebefffc0d3ca156453f0fb7cd3dcb94f4c # main
3333
```
3434
3535
## Versioning
3636
37-
- **Non-breaking** (fixes, dependency updates): `v1` tag moves forward
38-
- **Breaking** (removed inputs, changed behavior): new major `v2`
39-
- SHA pins inside workflows are auto-updated by Renovate
37+
- All workflow references use **SHA pinning** (no `@v1` tags)
38+
- SHA pins are auto-updated by **Renovate** (Dependabot is not used)
4039

4140
## Composite Actions
4241

43-
| Action | Description |
44-
|---|---|
42+
| Action | Description |
43+
| -------------------------- | ----------------------------------------------- |
4544
| `actions/apply-org-config` | Download org config if no local override exists |
4645

4746
## Automation
4847

49-
| Workflow | Schedule | Description |
50-
|---|---|---|
51-
| Compliance Audit | Monthly (1st) | Checks all repos for renovate.json, CI, branch protection |
52-
| Repo Sync | On push to `sync/` | Syncs PR template to all repos |
48+
| Workflow | Schedule | Description |
49+
| ---------------- | ------------------ | ------------------------------------------------------------------------------ |
50+
| Compliance Audit | Monthly (1st) | Checks all repos for renovate.json, CI, branch protection, LICENSE, CODEOWNERS |
51+
| Repo Sync | On push to `sync/` | Syncs PR/issue templates to all non-archived repos (dynamic) |
52+
53+
## Community Health Files
54+
55+
Org-wide defaults (applied to all repos without their own):
56+
57+
| File | Purpose |
58+
| ----------------- | ------------------------------ |
59+
| `SECURITY.md` | Vulnerability reporting policy |
60+
| `CONTRIBUTING.md` | Contribution guidelines |
61+
| `CODEOWNERS` | Default code review ownership |
62+
| `LICENSE` | MIT license |
63+
64+
## Dependency Policy
65+
66+
All repositories use **Renovate** exclusively for dependency management. Dependabot is not used.
67+
Shared presets are maintained in [h13/renovate-config](https://github.com/h13/renovate-config).
5368

5469
## Ecosystem
5570

5671
```text
5772
h13/dotfiles ← Dev environment + repo-init
5873
└─ repo-init --stack=node --github
5974
├─ generates → renovate.json ──→ h13/renovate-config
60-
├─ generates → .github/workflows/ci.yml (calls @v1)
75+
├─ generates → .github/workflows/ci.yml (SHA-pinned)
6176
└─ configures → GitHub settings (branch protection, labels, alerts)
6277
6378
h13/.github ← Reusable Workflows + shared config ★
6479
├─ ci-{node,go,php,terraform,markdown}.yml (reusable, SHA-pinned)
6580
├─ compliance-audit.yml (monthly)
66-
├─ repo-sync.yml (PR template sync)
81+
├─ repo-sync.yml (dynamic sync to all repos)
6782
└─ apply-org-config action
6883
6984
h13/renovate-config ← Shared Renovate presets
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Bug report
2+
description: Report a bug or unexpected behavior
3+
labels: ["bug"]
4+
body:
5+
- type: textarea
6+
id: description
7+
attributes:
8+
label: Description
9+
description: What happened?
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: expected
14+
attributes:
15+
label: Expected behavior
16+
description: What did you expect to happen?
17+
validations:
18+
required: true
19+
- type: textarea
20+
id: steps
21+
attributes:
22+
label: Steps to reproduce
23+
description: How can we reproduce the issue?
24+
validations:
25+
required: true
26+
- type: textarea
27+
id: environment
28+
attributes:
29+
label: Environment
30+
description: "OS, runtime version, etc."
31+
validations:
32+
required: false
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Feature request
2+
description: Suggest a new feature or improvement
3+
labels: ["enhancement"]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: Problem
9+
description: What problem does this solve?
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: solution
14+
attributes:
15+
label: Proposed solution
16+
description: How should it work?
17+
validations:
18+
required: true
19+
- type: textarea
20+
id: alternatives
21+
attributes:
22+
label: Alternatives considered
23+
description: Any other approaches you considered?
24+
validations:
25+
required: false

workflow-templates/ci-go.yml

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,5 @@ on:
66
pull_request:
77

88
jobs:
9-
test:
10-
runs-on: ubuntu-latest
11-
steps:
12-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
13-
14-
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
15-
with:
16-
go-version-file: go.mod
17-
18-
- run: go test ./...
19-
20-
lint:
21-
runs-on: ubuntu-latest
22-
steps:
23-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
24-
25-
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
26-
with:
27-
go-version-file: go.mod
28-
29-
- uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8
9+
ci:
10+
uses: h13/.github/.github/workflows/ci-go.yml@c62d0eebefffc0d3ca156453f0fb7cd3dcb94f4c # main

0 commit comments

Comments
 (0)