mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-28 19:47:25 +00:00
fix: verify final gate against remote main
This commit is contained in:
+1
-1
@@ -51,7 +51,7 @@ To release a new version (e.g., `v2.5.1`), follow these steps:
|
||||
git commit -m "release: prepare v2.5.1"
|
||||
npm run release:gate -- 2.5.1 --candidate
|
||||
```
|
||||
2. Commit the release notes and prepared version changes, open a pull request,
|
||||
2. Push the already committed and candidate-gated changes, open a pull request,
|
||||
and wait for required `verify`, `node20`, and `e2e` checks.
|
||||
3. After the PR is merged, fast-forward local `main`, wait for `verify`,
|
||||
`node20`, and `e2e` on the merge commit, then run the final local gate. It
|
||||
|
||||
@@ -58,6 +58,12 @@ export function linuxGateCommand() {
|
||||
].join(' && ');
|
||||
}
|
||||
|
||||
export function parseRemoteMain(text) {
|
||||
const match = /^([a-f0-9]{40})\trefs\/heads\/main\s*$/u.exec(String(text));
|
||||
if (!match) throw new Error(`could not resolve origin main from: ${String(text).trim() || '<empty>'}`);
|
||||
return match[1];
|
||||
}
|
||||
|
||||
function assertCleanTree() {
|
||||
const status = capture('git', ['status', '--porcelain=v1']);
|
||||
if (status) throw new Error(`release gate requires a clean working tree:\n${status}`);
|
||||
@@ -67,7 +73,9 @@ function assertFinalMainChecks() {
|
||||
const branch = capture('git', ['branch', '--show-current']);
|
||||
if (branch !== 'main') throw new Error(`final release gate requires branch main, found ${branch || '<detached>'}`);
|
||||
const head = capture('git', ['rev-parse', 'HEAD']);
|
||||
const remoteMain = capture('git', ['rev-parse', 'origin/main']);
|
||||
const remoteMain = parseRemoteMain(capture('git', [
|
||||
'ls-remote', '--exit-code', 'origin', 'refs/heads/main'
|
||||
]));
|
||||
if (head !== remoteMain) throw new Error(`HEAD ${head} does not match origin/main ${remoteMain}`);
|
||||
|
||||
const checksText = capture('gh', [
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
linuxGateCommand,
|
||||
parseGateArgs,
|
||||
parseRemoteMain,
|
||||
playwrightImageFromLock
|
||||
} from './release-local-gate.mjs';
|
||||
|
||||
@@ -20,6 +21,13 @@ describe('local release gate contract', () => {
|
||||
expect(() => playwrightImageFromLock({ packages: {} })).toThrow('must pin');
|
||||
});
|
||||
|
||||
it('extracts main only from the exact remote branch record', () => {
|
||||
const sha = '0123456789abcdef0123456789abcdef01234567';
|
||||
expect(parseRemoteMain(`${sha}\trefs/heads/main\n`)).toBe(sha);
|
||||
expect(() => parseRemoteMain('')).toThrow('could not resolve origin main');
|
||||
expect(() => parseRemoteMain(`${sha}\trefs/heads/not-main`)).toThrow('could not resolve origin main');
|
||||
});
|
||||
|
||||
it('runs the complete CI-equivalent dependency, verify, and browser sequence', () => {
|
||||
expect(linuxGateCommand()).toBe([
|
||||
'git clone --no-local /src /work',
|
||||
|
||||
Reference in New Issue
Block a user