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
15 changes: 9 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/automation/dependabot.yml
# @Project: gitmulti
# @Filename: /.github/dependabot.yml
# @Date: 2026-05-26 00:00:00 -07:00 (1782460800)
# @Author: Nate Corcoran <CLDMV>
# @Email: <Shinrai@users.noreply.github.com>
Expand Down Expand Up @@ -69,10 +69,13 @@ updates:
prefix: "deps"
groups:
# vitest and @vitest/coverage-v8 (and other @vitest/* packages) peer
# each other exactly, so bumping one without the other breaks
# `npm ci` with an ERESOLVE. Bump the whole family together in one
# PR. Must come before security/patch/minor below β€” Dependabot
# assigns each update to the FIRST matching group.
# each other EXACTLY, so a partial bump (e.g. vitest to 5.0.0 while
# @vitest/coverage-v8 stays 4.1.11) breaks `npm ci` with an ERESOLVE.
# Bump the whole family together in one PR so the exact-peer
# versions never diverge. Must come before security/patch/minor
# below β€” Dependabot assigns each update to the FIRST matching
# group, and this one has no applies-to restriction so it always
# wins for vitest-family packages regardless of update type.
vitest:
patterns:
- "vitest"
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/branch-retention.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ on:
branches: [master, main, next, hotfixes]

permissions:
contents: write
pull-requests: read
contents: read

jobs:
retain:
permissions:
contents: write
pull-requests: read
if: github.event.pull_request.merged == true
uses: CLDMV/.github/.github/workflows/reusable-branch-retention.yml@v4
secrets:
Expand Down
586 changes: 313 additions & 273 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions .github/workflows/cla.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ on:

permissions:
contents: read
pull-requests: write
statuses: write
issues: write

jobs:
cla:
permissions:
contents: read
pull-requests: write
statuses: write
issues: write
uses: CLDMV/.github/.github/workflows/reusable-cla.yml@v4
with:
cla_version: "1.0"
Expand Down
17 changes: 15 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@

# Individual repo: .github/workflows/codeql.yml
#
# PRIVATE REPOS are skipped by DEFAULT: the bootstrap's `variables` phase
# sets CLDMV_SKIP_CODE_SCANNING (this workflow then uploads an empty 0-alert
# SARIF instead of analyzing) on every private repo not opted in, since Code
# Security bills per active committer there. To actually scan a private
# repo: pay for GitHub Code Security and add the repo to the `scan` list in
# data/code-scanning-skips.json in CLDMV/.github. Public repos scan by
# default (free); a public repo with nothing to analyze goes in that file's
# `skip` section. Consumers outside CLDMV can pass `skip_code_scanning:
# true` below instead. Do NOT just delete this file on a repo whose ruleset
# requires code_scanning β€” the gate then waits forever.
#
# REQUIRED REPO SETTING β€” CodeQL must be in "Advanced" mode for this workflow
# to upload SARIF. If the repo has CodeQL "Default setup" enabled (the
# GitHub-managed alternative), upload runs fail with:
Expand Down Expand Up @@ -50,16 +61,18 @@ on:
- cron: "37 14 * * 1" # weekly Monday 14:37 UTC; GitHub updates queries over time

permissions:
security-events: write
contents: read
actions: read

concurrency:
group: codeql-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' }}

jobs:
analyze:
permissions:
security-events: write
contents: read
actions: read
uses: CLDMV/.github/.github/workflows/reusable-codeql.yml@v4
with:
languages: "javascript-typescript"
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,20 @@ on:
types: [opened, reopened, synchronize, ready_for_review]

permissions:
contents: write
pull-requests: write
contents: read

jobs:
automerge:
permissions:
contents: write
pull-requests: write
# Pre-filter at workflow level so this doesn't spin up for every PR.
if: github.event.pull_request.user.login == 'dependabot[bot]'
uses: CLDMV/.github/.github/workflows/reusable-dependabot-auto-merge.yml@v4
with:
bump_types: "patch,minor"
# merge_method defaults to "merge" β€” Dependabot PRs target next / hotfixes,
# whose rulesets are merge-only. Override only if your branches differ.
merge_method: "squash"
# also_for_actors: "renovate[bot]" # extend if you adopt Renovate
secrets:
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/dependabot-recreate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#
# @Project: gitmulti
# @Filename: /.github/workflows/dependabot-recreate.yml
# @Date: 2026-07-31 00:00:00 -07:00 (1785481200)
# @Author: Nate Corcoran <CLDMV>
# @Email: <Shinrai@users.noreply.github.com>
# @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved.
#

