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
84 changes: 84 additions & 0 deletions .github/scripts/__tests__/sync-run-contract.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,75 @@ const test = require('node:test');
const assert = require('node:assert/strict');

const {
buildNoChangeEvidence,
buildNoChangeCanaryEvidence,
mergeCampaignNoChangeEvidence,
buildMarkdownSummary,
buildSyncRunReport,
summarizeResults,
} = require('../sync_run_contract');

test('buildNoChangeEvidence binds unchanged delivery repos to an immutable campaign plan', () => {
const planId = `sha256:${'a'.repeat(64)}`;
const sourceCommit = 'b'.repeat(40);
const result = buildNoChangeEvidence({
expectedRepositories: ['stranske/Ready'],
planId,
planScope: 'full',
sourceCommit,
results: [{
repo: 'stranske/Ready', status: 'no_changes', plan_id: planId,
plan_scope: 'full', scope_base_sha: '', source_commit: sourceCommit,
consumer_head_sha: 'c'.repeat(40),
}],
});
assert.equal(result.ok, true);
assert.equal(result.evidence.schema, 'workflows.consumer-sync-no-change-evidence/v1');
assert.equal(result.evidence.results[0].evidence_source, 'no-change-delivery');
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

test('buildNoChangeEvidence fails closed on immutable mismatches and duplicate rows', () => {
const planId = `sha256:${'a'.repeat(64)}`;
const sourceCommit = 'b'.repeat(40);
const base = {
repo: 'stranske/Ready', status: 'no_changes', plan_id: planId,
plan_scope: 'source-delta', scope_base_sha: 'c'.repeat(40),
source_commit: sourceCommit, consumer_head_sha: 'd'.repeat(40),
};
const mismatch = buildNoChangeEvidence({
expectedRepositories: ['stranske/Ready'],
planId,
planScope: 'source-delta',
scopeBaseSha: 'c'.repeat(40),
sourceCommit,
results: [{
...base,
plan_id: `sha256:${'e'.repeat(64)}`,
plan_scope: 'full',
scope_base_sha: 'f'.repeat(40),
source_commit: '0'.repeat(40),
consumer_head_sha: 'not-a-sha',
}],
});
assert.equal(mismatch.ok, false);
assert.ok(mismatch.errors.includes('no_change_delivery_plan_mismatch:stranske/Ready'));
assert.ok(mismatch.errors.includes('no_change_delivery_scope_mismatch:stranske/Ready'));
assert.ok(mismatch.errors.includes('no_change_delivery_scope_base_mismatch:stranske/Ready'));
assert.ok(mismatch.errors.includes('no_change_delivery_source_mismatch:stranske/Ready'));
assert.ok(mismatch.errors.includes('no_change_delivery_head_invalid:stranske/Ready'));

const duplicate = buildNoChangeEvidence({
expectedRepositories: ['stranske/Ready'],
planId,
planScope: 'source-delta',
scopeBaseSha: 'c'.repeat(40),
sourceCommit,
results: [base, base],
});
assert.equal(duplicate.ok, false);
assert.ok(duplicate.errors.includes('duplicate_no_change_delivery:stranske/Ready'));
});

test('buildNoChangeCanaryEvidence binds no-diff canaries to the exact plan and head', () => {
const planId = `sha256:${'a'.repeat(64)}`;
const sourceCommit = 'b'.repeat(40);
Expand Down Expand Up @@ -92,6 +155,27 @@ test('buildNoChangeCanaryEvidence rejects duplicate and immutable scope mismatch
assert.ok(result.errors.includes('duplicate_no_change_canary:stranske/Ready'));
});

test('mergeCampaignNoChangeEvidence dedupes overlapping canary and delivery rows by repo', () => {
const delivery = {
schema: 'workflows.consumer-sync-no-change-evidence/v1',
version: 1,
results: [
{ repo: 'stranske/Ready', evidence_source: 'no-change-delivery', head_sha: 'd'.repeat(40) },
{ repo: 'stranske/Travel', evidence_source: 'no-change-delivery', head_sha: 'e'.repeat(40) },
],
};
const canaryRows = [
{ repo: 'stranske/Ready', evidence_source: 'no-change-canary', head_sha: 'c'.repeat(40) },
];
const merged = mergeCampaignNoChangeEvidence(canaryRows, delivery);
assert.equal(merged.schema, delivery.schema);
assert.equal(merged.version, delivery.version);
assert.equal(merged.results.length, 2);
const ready = merged.results.find((row) => row.repo === 'stranske/Ready');
assert.equal(ready.evidence_source, 'no-change-canary');
assert.equal(ready.head_sha, 'c'.repeat(40));
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

test('summarizeResults counts known statuses and buckets unknown as error', () => {
assert.deepEqual(
summarizeResults([
Expand Down
45 changes: 43 additions & 2 deletions .github/scripts/__tests__/sync_dependency_campaign.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ test('mergeDeliveryHandoffs retains one current record per generated PR', () =>
...current,
branch: '',
lane: '',
continuation: { class: '', lane: '', reason: '', resume_after: '' },
plan_id: '',
plan_scope: '',
scope_base_sha: '',
source_commit: '',
canary_baseline_evidence_json: '',
campaign_no_change_evidence_json: '',
continuation: { class: '', lane: '', reason: '', resume_after: '', key: '' },
observed_at: '2026-08-02T00:00:00Z',
}]);
});
Expand Down Expand Up @@ -87,7 +93,7 @@ test('plans only due transient Maint 71 lanes and suppresses candidates during d
}).length, 0);
assert.deepEqual(planMaint71Continuations([candidate], {
now: '2026-08-15T12:10:00Z',
}), []);
}).map((item) => item.lane), ['candidate']);
assert.deepEqual(planMaint71Continuations([candidate], {
now: '2026-08-15T12:10:00.001Z',
}).map((item) => ({ lane: item.lane, branch: item.branch })), [{
Expand All @@ -106,6 +112,41 @@ test('plans only due transient Maint 71 lanes and suppresses candidates during d
}).map((item) => item.lane), ['candidate']);
});

test('campaign continuations preserve idempotency and immutable plan bindings', () => {
const campaign = {
schema: 'workflows-generated-delivery-handoff/v1',
repository: 'stranske/Travel',
pr: 11,
branch: 'sync/workflows-candidate',
head_sha: 'abc',
delivery_generation: 'g1',
disposition: 'awaiting-checks',
blocker_owner: 'ci',
next_command: 'await-required-checks',
check_state: 'checks_pending',
review_state: 'clear',
plan_id: 'plan-abc',
plan_scope: 'source-delta',
scope_base_sha: 'base-abc',
source_commit: 'source-abc',
continuation: {
class: 'transient', lane: 'campaign', reason: 'checks_pending',
resume_after: '2026-08-15T12:10:00Z', key: 'continuation-abc',
},
};
const [planned] = planMaint71Continuations([campaign], {
now: '2026-08-15T12:10:00Z',
});
assert.equal(planned.lane, 'campaign');
assert.equal(planned.continuation_key, 'continuation-abc');
assert.deepEqual(planned.immutable_handoff, {
plan_id: 'plan-abc',
plan_scope: 'source-delta',
scope_base_sha: 'base-abc',
source_commit: 'source-abc',
});
});

test('normalizeDeliveryHandoff rejects incomplete restart fields', () => {
assert.equal(normalizeDeliveryHandoff({
schema: 'workflows-generated-delivery-handoff/v1', repository: 'stranske/Ready', pr: 11,
Expand Down
Loading
Loading