From 1ddbe0c92d91a56c2a2f56678cbaf13dc717158c Mon Sep 17 00:00:00 2001 From: "cldmv-bot[bot]" <230771808+cldmv-bot[bot]@users.noreply.github.com> Date: Sun, 19 Jul 2026 22:48:38 -0700 Subject: [PATCH 01/12] fix: stop overriding master-commit-audit's allowed_patterns with a stale copy (#22) --- .github/workflows/master-commit-audit.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/master-commit-audit.yml b/.github/workflows/master-commit-audit.yml index ad6b2e8..44bb32a 100644 --- a/.github/workflows/master-commit-audit.yml +++ b/.github/workflows/master-commit-audit.yml @@ -48,13 +48,16 @@ jobs: uses: CLDMV/.github/.github/actions/git/jobs/audit-commit-subject@v4 with: commit_sha: ${{ github.sha }} - # Allow release commits (from the release workflow), maintenance - # commits, and standard merge commits. Customize per repo if - # your conventions differ. - allowed_patterns: | - ^release: v\d+\.\d+\.\d+( \(#\d+\))?$ - ^chore(\([^)]+\))?: .+ - ^Merge pull request #\d+ from .+ + # allowed_patterns omitted -> inherit the canonical default from + # audit-commit-subject (release/chore/merge patterns, including + # the "release: vX.Y.Z - " 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. From a38fa1b2d417311db92717374452bae3d09f7968 Mon Sep 17 00:00:00 2001 From: "cldmv-bot[bot]" <230771808+cldmv-bot[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 05:49:10 +0000 Subject: [PATCH 02/12] chore: bump version to 1.1.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b2f0fc..1e50c23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cldmv/git-embedded", - "version": "1.1.2", + "version": "1.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cldmv/git-embedded", - "version": "1.1.2", + "version": "1.1.3", "license": "Apache-2.0", "dependencies": { "@cldmv/slothlet": "^3.7.0", diff --git a/package.json b/package.json index 2005b55..1f367f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cldmv/git-embedded", - "version": "1.1.2", + "version": "1.1.3", "description": "Manage embedded git repositories (anonymous gitlinks) without .gitmodules. Provides hooks that restore standard git-command ergonomics for embedded children while keeping the child's origin URL out of the public parent repo.", "type": "module", "license": "Apache-2.0", From 67e529f27869e481e8833d188668b63ac763dd74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 21:34:45 +0000 Subject: [PATCH 03/12] deps: bump the minor group with 2 updates Bumps the minor group with 2 updates: [@cldmv/slothlet](https://github.com/CLDMV/slothlet) and [prettier](https://github.com/prettier/prettier). Updates `@cldmv/slothlet` from 3.7.0 to 3.12.1 - [Release notes](https://github.com/CLDMV/slothlet/releases) - [Commits](https://github.com/CLDMV/slothlet/compare/v3.7...@cldmv/slothlet-i18n@3.12.1) Updates `prettier` from 3.8.3 to 3.9.6 - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.8.3...3.9.6) --- updated-dependencies: - dependency-name: "@cldmv/slothlet" dependency-version: 3.12.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor - dependency-name: prettier dependency-version: 3.9.6 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e50c23..eae31e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,28 +99,36 @@ } }, "node_modules/@cldmv/slothlet": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@cldmv/slothlet/-/slothlet-3.7.0.tgz", - "integrity": "sha512-HZmZlj+Wmo+952UDTnrlBR8Cv05hNTv3DEdQDbOL6nPh0BKqgSOdtt9UOby+6Lvgi1eOaRhrpIq+uFWWcsYlPQ==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@cldmv/slothlet/-/slothlet-3.12.1.tgz", + "integrity": "sha512-JgL2cUrDVCgo2TQdsRXrhE+6G+ML0+Ji87RHrA6+bMFaTXBSpFBdnRAakW9lGx2uzaXM3y7pcIIc2YVJ76jTEQ==", "license": "Apache-2.0", "bin": { "slothlet": "bin/slothlet.mjs" }, "engines": { - "node": ">=20.19.0" + "node": ">=22.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/shinrai" }, "optionalDependencies": { - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17" + "@rolldown/binding-linux-x64-gnu": "1.0.3" }, "peerDependencies": { + "@cldmv/slothlet-i18n": "^3.11.0", + "@cldmv/slothlet-types": "^3.11.0", "esbuild": "^0.28.0", "typescript": "^6.0.3" }, "peerDependenciesMeta": { + "@cldmv/slothlet-i18n": { + "optional": true + }, + "@cldmv/slothlet-types": { + "optional": true + }, "esbuild": { "optional": true }, @@ -766,9 +774,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.17", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz", - "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", "cpu": [ "x64" ], @@ -3675,9 +3683,9 @@ } }, "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "dev": true, "license": "MIT", "bin": { From dccf5babcecc289745b07f8409f13bd58b0a2c35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 21:34:52 +0000 Subject: [PATCH 04/12] deps: bump @eslint/json from 0.10.0 to 2.0.1 Bumps [@eslint/json](https://github.com/eslint/json) from 0.10.0 to 2.0.1. - [Release notes](https://github.com/eslint/json/releases) - [Changelog](https://github.com/eslint/json/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/json/compare/json-v0.10.0...json-v2.0.1) --- updated-dependencies: - dependency-name: "@eslint/json" dependency-version: 2.0.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 47 +++++++++++++++++------------------------------ package.json | 2 +- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e50c23..288cc6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "devDependencies": { "@cldmv/vitest-runner": "^1.2.0", "@eslint/js": "^9.18.0", - "@eslint/json": "^0.10.0", + "@eslint/json": "^2.0.1", "@eslint/markdown": "^6.2.2", "@vitest/coverage-v8": "^4.1.10", "eslint": "^9.18.0", @@ -289,16 +289,16 @@ } }, "node_modules/@eslint/core": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", - "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/eslintrc": { @@ -352,19 +352,19 @@ } }, "node_modules/@eslint/json": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@eslint/json/-/json-0.10.0.tgz", - "integrity": "sha512-aW0181XofoAwuB0sI263bhwnvAlb6OGnGGxHjTZQNLFErfsAXCnwRD+Uxx6/pK73XtKuQ2w1wbhiTJ2BC/erAQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/json/-/json-2.0.1.tgz", + "integrity": "sha512-Thz2j92ceUF3Bq/0TuWb3MWn3Z+Cwc8k5ptF0fakl2D4Mp8mSx07Xr1aQM4R5NoihzarWUdxfOmQ8DesGy4jOg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.10.0", - "@eslint/plugin-kit": "^0.2.5", - "@humanwhocodes/momoa": "^3.3.4", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanwhocodes/momoa": "^3.3.10", "natural-compare": "^1.4.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/markdown": { @@ -441,30 +441,17 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.13.0", + "@eslint/core": "^1.2.1", "levn": "^0.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@humanfs/core": { diff --git a/package.json b/package.json index 1f367f6..25d11d4 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "devDependencies": { "@cldmv/vitest-runner": "^1.2.0", "@eslint/js": "^9.18.0", - "@eslint/json": "^0.10.0", + "@eslint/json": "^2.0.1", "@eslint/markdown": "^6.2.2", "@vitest/coverage-v8": "^4.1.10", "eslint": "^9.18.0", From 118df83cd6f5b58933c9ede14c4e5ca558db3a07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 21:35:10 +0000 Subject: [PATCH 05/12] deps: bump globals from 15.15.0 to 17.7.0 Bumps [globals](https://github.com/sindresorhus/globals) from 15.15.0 to 17.7.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v15.15.0...v17.7.0) --- updated-dependencies: - dependency-name: globals dependency-version: 17.7.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e50c23..cd1dd51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@eslint/markdown": "^6.2.2", "@vitest/coverage-v8": "^4.1.10", "eslint": "^9.18.0", - "globals": "^15.14.0", + "globals": "^17.7.0", "prettier": "^3.4.2", "vitest": "^4.1.10" }, @@ -1940,9 +1940,9 @@ } }, "node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", + "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 1f367f6..bac4151 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "@eslint/markdown": "^6.2.2", "@vitest/coverage-v8": "^4.1.10", "eslint": "^9.18.0", - "globals": "^15.14.0", + "globals": "^17.7.0", "prettier": "^3.4.2", "vitest": "^4.1.10" } From 44774433021e5ec03a436b20b9022e568e562ca7 Mon Sep 17 00:00:00 2001 From: Shinrai Date: Tue, 28 Jul 2026 05:58:34 -0700 Subject: [PATCH 06/12] chore: centralize release-flow workflows into thin @v4 callers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the six full-copy release-flow workflows (feature-pr, hotfix-redirector, next-release, next-reset, hotfixes-release, pr-title-normalizer) with thin callers of CLDMV/.github's workflow-*.yml@v4 reusables. Picks up the centralized job logic β€” including the checkout + git-identity the Dependabot-security cherry-pick path needs, which the old copied hotfix-redirector lacked (it still said "DO NOT add a checkout step"). Behavior unchanged; each file collapses from ~180-260 lines to a thin trigger + uses: job. --- .github/workflows/feature-pr.yml | 243 ++-------------------- .github/workflows/hotfix-redirector.yml | 64 +++--- .github/workflows/hotfixes-release.yml | 171 +++------------ .github/workflows/next-release.yml | 179 +++------------- .github/workflows/next-reset.yml | 186 ++--------------- .github/workflows/pr-title-normalizer.yml | 67 +++--- 6 files changed, 144 insertions(+), 766 deletions(-) diff --git a/.github/workflows/feature-pr.yml b/.github/workflows/feature-pr.yml index ffbb123..fcee49e 100644 --- a/.github/workflows/feature-pr.yml +++ b/.github/workflows/feature-pr.yml @@ -1,7 +1,6 @@ # -# @Project: @cldmv/git-embedded -# @Filename: /.github/workflows/feature-pr.yml -# @Date: 2026-07-18 15:49:12 -07:00 (1784414952) +# @Project: @cldmv/.github +# @Filename: /examples/individual-repo-workflows/release-flow-v4/feature-pr.yml # @Author: Nate Corcoran # @Email: # @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. @@ -9,34 +8,28 @@ # 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. +# 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). +# Reserved branches NOT auto-PR'd: dependabot/* and copilot/* (they manage their +# own PRs); badges, gh-pages (bot-only); master/main (the target). # -# On first push: creates the PR with a categorized changelog body (same -# format the v4 release-PR machinery generates). On subsequent pushes: -# refreshes the existing PR's body with the latest categorized commits. -# Uses the shared get-commit-range + generate-comprehensive-changelog -# actions for the format, so consumer PRs look identical to release PRs -# in structure (Breaking Changes / Features / Bug Fixes / Other Changes / -# Contributors). -# -# Skipped automatically: bot pushes (your bot App's login / github-actions[bot]) -# and any push whose head commit starts with 'chore: bump version'. +# 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 below. + # repo uses. Must align with the `case` statement in the reusable. - 'feat/**' - 'feature/**' - 'fix/**' @@ -50,215 +43,17 @@ on: - 'style/**' - 'hotfix/**' -permissions: - contents: read - pull-requests: write - -# Serialize per-branch so a flurry of pushes doesn't race the -# "does a PR already exist?" check. concurrency: group: feature-pr-${{ github.repository }}-${{ github.ref }} cancel-in-progress: false jobs: open-pr: - # Loop guard: replace 'cldmv-bot[bot]' with your bot App's login. - if: | - github.actor != 'cldmv-bot[bot]' && - github.actor != 'github-actions[bot]' && - !startsWith(github.event.head_commit.message, 'chore: bump version') - runs-on: ubuntu-latest - steps: - - name: Determine target branch - id: target - shell: bash - run: | - branch="${GITHUB_REF#refs/heads/}" - echo "branch=$branch" >> "$GITHUB_OUTPUT" - # CUSTOMIZE: adjust the case arms to match your branch - # conventions. Anything not matched is silently skipped - # (so master/main, badges, gh-pages, dependabot/*, etc. - # are safe regardless of what fires the workflow). - # The flow_label sorts first in the PR's label list - # (the leading `!` precedes every letter alphabetically) - # so a glance at any PR's badges reveals which lane it's in. - # Lane (target) AND declared type both come from the branch - # prefix β€” the v4 convention requires a typed prefix, so a - # `docs/*` branch is a docs change, `fix/*` a fix, etc. The flow - # label is `! β†’ ` so it reflects what the PR actually - # is, not a blanket "feature". (Previously every next-lane branch - # got `! feature β†’ next`, mislabelling docs/fix/chore PRs.) - case "$branch" in - hotfix/*) target="hotfixes"; type="hotfix" ;; - feat/*|feature/*) target="next"; type="feature" ;; - fix/*) target="next"; type="fix" ;; - docs/*) target="next"; type="docs" ;; - chore/*) target="next"; type="chore" ;; - refactor/*) target="next"; type="refactor" ;; - ci/*) target="next"; type="ci" ;; - perf/*) target="next"; type="perf" ;; - test/*) target="next"; type="test" ;; - style/*) target="next"; type="style" ;; - release/*) target="next"; type="release" ;; - *) - target=""; type=""; flow_label="" - echo "::notice::Branch '$branch' does not match any auto-PR pattern; skipping." - ;; - esac - # Leading `!` sorts the flow label first in the PR's badge list, - # so a glance reveals both the change type and its lane. - if [ -n "$target" ]; then - flow_label="! ${type} β†’ ${target}" - fi - echo "target=$target" >> "$GITHUB_OUTPUT" - echo "flow_label=$flow_label" >> "$GITHUB_OUTPUT" - - - name: Create App token - id: app-token - if: steps.target.outputs.target != '' - 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: Check for existing PR - id: existing - if: steps.target.outputs.target != '' - shell: bash - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - pr=$(gh pr list --repo "$GITHUB_REPOSITORY" \ - --head "${{ steps.target.outputs.branch }}" \ - --base "${{ steps.target.outputs.target }}" \ - --state open \ - --json number --jq '.[0].number // ""') - echo "number=$pr" >> "$GITHUB_OUTPUT" - if [ -n "$pr" ]; then - echo "::notice::Existing PR #$pr will be refreshed." - fi - - - name: Checkout (full history for git log) - if: steps.target.outputs.target != '' - uses: CLDMV/.github/.github/actions/common/steps/checkout-code@v4 - with: - fetch-depth: 0 - - - name: Fetch target branch ref - if: steps.target.outputs.target != '' - shell: bash - run: | - git fetch --quiet origin "${{ steps.target.outputs.target }}" - - - name: Get categorized commits (base..head) - id: commits - if: steps.target.outputs.target != '' - uses: CLDMV/.github/.github/actions/git/steps/get-commit-range@v4 - with: - base-ref: origin/${{ steps.target.outputs.target }} - head-ref: HEAD - - - name: Detect feature commits in range - id: feat - if: steps.target.outputs.target != '' - shell: bash - env: - COMMITS: ${{ steps.commits.outputs.commits }} - run: | - # `type: feature` is applied when the range contains a feature, - # mirroring the changelog's own "Features" section: get-commit- - # range tags `feat:` (and content-categorized add/new) commits - # as category "feature". Reuses the already-computed commits. - has_feature=false - if printf '%s' "$COMMITS" | jq -e 'any(.[]; .category == "feature")' >/dev/null 2>&1; then - has_feature=true - fi - echo "has_feature=$has_feature" >> "$GITHUB_OUTPUT" - echo "πŸ“Š feature detected in range: $has_feature" - - - name: Generate categorized changelog body - id: changelog - if: steps.target.outputs.target != '' - uses: CLDMV/.github/.github/actions/git/steps/generate-comprehensive-changelog@v4 - with: - commits: ${{ steps.commits.outputs.commits }} - commit-range: ${{ steps.commits.outputs.commit-range }} - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - - - name: Save body to file - if: steps.target.outputs.target != '' - shell: bash - env: - BODY: ${{ steps.changelog.outputs.changelog-content }} - run: | - printf '%s' "$BODY" > /tmp/pr-body.md - - - name: Create PR (first push) - if: steps.target.outputs.target != '' && steps.existing.outputs.number == '' - shell: bash - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - HEAD_COMMIT_MSG: ${{ github.event.head_commit.message }} - HEAD_BRANCH: ${{ steps.target.outputs.branch }} - BASE_BRANCH: ${{ steps.target.outputs.target }} - run: | - # Title = head commit's first line β€” preserves the - # conventional-commit prefix the release-PR title-normalizer - # and commit-type aggregator expect. - title=$(printf '%s\n' "$HEAD_COMMIT_MSG" | head -1) - pr_url=$(gh pr create \ - --repo "$GITHUB_REPOSITORY" \ - --base "$BASE_BRANCH" \ - --head "$HEAD_BRANCH" \ - --title "$title" \ - --body-file /tmp/pr-body.md) - echo "::notice::Opened $pr_url" - # Apply the flow label (sorts first in the PR's badge list). - # `|| true` so a missing label in the repo (catalog not yet - # synced) doesn't fail the workflow. - if [ -n "${{ steps.target.outputs.flow_label }}" ]; then - gh pr edit "$pr_url" --add-label "${{ steps.target.outputs.flow_label }}" || true - fi - # Apply `type: feature` when the range implements a feature. - if [ "${{ steps.feat.outputs.has_feature }}" = "true" ]; then - gh pr edit "$pr_url" --add-label "type: feature" || true - fi - { - echo "### πŸ”€ Auto-opened PR" - echo "" - echo "$pr_url" - } >> "$GITHUB_STEP_SUMMARY" - - - name: Refresh existing PR body - if: steps.target.outputs.target != '' && steps.existing.outputs.number != '' - shell: bash - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - PR_NUMBER: ${{ steps.existing.outputs.number }} - run: | - gh pr edit "$PR_NUMBER" \ - --repo "$GITHUB_REPOSITORY" \ - --body-file /tmp/pr-body.md - # Re-apply the flow label so a manual removal doesn't - # strand the PR without its lane indicator. - if [ -n "${{ steps.target.outputs.flow_label }}" ]; then - gh pr edit "$PR_NUMBER" \ - --repo "$GITHUB_REPOSITORY" \ - --add-label "${{ steps.target.outputs.flow_label }}" || true - fi - # Apply `type: feature` when the range implements a feature. - if [ "${{ steps.feat.outputs.has_feature }}" = "true" ]; then - gh pr edit "$PR_NUMBER" \ - --repo "$GITHUB_REPOSITORY" \ - --add-label "type: feature" || true - fi - echo "::notice::Refreshed PR #${PR_NUMBER} body" - { - echo "### πŸ”€ Refreshed PR body" - echo "" - echo "PR #${PR_NUMBER}" - } >> "$GITHUB_STEP_SUMMARY" + 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 }} diff --git a/.github/workflows/hotfix-redirector.yml b/.github/workflows/hotfix-redirector.yml index 79383d5..830cad6 100644 --- a/.github/workflows/hotfix-redirector.yml +++ b/.github/workflows/hotfix-redirector.yml @@ -1,6 +1,6 @@ # -# @Project: @cldmv/git-embedded -# @Filename: /.github/workflows/hotfix-redirector.yml +# @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 # @Email: @@ -13,55 +13,39 @@ # # 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 the PR body references a GHSA security -# advisory (Dependabot's security-update PRs flow into the hotfix lane; -# routine version bumps stay on `next`). +# 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". # -# The redirect-hotfix-pr action owns all detection logic β€” it skips non-matching -# bot PRs, non-matching heads, and PRs already on `hotfixes`, and posts a -# one-time explanatory comment with the appropriate reason. +# 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. SAFE here because it is API-only β€” the -# redirect-hotfix-pr action never checks out or executes PR content. -# DO NOT add a checkout step. +# 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. +# `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] -permissions: - contents: read - pull-requests: write - concurrency: group: hotfix-redirector-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: redirect: - name: "πŸ”€ Redirect to hotfixes" - runs-on: ubuntu-latest - steps: - - name: Create App 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: Redirect hotfix/security PR to hotfixes - uses: CLDMV/.github/.github/actions/github/steps/redirect-hotfix-pr@v4 - with: - pr-number: ${{ github.event.pull_request.number }} - github-token: ${{ steps.app-token.outputs.token }} - head-ref: ${{ github.event.pull_request.head.ref }} - base-ref: ${{ github.event.pull_request.base.ref }} - user-type: ${{ github.event.pull_request.user.type }} - target-base: hotfixes + 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 }} diff --git a/.github/workflows/hotfixes-release.yml b/.github/workflows/hotfixes-release.yml index d7cfeea..a228e45 100644 --- a/.github/workflows/hotfixes-release.yml +++ b/.github/workflows/hotfixes-release.yml @@ -1,6 +1,6 @@ # -# @Project: @cldmv/git-embedded -# @Filename: /.github/workflows/hotfixes-release.yml +# @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 # @Email: @@ -12,153 +12,44 @@ # 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. Patches -# the current release independently of whatever is pending on `next`. +# (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. # -# Same model as the next lane: the version bump rides on `hotfixes` as a -# `chore: bump version` commit, carried to master through the squash (Β§8.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` / `build_command` to match your package (same values +# as your next-release.yml). name: πŸš‘ Hotfixes Release (v4) on: push: branches: [hotfixes] - -permissions: - contents: write - pull-requests: write + 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: - plan: - # Loop guard: skip the bot's own chore-bump pushes and reset pushes. - # Replace `cldmv-bot[bot]` with your bot App's login if different. - if: | - github.actor != 'cldmv-bot[bot]' && - github.actor != 'github-actions[bot]' && - !startsWith(github.event.head_commit.message, 'chore: bump version') - name: "πŸ” Plan (detect changes + resolve PR)" - runs-on: ubuntu-latest - outputs: - has-changes: ${{ steps.detect.outputs.has-changes }} - pr-number: ${{ steps.resolve.outputs.pr-number }} - steps: - - name: Create App 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: Checkout hotfixes - uses: CLDMV/.github/.github/actions/common/steps/checkout-code@v4 - with: - ref: hotfixes - fetch-depth: 0 - - - name: Detect master..hotfixes changes - id: detect - shell: bash - run: | - git fetch origin master --quiet - count=$(git rev-list --count origin/master..HEAD) - echo "πŸ“Š commits on hotfixes not yet on master: $count" - if [ "$count" -gt 0 ]; then - echo "has-changes=true" >> "$GITHUB_OUTPUT" - else - echo "has-changes=false" >> "$GITHUB_OUTPUT" - echo "ℹ️ hotfixes is in sync with master β€” nothing to release." - fi - - - name: Resolve persistent hotfixesβ†’master PR - id: resolve - if: steps.detect.outputs.has-changes == 'true' - shell: bash - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - pr=$(gh pr list --repo "$GITHUB_REPOSITORY" --head hotfixes --base master \ - --state open --json number --jq '.[0].number // ""') - echo "pr-number=$pr" >> "$GITHUB_OUTPUT" - if [ -n "$pr" ]; then - echo "πŸ” existing hotfix release PR: #$pr β€” will refresh" - else - echo "πŸ†• no hotfix release PR yet β€” will create" - fi - - create: - name: "πŸ†• Create hotfix release PR" - needs: plan - if: needs.plan.outputs.has-changes == 'true' && needs.plan.outputs.pr-number == '' - runs-on: ubuntu-latest - steps: - - name: Create App 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 }} - - # Customize `package-name` + `build-command` to match this repo β€” - # see notes in next-release.yml. - - name: Create release PR - uses: CLDMV/.github/.github/actions/github/jobs/create-release-pr@v4 - with: - package-name: "@cldmv/git-embedded" - build-command: "echo 'βœ“ no build step'" - github-token: ${{ steps.app-token.outputs.token }} - - refresh: - name: "πŸ” Refresh hotfix release PR #${{ needs.plan.outputs.pr-number }}" - needs: plan - if: needs.plan.outputs.has-changes == 'true' && needs.plan.outputs.pr-number != '' - runs-on: ubuntu-latest - steps: - - name: Create App 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: Refresh release PR - id: refresh - uses: CLDMV/.github/.github/actions/github/jobs/update-release-pr@v4 - with: - head-ref: hotfixes - pr-number: ${{ needs.plan.outputs.pr-number }} - package-name: "@cldmv/git-embedded" - build-command: "echo 'βœ“ no build step'" - github-token: ${{ steps.app-token.outputs.token }} - - # Optional: release-PR notifier. See next-release.yml for the - # rationale. Delete the step to opt out entirely; leave a webhook - # secret unset to opt out of that one channel. - - name: Notify on release-PR version bump - if: steps.refresh.outputs.version-changed == 'true' - uses: CLDMV/.github/.github/actions/community/jobs/release-notifier@v4 - with: - event_kind: release_pr - pr_number: ${{ needs.plan.outputs.pr-number }} - version: ${{ steps.refresh.outputs.new-version }} - github_token: ${{ steps.app-token.outputs.token }} - env: - 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 }} + release: + permissions: + contents: write + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-hotfixes-release.yml@v4 + with: + package_name: "@cldmv/git-embedded" + build_command: "echo 'βœ“ no build step'" + 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 }} diff --git a/.github/workflows/next-release.yml b/.github/workflows/next-release.yml index bf0c701..5d4a9f8 100644 --- a/.github/workflows/next-release.yml +++ b/.github/workflows/next-release.yml @@ -1,6 +1,6 @@ # -# @Project: @cldmv/git-embedded -# @Filename: /.github/workflows/next-release.yml +# @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 # @Email: @@ -17,19 +17,19 @@ # 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). # -# The version bump rides on `next` as a `chore: bump version` commit pushed -# by the release-PR machinery; it's carried to master through the squash -# (Β§8.1 β€” master accepts changes only via PR squash, and the publish flow -# reads package.json as-is). +# 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] - -permissions: - contents: write - pull-requests: write + 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. @@ -38,141 +38,24 @@ concurrency: cancel-in-progress: false jobs: - plan: - # Loop guard: the refresh/create steps push a `chore: bump version` - # commit to `next` (as the bot), and next-reset.yml force-pushes - # `next` (as the bot). Neither should re-trigger a release-PR refresh. - # Replace `cldmv-bot[bot]` with your bot App's login if different. - if: | - github.actor != 'cldmv-bot[bot]' && - github.actor != 'github-actions[bot]' && - !startsWith(github.event.head_commit.message, 'chore: bump version') - name: "πŸ” Plan (detect changes + resolve PR)" - runs-on: ubuntu-latest - outputs: - has-changes: ${{ steps.detect.outputs.has-changes }} - pr-number: ${{ steps.resolve.outputs.pr-number }} - steps: - - name: Create App 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: Checkout next - uses: CLDMV/.github/.github/actions/common/steps/checkout-code@v4 - with: - ref: next - fetch-depth: 0 - - - name: Detect master..next changes - id: detect - shell: bash - run: | - git fetch origin master --quiet - count=$(git rev-list --count origin/master..HEAD) - echo "πŸ“Š commits on next not yet on master: $count" - if [ "$count" -gt 0 ]; then - echo "has-changes=true" >> "$GITHUB_OUTPUT" - else - echo "has-changes=false" >> "$GITHUB_OUTPUT" - echo "ℹ️ next is in sync with master β€” nothing to release." - fi - - - name: Resolve persistent nextβ†’master PR - id: resolve - if: steps.detect.outputs.has-changes == 'true' - shell: bash - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - # The persistent release PR is the open PR with head=next, - # base=master. There is at most one (concurrency-serialized). - pr=$(gh pr list --repo "$GITHUB_REPOSITORY" --head next --base master \ - --state open --json number --jq '.[0].number // ""') - echo "pr-number=$pr" >> "$GITHUB_OUTPUT" - if [ -n "$pr" ]; then - echo "πŸ” existing release PR: #$pr β€” will refresh" - else - echo "πŸ†• no release PR yet β€” will create" - fi - - create: - name: "πŸ†• Create release PR" - needs: plan - if: needs.plan.outputs.has-changes == 'true' && needs.plan.outputs.pr-number == '' - runs-on: ubuntu-latest - steps: - - name: Create App 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 }} - - # Runs on the `next` ref β†’ create-release-pr opens next β†’ master and - # pushes the chore-bump commit to next. 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 - - name: Create release PR - uses: CLDMV/.github/.github/actions/github/jobs/create-release-pr@v4 - with: - package-name: "@cldmv/git-embedded" - build-command: "echo 'βœ“ no build step'" - github-token: ${{ steps.app-token.outputs.token }} - - refresh: - name: "πŸ” Refresh release PR #${{ needs.plan.outputs.pr-number }}" - needs: plan - if: needs.plan.outputs.has-changes == 'true' && needs.plan.outputs.pr-number != '' - runs-on: ubuntu-latest - steps: - - name: Create App 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: Refresh release PR - id: refresh - uses: CLDMV/.github/.github/actions/github/jobs/update-release-pr@v4 - with: - head-ref: next - pr-number: ${{ needs.plan.outputs.pr-number }} - package-name: "@cldmv/git-embedded" - build-command: "echo 'βœ“ no build step'" - github-token: ${{ steps.app-token.outputs.token }} - - # Optional: release-PR notifier. Fires only when the target - # version actually changes (PR open or version-bump shift), not - # on the changelog-only refreshes that run on every push. Each - # secret is independently opt-in: leave a webhook unset and that - # channel is silently skipped. Delete this step to opt out - # entirely. - - name: Notify on release-PR version bump - if: steps.refresh.outputs.version-changed == 'true' - uses: CLDMV/.github/.github/actions/community/jobs/release-notifier@v4 - with: - event_kind: release_pr - pr_number: ${{ needs.plan.outputs.pr-number }} - version: ${{ steps.refresh.outputs.new-version }} - github_token: ${{ steps.app-token.outputs.token }} - env: - 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 }} + release: + permissions: + contents: write + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-next-release.yml@v4 + with: + package_name: "@cldmv/git-embedded" + build_command: "echo 'βœ“ no build step'" + 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 }} diff --git a/.github/workflows/next-reset.yml b/.github/workflows/next-reset.yml index f19a665..87ba088 100644 --- a/.github/workflows/next-reset.yml +++ b/.github/workflows/next-reset.yml @@ -1,6 +1,6 @@ # -# @Project: @cldmv/git-embedded -# @Filename: /.github/workflows/next-reset.yml +# @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 # @Email: @@ -16,184 +16,28 @@ # - `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). The merge is a no-op (204) when next has no extra work. +# * hotfix release (hotfixes β†’ master): MERGE master into `next` instead, +# so next's accumulated feature work is preserved (Β§7.2, option B). # -# The released lane is detected from the PR head ref behind the squash -# commit's trailing "(#N)". -# -# wait-for-tags gate: a release also fires update-major-version-tags, which -# rolls the major tags. Jobs resolve `uses: ...@vN` at job start, so without -# this gate the sync job can run the PREVIOUS release's action code. The gate -# polls the RELEASED major's tag β€” parsed from the `release: vX.Y.Z` commit -# β€” until it matches the release commit. -# -# Self-healing: no-ops pre-cutover (neither integration branch exists), but -# post-cutover it RECREATES a branch that went missing β€” e.g. branch-retention -# deleting `next` as a merged PR head. force-reset-branch creates the ref -# when it's absent. +# 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] -permissions: - contents: write - concurrency: group: next-reset-${{ github.repository }} cancel-in-progress: false jobs: - wait-for-tags: - # Only fire on a release commit (the squash-merge of a release PR). - if: startsWith(github.event.head_commit.message, 'release:') - name: "⏳ Wait for the released major tag to roll forward" - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Poll the released major tag until it matches the release commit - shell: bash - env: - TARGET_SHA: ${{ github.sha }} - REPO: ${{ github.repository }} - COMMIT_MSG: ${{ github.event.head_commit.message }} - run: | - echo "πŸ” Release commit: $TARGET_SHA" - # Parse the released MAJOR from the `release: vX.Y.Z` subject - # and poll THAT tag (e.g. @v4 for v4.x). update-major-version- - # tags rolls @v to the release commit; a hardcoded @v3 - # would never match on a major bump (which creates @v4). - major=$(printf '%s' "$COMMIT_MSG" | grep -oiE 'release:[^0-9]*v?[0-9]+' | grep -oE '[0-9]+$' | head -1) - if [ -z "$major" ]; then - echo "⚠️ Could not parse a major version from the commit subject β€” skipping the gate." - exit 0 - fi - tag="v${major}" - echo "⏳ Gating on @${tag}…" - max_attempts=24 # 24 * 5s = 120s - for attempt in $(seq 1 $max_attempts); do - sha=$(git ls-remote "https://github.com/${REPO}.git" "refs/tags/${tag}^{}" 2>/dev/null | awk '{print $1}') - [ -z "$sha" ] && sha=$(git ls-remote "https://github.com/${REPO}.git" "refs/tags/${tag}" 2>/dev/null | awk '{print $1}') - echo "Attempt $attempt/$max_attempts: @${tag} β†’ ${sha:-}" - if [ "$sha" = "$TARGET_SHA" ]; then - echo "βœ… @${tag} matches the release commit β€” safe to proceed" - exit 0 - fi - [ "$attempt" -lt "$max_attempts" ] && sleep 5 - done - echo "⚠️ Timed out waiting for @${tag} β€” proceeding anyway." - - sync-branches: - name: "♻️ Sync next + hotfixes to master" - needs: wait-for-tags - if: startsWith(github.event.head_commit.message, 'release:') - runs-on: ubuntu-latest - steps: - - name: Create App 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 }} - # Pushing/merging master's tree (which includes - # .github/workflows/**) requires contents + workflows write. - permission_contents: "true" - permission_workflows: "true" - env: - BOT_APP_CLIENT_ID: ${{ secrets.CLDMV_BOT_APP_CLIENT_ID }} - BOT_APP_PRIVATE_KEY: ${{ secrets.CLDMV_BOT_APP_PRIVATE_KEY }} - - - name: Checkout master - uses: CLDMV/.github/.github/actions/common/steps/checkout-code@v4 - with: - fetch-depth: 0 - - - name: Determine released lane - id: lane - shell: bash - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - COMMIT_MSG: ${{ github.event.head_commit.message }} - run: | - # The squash commit ends with "(#N)" β€” the merged PR number. - prnum=$(printf '%s' "$COMMIT_MSG" | grep -oE '#[0-9]+' | tail -1 | tr -d '#') - head="" - if [ -n "$prnum" ]; then - head=$(gh pr view "$prnum" --repo "$GITHUB_REPOSITORY" \ - --json headRefName --jq '.headRefName' 2>/dev/null || echo "") - fi - echo "released PR #${prnum:-?} head ref: ${head:-}" - if [ "$head" = "hotfixes" ]; then - echo "lane=hotfix" >> "$GITHUB_OUTPUT" - else - echo "lane=other" >> "$GITHUB_OUTPUT" - fi - - - name: Guard β€” is this repo on v4? (do next/hotfixes exist?) - id: guard - shell: bash - run: | - next_exists=false; hotfixes_exists=false - if git ls-remote --exit-code --heads origin next >/dev/null 2>&1; then - next_exists=true - git fetch origin next:refs/remotes/origin/next --quiet || true - fi - if git ls-remote --exit-code --heads origin hotfixes >/dev/null 2>&1; then - hotfixes_exists=true - git fetch origin hotfixes:refs/remotes/origin/hotfixes --quiet || true - fi - # "v4 adopted" = at least one integration branch exists. Keeps - # the reset a no-op on pre-cutover repos (neither exists) while - # letting it RECREATE a branch that went missing post-cutover - # (e.g. one was deleted as a merged PR head). force-reset-branch - # creates if absent. - v4_adopted=false - { [ "$next_exists" = true ] || [ "$hotfixes_exists" = true ]; } && v4_adopted=true - { - echo "next-exists=$next_exists" - echo "hotfixes-exists=$hotfixes_exists" - echo "v4-adopted=$v4_adopted" - } >> "$GITHUB_OUTPUT" - echo "ℹ️ next=$next_exists hotfixes=$hotfixes_exists v4-adopted=$v4_adopted lane=${{ steps.lane.outputs.lane }}" - - # hotfixes always tracks master after a release β€” created if missing. - - name: Ensure hotfixes = master HEAD (reset; create if missing) - if: steps.guard.outputs.v4-adopted == 'true' - uses: CLDMV/.github/.github/actions/git/steps/force-reset-branch@v4 - with: - target-branch: hotfixes - source-ref: master - github-token: ${{ steps.app-token.outputs.token }} - - # Normal release β†’ next is force-reset (its work just shipped), and - # recreated if it was deleted on merge. - - name: Ensure next = master HEAD (normal release; create if missing) - if: steps.guard.outputs.v4-adopted == 'true' && steps.lane.outputs.lane != 'hotfix' - uses: CLDMV/.github/.github/actions/git/steps/force-reset-branch@v4 - with: - target-branch: next - source-ref: master - github-token: ${{ steps.app-token.outputs.token }} - - # Hotfix release + next still exists β†’ merge master into next to - # preserve its accumulated feature work (Β§7.2 option B). - - name: Merge master into next (hotfix release; next exists) - if: steps.guard.outputs.v4-adopted == 'true' && steps.lane.outputs.lane == 'hotfix' && steps.guard.outputs.next-exists == 'true' - uses: CLDMV/.github/.github/actions/github/steps/merge-master-into-branch@v4 - with: - target-branch: next - source-ref: master - github-token: ${{ steps.app-token.outputs.token }} - - # Hotfix release but next is MISSING (deleted) β†’ recreate it at master - # HEAD; there's no accumulated work to preserve. - - name: Recreate next at master HEAD (hotfix release; next missing) - if: steps.guard.outputs.v4-adopted == 'true' && steps.lane.outputs.lane == 'hotfix' && steps.guard.outputs.next-exists == 'false' - uses: CLDMV/.github/.github/actions/git/steps/force-reset-branch@v4 - with: - target-branch: next - source-ref: master - github-token: ${{ steps.app-token.outputs.token }} + 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 }} diff --git a/.github/workflows/pr-title-normalizer.yml b/.github/workflows/pr-title-normalizer.yml index f7dd668..adba973 100644 --- a/.github/workflows/pr-title-normalizer.yml +++ b/.github/workflows/pr-title-normalizer.yml @@ -1,6 +1,6 @@ # -# @Project: @cldmv/git-embedded -# @Filename: /.github/workflows/pr-title-normalizer.yml +# @Project: @cldmv/.github +# @Filename: /examples/individual-repo-workflows/release-flow-v4/pr-title-normalizer.yml # @Date: 2026-05-22 00:00:00 -07:00 (1779778800) # @Author: Nate Corcoran # @Email: @@ -9,56 +9,37 @@ # Individual repo: .github/workflows/pr-title-normalizer.yml # -# Normalize contributor PR titles to Conventional Commits format, derived -# from the highest-priority commit in the PR. The release flow expects this -# shape, so a v4 repo wants this enabled. (Also backportable to v3 repos β€” -# it wires the normalize-pr-title action, shipped in v3.3.0; the action owns -# all skip logic: bot authors, the long-running release PRs, titles already -# starting with `release:`, and titles that already conform.) +# Normalize contributor PR titles to Conventional Commits format, derived from +# the highest-priority commit in the PR. The release flow expects this shape, so +# a v4 repo wants this enabled. (Also backportable to v3 repos β€” the underlying +# action shipped in v3.3.0; it owns all skip logic: bot authors, the +# long-running release PRs, titles already starting with `release:`, and titles +# that already conform.) +# +# Thin caller: all job logic lives in the reusable, pinned at @v4. Bumping the +# pin carries fixes without editing this file. name: 🏷️ PR Title Normalizer -# SECURITY NOTE: pull_request_target runs in the BASE repo's context with -# WRITE permissions and access to secrets. SAFE for THIS workflow because it -# is API-only β€” the normalize-pr-title action never checks out the PR head -# and never executes PR content. DO NOT add a checkout step. -# -# Triggers on opened + synchronize only (NOT edited): a maintainer hand- -# editing the title must not kick off a re-normalize loop. +# SECURITY NOTE: pull_request_target runs in the BASE repo's context with WRITE +# permissions and access to secrets. SAFE β€” the reusable's path is API-only (it +# never checks out or executes PR content). Triggers on opened + synchronize +# only (NOT edited): a maintainer hand-editing the title must not kick off a +# re-normalize loop. on: pull_request_target: types: [opened, synchronize] -permissions: - contents: read - pull-requests: write - -# Collapse a burst of pushes to one normalize run per PR; the newest push -# carries the authoritative commit set, so cancelling an in-flight run is fine. concurrency: group: pr-title-normalizer-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: normalize: - name: "✏️ Normalize title" - runs-on: ubuntu-latest - steps: - - 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: Normalize PR title - uses: CLDMV/.github/.github/actions/github/steps/normalize-pr-title@v4 - with: - pr-number: ${{ github.event.pull_request.number }} - github-token: ${{ steps.app-token.outputs.token }} - base-ref: ${{ github.event.pull_request.base.ref }} - head-ref: ${{ github.event.pull_request.head.ref }} - user-type: ${{ github.event.pull_request.user.type }} - user-login: ${{ github.event.pull_request.user.login }} + permissions: + contents: read + pull-requests: write + uses: CLDMV/.github/.github/workflows/workflow-pr-title-normalizer.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 }} From 77c28b8521178856df52d7408355506e9c9317e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:46:06 +0000 Subject: [PATCH 07/12] deps: bump eslint from 9.39.4 to 10.8.0 Bumps [eslint](https://github.com/eslint/eslint) from 9.39.4 to 10.8.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v9.39.4...v10.8.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.7.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 347 +++++++++++----------------------------------- package.json | 2 +- 2 files changed, 82 insertions(+), 267 deletions(-) diff --git a/package-lock.json b/package-lock.json index 123a92a..4c66eac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@eslint/json": "^2.0.1", "@eslint/markdown": "^6.2.2", "@vitest/coverage-v8": "^4.1.10", - "eslint": "^9.18.0", + "eslint": "^10.8.0", "globals": "^17.7.0", "prettier": "^3.4.2", "vitest": "^4.1.10" @@ -256,44 +256,31 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.7", + "@eslint/object-schema": "^3.0.5", "debug": "^4.3.1", - "minimatch": "^3.1.5" + "minimatch": "^10.2.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", + "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers/node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" + "@eslint/core": "^1.2.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/core": { @@ -309,43 +296,6 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.14.0", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.5", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { "version": "9.39.4", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", @@ -439,13 +389,13 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/plugin-kit": { @@ -934,6 +884,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -1117,9 +1074,9 @@ } }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, "license": "MIT", "bin": { @@ -1204,13 +1161,6 @@ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "license": "MIT" }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -1234,31 +1184,26 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/brace-expansion": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "dev": true, "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, "engines": { - "node": ">=6" + "node": "20 || >=22" } }, "node_modules/ccount": { @@ -1404,13 +1349,6 @@ "node": ">=20" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -1560,33 +1498,33 @@ } }, "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "version": "10.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.8.0.tgz", + "integrity": "sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==", "dev": true, "license": "MIT", + "workspaces": [ + "packages/*" + ], "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.2", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", - "@eslint/plugin-kit": "^0.4.1", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.7.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", - "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -1596,8 +1534,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.5", + "minimatch": "^10.2.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -1605,7 +1542,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" @@ -1620,92 +1557,50 @@ } }, "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/eslint/node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.15.0", + "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "eslint-visitor-keys": "^5.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -1982,23 +1877,6 @@ "node": ">= 4" } }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2094,29 +1972,6 @@ "dev": true, "license": "MIT" }, - "node_modules/js-yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", - "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -2451,13 +2306,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -3405,16 +3253,19 @@ "license": "MIT" }, "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "*" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ms": { @@ -3549,19 +3400,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -3704,16 +3542,6 @@ "node": ">=0.10.0" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/rolldown": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", @@ -3882,19 +3710,6 @@ "node": ">=8" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 5bed67d..473984e 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "@eslint/json": "^2.0.1", "@eslint/markdown": "^6.2.2", "@vitest/coverage-v8": "^4.1.10", - "eslint": "^9.18.0", + "eslint": "^10.8.0", "globals": "^17.7.0", "prettier": "^3.4.2", "vitest": "^4.1.10" From 948f46da0cde73ca5856853cf7181eaee89e3a98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:46:10 +0000 Subject: [PATCH 08/12] deps: bump @eslint/markdown from 6.6.0 to 8.0.3 Bumps [@eslint/markdown](https://github.com/eslint/markdown) from 6.6.0 to 8.0.3. - [Release notes](https://github.com/eslint/markdown/releases) - [Changelog](https://github.com/eslint/markdown/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/markdown/compare/v6.6.0...v8.0.3) --- updated-dependencies: - dependency-name: "@eslint/markdown" dependency-version: 8.0.3 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 160 ++++++++++++++++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 112 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 123a92a..f02f99a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "@cldmv/vitest-runner": "^1.2.0", "@eslint/js": "^9.18.0", "@eslint/json": "^2.0.1", - "@eslint/markdown": "^6.2.2", + "@eslint/markdown": "^8.0.3", "@vitest/coverage-v8": "^4.1.10", "eslint": "^9.18.0", "globals": "^17.7.0", @@ -376,66 +376,29 @@ } }, "node_modules/@eslint/markdown": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-6.6.0.tgz", - "integrity": "sha512-IsWPy2jU3gaQDlioDC4sT4I4kG1hX1OMWs/q2sWwJrPoMASHW/Z4SDw+6Aql6EsHejGbagYuJbFq9Zvx+Y1b1Q==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-8.0.3.tgz", + "integrity": "sha512-rBTSSShrq7e4O+PWfeE4azH4/CWPNrC+VGxBXiW00o3vYVJnznsZiDayj3KC9JztIMVRZxZHn2nrDIUau/4j7A==", "dev": true, "license": "MIT", "workspaces": [ "examples/*" ], "dependencies": { - "@eslint/core": "^0.14.0", - "@eslint/plugin-kit": "^0.3.1", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", "github-slugger": "^2.0.0", "mdast-util-from-markdown": "^2.0.2", "mdast-util-frontmatter": "^2.0.1", - "mdast-util-gfm": "^3.0.0", + "mdast-util-gfm": "^3.1.0", + "mdast-util-math": "^3.0.0", "micromark-extension-frontmatter": "^2.0.0", - "micromark-extension-gfm": "^3.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/markdown/node_modules/@eslint/core": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", - "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/markdown/node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.15.2", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/markdown/node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" + "micromark-extension-gfm": "^3.0.0", + "micromark-extension-math": "^3.1.0", + "micromark-util-normalize-identifier": "^2.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/object-schema": { @@ -941,6 +904,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -948,6 +921,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -2138,6 +2118,33 @@ "dev": true, "license": "MIT" }, + "node_modules/katex": { + "version": "0.16.47", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -2745,6 +2752,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", @@ -3012,6 +3039,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -4032,6 +4079,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", diff --git a/package.json b/package.json index 5bed67d..5079639 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "@cldmv/vitest-runner": "^1.2.0", "@eslint/js": "^9.18.0", "@eslint/json": "^2.0.1", - "@eslint/markdown": "^6.2.2", + "@eslint/markdown": "^8.0.3", "@vitest/coverage-v8": "^4.1.10", "eslint": "^9.18.0", "globals": "^17.7.0", From 266ebdf33bd54b28435c05c7584b8350cd1209b2 Mon Sep 17 00:00:00 2001 From: Shinrai Date: Wed, 29 Jul 2026 20:54:09 -0700 Subject: [PATCH 09/12] ci: add no-op build script so the coverage-badge leg passes --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e1b177a..dddc35b 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,8 @@ "lint": "eslint --config .configs/eslint.config.mjs .", "lint:fix": "eslint --config .configs/eslint.config.mjs . --fix", "format": "prettier --config .configs/.prettierrc --write .", - "format:check": "prettier --config .configs/.prettierrc --check ." + "format:check": "prettier --config .configs/.prettierrc --check .", + "build": "echo 'no build step - stopgap for CI coverage-badge; see tracking issue'" }, "dependencies": { "@cldmv/slothlet": "^3.7.0", From b6f93fbe7e8c2b66215177d8144f1f811e89230c Mon Sep 17 00:00:00 2001 From: Shinrai Date: Thu, 30 Jul 2026 20:52:36 -0700 Subject: [PATCH 10/12] deps: drop Node 20, bump chalk to 6 and commander to 15 Node 20 reached EOL in April 2026. chalk 6 requires Node >=22 and commander 15 requires Node >=22.12.0, so this drops Node 20 support and updates engines.node accordingly. API usage of both packages is unchanged: chalk's .bold/.yellow/.magenta etc. are untouched; commander's lone --no-symlinks option is unaffected by the v15 --no-* default-handling fix (only paired options change). CI and publish matrices updated to min_node_version: 22 to match. --- .github/workflows/ci.yml | 12 +++++----- .github/workflows/publish.yml | 4 ++-- package-lock.json | 45 +++++++++++++++++++++++++++-------- package.json | 6 ++--- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 49dad7c..c1c49eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,10 +54,10 @@ on: required: false default: "lts/*" min_node_version: - description: "Minimum Node.js version for matrix testing (default: 20, oldest non-EOL)" + description: "Minimum Node.js version for matrix testing (default: 22, oldest non-EOL LTS)" type: string required: false - default: "20" + default: "22" max_node_major: description: "Override max Node.js major version (default: 22)" type: string @@ -184,12 +184,12 @@ jobs: .gitignore debug: ${{ github.event.inputs.debug == 'true' }} node_version: ${{ github.event.inputs.node_version || 'lts/*' }} - min_node_version: ${{ github.event.inputs.min_node_version || '20' }} + min_node_version: ${{ github.event.inputs.min_node_version || '22' }} max_node_major: ${{ github.event.inputs.max_node_major || '22' }} - # LTS-only matrix (even majors: 20, 22, 24, …) on every event. Odd majors - # (21, 23, …) are non-LTS interim releases, and the native-binding test + # LTS-only matrix (even majors: 22, 24, …) on every event. Odd majors + # (23, 25, …) are non-LTS interim releases, and the native-binding test # toolchain (vitest 4 / rolldown / vite 8) excludes them via `engines` - # (`^20.19.0 || >=22.12.0`), so a "full matrix" on them only re-discovers a + # (`>=22.12.0`), so a "full matrix" on them only re-discovers a # known toolchain gap ("Cannot find native binding") rather than a real # per-version regression. workflow_dispatch can still opt out (set false). lts_only_matrix: ${{ github.event.inputs.lts_only_matrix != 'false' }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9914a0b..814b87a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -63,7 +63,7 @@ on: description: "Minimum Node.js version for matrix testing (enables matrix when set)" type: string required: false - default: "20" + default: "22" max_node_major: description: "Override max Node.js major version (default: 22)" type: string @@ -101,7 +101,7 @@ jobs: publish_to_github_packages: ${{ github.event.inputs.publish_to_github_packages != 'false' }} publish_command: "" github_packages_publish_command: "" - min_node_version: ${{ github.event.inputs.min_node_version || '20' }} + min_node_version: ${{ github.event.inputs.min_node_version || '22' }} max_node_major: ${{ github.event.inputs.max_node_major || '22' }} test_command: "npm test" # Use defaults: NODE_ENV=development, NODE_OPTIONS=--conditions=development # test_command: "NODE_OPTIONS='--conditions=slothlet-dev' npm test" # Override NODE_OPTIONS only diff --git a/package-lock.json b/package-lock.json index 7523e73..c232830 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "dependencies": { "@cldmv/slothlet": "^3.7.0", "@cldmv/wisp": "^1.0.1", - "chalk": "^5.4.1", - "commander": "^14.0.0", + "chalk": "^6.0.0", + "commander": "^15.0.0", "marked": "^15.0.12", "marked-terminal": "^7.3.0" }, @@ -156,6 +156,19 @@ "vitest": ">=1.0.0" } }, + "node_modules/@cldmv/vitest-runner/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/@cldmv/wisp": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@cldmv/wisp/-/wisp-1.0.1.tgz", @@ -1208,12 +1221,12 @@ } }, "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.0.tgz", + "integrity": "sha512-2uNTXIuTTxk7ciZgAU1BQcgnchcG0xXnrs6jzkQfj9SsRa9M2s5zE8WT96hS6KmG4MzWHSrvH43DF1m4XRkrFg==", "license": "MIT", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=22" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" @@ -1321,12 +1334,12 @@ "license": "MIT" }, "node_modules/commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.12.0" } }, "node_modules/convert-source-map": { @@ -2406,6 +2419,18 @@ "marked": ">=1 <16" } }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/mdast-util-find-and-replace": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", diff --git a/package.json b/package.json index dddc35b..43a0b09 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "module", "license": "Apache-2.0", "engines": { - "node": ">=20.19.0" + "node": ">=22.12.0" }, "author": { "name": "Shinrai", @@ -81,8 +81,8 @@ "dependencies": { "@cldmv/slothlet": "^3.7.0", "@cldmv/wisp": "^1.0.1", - "chalk": "^5.4.1", - "commander": "^14.0.0", + "chalk": "^6.0.0", + "commander": "^15.0.0", "marked": "^15.0.12", "marked-terminal": "^7.3.0" }, From fb27adf8635a089e43d4f45b71701b1ab3a96999 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 05:59:21 +0000 Subject: [PATCH 11/12] deps: bump globals in the minor group across 1 directory Bumps the minor group with 1 update in the / directory: [globals](https://github.com/sindresorhus/globals). Updates `globals` from 17.7.0 to 17.8.0 - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v17.7.0...v17.8.0) --- updated-dependencies: - dependency-name: globals dependency-version: 17.8.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7523e73..ddba15e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1810,9 +1810,9 @@ } }, "node_modules/globals": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", - "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", + "version": "17.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.8.0.tgz", + "integrity": "sha512-Zz/LMDZScFmkakeL2cTHzf+PbWKdpU3uclqkZT7TjDG58j5WPt0PpA+n9uPI24fZtlw07q0OtEi84K+umsRzqQ==", "dev": true, "license": "MIT", "engines": { From a67338fec222f9ba03fe0c7c9408bbc9dc5c87cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 05:59:43 +0000 Subject: [PATCH 12/12] deps: bump @cldmv/slothlet in the patch group across 1 directory Bumps the patch group with 1 update in the / directory: [@cldmv/slothlet](https://github.com/CLDMV/slothlet). Updates `@cldmv/slothlet` from 3.12.1 to 3.12.2 - [Release notes](https://github.com/CLDMV/slothlet/releases) - [Commits](https://github.com/CLDMV/slothlet/compare/@cldmv/slothlet-i18n@3.12.1...@cldmv/slothlet-i18n@3.12.2) --- updated-dependencies: - dependency-name: "@cldmv/slothlet" dependency-version: 3.12.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7523e73..7d47f26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,9 +99,9 @@ } }, "node_modules/@cldmv/slothlet": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@cldmv/slothlet/-/slothlet-3.12.1.tgz", - "integrity": "sha512-JgL2cUrDVCgo2TQdsRXrhE+6G+ML0+Ji87RHrA6+bMFaTXBSpFBdnRAakW9lGx2uzaXM3y7pcIIc2YVJ76jTEQ==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@cldmv/slothlet/-/slothlet-3.12.2.tgz", + "integrity": "sha512-YRYdh5uhY0ynsgcT6nWFOzHyVsFlp8XhFkF52atq6WA/HgHPD/D/cxruSx2eDZUfHL/t2W4uspIINgsfQbatqg==", "license": "Apache-2.0", "bin": { "slothlet": "bin/slothlet.mjs"