fix(release): isolate draft validation from published assets

This commit is contained in:
Relakkes Yang
2026-08-23 19:36:21 +08:00
parent 417cfdfd69
commit 5fafabfca1
2 changed files with 44 additions and 0 deletions
+31
View File
@@ -15,6 +15,11 @@ on:
required: false
default: true
type: boolean
publish_draft_release:
description: 'Publish manual draft artifacts to GitHub Releases'
required: false
default: false
type: boolean
permissions:
actions: read
@@ -700,6 +705,7 @@ jobs:
if-no-files-found: error
publish-release:
if: github.event_name == 'push' || inputs.draft == false || inputs.publish_draft_release == true
needs: build
runs-on: ubuntu-latest
@@ -724,6 +730,31 @@ jobs:
exit 1
fi
- name: Refuse to overwrite an existing published release
if: github.event_name == 'workflow_dispatch' && inputs.draft == true
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
error_file="${RUNNER_TEMP}/release-view-error.txt"
set +e
release_state=$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/v${{ steps.version.outputs.value }}" --jq '.draft' 2>"$error_file")
status=$?
set -e
if [ "$status" -ne 0 ]; then
if grep -q 'HTTP 404' "$error_file"; then
exit 0
fi
cat "$error_file" >&2
exit "$status"
fi
if [ "$release_state" = "false" ]; then
echo "::error::Refusing to overwrite published release v${{ steps.version.outputs.value }} with manual draft artifacts."
exit 1
fi
- name: Load release notes
id: release_notes
shell: bash
+13
View File
@@ -402,6 +402,19 @@ describe('release desktop workflow', () => {
expect(buildJob).not.toContain('Load release notes')
})
test('manual draft validation cannot overwrite an existing published release', () => {
const workflow = readReleaseWorkflow()
const publishJob = extractJob(workflow, 'publish-release')
expect(workflow).toContain('publish_draft_release:')
expect(workflow).toContain("description: 'Publish manual draft artifacts to GitHub Releases'")
expect(publishJob).toContain("if: github.event_name == 'push' || inputs.draft == false || inputs.publish_draft_release == true")
expect(publishJob).toContain('Refuse to overwrite an existing published release')
expect(publishJob).toContain("if: github.event_name == 'workflow_dispatch' && inputs.draft == true")
expect(publishJob).toContain('Refusing to overwrite published release v${{ steps.version.outputs.value }} with manual draft artifacts')
expect(publishJob.indexOf('Refuse to overwrite an existing published release')).toBeLessThan(publishJob.indexOf('Publish complete GitHub release'))
})
test('release workflow publishes all release assets only after all matrix builds pass', () => {
const workflow = readReleaseWorkflow()
const publishJob = extractJob(workflow, 'publish-release')