fix(ci): limit prepared release permissions

This commit is contained in:
Timo
2026-08-25 22:49:31 +02:00
parent 5fffeadded
commit e736bb9861
3 changed files with 22 additions and 1 deletions
+2
View File
@@ -85,6 +85,8 @@ jobs:
verify-prepared-release:
needs: [preflight, prepare-release]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout prepared release commit
uses: actions/checkout@v7
+11 -1
View File
@@ -66,7 +66,7 @@ export function parseRemoteMain(text) {
}
export function validateReleaseWorkflowContract(text) {
const workflow = String(text);
const workflow = String(text).replace(/\r\n/gu, '\n');
const image = 'ghcr.io/shik3i/koalasync';
if (!workflow.includes(`IMAGE: ${image}`)) {
throw new Error(`release workflow must define the lowercase canonical image ${image}`);
@@ -97,6 +97,16 @@ export function validateReleaseWorkflowContract(text) {
if (/git push origin HEAD:main\s*(?:\|\||;\s*true)/u.test(workflow)) {
throw new Error('release workflow must stop when the automatic main push fails');
}
const verificationPermissions = [
' verify-prepared-release:',
' needs: [preflight, prepare-release]',
' runs-on: ubuntu-latest',
' permissions:',
' contents: read'
].join('\n');
if (!workflow.includes(verificationPermissions)) {
throw new Error('prepared release verification must explicitly limit GITHUB_TOKEN to contents: read');
}
return image;
}
+9
View File
@@ -40,6 +40,11 @@ describe('local release gate contract', () => {
'node scripts/release-preflight.mjs --sources "$VERSION"',
'git commit -m "chore(release): update versions to v$VERSION [skip ci]"',
'git push origin HEAD:main',
' verify-prepared-release:',
' needs: [preflight, prepare-release]',
' runs-on: ubuntu-latest',
' permissions:',
' contents: read',
'ref: ${{ needs.prepare-release.outputs.prepared-commit }}',
'ref: ${{ needs.prepare-release.outputs.prepared-commit }}',
'ref: ${{ needs.prepare-release.outputs.prepared-commit }}',
@@ -66,6 +71,10 @@ describe('local release gate contract', () => {
'git push origin HEAD:main',
'git push origin HEAD:main || true'
))).toThrow('stop when the automatic main push fails');
expect(() => validateReleaseWorkflowContract(workflow.replace(
/ permissions:\r?\n contents: read\r?\n steps:/u,
' steps:'
))).toThrow('explicitly limit GITHUB_TOKEN');
});
it('runs the complete CI-equivalent dependency, verify, and browser sequence', () => {