Skip to content
Closed
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
379 changes: 291 additions & 88 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/security/codeql.yml
# @Date: 2026-05-20 00:00:00 -07:00 (1779606000)
# @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/codeql.yml
#
# 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:
#
# "Code Scanning could not process the submitted SARIF file: CodeQL
# analyses from advanced configurations cannot be processed when the
# default setup is enabled"
#
# The org-bootstrap-repo action automatically disables default setup
# (overwrite-with-warn) on every fanout run, so a freshly-bootstrapped
# repo lands in the right state by default. If you want to KEEP default
# setup (the GitHub-managed config) instead of this workflow, DELETE
# this codeql.yml file — with the conflict gone, the bootstrap leaves
# default setup alone on subsequent runs.
#
# Manual fix when running outside the bootstrap:
# Settings → Code security and analysis → Code scanning → CodeQL
# analysis → ⚙️ → Switch to advanced.
name: 🔍 CodeQL

on:
push:
branches: [master, main]
# Same fork-PR consideration as ci.yml: pull_request fires for forks; SARIF
# upload to base-repo Security tab fails with read-only token. Acceptable —
# push-to-master analysis after merge catches anything missed. DO NOT use
# pull_request_target (runs base-repo workflow with secrets against fork
# code; dangerous).
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
# Include the v4 integration branches (`next`, `hotfixes`) so feature
# and hotfix PRs trigger CodeQL. Without these, branch protection
# rulesets that require the CodeQL check on `next`/`hotfixes` will
# sit on "waiting for results" indefinitely. Branches that don't
# exist in a given repo simply never trigger the workflow — harmless
# for repos that haven't adopted the v4 staging-branch flow.
branches: [master, main, next, hotfixes]
schedule:
- 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:
uses: CLDMV/.github/.github/workflows/reusable-codeql.yml@v4
with:
languages: "javascript-typescript"
# Override defaults if needed:
# queries: "security-extended,security-and-quality"
# paths_ignore: "node_modules/,dist/,coverage/,**/test/**"
# config_file: ".github/codeql-config.yml"
# build_mode: "autobuild"
59 changes: 59 additions & 0 deletions .github/workflows/feature-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/feature-pr.yml
# @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/feature-pr.yml
#
# v4 ergonomics: auto-opens (and refreshes) a PR from a code-side branch to the
# right integration branch on every push.
#
# Mapping (matches CLDMV/.github docs/conventions/branch-naming.md):
# feat/*, feature/*, fix/*, release/*, chore/*, refactor/*,
# docs/*, ci/*, perf/*, test/*, style/* → next
# hotfix/* → hotfixes
#
# Reserved branches NOT auto-PR'd: dependabot/* and copilot/* (they manage their
# own PRs); badges, gh-pages (bot-only); master/main (the target).
#
# Thin caller: all job logic (target detection, changelog body, PR create/
# refresh) lives in the reusable, pinned at @v4. Bumping the pin carries fixes
# without editing this file. The `push` trigger and its branch-prefix list stay
# here (GitHub requires the trigger local, and the list is per-repo config).
name: 🔀 Feature PR (v4)

on:
push:
branches:
# CUSTOMIZE: prune this list to whichever branch prefixes your
# repo uses. Must align with the `case` statement in the reusable.
- 'feat/**'
- 'feature/**'
- 'fix/**'
- 'release/**'
- 'chore/**'
- 'refactor/**'
- 'docs/**'
- 'ci/**'
- 'perf/**'
- 'test/**'
- 'style/**'
- 'hotfix/**'

concurrency:
group: feature-pr-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: false

