Problem
As per https://github.com/holdex/contractor-terms/actions/runs/23833403833, the node_moduldes folder is being created locally when action is triggered.
There's the culprit. When no commitlint config is found (which is the case in this repo), this step runs:
bun i -D @commitlint/config-conventional
-Dis a **local dev dependency**, not a global install — so bun creates anode_modulesin the workspace root. It's doing this to make the@commitlint/config-conventionalpreset resolvable whencommitlintruns. The config file it generates references@commitlint/config-conventionalby name, and commitlint needs to be able torequire()` it, which only works if it's installed locally.
Solution
The fix would be in the action itself — it should use a global install path or pass the config inline to avoid creating node_modules.
The root cause: @commitlint/config-conventional is installed as -D (local dev dependency) but @commitlint/cli is installed with -g (global). They should both be global — commitlint resolves extends packages relative to itself when run globally.
The fix — change the fallback install step from -D to -g:
# current — creates node_modules in workspace
- name: Install commitlint globally if no config
if: github.event_name == 'pull_request' && steps.commitlint-config.outputs.has-config == 'false'
shell: bash
run: |
if [ "${{ inputs.package-manager }}" = "pnpm" ]; then
pnpm add -D @commitlint/config-conventional
elif [ "${{ inputs.package-manager }}" = "npm" ]; then
npm install --save-dev @commitlint/config-conventional
else
bun i -D @commitlint/config-conventional
fi
# proposed — no workspace pollution
- name: Install commitlint globally if no config
if: github.event_name == 'pull_request' && steps.commitlint-config.outputs.has-config == 'false'
shell: bash
run: |
if [ "${{ inputs.package-manager }}" = "pnpm" ]; then
pnpm add -g @commitlint/config-conventional
elif [ "${{ inputs.package-manager }}" = "npm" ]; then
npm install -g @commitlint/config-conventional
else
bun i -g @commitlint/config-conventional
fi
One-line change per package manager: -D/--save-dev → -g. Since @commitlint/cli is already installed globally in the step above, commitlint will resolve the extends preset from the global package store without needing a local node_modules.
Problem
As per https://github.com/holdex/contractor-terms/actions/runs/23833403833, the node_moduldes folder is being created locally when action is triggered.
There's the culprit. When no commitlint config is found (which is the case in this repo), this step runs:
-D
is a **local dev dependency**, not a global install — so bun creates anode_modulesin the workspace root. It's doing this to make the@commitlint/config-conventionalpreset resolvable whencommitlintruns. The config file it generates references@commitlint/config-conventionalby name, and commitlint needs to be able torequire()` it, which only works if it's installed locally.Solution
The fix would be in the action itself — it should use a global install path or pass the config inline to avoid creating
node_modules.The root cause:
@commitlint/config-conventionalis installed as-D(local dev dependency) but@commitlint/cliis installed with-g(global). They should both be global — commitlint resolvesextendspackages relative to itself when run globally.The fix — change the fallback install step from
-Dto-g:One-line change per package manager:
-D/--save-dev→-g. Since@commitlint/cliis already installed globally in the step above, commitlint will resolve theextendspreset from the global package store without needing a localnode_modules.