Skip to content
Merged
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
17 changes: 14 additions & 3 deletions .github/scripts/trunk-impacted-targets.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,21 @@ function isTripwire(file) {
return TRIPWIRE_MATCHERS.some((re) => re.test(file))
}

// Tool caches share the directory with the products, so a local run can pick up
// directories such as .ruff_cache, .pytest_cache, and __pycache__ as products and
// invent a lane for each. CI never sees them because a fresh checkout has only
// tracked directories and this job does not run Python, so this keeps a local run
// consistent with CI rather than fixing a live miscount. Dropping a real product
// would only ever widen, because an unrecognized product name falls through to
// ALL, so the filter is safe in the one direction it can be wrong.
function isProductDirectory(name) {
return !name.startsWith('.') && !name.startsWith('__') && name !== 'node_modules'
}

function listProducts(repoRoot) {
return fs
.readdirSync(path.join(repoRoot, 'products'), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.filter((entry) => entry.isDirectory() && isProductDirectory(entry.name))
.map((entry) => entry.name)
.sort()
}
Expand Down Expand Up @@ -275,8 +286,7 @@ function compileContractMatcher(inputs) {
if (include.length === 0) {
return null
}
return (relativePath) =>
include.some((re) => re.test(relativePath)) && !exclude.some((re) => re.test(relativePath))
return (relativePath) => include.some((re) => re.test(relativePath)) && !exclude.some((re) => re.test(relativePath))
}

// Only products that narrow `backend:contract-check` in their own turbo.json get
Expand Down Expand Up @@ -763,6 +773,7 @@ module.exports = {
buildContext,
compileContractMatcher,
globToRegExp,
isProductDirectory,
isTripwire,
parseCrateDependencies,
parseCrateName,
Expand Down
13 changes: 13 additions & 0 deletions .github/scripts/trunk-impacted-targets.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const {
computeTargets,
compileContractMatcher,
globToRegExp,
isProductDirectory,
isTripwire,
parseCrateDependencies,
reverseClosure,
Expand Down Expand Up @@ -301,6 +302,18 @@ test('product frontend and backend changes land in separate domains', () => {
assert.deepEqual(computeTargets(['products/beta/backend/api.py'], CONTEXT), ['py:product:beta'])
})

// ruff and pytest leave caches next to the products, and a run that treats them
// as products invents a lane per cache. Nothing downstream rejects a nonsense
// target name, so the only symptom is a local run disagreeing with CI.
test('tool caches beside the products are not products', () => {
for (const name of ['.ruff_cache', '.pytest_cache', '__pycache__', 'node_modules']) {
assert.equal(isProductDirectory(name), false, name)
}
for (const name of ['surveys', 'error_tracking', 'desktop']) {
assert.equal(isProductDirectory(name), true, name)
}
})

test('a product file that is neither backend nor frontend claims both domains', () => {
const targets = computeTargets(['products/beta/mcp/tools.yaml'], CONTEXT)
assert.equal(targets.includes('py:product:beta'), true)
Expand Down
Loading