fix: treat pending Gitea CI as acceptable on synced main
Memind CI / Test, build, and release guards (push) Successful in 1m39s
Memind CI / Test, build, and release guards (push) Successful in 1m39s
Normal Portal releases should not block when commit status stays pending after the candidate is already pushed to origin/main. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -54,7 +54,8 @@ Gate 只为自动选中的场景生成结果,所有选中项都必须执行并
|
|||||||
在隔离本地 Portal、390×844 移动视口和公开页 fixture 上运行;COMP-09 由独立执行器
|
在隔离本地 Portal、390×844 移动视口和公开页 fixture 上运行;COMP-09 由独立执行器
|
||||||
要求 active 脱敏回归 manifest 并逐条回放。没有 manifest 时 COMP-09 明确 `failed`,
|
要求 active 脱敏回归 manifest 并逐条回放。没有 manifest 时 COMP-09 明确 `failed`,
|
||||||
不会因“没有用例”而通过。`REL-02` 在候选不落后 `origin/main` 且 Gitea commit status 为
|
不会因“没有用例”而通过。`REL-02` 在候选不落后 `origin/main` 且 Gitea commit status 为
|
||||||
`success` 时通过;若仓库未接入 commit status,候选 SHA 已等于 `origin/main` 时也视为通过。
|
`success` 时通过;若仓库未接入 commit status 或状态仍为 pending,候选 SHA 已等于
|
||||||
|
`origin/main` 时也视为通过。
|
||||||
仍可用 `MEMIND_RELEASE_CI_STATUS=success` 显式注入。`REL-01` 会忽略 `.release-gate/`
|
仍可用 `MEMIND_RELEASE_CI_STATUS=success` 显式注入。`REL-01` 会忽略 `.release-gate/`
|
||||||
与 `.runtime/` 下的本地构建产物,避免 Gate 前构建 runtime 误报工作区脏。
|
与 `.runtime/` 下的本地构建产物,避免 Gate 前构建 runtime 误报工作区脏。
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,14 @@ export function isReleaseCiAcceptable(ciStatus, { headSha, remoteSha } = {}) {
|
|||||||
const normalized = String(ciStatus ?? 'missing').trim().toLowerCase();
|
const normalized = String(ciStatus ?? 'missing').trim().toLowerCase();
|
||||||
if (normalized === 'success') return true;
|
if (normalized === 'success') return true;
|
||||||
if (normalized === 'failure' || normalized === 'error') return false;
|
if (normalized === 'failure' || normalized === 'error') return false;
|
||||||
// Self-hosted releases often have no Gitea commit status integration. Once the
|
// Self-hosted releases often have no meaningful Gitea commit status. Once the
|
||||||
// candidate is fully pushed to origin/main, treat missing CI as acceptable.
|
// candidate is fully pushed to origin/main, treat missing/pending CI as acceptable.
|
||||||
if (normalized === 'missing' && remoteSha && headSha === remoteSha) return true;
|
if (
|
||||||
|
(normalized === 'missing' || normalized === 'pending')
|
||||||
|
&& remoteSha
|
||||||
|
&& headSha === remoteSha
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,18 +20,22 @@ test('release CI accepts explicit success and rejects explicit failure', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('release CI accepts missing status when candidate equals origin/main', () => {
|
test('release CI accepts missing or pending status when candidate equals origin/main', () => {
|
||||||
const sha = 'c7718c683b216f08865e04edc67f4217f6abc3c1';
|
const sha = 'c7718c683b216f08865e04edc67f4217f6abc3c1';
|
||||||
assert.equal(
|
assert.equal(
|
||||||
isReleaseCiAcceptable('missing', { headSha: sha, remoteSha: sha }),
|
isReleaseCiAcceptable('missing', { headSha: sha, remoteSha: sha }),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
assert.equal(
|
||||||
|
isReleaseCiAcceptable('pending', { headSha: sha, remoteSha: sha }),
|
||||||
|
true,
|
||||||
|
);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
isReleaseCiAcceptable('missing', { headSha: sha, remoteSha: 'other' }),
|
isReleaseCiAcceptable('missing', { headSha: sha, remoteSha: 'other' }),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
isReleaseCiAcceptable('pending', { headSha: sha, remoteSha: sha }),
|
isReleaseCiAcceptable('pending', { headSha: sha, remoteSha: 'other' }),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user