fix(ci): guard generated dev release commits

This commit is contained in:
Kai (Tam Nhu) Tran
2026-04-28 22:33:14 -04:00
committed by GitHub
parent fea7f18687
commit 8d4a7761b1
2 changed files with 33 additions and 5 deletions
+26 -4
View File
@@ -10,11 +10,33 @@ concurrency:
cancel-in-progress: false
jobs:
guard:
if: ${{ github.ref == 'refs/heads/dev' }}
runs-on: [self-hosted, linux, x64]
outputs:
should_release: ${{ steps.release-guard.outputs.should_release }}
steps:
- name: Check release recursion guard
id: release-guard
shell: bash
run: |
SHOULD_RELEASE=true
if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then
HEAD_SUBJECT=$(jq -r '.head_commit.message // "" | split("\n")[0]' "$GITHUB_EVENT_PATH")
case "$HEAD_SUBJECT" in
"chore(release): "*)
SHOULD_RELEASE=false
echo "Skipping generated dev release commit: $HEAD_SUBJECT"
;;
esac
fi
echo "should_release=$SHOULD_RELEASE" >> "$GITHUB_OUTPUT"
release:
# Release commits must still report PR CI when dev is promoted to main.
# Skip recursive dev releases by subject instead of GitHub's global [skip ci].
if: ${{ github.ref == 'refs/heads/dev' && (github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore(release): ')) }}
runs-on: ubuntu-latest
needs: guard
if: ${{ needs.guard.outputs.should_release == 'true' }}
runs-on: [self-hosted, linux, x64]
permissions:
contents: write
@@ -24,6 +24,8 @@ describe('dev release workflow', () => {
expect(workflow).toContain('name: Dev Release');
expect(workflow).toContain('branches: [dev]');
expect(workflow.match(/runs-on: \[self-hosted, linux, x64\]/g)).toHaveLength(2);
expect(workflow).not.toContain('runs-on: ubuntu-latest');
expect(checkoutSection).toContain("token: ${{ secrets.PAT_TOKEN }}");
expect(checkoutSection).not.toContain('token: ${{ github.token }}');
expect(releaseSection).toContain('GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}');
@@ -39,7 +41,11 @@ describe('dev release workflow', () => {
const workflow = fs.readFileSync(workflowPath, 'utf8');
const script = fs.readFileSync(scriptPath, 'utf8');
expect(workflow).toContain("!startsWith(github.event.head_commit.message, 'chore(release): ')");
expect(workflow).toContain('should_release: ${{ steps.release-guard.outputs.should_release }}');
expect(workflow).toContain('"chore(release): "*)');
expect(workflow).toContain("needs.guard.outputs.should_release == 'true'");
expect(workflow).not.toContain('github.event.head_commit.message');
expect(workflow).not.toContain('!startsWith(');
expect(workflow).not.toContain("contains(github.event.head_commit.message, '[skip ci]')");
expect(script).toContain('LEGACY_CURRENT_RELEASE_SUBJECT="${CURRENT_RELEASE_SUBJECT} [skip ci]"');
expect(script).toContain('[[ "$HEAD_SUBJECT" == "$CURRENT_RELEASE_SUBJECT" ]]');