mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-30 12:29:27 +00:00
fix(release): close remaining PR review gaps
This commit is contained in:
+29
-15
@@ -13,67 +13,81 @@ export function replaceExactly(text, pattern, replacement, label) {
|
||||
return text.replace(pattern, replacement);
|
||||
}
|
||||
|
||||
function writeJson(root, relativePath, update) {
|
||||
function stageJson(stagedUpdates, root, relativePath, update) {
|
||||
const absolutePath = path.join(root, relativePath);
|
||||
const value = JSON.parse(fs.readFileSync(absolutePath, 'utf8'));
|
||||
const current = stagedUpdates.has(absolutePath)
|
||||
? stagedUpdates.get(absolutePath)
|
||||
: fs.readFileSync(absolutePath, 'utf8');
|
||||
const value = JSON.parse(current);
|
||||
update(value);
|
||||
fs.writeFileSync(absolutePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
||||
stagedUpdates.set(absolutePath, `${JSON.stringify(value, null, 2)}\n`);
|
||||
}
|
||||
|
||||
function updateText(root, relativePath, pattern, replacement, label) {
|
||||
function stageText(stagedUpdates, root, relativePath, pattern, replacement, label) {
|
||||
const absolutePath = path.join(root, relativePath);
|
||||
const current = fs.readFileSync(absolutePath, 'utf8');
|
||||
fs.writeFileSync(absolutePath, replaceExactly(current, pattern, replacement, label), 'utf8');
|
||||
const current = stagedUpdates.has(absolutePath)
|
||||
? stagedUpdates.get(absolutePath)
|
||||
: fs.readFileSync(absolutePath, 'utf8');
|
||||
stagedUpdates.set(absolutePath, replaceExactly(current, pattern, replacement, label));
|
||||
}
|
||||
|
||||
export function prepareRelease(version, date = new Date(), root = repoRoot) {
|
||||
versionFromTag(`v${version}`);
|
||||
const timestamp = date.toISOString().replace(/\.\d{3}Z$/u, 'Z');
|
||||
writeJson(root, 'package.json', value => { value.version = version; });
|
||||
writeJson(root, 'package-lock.json', value => {
|
||||
const stagedUpdates = new Map();
|
||||
stageJson(stagedUpdates, root, 'package.json', value => { value.version = version; });
|
||||
stageJson(stagedUpdates, root, 'package-lock.json', value => {
|
||||
value.version = version;
|
||||
value.packages[''].version = version;
|
||||
});
|
||||
writeJson(root, 'extension/manifest.base.json', value => { value.version = version; });
|
||||
writeJson(root, 'website/version.json', value => {
|
||||
stageJson(stagedUpdates, root, 'extension/manifest.base.json', value => { value.version = version; });
|
||||
stageJson(stagedUpdates, root, 'website/version.json', value => {
|
||||
value.version = version;
|
||||
value.date = timestamp;
|
||||
});
|
||||
updateText(
|
||||
stageText(
|
||||
stagedUpdates,
|
||||
root,
|
||||
'shared/constants.js',
|
||||
/export const APP_VERSION = ["'][^"']+["'];/gu,
|
||||
`export const APP_VERSION = "${version}";`,
|
||||
'shared/constants.js'
|
||||
);
|
||||
updateText(
|
||||
stageText(
|
||||
stagedUpdates,
|
||||
root,
|
||||
'website/template.html',
|
||||
/"softwareVersion": "[^"]+"/gu,
|
||||
`"softwareVersion": "${version}"`,
|
||||
'website/template.html'
|
||||
);
|
||||
updateText(
|
||||
stageText(
|
||||
stagedUpdates,
|
||||
root,
|
||||
'website/llms.txt',
|
||||
/Current website release: .+/gu,
|
||||
`Current website release: ${version}`,
|
||||
'website/llms.txt'
|
||||
);
|
||||
updateText(
|
||||
stageText(
|
||||
stagedUpdates,
|
||||
root,
|
||||
'README.md',
|
||||
/Release-v\d+\.\d+\.\d+-blue/gu,
|
||||
`Release-v${version}-blue`,
|
||||
'README.md release badge'
|
||||
);
|
||||
updateText(
|
||||
stageText(
|
||||
stagedUpdates,
|
||||
root,
|
||||
'README.md',
|
||||
/New v\d+\.\d+\.\d+ Release!/gu,
|
||||
`New v${version} Release!`,
|
||||
'README.md release banner'
|
||||
);
|
||||
for (const [absolutePath, content] of stagedUpdates) {
|
||||
fs.writeFileSync(absolutePath, content, 'utf8');
|
||||
}
|
||||
console.log(`Prepared release v${version} at ${timestamp}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,4 +87,16 @@ describe('release preparation helpers', () => {
|
||||
.toThrow('vMAJOR.MINOR.PATCH');
|
||||
expect(readFixture(root)).toEqual(before);
|
||||
});
|
||||
|
||||
it('does not partially update release sources when a later marker is invalid', () => {
|
||||
const root = createReleaseFixture();
|
||||
const llmsPath = path.join(root, 'website/llms.txt');
|
||||
fs.writeFileSync(llmsPath, fs.readFileSync(llmsPath, 'utf8')
|
||||
.replace(/Current website release: .+/u, 'Release marker intentionally missing'), 'utf8');
|
||||
const before = readFixture(root);
|
||||
|
||||
expect(() => prepareRelease('9.8.7', new Date('2030-01-01T00:00:00Z'), root))
|
||||
.toThrow('website/llms.txt must contain exactly one release-version marker');
|
||||
expect(readFixture(root)).toEqual(before);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -575,17 +575,22 @@ try {
|
||||
assert.equal(mod.rooms.has(msgateRid), false, 'empty-room cleanup removes canonical state with the room');
|
||||
// --- Terminal room timeout: coded error + complete membership cleanup ---
|
||||
const timeoutClient = await c();
|
||||
const timeoutPeer = await c();
|
||||
const timeoutRoomId = 'timeout-'+Date.now();
|
||||
await j(timeoutClient, timeoutRoomId, 'timeout-peer');
|
||||
timeoutClient._m.length = 0;
|
||||
await j(timeoutPeer, timeoutRoomId, 'timeout-peer-2');
|
||||
timeoutClient._m.length = timeoutPeer._m.length = 0;
|
||||
mod.rooms.get(timeoutRoomId).lastActivity = 0;
|
||||
mod.cleanupInactiveRooms(Date.now());
|
||||
const [timeoutEvent, timeoutData] = await a(timeoutClient);
|
||||
assert.equal(timeoutEvent, 'error');
|
||||
const timeoutData = await w(timeoutClient, 'error');
|
||||
const timeoutPeerData = await w(timeoutPeer, 'error');
|
||||
assert.equal(timeoutData.code, 'room_closed');
|
||||
assert.equal(timeoutData.message, 'Room closed');
|
||||
assert.equal(timeoutPeerData.code, 'room_closed');
|
||||
await delay(80);
|
||||
assert.deepEqual(timeoutClient._m, [], 'terminal room cleanup emits nothing after room_closed');
|
||||
assert.deepEqual(timeoutPeer._m, [], 'terminal room cleanup emits nothing after room_closed');
|
||||
assert.equal(mod.rooms.has(timeoutRoomId), false, 'inactive room is deleted');
|
||||
timeoutClient._m.length = 0;
|
||||
|
||||
// The same connected socket must be able to join that room again. This
|
||||
// proves timeout cleanup removed its stale socketToRoom membership.
|
||||
|
||||
Reference in New Issue
Block a user