ci: restore hosted-run headroom

This commit is contained in:
Tianyi Cui
2026-07-21 20:51:28 +08:00
parent c0831f0e99
commit 3d96508244
6 changed files with 105 additions and 12 deletions

View File

@@ -0,0 +1,34 @@
import { describe, expect, it } from 'vitest'
import { selectLintShard } from './lint-shards.ts'
describe('lint gate shards', () => {
it('keeps the unsharded local command complete', () => {
expect(selectLintShard()).toEqual({ eslintTargets: ['.'], includeDuplication: true })
expect(selectLintShard('')).toEqual({ eslintTargets: ['.'], includeDuplication: true })
})
it('partitions package sources, package tests, and their repository complement', () => {
expect(selectLintShard('package-sources')).toEqual({
eslintTargets: ['packages/*/*/src/**/*.ts'],
includeDuplication: false,
})
expect(selectLintShard('package-tests')).toEqual({
eslintTargets: ['packages/*/*/tests/**/*.ts'],
includeDuplication: false,
})
expect(selectLintShard('repository')).toEqual({
eslintTargets: [
'.',
'--ignore-pattern',
'packages/*/*/src/**',
'--ignore-pattern',
'packages/*/*/tests/**',
],
includeDuplication: true,
})
})
it('rejects an unknown lane', () => {
expect(() => selectLintShard('missing')).toThrow('unknown DSH_LINT_SHARD')
})
})

40
scripts/lint-shards.ts Normal file
View File

@@ -0,0 +1,40 @@
/** Lint-lane selection for GitHub Actions. */
/** One ESLint target set and whether it owns the cross-file duplication gate. */
export interface LintSelection {
/** Shell-free arguments passed to ESLint before its cache options. */
eslintTargets: readonly string[]
/** Whether this lane also runs the repository-wide duplication check. */
includeDuplication: boolean
}
/**
* Select an exhaustive lint partition without changing the ordinary local lint command.
*
* @param name Optional stable shard name from `DSH_LINT_SHARD`.
* @returns ESLint targets and ownership of the duplication gate.
*/
export function selectLintShard(name?: string): LintSelection {
switch (name) {
case undefined:
case '':
return { eslintTargets: ['.'], includeDuplication: true }
case 'package-sources':
return { eslintTargets: ['packages/*/*/src/**/*.ts'], includeDuplication: false }
case 'package-tests':
return { eslintTargets: ['packages/*/*/tests/**/*.ts'], includeDuplication: false }
case 'repository':
return {
eslintTargets: [
'.',
'--ignore-pattern',
'packages/*/*/src/**',
'--ignore-pattern',
'packages/*/*/tests/**',
],
includeDuplication: true,
}
default:
throw new Error(`run-gates: unknown DSH_LINT_SHARD ${JSON.stringify(name)}.`)
}
}

View File

@@ -9,6 +9,7 @@ import { availableParallelism } from 'node:os'
import { resolve } from 'node:path'
import { performance } from 'node:perf_hooks'
import { coverageArgs } from './coverage-shards.ts'
import { selectLintShard } from './lint-shards.ts'
import { selectStaticGates } from './static-shards.ts'
type Mode =
@@ -162,11 +163,13 @@ function gatesForMode(selected: Mode): Gate[] {
return ciPrimaryGates()
case 'ci-static':
return ciStaticGates()
case 'ci-lint':
case 'ci-lint': {
const selection = selectLintShard(process.env.DSH_LINT_SHARD)
return [
lintGate(),
pnpmScript('duplication', 'duplication'),
lintGate(selection.eslintTargets),
...selection.includeDuplication ? [pnpmScript('duplication', 'duplication')] : [],
]
}
case 'ci-coverage':
return [coverageGate()]
case 'ci-snapshot':
@@ -267,11 +270,11 @@ function ciArtifactGates(): Gate[] {
return [...metadataGates, builtBinSmokeGate()]
}
function lintGate(): Gate {
function lintGate(eslintTargets: readonly string[] = ['.']): Gate {
if (process.env.DSH_ESLINT_CACHE === '1') {
return pnpmExec('lint', [
'eslint',
'.',
...eslintTargets,
'--cache',
'--cache-location',
'.cache/eslint/',

View File

@@ -23,7 +23,7 @@ export const staticShards = [
},
{
name: 'api-contracts',
gateIds: ['doc-typecheck', 'export-jsdoc', 'scoped-events', 'type-equivalence'],
gateIds: ['doc-typecheck', 'cordis-api', 'export-jsdoc', 'scoped-events', 'type-equivalence'],
},
{
name: 'catalogs',