skills/add-ci/SKILL.md
In a new branch, create a GitHub Actions CI workflow that runs the appropriate test suite and linter(s) for the project (TypeScript, Python, or both)
npx skillsauth add stevenmburns/dot-claude-files add-ciInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Detect the languages and tooling used in this project, create a new branch, then write a GitHub Actions workflow that runs tests and linting.
Search the repo for the following signals. Build a mental model of which apply:
TypeScript / JavaScript:
package.json files (note their locations — could be root or subdirectories like frontend/)scripts.test field in package.json → determines test command (e.g. vitest, jest)scripts.lint field in package.json → determines lint command (e.g. eslint .)vitest.config.* or jest.config.* → confirms test runnereslint.config.*, .eslintrc.*, .eslintrc.js/ts/json → confirms ESLint.prettierrc* → Prettier present.nvmrc, .node-version, or engines.node in package.json; fall back to node --versionPython:
pyproject.toml, setup.py, setup.cfg, requirements*.txt[tool.pytest.ini_options] in pyproject.toml → pytestpytest.ini, conftest.py → pytest[tool.ruff] in pyproject.toml → ruff linter (preferred over flake8).flake8, [flake8] in setup.cfg → flake8[tool.mypy] or mypy.ini → mypy type-checker.python-version or pyproject.toml requires-pythonRead the relevant package.json and config files you find. Do not guess — base every decision on what you actually find.
If package.json is inside a subdirectory (e.g. frontend/), note that path — CI steps will need working-directory.
Run:
git checkout -b ci/add-github-actions
.github/workflows/ci.ymlCreate the directory if needed: mkdir -p .github/workflows
Write a workflow file with these principles:
push: branches: [main] and pull_request: branches: [main] — this ensures exactly one run per event (pushing to a PR branch triggers only pull_request; merging to main triggers only push). Never use bare on: push without a branch filter alongside on: pull_request — it causes duplicate runs.ubuntu-latestlint and test (or combine if minimal tooling)actions/checkout@v4, actions/setup-node@v4, actions/setup-python@v4, actions/cache@v4)20 if unknown)3.12 if unknown)working-directory is needed for npm steps, set it at the job level or step levelTypeScript-only template (adapt as needed):
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: <subdir> # omit if root
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '<version>'
cache: npm
cache-dependency-path: <subdir>/package-lock.json # omit if root
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: <subdir> # omit if root
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '<version>'
cache: npm
cache-dependency-path: <subdir>/package-lock.json # omit if root
- run: npm ci
- run: npm test
Python-only template (adapt as needed):
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '<version>'
- run: pip install ruff # or flake8/mypy
- run: ruff check . # adapt to detected linter
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '<version>'
- run: pip install -e ".[dev]" # adapt to project install method
- run: pytest
Both languages: add both sets of jobs, prefixing job names with ts- and py- (e.g. ts-lint, py-test).
For npm test commands: if scripts.test is just vitest (without run), use npx vitest run --reporter=verbose in the workflow instead — plain vitest starts in watch mode and will hang forever in CI. The --reporter=verbose flag prints each test name inline so CI logs clearly show what ran. Similarly, jest --watch should become jest --ci. Always use the one-shot / CI-safe variant of the test runner.
For other npm scripts (lint, build, etc.) use the actual commands from scripts.
Stage and commit the new file:
git add .github/workflows/ci.yml
git commit -m "ci: add GitHub Actions workflow for lint and tests"
Tell the user:
/create-pr when ready to open a PRtools
Scan open GitHub issues, flag duplicates, and summarize with suggested priorities
testing
Interactively clean up the current branch's commits (squash fixups, reword sloppy messages, reorder, drop) before merging — especially important on repos using rebase-merge where every branch commit lands on main verbatim
tools
Analyze the changes in the current PR and suggest a more accurate title if the current one no longer fits
data-ai
Merge the open PR for the current branch into main, delete the branch, and pull main