Skip to content

ci: install commitlint with pnpm - #90

Merged
martinfrancois merged 2 commits into
mainfrom
chore/migrate-npm-to-pnpm
Sep 21, 2026
Merged

martinfrancois merged 2 commits into
mainfrom
chore/migrate-npm-to-pnpm

Conversation

@martinfrancois

@martinfrancois martinfrancois commented Sep 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Problem: this repository has no package.json and no Node dependencies of its own, yet CI still reached for npm to install commitlint into a scratch directory.
  • Why it matters: it was the last npm usage here, and the owner is standardising on pnpm across his repositories.
  • What changed: the two scripts that install commitlint call pnpm --dir where they called npm --prefix, and the two workflows that run them activate pnpm with corepack after actions/setup-node.
  • What did not change: the pinned commitlint versions, every action SHA, and the README install tables, which document how a consumer installs this skill with their own package runner.

Review follow-up in this PR: a Renovate regex manager for the corepack prepare pnpm@x pin (no manager read it before) and a comment in both workflows on why corepack ties the step to the pinned Node major.

Change Type

Choose all that apply.

  • Skill behavior
  • Evals or scoring
  • Documentation
  • CI, release, or dependency automation
  • Repository metadata or contribution process
  • Other maintenance

Linked Issue

None. This is one repository in a set being moved from npm to pnpm together.

User-Visible Behavior

None for a consumer of the skill. For a contributor, the commitlint check in CI installs through pnpm instead of npm and reports the same failures as before.

Bug Fix Details

N/A. No bug, no regression.

  • Root cause: N/A
  • Test, eval, or guardrail added: N/A
  • If no test or eval was added, why not: the change is a package manager swap in CI. It is exercised by the commitlint job on this pull request, and it was run end to end locally, see below.

Validation