jobs:
open-pr:
permissions:
contents: read
pull-requests: write
uses: CLDMV/.github/.github/workflows/workflow-feature-pr.yml@v4
secrets:
# 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 }}
51 changes: 51 additions & 0 deletions .github/workflows/hotfix-redirector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/hotfix-redirector.yml
# @Date: 2026-05-22 00:00:00 -07:00 (1779778800)
# @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/hotfix-redirector.yml
#
# v4 hotfix lane: retarget hotfix/security PRs to the `hotfixes` branch.
#
# Two paths trigger a redirect (CLDMV/.github docs/conventions/release-flow-v4.md §5.2, §6.5):
# 1. Head branch matches `hotfix/*` or `security/*` (human-driven hotfix flow).
# 2. Author is `dependabot[bot]` AND its base isn't Dependabot's routine
# target-branch (default "next") — GitHub always overrides dependabot.yml's
# target-branch for security updates, so a base landing on the default
# branch instead of "next" is itself the signal. Routine version bumps stay
# on "next".
#
# Thin caller: all job logic (token, checkout, git identity, redirect action)
# lives in the reusable, pinned at @v4. Bumping the pin carries new requirements
# (e.g. the checkout + git identity the cherry-pick path needs) without editing
# this file.
name: 🔀 Hotfix PR Redirector (v4)

# SECURITY NOTE: pull_request_target runs in the BASE repo's context with WRITE
# permissions + secrets. The reusable checks out `hotfixes` (a trusted base-repo
# branch, NOT the PR head/fork) and only cherry-picks/pushes against it.
#
# `opened` only (NOT `edited`): if a maintainer manually re-targets the PR, we
# must not fight them by redirecting again.
on:
pull_request_target:
types: [opened]

concurrency:
group: hotfix-redirector-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
redirect:
permissions:
contents: write
pull-requests: write
uses: CLDMV/.github/.github/workflows/workflow-hotfix-redirector.yml@v4
secrets:
# 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 }}
55 changes: 55 additions & 0 deletions .github/workflows/hotfixes-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/hotfixes-release.yml
# @Date: 2026-05-22 00:00:00 -07:00 (1779778800)
# @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/hotfixes-release.yml
#
# v4 hotfix lane: maintain the ONE persistent `hotfixes → master` release PR.
#
# Mirror of next-release.yml but for the `hotfixes` integration branch
# (CLDMV/.github docs/conventions/release-flow-v4.md §5.4, §6.2). Fires on every
# push to `hotfixes` (hotfix/security PR squash-merges land here), and
# resolves-or-creates the persistent `hotfixes → master` release PR.
#
# Thin caller: all job logic (plan / create / refresh) lives in the reusable,
# pinned at @v4. Bumping the pin carries fixes without editing this file.
# CUSTOMIZE `package_name` / `build_command` to match your package (same values
# as your next-release.yml).
name: 🚑 Hotfixes Release (v4)

on:
push:
branches: [hotfixes]
workflow_dispatch: # manual kick — e.g. to open/refresh the PR for content already on `hotfixes`

concurrency:
group: hotfixes-release-${{ github.repository }}
cancel-in-progress: false

jobs:
release:
permissions:
contents: write
pull-requests: write
uses: CLDMV/.github/.github/workflows/workflow-hotfixes-release.yml@v4
with:
package_name: "@cldmv/vitest-runner"
build_command: "npm run build:ci"
secrets:
# 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 release-PR notifier webhooks — each is independently
# opt-in: leave one unset and that channel is silently skipped.
# Delete the lines you don't use.
DISCORD_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PUBLIC_WEBHOOK }}
DISCORD_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PRIVATE_WEBHOOK }}
SLACK_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PUBLIC_WEBHOOK }}
SLACK_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PRIVATE_WEBHOOK }}
GENERIC_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PUBLIC_WEBHOOK }}
GENERIC_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PRIVATE_WEBHOOK }}
52 changes: 52 additions & 0 deletions .github/workflows/master-commit-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-companions/master-commit-audit.yml
# @Date: 2026-05-31 00:00:00 -07:00 (1780210800)
# @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/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.
#
# Catches: release-workflow title-generation regressions, branch-protection
# bypasses, unexpected bot commits, direct emergency pushes.
#
# 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:
push:
branches: [master, main]

