classifier + orchestrator: see untracked files, re-mirror after bump
Two real bugs surfaced from the MCPTest2 v1.1.0.0 -> v1.2.0.0 round.
Fix 1: classifier didn't see untracked files (CLASSIFICATION GAP)
Adding FB_Position + FB_Random5s via create_pou + mirror_export
produced new untracked .st files in mcp-mirror/. The classifier
ran `git diff --name-status` which ONLY reports tracked changes;
the new files were invisible until git-added. Result: classifier
counted only 1 'modified' (PLC_PRG, the wiring update) instead
of 1 modified + 2 added, and resolved 'revision' instead of
'minor'. Added a `git ls-files --others --exclude-standard --
mcp-mirror/` pass that pulls untracked files and tags them as
adds (`added (untracked): <path>`). Now create_pou + release
correctly classifies as minor.
Fix 2: orchestrator didn't re-mirror after bump (DESYNC)
Pipeline was: mirror_export -> classify -> bump -> regen md ->
git commit. mirror_export ran BEFORE the bump, so the captured
mcp-mirror/_MCP_PROJECT_VERSION.st reflected the pre-bump GVL
value. Then bump updated the in-memory GVL + saved the .project
binary. Then commit went out with mcp-mirror at the OLD value
while the binary already had the NEW value. Two consequences:
- Next release call sees _MCP_PROJECT_VERSION.st as 'modified'
vs the just-pushed v* tag (because the next mirror_export
pulls the post-bump value, which now differs from the
still-pre-bump mirror in the tag), triggering another bump.
- The runtime-anchor on disk and the runtime-anchor inside the
running PLC binary were silently desynced from the docs.
Surfaced as MCPTest2 v1.1.0.0 (8d79193) shipping with binary
GVL = 1.0.2.0 while docs said 1.1.0.0; resolved by the v1.2.0.0
re-sync (1513e9c).
Added a SECOND mirror_export call right after the bump, before
regenerating library.md / pou-dump.md / Changelog. Soft-fails
with WARNING -- the bump itself already succeeded, post-bump
mirror is the documentation step.
Together these two fixes make release_project_version end-to-end
deterministic: 1 release call -> 1 release commit, no manual finish,
no re-bump on the next call. Verified offline: the path of the new
untracked-detection through ls-files --others, plus the second
mirror_export, give the orchestrator the post-bump state it
previously lacked.
This commit is contained in:
parent
9854c31b66
commit
c50970b15e
1 changed files with 50 additions and 1 deletions
|
|
@ -288,7 +288,26 @@ function classifyMcpMirrorChanges(projectDir: string): ClassifyResult {
|
|||
evidence.push(`git diff against ${baseRef} failed -- treating as no-changes`);
|
||||
return { kind: 'no-changes', evidence };
|
||||
}
|
||||
if (!raw.trim()) {
|
||||
|
||||
// git diff only reports TRACKED changes. New files that mirror_export just
|
||||
// wrote are untracked from git's POV until added, and would otherwise be
|
||||
// invisible to the classifier (they wouldn't trigger a 'minor' bump even
|
||||
// though they're new public symbols). Pull them in via ls-files --others.
|
||||
// Surfaced on MCPTest2 today: adding FB_Position + FB_Random5s via
|
||||
// create_pou caused the classifier to see only 1 modified file (PLC_PRG)
|
||||
// and classify as 'revision' instead of 'minor'. The added FBs were
|
||||
// untracked at classify time.
|
||||
let untracked = '';
|
||||
try {
|
||||
untracked = execSync(
|
||||
`git -C "${projectDir}" ls-files --others --exclude-standard -- mcp-mirror/`,
|
||||
{ encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }
|
||||
);
|
||||
} catch {
|
||||
// ls-files failure shouldn't block classification on tracked diff alone
|
||||
}
|
||||
|
||||
if (!raw.trim() && !untracked.trim()) {
|
||||
evidence.push('no changes in mcp-mirror/ since baseline');
|
||||
return { kind: 'no-changes', evidence };
|
||||
}
|
||||
|
|
@ -315,6 +334,10 @@ function classifyMcpMirrorChanges(projectDir: string): ClassifyResult {
|
|||
evidence.push(`modified: ${rest}`);
|
||||
}
|
||||
}
|
||||
for (const line of untracked.split('\n').filter((l) => l.trim())) {
|
||||
hasAdd = true;
|
||||
evidence.push(`added (untracked): ${line}`);
|
||||
}
|
||||
|
||||
if (hasDelete || hasRename) return { kind: 'bump', level: 'major', evidence };
|
||||
if (hasAdd) return { kind: 'bump', level: 'minor', evidence };
|
||||
|
|
@ -1836,6 +1859,32 @@ export async function startMcpServer(config: ServerConfig): Promise<void> {
|
|||
}
|
||||
log.push(`bump: ${from ?? '(none)'} -> ${newVersion}`);
|
||||
|
||||
// 3b. Re-run mirror_export AFTER the bump. The pre-bump mirror
|
||||
// captured the old _MCP_PROJECT_VERSION.sVersion value and (when
|
||||
// applicable) the old Project Information.Version. After the bump,
|
||||
// those values changed in CODESYS in-memory and got saved to the
|
||||
// .project binary. The mirror needs to reflect the post-bump state
|
||||
// or the next 'release' call will see _MCP_PROJECT_VERSION.st as
|
||||
// a real diff vs the just-tagged release and bump again. Surfaced
|
||||
// on MCPTest2 v1.1.0.0 (commit 8d79193): the binary GVL was
|
||||
// 1.0.2.0 while the docs said 1.1.0.0 because mirror_export
|
||||
// didn't re-run after the bump.
|
||||
try {
|
||||
const mirrorScript2 = scriptManager.prepareScriptWithHelpers(
|
||||
'mirror_export',
|
||||
{ PROJECT_FILE_PATH: escaped, MIRROR_ROOT: path.join(projectDir, 'mcp-mirror') },
|
||||
['ensure_project_open']
|
||||
);
|
||||
const mirror2 = await executor.executeScript(mirrorScript2);
|
||||
if (mirror2.success && mirror2.output.includes('SCRIPT_SUCCESS')) {
|
||||
log.push('mirror_export (post-bump): OK');
|
||||
} else {
|
||||
log.push('mirror_export (post-bump): WARNING -- post-bump mirror may be stale');
|
||||
}
|
||||
} catch (e) {
|
||||
log.push(`mirror_export (post-bump): WARNING -- ${e instanceof Error ? e.message : String(e)}`);
|
||||
}
|
||||
|
||||
// 4. Append Changelog (the manual-bump path doesn't auto-append; do it here)
|
||||
appendChangelogEntry(projectDir, from, newVersion, levelLabel, classification.evidence);
|
||||
log.push(`Changelog.md: appended v${newVersion}`);
|
||||
|
|
|
|||
Loading…
Reference in a new issue