mirror of
https://github.com/nocobase/nocobase.git
synced 2026-10-13 16:17:11 +08:00
128 lines
3.2 KiB
JavaScript
128 lines
3.2 KiB
JavaScript
import { execFileSync } from 'node:child_process';
|
|
import { appendFileSync } from 'node:fs';
|
|
|
|
export const databases = [
|
|
'sqlite',
|
|
'postgres',
|
|
'mysql',
|
|
'oceanbase',
|
|
'oracle',
|
|
'mssql',
|
|
'dameng',
|
|
'kingbase',
|
|
];
|
|
|
|
// Keep whole packages covered, including their tests, manifests, and local configuration.
|
|
const sharedDirectories = [
|
|
'packages/libs/db/',
|
|
'packages/libs/db-testkit/',
|
|
'packages/libs/service-provider/',
|
|
'packages/libs/repository-input/',
|
|
'packages/tools/dev-config/',
|
|
'patches/',
|
|
];
|
|
|
|
const sharedFiles = new Set([
|
|
'package.json',
|
|
'pnpm-lock.yaml',
|
|
'pnpm-workspace.yaml',
|
|
'.npmrc',
|
|
'.pnpmfile.cjs',
|
|
'pnpmfile.cjs',
|
|
'scripts/select-db-integration-matrix.mjs',
|
|
'tests/scripts/select-db-integration-matrix.test.mjs',
|
|
]);
|
|
|
|
export function selectDatabases(changedPaths) {
|
|
const selected = new Set();
|
|
for (const file of changedPaths) {
|
|
if (
|
|
sharedFiles.has(file) ||
|
|
sharedDirectories.some((directory) => file.startsWith(directory))
|
|
) {
|
|
return [...databases];
|
|
}
|
|
for (const database of databases) {
|
|
if (file.startsWith(`packages/libs/db-${database}/`)) {
|
|
selected.add(database);
|
|
}
|
|
}
|
|
}
|
|
return databases.filter((database) => selected.has(database));
|
|
}
|
|
|
|
export function planDbIntegration({ baseSha, headSha, cwd = process.cwd() }) {
|
|
const git = (args) =>
|
|
execFileSync('git', args, {
|
|
cwd,
|
|
encoding: 'utf8',
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
maxBuffer: 16 * 1024 * 1024,
|
|
});
|
|
|
|
// A new branch, unavailable history, or an event without a base must never skip coverage.
|
|
if (!baseSha || /^0+$/.test(baseSha) || !headSha) {
|
|
return {
|
|
databases: [...databases],
|
|
reason: 'No comparison range; running every database.',
|
|
};
|
|
}
|
|
|
|
let base;
|
|
let head;
|
|
try {
|
|
base = git([
|
|
'rev-parse',
|
|
'--verify',
|
|
'--end-of-options',
|
|
`${baseSha}^{commit}`,
|
|
]).trim();
|
|
head = git([
|
|
'rev-parse',
|
|
'--verify',
|
|
'--end-of-options',
|
|
`${headSha}^{commit}`,
|
|
]).trim();
|
|
} catch {
|
|
return {
|
|
databases: [...databases],
|
|
reason: 'Comparison commits unavailable; running every database.',
|
|
};
|
|
}
|
|
|
|
// Treat renames as deletion + addition so moves into AND out of a package are covered.
|
|
// NUL delimiters preserve filenames containing whitespace, newlines, or non-ASCII characters.
|
|
// Do not catch diff errors: a broken selector must fail the planning job, never report a skip.
|
|
const changedPaths = git([
|
|
'diff',
|
|
'--name-only',
|
|
'--no-renames',
|
|
'-z',
|
|
base,
|
|
head,
|
|
'--',
|
|
])
|
|
.split('\0')
|
|
.filter(Boolean);
|
|
const selected = selectDatabases(changedPaths);
|
|
return {
|
|
databases: selected,
|
|
reason: selected.length
|
|
? `Selected databases: ${selected.join(', ')}.`
|
|
: 'No database-related changes.',
|
|
};
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
const plan = planDbIntegration({
|
|
baseSha: process.env.BASE_SHA,
|
|
headSha: process.env.HEAD_SHA,
|
|
});
|
|
const output = `databases=${JSON.stringify(plan.databases)}\nshould_run=${plan.databases.length > 0}\n`;
|
|
if (process.env.GITHUB_OUTPUT) {
|
|
appendFileSync(process.env.GITHUB_OUTPUT, output);
|
|
}
|
|
console.log(plan.reason);
|
|
process.stdout.write(output);
|
|
}
|