# Individual repo: .github/workflows/dependabot-recreate.yml
#
# Auto-fires `@dependabot recreate` when a Dependabot PR gets stuck in the
# "edited by someone other than Dependabot" state. That state breaks
# `@dependabot rebase` and β€” under a required-signed-commits ruleset β€” blocks
# the PR with an unsigned commit. `recreate` rebuilds it as a fresh, signed
# Dependabot commit that dependabot-auto-merge.yml then merges. See
# reusable-dependabot-recreate.yml for the mechanics + the command-actor caveat.
#
# Default in v4: ON. Delete this file to opt out entirely; add a `no-recreate`
# label to a specific PR to exempt just that one (e.g. one you've hand-edited
# on purpose and don't want overwritten).
#
# Triggers:
# - issue_comment: catches Dependabot's own "can't rebase, use recreate" reply
# (Dependabot only comments back when a rebase FAILS β€” success is a silent
# πŸ‘ + force-push).
# - pull_request_target: proactive net for a Dependabot PR whose head commit
# is unverified. pull_request_target (not pull_request) is required so the
# job can read the bot-App secrets β€” Dependabot-triggered `pull_request`
# runs get a read-only token and no secrets. It is SAFE here: Dependabot PRs
# are same-repo branches (not forks), and this workflow never checks out or
# runs PR code β€” it only reads the PR and posts a comment via the API.
name: πŸ” Dependabot Auto-Recreate

on:
issue_comment:
types: [created]
pull_request_target:
types: [opened, synchronize, reopened]

permissions:
contents: read
pull-requests: write
issues: write

jobs:
recreate:
# A) Dependabot replied that it can't rebase (the PR was edited), or
# B) a Dependabot PR opened/updated β€” the reusable then checks whether
# its head commit is actually unverified before doing anything.
if: >-
(github.event_name == 'issue_comment'
&& github.event.issue.pull_request
&& github.event.comment.user.login == 'dependabot[bot]'
&& contains(github.event.comment.body, 'edited by someone other than Dependabot'))
|| (github.event_name == 'pull_request_target'
&& github.event.pull_request.user.login == 'dependabot[bot]')
uses: CLDMV/.github/.github/workflows/reusable-dependabot-recreate.yml@v4
with:
skip_label: "no-recreate"
secrets:
BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }}
BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }}
8 changes: 8 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
#

# Individual repo: .github/workflows/dependency-review.yml
#
# PRIVATE REPOS are skipped by DEFAULT (the dependency-review API needs
# GitHub Advanced Security there): the bootstrap's `variables` phase sets
# CLDMV_SKIP_DEPENDENCY_REVIEW on every private repo not opted into the
# `scan` list in data/code-scanning-skips.json in CLDMV/.github. To run the
# review on a private repo, pay for Code Security and add it to that list.
# Consumers outside CLDMV can pass `skip_dependency_review: true` below
# instead.
name: πŸ”’ Dependency Review

on:
Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/feature-pr.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/feature-pr.yml
# @Project: gitmulti
# @Filename: /.github/workflows/feature-pr.yml
# @Author: Nate Corcoran <CLDMV>
# @Email: <Shinrai@users.noreply.github.com>
# @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved.
Expand All @@ -12,7 +12,7 @@
# right integration branch on every push.
#
# Mapping (matches CLDMV/.github docs/conventions/branch-naming.md):
# feat/*, feature/*, fix/*, release/*, chore/*, refactor/*,
# feat/*, feature/*, fix/*, release/*, chore/*, deps/*, refactor/*,
# docs/*, ci/*, perf/*, test/*, style/* β†’ next
# hotfix/* β†’ hotfixes
#
Expand All @@ -35,6 +35,7 @@ on:
- 'fix/**'
- 'release/**'
- 'chore/**'
- 'deps/**'
- 'refactor/**'
- 'docs/**'
- 'ci/**'
Expand All @@ -47,6 +48,9 @@ concurrency:
group: feature-pr-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

jobs:
open-pr:
permissions:
Expand All @@ -57,5 +61,10 @@ jobs:
# Map your repo/org secrets to the expected names.
BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }}
BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }}
# Optional: only needed if you also use reusable-lint-format.yml /
# reusable-coverage-badge.yml (or otherwise sign a commit locally as
# this identity). Passed through so this PR's changelog body
# recognizes that identity as a bot instead of listing it as a
# contributor.
BOT_NAME: ${{ secrets.CLDMV_BOT_NAME }}
BOT_EMAIL: ${{ secrets.CLDMV_BOT_EMAIL }}
12 changes: 10 additions & 2 deletions .github/workflows/hotfix-redirector.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/hotfix-redirector.yml
# @Project: gitmulti
# @Filename: /.github/workflows/hotfix-redirector.yml
# @Date: 2026-05-22 00:00:00 -07:00 (1779778800)
# @Author: Nate Corcoran <CLDMV>
# @Email: <Shinrai@users.noreply.github.com>
Expand Down Expand Up @@ -39,6 +39,9 @@ concurrency:
group: hotfix-redirector-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
redirect:
permissions:
Expand All @@ -49,6 +52,11 @@ jobs:
# Map your repo/org secrets to the expected names.
BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }}
BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }}
# GPG signing identity β€” REQUIRED if this repo redirects Dependabot
# SECURITY PRs: that path cherry-picks a commit onto `hotfixes`, and
# an unsigned commit is silently blocked by required-signatures (no
# failing check names the cause). The commit is signed and authored as
# this real-user bot account (the GPG key's owner), not the App bot.
BOT_NAME: ${{ secrets.CLDMV_BOT_NAME }}
BOT_EMAIL: ${{ secrets.CLDMV_BOT_EMAIL }}
BOT_GPG_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_GPG_PRIVATE_KEY }}
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/hotfixes-release.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/hotfixes-release.yml
# @Project: gitmulti
# @Filename: /.github/workflows/hotfixes-release.yml
# @Date: 2026-05-22 00:00:00 -07:00 (1779778800)
# @Author: Nate Corcoran <CLDMV>
# @Email: <Shinrai@users.noreply.github.com>
Expand Down Expand Up @@ -31,6 +31,9 @@ concurrency:
group: hotfixes-release-${{ github.repository }}
cancel-in-progress: false