permissions:
contents: read
issues: write

jobs:
audit:
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 }}
61 changes: 61 additions & 0 deletions .github/workflows/next-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/next-release.yml
# @Date: 2026-05-22 00:00:00 -07:00 (1779778800)
# @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/next-release.yml
#
# v4 core: maintain the ONE persistent `next → master` release PR for this repo.
#
# Fires on every push to `next` (contributor PR squash-merges land here).
# Resolves the existing release PR and refreshes it, or creates it the first
# time `next` diverges from master. The release PR batches all accumulated
# feature commits into a single release — that batching is v4's whole point
# (see CLDMV/.github docs/conventions/release-flow-v4.md §5.3, §6.1).
#
# Thin caller: all job logic (plan / create / refresh) lives in the reusable,
# pinned at @v4. Bumping the pin carries fixes without editing this file.
# CUSTOMIZE:
# - `package_name` → your npm package (or any unique identifier)
# - `build_command` → your build script, or a stub like
# `echo '✓ no build step'` for a meta package (optional;
# defaults to `npm run build:ci`)
name: 🚀 Next Release (v4)

on:
push:
branches: [next]
workflow_dispatch: # manual kick — e.g. to open/refresh the PR for content already on `next`

# Serialize: each run re-resolves the current PR state, so queueing (not
# cancelling) avoids a create/refresh race when pushes land back-to-back.
concurrency:
group: next-release-${{ github.repository }}
cancel-in-progress: false

jobs:
release:
permissions:
contents: write
pull-requests: write
uses: CLDMV/.github/.github/workflows/workflow-next-release.yml@v4
with:
package_name: "@cldmv/vitest-runner"
build_command: "npm run build:ci"
secrets:
# 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 release-PR notifier webhooks — each is independently
# opt-in: leave one unset and that channel is silently skipped.
# Delete the lines you don't use.
DISCORD_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PUBLIC_WEBHOOK }}
DISCORD_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.DISCORD_RELEASE_PR_PRIVATE_WEBHOOK }}
SLACK_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PUBLIC_WEBHOOK }}
SLACK_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.SLACK_RELEASE_PR_PRIVATE_WEBHOOK }}
GENERIC_RELEASE_PR_PUBLIC_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PUBLIC_WEBHOOK }}
GENERIC_RELEASE_PR_PRIVATE_WEBHOOK: ${{ secrets.GENERIC_RELEASE_PR_PRIVATE_WEBHOOK }}
43 changes: 43 additions & 0 deletions .github/workflows/next-reset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#
# @Project: @cldmv/.github
# @Filename: /examples/individual-repo-workflows/release-flow-v4/next-reset.yml
# @Date: 2026-05-22 00:00:00 -07:00 (1779778800)
# @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/next-reset.yml
#
# v4 core: after a release lands on master, re-sync the integration branches
# (CLDMV/.github docs/conventions/release-flow-v4.md §6.3, §7).
#
# - `hotfixes` is ALWAYS force-reset to master HEAD after any release.
# - `next` depends on which lane released:
# * normal release (next → master, or a v3-style feat → master):
# force-reset `next` to master HEAD (§7.1).
# * hotfix release (hotfixes → master): MERGE master into `next` instead,
# so next's accumulated feature work is preserved (§7.2, option B).
#
# Thin caller: all job logic (the wait-for-tags gate + the branch sync) lives in
# the reusable, pinned at @v4. Bumping the pin carries fixes without editing
# this file.
name: ♻️ Next/Hotfixes Reset (v4)

on:
push:
branches: [master, main]

concurrency:
group: next-reset-${{ github.repository }}
cancel-in-progress: false

jobs:
sync:
permissions:
contents: write
uses: CLDMV/.github/.github/workflows/workflow-next-reset.yml@v4
secrets:
# 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 }}
Loading
Loading