mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-18 15:50:25 +02:00
fix: filter epic sync issues by label (#3089)
github-coordination sync listed every repo issue and pushed the epic label onto all of them (#3084). Scope the listing to issues carrying the policy's epic label plus issues whose body still holds the coordination marker (label-drift recovery), deduped by number, and reject an empty labels.epic in loadPolicy. Tests cover the filtered path and the recovery path with exact gh argv. Independent exact-head review passed with no P0/P1; CI 44/44 at the head.
This commit is contained in:
@@ -84,7 +84,24 @@ function applySync(repo, options = {}, context = {}) {
|
||||
assertValidRepo(repo);
|
||||
const policy = context.policy || loadPolicy(context.rootDir || process.cwd(), options.configPath);
|
||||
const store = context.store || null;
|
||||
const issues = listIssues(repo, { ...options, state: options.state || 'all', limit: options.limit || 100 });
|
||||
const labelIssues = listIssues(repo, {
|
||||
...options,
|
||||
state: options.state || 'all',
|
||||
limit: options.limit || 100,
|
||||
label: policy.labels && policy.labels.epic,
|
||||
});
|
||||
const marker = policy.sectionMarker || 'ecc-coordination';
|
||||
const coordinatedIssues = listIssues(repo, {
|
||||
...options,
|
||||
state: options.state || 'all',
|
||||
limit: options.limit || 100,
|
||||
search: `in:body "${marker}:start"`,
|
||||
});
|
||||
const issues = Array.from(
|
||||
new Map(
|
||||
[...labelIssues, ...coordinatedIssues].map(issue => [String(issue.number), issue])
|
||||
).values()
|
||||
);
|
||||
const syncedAt = new Date().toISOString();
|
||||
const results = [];
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ function listIssues(repo, options = {}) {
|
||||
const { owner, name } = normalizeRepo(repo);
|
||||
const limit = Number.isFinite(options.limit) ? options.limit : 100;
|
||||
const state = options.state || 'all';
|
||||
return runGhJson([
|
||||
const args = [
|
||||
'issue',
|
||||
'list',
|
||||
'--repo',
|
||||
@@ -111,9 +111,12 @@ function listIssues(repo, options = {}) {
|
||||
state,
|
||||
'--limit',
|
||||
String(limit),
|
||||
...(options.label ? ['--label', options.label] : []),
|
||||
...(options.search ? ['--search', options.search] : []),
|
||||
'--json',
|
||||
'number,title,body,url,state,labels,author,updatedAt,assignees',
|
||||
], options) || [];
|
||||
];
|
||||
return runGhJson(args, options) || [];
|
||||
}
|
||||
|
||||
function editIssue(repo, issueNumber, options = {}) {
|
||||
|
||||
@@ -74,10 +74,14 @@ function loadPolicy(rootDir = process.cwd(), configPath = null) {
|
||||
const branchModel = typeof parsed.branchModel === 'object' && parsed.branchModel !== null && !Array.isArray(parsed.branchModel) ? parsed.branchModel : {};
|
||||
const project = typeof parsed.project === 'object' && parsed.project !== null && !Array.isArray(parsed.project) ? parsed.project : {};
|
||||
const fieldNames = typeof project.fieldNames === 'object' && project.fieldNames !== null && !Array.isArray(project.fieldNames) ? project.fieldNames : {};
|
||||
const mergedLabels = { ...DEFAULT_LABELS, ...labels };
|
||||
if (typeof mergedLabels.epic !== 'string' || !mergedLabels.epic.trim()) {
|
||||
throw new Error(`Policy file ${resolvedPath} must define labels.epic as a non-empty string`);
|
||||
}
|
||||
return {
|
||||
...DEFAULT_POLICY,
|
||||
...parsed,
|
||||
labels: { ...DEFAULT_LABELS, ...labels },
|
||||
labels: mergedLabels,
|
||||
review: { ...DEFAULT_POLICY.review, ...review },
|
||||
validation: { ...DEFAULT_POLICY.validation, ...validation },
|
||||
branchModel: { ...DEFAULT_POLICY.branchModel, ...branchModel },
|
||||
|
||||
Reference in New Issue
Block a user