Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .github/actions/npm-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ inputs:
description: "Node.js version to use"
required: true
workspace:
description: "Workspace to install"
required: true
description: "Workspace to install. Leave empty to install every workspace"
required: false
default: ""

outputs:
workspace_path:
Expand All @@ -24,7 +25,10 @@ runs:
shell: bash
id: set-workspace
run: |
if [ "${{ inputs.workspace }}" = "testcontainers" ]; then
if [ -z "${{ inputs.workspace }}" ]; then
workspace_path=""
cache_paths=$'node_modules\npackages/testcontainers/node_modules\npackages/modules/*/node_modules'
elif [ "${{ inputs.workspace }}" = "testcontainers" ]; then
workspace_path="packages/testcontainers"
cache_paths=$'node_modules\npackages/testcontainers/node_modules'
else
Expand All @@ -51,12 +55,17 @@ runs:
id: npm-cache
with:
path: ${{ steps.set-workspace.outputs.cache_paths }}
key: npm-v2-${{ inputs.runner }}-node-${{ inputs.node-version }}-${{ inputs.workspace }}-${{ hashFiles('package-lock.json') }}
key: npm-v2-${{ inputs.runner }}-node-${{ inputs.node-version }}-${{ inputs.workspace || 'all-workspaces' }}-${{ hashFiles('package-lock.json') }}

- name: Install dependencies
if: steps.npm-cache.outputs.cache-hit != 'true'
shell: bash
run: npm ci --workspace "${WORKSPACE_PATH}" --include-workspace-root
run: |
if [ -n "${WORKSPACE_PATH}" ]; then
npm ci --workspace "${WORKSPACE_PATH}" --include-workspace-root
else
npm ci
fi

- name: Save dependencies cache
if: steps.npm-cache.outputs.cache-hit != 'true'
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,22 @@ jobs:
WORKSPACE_PATH: ${{ steps.npm-install-modules.outputs.workspace_path }}
run: npm run lint:ci

knip:
# Knip analyses every workspace together and reads the manifests of their installed dependencies, so it runs
# once with every workspace installed instead of per module.
name: Knip
runs-on: ubuntu-24.04
steps:
- name: Code checkout
uses: actions/checkout@v7
- name: Install Node and Dependencies
uses: ./.github/actions/npm-setup
with:
runner: ubuntu-24.04
node-version: 24.x
- name: Find unused files, exports and dependencies
run: npm run knip

compile:
if: ${{ needs.detect-modules.outputs.modules_count != '0' }}
name: Compile
Expand Down Expand Up @@ -207,6 +223,7 @@ jobs:
needs:
- detect-modules
- lint
- knip
- compile
- smoke-test
- smoke-test-bun
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ It captures practical rules that prevent avoidable CI and PR churn.

- If a public API changes, update the relevant docs in the same PR.
- If new types are made part of the public API, export them from the package's `index.ts` in the same PR.
- Only what a package's `index.ts` exports is public API. `npm run knip` fails on any other export that no other file uses: drop the `export` keyword, or export it from `index.ts` if consumers need it.
- If new learnings or misunderstandings are discovered, propose an `AGENTS.md` update in the same PR.
- In docs Markdown, keep `<!--codeinclude-->` blocks tight with no blank lines between the markers and the include line, or the rendered snippet will contain blank lines between code lines.
- Tests should verify observable behavior changes, not only internal/config state.
Expand Down Expand Up @@ -86,7 +87,7 @@ reviewers can follow the reasoning.
1. Start from `main`.
2. Create a branch prefixed with `<agent-name>/` (for example `claude/fix-exec-output-truncation`). The PR title must not carry such prefixes (see step 9).
3. Implement scoped changes only.
4. Run required checks: `npm run format`, `npm run lint`, `npm run check-compiles` when touching `packages/testcontainers` APIs consumed by modules, and targeted tests.
4. Run required checks: `npm run format`, `npm run lint`, `npm run knip`, `npm run check-compiles` when touching `packages/testcontainers` APIs consumed by modules, and targeted tests.
- When working in a fresh git worktree, dependencies are not installed (`node_modules` is absent), so verification commands (tests, `lint`, `format`, `check-compiles`) will fail with "Cannot find module" errors. Run `npm ci` once before verifying. `npm ci` only populates `node_modules` and must not modify `package-lock.json`; if it does, treat that as drift to investigate.
5. Verify git diff only contains intended files.
6. Never commit, push, or post on GitHub (issues, PRs, or comments) without first sharing the proposed diff/message and getting explicit user approval.
Expand Down
33 changes: 33 additions & 0 deletions knip.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "https://unpkg.com/knip@6/schema-jsonc.json",
"workspaces": {
".": {
// Loaded by a <script> tag in docs/site/theme/main.html, not imported by any module.
"entry": ["docs/site/js/tc-header.js"]
},
"packages/testcontainers": {
// Run by Jest in the Checks workflow via `--testMatch`, which knip can't trace back to a file.
"entry": ["smoke-test.jest.js"],
// Docker build contexts that tests copy into images, never imported.
"ignoreFiles": ["fixtures/**"]
},
"packages/modules/chromadb": {
// chromadb dynamic-imports it as the default embedding function when a collection doesn't set one.
"ignoreDependencies": ["@chroma-core/default-embed"]
},
"packages/modules/gcloud": {
// firebase-admin/firestore requires it at runtime, but firebase-admin only lists it as optional.
"ignoreDependencies": ["@google-cloud/firestore"]
},
// TODO: remove the three entries below once #1485 declares these dependencies.
"packages/modules/azurite": {
"ignoreDependencies": ["@azure/core-auth"]
},
"packages/modules/k3s": {
"ignoreDependencies": ["tar-stream"]
},
"packages/modules/selenium": {
"ignoreDependencies": ["tar-fs", "tmp"]
}
}
}
Loading
Loading