permissions:
contents: read

jobs:
release:
permissions:
Expand All @@ -44,6 +47,12 @@ jobs:
# Map your repo/org secrets to the expected names.
BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }}
BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }}
# Optional: only needed if you also use reusable-lint-format.yml /
# reusable-coverage-badge.yml (or otherwise sign a commit locally as
# this identity). Passed through so the release-PR changelog
# recognizes that identity as a bot instead of listing it as a
# contributor β€” see CLDMV_BOT_NAME/CLDMV_BOT_EMAIL in your other
# workflows for the same values.
BOT_NAME: ${{ secrets.CLDMV_BOT_NAME }}
BOT_EMAIL: ${{ secrets.CLDMV_BOT_EMAIL }}
# Optional release-PR notifier webhooks β€” each is independently
Expand Down
62 changes: 24 additions & 38 deletions .github/workflows/master-commit-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
# Individual repo: .github/workflows/master-commit-audit.yml
#
# Post-merge safety net: when any commit lands on the default branch, verify
# its subject matches the expected release-flow patterns. On miss, auto-file
# a GitHub Issue (deduped by SHA) so the alert is persistent and assignable
# β€” not just a red ❌ that dies in inbox.
# its subject matches the expected release-flow patterns. On miss, auto-file a
# GitHub Issue (deduped by SHA) so the alert is persistent and assignable β€”
# not just a red ❌ that dies in inbox.
#
# Catches: release-workflow title-generation regressions, branch-protection
# bypasses, unexpected bot commits, direct emergency pushes.
#
# Batch 5.1 from tmp/plan-future-workflows.md.
# Thin caller: steps, the action ref, and the canonical commit-subject pattern
# set all live in reusable-master-commit-audit.yml@v4 (the patterns come from
# the audit-commit-subject action's default). Nothing here can drift.
name: 🧾 Master Commit Audit

on:
Expand All @@ -30,37 +32,21 @@ permissions:

jobs:
audit:
runs-on: ubuntu-latest
steps:
# Optional. Without these, the audit issue is filed by
# github-actions[bot]. With them, the issue is filed by your bot App.
- name: Create App token (falls back to GITHUB_TOKEN)
id: app-token
uses: CLDMV/.github/.github/actions/github/steps/create-app-token@v4
with:
client_id: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }}
private_key: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }}
env:
BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }}
BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }}

- name: Audit commit subject
uses: CLDMV/.github/.github/actions/git/jobs/audit-commit-subject@v4
with:
commit_sha: ${{ github.sha }}
# allowed_patterns omitted -> inherit the canonical default from
# audit-commit-subject (release/chore/merge patterns, including
# the "release: vX.Y.Z - <description>" form). Customize only if
# this repo's conventions genuinely differ β€” a hardcoded copy
# here goes stale the next time the canonical default changes.
# allowed_patterns: |
# ^release: v\d+\.\d+\.\d+( - .+?)?( \(#\d+\))?$
# ^chore(\([^)]+\))?: .+
# ^Merge pull request #\d+ from .+
# ^feat(\([^)]+\))?: .+
# Canonical label names from CLDMV/.github's data/github-labels.json
# (note the space after each colon). Replace with names that exist
# in your repo's label catalog.
issue_labels: "type: ci,priority: high"
# issue_assignee: "shinrai" # uncomment to auto-assign
github_token: ${{ steps.app-token.outputs.token }}
uses: CLDMV/.github/.github/workflows/reusable-master-commit-audit.yml@v4
with:
# allowed_patterns omitted β†’ inherit the canonical default
# (release + chore + merge). Uncomment ONLY if this repo lands other
# commit shapes directly on the default branch:
# allowed_patterns: |
# ^release: v\d+\.\d+\.\d+( - .+?)?( \(#\d+\))?$
# ^chore(\([^)]+\))?: .+
# ^Merge pull request #\d+ from .+
# ^feat(\([^)]+\))?: .+
issue_labels: "type: ci,priority: high"
# issue_assignee: "shinrai" # uncomment to auto-assign
# Optional bot App credentials β€” when set, the audit issue is filed by
# the consumer's bot App instead of github-actions[bot]. Remove both
# lines to fall back to GITHUB_TOKEN.
secrets:
BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }}
BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }}
Loading
Loading