Checks most contributors can run:

  • python3 scripts/validate_skill.py skills/java-streams
  • python3 scripts/validate_eval_criteria.py evals evals-reference evals-regression
  • python3 -m py_compile scripts/*.py
  • bash -n scripts/*.sh
  • tessl plugin lint .
  • Manual rendered-doc or example review, if docs or examples changed

Tessl-authenticated checks:

  • bash scripts/check_publish_dry_run.sh .
  • tessl plugin publish --dry-run --bump patch .
  • tessl review run --workspace martinfrancois --threshold 100 skills/java-streams/SKILL.md, if skill text or references changed
  • Targeted main/reference scripts/run_eval_suite.sh <main|reference> <scenario-name>, if skill behavior or those evals changed
  • Targeted regression scripts/run_eval_suite.sh regression <scenario-name>, if regression evals changed
  • Every substantively changed eval scenario was rerun targeted and reached 100% with context, or the PR explains the Tessl blocker and remaining work
  • Runtime skill/reference changes only: full scripts/run_eval_suite.sh reference was run after the final runtime-context change, or the PR links the blocker issue
  • Runtime skill/reference changes only: full scripts/run_eval_suite.sh regression was run after the final runtime-context change, or the PR links the blocker issue
  • Pure eval suite moves did not change task wording, scoring criteria, or capability text beyond suite-placement metadata/numbering notes
  • scripts/classify_eval_result.py <run-json> --scenario-dir <scenario-dir>, if a scenario was added or moved between suites
  • Full/main scripts/run_eval_suite.sh main, if benchmark claims changed or targeted with-context results are clean

Unchecked and why: no skill text, reference, eval or benchmark claim changed here, so the eval suites, tessl review run and the rendered-doc review have nothing to act on. tessl plugin publish --dry-run --bump patch . is not checked because scripts/check_publish_dry_run.sh runs the dry run with --skip-evals, which is not the same command, and that script is what ran.

Details:

python3 scripts/validate_skill.py skills/java-streams      -> Skill is valid.
python3 scripts/validate_eval_criteria.py ...  -> Validated 29 scenarios, 11 natural and 18 explicit.
python3 -m py_compile scripts/*.py             -> exit 0
bash -n scripts/*.sh                           -> exit 0
tessl plugin lint .                            -> Plugin martinfrancois/java-streams@1.2.0 is valid
bash scripts/check_publish_dry_run.sh .        -> Dry run complete, all pre-publish checks passed

Human Verification

The edited script was run end to end rather than only read, with RUNNER_TEMP and GITHUB_ENV pointed at a scratch directory, exactly as the workflow invokes it:

corepack prepare pnpm@12.4.1 --activate       -> pnpm 12.4.1
scripts/install_commitlint.sh                 -> exit 0
installed commitlint                          -> @commitlint/cli@21.2.2
printf 'feat: add a thing\n' | commitlint     -> exit 0
printf 'nonsense\n' | commitlint              -> exit 1, subject-empty and type-empty

The scratch directory afterwards contains pnpm-lock.yaml and node_modules/.bin/commitlint, so pnpm and not npm performed the install, and --silent and --ignore-scripts both behave on pnpm add.

scripts/commitlint_release_pr.sh was run on a real origin/main..HEAD range: it passes with a valid release title and exits 1 on an invalid one.

The Renovate custom manager that keeps the commitlint pins current was verified by running its matchStrings regex against the file before and after the edit, in Node, rather than by eye. The match sets are identical, so Renovate keeps updating commitlint here.

Both edited workflow files were parsed with a YAML parser and the step order asserted: actions/setup-node, then Enable pnpm, then the step that runs the script. corepack needs Node on PATH, which is why that order is required.

Review Checklist

  • The change is scoped to the sections, skill files, evals, or workflows described above.
  • Validation that applies to this change is checked above, or any unavailable check is explained.
  • If Java stream guidance changed, Java baseline compatibility plus ordering, null handling, and parallelism were considered.
  • If evals or benchmark claims changed, the eval scenarios remain fair and do not leak answer keys, run IDs, or fixed score claims into runtime references.
  • If runtime skill text or references changed, hosted checks were widened from targeted affected scenarios to main/reference/regression as described in docs/agents/workflow.md, or any Tessl blocker is documented.
  • If a runtime skill/reference change was released, the final report includes the published main eval run plus post-change reference and regression run IDs, or a blocker issue for missing broad suites.
  • Main and reference evals were run with both variants when hosted evals were needed; regression evals were run with context only unless reclassification back to reference was being checked.
  • New or moved eval scenarios follow the classifier recommendation, or the PR explains the maintainer-approved override.
  • Every retained eval scenario has a 100% with-context result, or any below-100 result is documented as blocking follow-up rather than classified/reportable coverage.
  • PR title or squash title uses Conventional Commits.
  • Redaction checked: no tokens, private links, private eval artifacts, local host paths, or proprietary Java source.

The eval and skill-text items are ticked because their condition does not arise: this pull request changes two shell scripts and two workflow files and touches no skill text, reference, eval or benchmark claim.

AI Assistance (if used)

  • AI-assisted PR
  • I confirm I understand and reviewed the change

Written with Claude Code. The change was specified, executed and verified by the agent; the second box is a human attestation, so it is left for the maintainer to tick on review.

🤖 Generated with Claude Code

This repository has no package.json and no Node dependencies of its own.
The only npm usage is installing commitlint into a scratch directory
during CI, so that install now runs through pnpm instead.

scripts/install_commitlint.sh and scripts/commitlint_release_pr.sh call
pnpm --dir where they called npm --prefix. The two workflows that run
them, commitlint.yml and release-please.yml, activate pnpm 12.4.1 with
corepack after actions/setup-node, because corepack needs Node on PATH
and the scripts need pnpm. 12.4.1 is older than the seven day
minimumReleaseAge this repository sets for Renovate. The newer pnpm
releases are not.

The pinned commitlint versions stay where they were. This changes the
package manager, not the dependency. The Renovate custom manager that
keeps those pins current matches the package lines, which this change
leaves untouched, and it reports the same versions before and after.
Review of this PR found that corepack prepare pnpm@x is an exact pin no
Renovate manager reads. A third regex manager now tracks it against the
npm registry, and the workflows say why corepack is only good for the
pinned Node major.
@martinfrancois
martinfrancois force-pushed the chore/migrate-npm-to-pnpm branch from d66cdae to 56bd9f4 Compare September 21, 2026 04:28
@martinfrancois
martinfrancois merged commit fce6a16 into main Sep 21, 2026
7 checks passed
@martinfrancois
martinfrancois deleted the chore/migrate-npm-to-pnpm branch September 21, 2026 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant