mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-26 06:17:21 +02:00
83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
/**
|
|
* CI Metadata for LangSmith experiments.
|
|
*
|
|
* Distinguishes CI runs from local development runs and tracks provenance
|
|
* of automated evaluation results.
|
|
*
|
|
* Note: git info (commit SHA, branch) is tracked by LangSmith automatically
|
|
* via LANGSMITH_REVISION_ID and LANGSMITH_BRANCH env vars — set them in the
|
|
* CI workflow and the SDK picks them up.
|
|
*/
|
|
|
|
import { execSync } from 'node:child_process';
|
|
|
|
export interface CIMetadata {
|
|
source: 'ci' | 'local';
|
|
/** GitHub Actions event that triggered this run (e.g., 'pull_request', 'merge_group', 'workflow_dispatch') */
|
|
trigger?: string;
|
|
/** GitHub Actions run ID for linking back to the workflow run */
|
|
runId?: string;
|
|
}
|
|
|
|
export function buildCIMetadata(): CIMetadata {
|
|
const isCI = process.env.GITHUB_ACTIONS === 'true';
|
|
|
|
if (!isCI) {
|
|
return { source: 'local' };
|
|
}
|
|
|
|
return {
|
|
source: 'ci',
|
|
trigger: process.env.GITHUB_EVENT_NAME,
|
|
runId: process.env.GITHUB_RUN_ID,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Compute an informative experiment name prefix from branch and commit info.
|
|
* Falls back to a generic name if no git context is available.
|
|
*
|
|
* - CI: `ci-{branch}-{short-sha}` from GitHub Actions env vars
|
|
* - Local: `local-{branch}-{short-sha}[-dirty]` from git, dirty suffix if there are uncommitted changes
|
|
* - Fallback: `instance-ai-workflow-evals`
|
|
*
|
|
* LangSmith appends its own random suffix, so this doesn't need to be unique.
|
|
*/
|
|
export function computeExperimentPrefix(): string {
|
|
const ciName = computeCIExperimentName();
|
|
if (ciName) return ciName;
|
|
|
|
const localName = computeLocalExperimentName();
|
|
if (localName) return localName;
|
|
|
|
return 'instance-ai-workflow-evals';
|
|
}
|
|
|
|
function computeCIExperimentName(): string | undefined {
|
|
if (process.env.GITHUB_ACTIONS !== 'true') return undefined;
|
|
|
|
const branch = process.env.GITHUB_HEAD_REF ?? process.env.GITHUB_REF_NAME;
|
|
const sha = process.env.GITHUB_SHA;
|
|
if (!branch || !sha) return undefined;
|
|
|
|
return sanitize(`ci-${branch}-${sha.slice(0, 7)}`);
|
|
}
|
|
|
|
function computeLocalExperimentName(): string | undefined {
|
|
try {
|
|
const run = (cmd: string): string =>
|
|
execSync(cmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
|
|
const branch = run('git rev-parse --abbrev-ref HEAD');
|
|
const sha = run('git rev-parse --short HEAD');
|
|
const dirty = run('git status --porcelain').length > 0 ? '-dirty' : '';
|
|
return sanitize(`local-${branch}-${sha}${dirty}`);
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
function sanitize(name: string): string {
|
|
return name.replace(/[^a-zA-Z0-9_.-]/g, '_').replace(/_{2,}/g, '_');
|
|
}
|