From 0ce41a6b4ecb755ee4b704937ef9b518be911f6e Mon Sep 17 00:00:00 2001 From: Jhin Lee Date: Sun, 18 Oct 2026 11:12:45 -0400 Subject: [PATCH] ci: support preparing SD release artifacts without publishing --- .github/workflows/native_release.yml | 27 ++++++++++++++++++-- README.md | 7 +++++ tests/test_release_workflow.py | 38 ++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/test_release_workflow.py diff --git a/.github/workflows/native_release.yml b/.github/workflows/native_release.yml index efaddd9..73e595f 100644 --- a/.github/workflows/native_release.yml +++ b/.github/workflows/native_release.yml @@ -6,13 +6,17 @@ on: tag: description: Release tag, such as v0.1.0 or v0.1.0-2 required: true + publish: + description: Publish the prepared artifacts as a GitHub release + type: boolean + default: true prerelease: description: Mark the GitHub release as a prerelease type: boolean default: true permissions: - contents: write + contents: read jobs: build: @@ -65,7 +69,7 @@ jobs: path: bin/${{ matrix.target }} if-no-files-found: error - release: + package: needs: build # The SwiftPM XCFramework needs xcodebuild. runs-on: macos-latest @@ -96,6 +100,25 @@ jobs: run: >- python3 tools/apple_xcframework.py consumer "dist/stable-diffusion-native-apple-xcframework-${{ inputs.tag }}.zip" + - name: Upload the prepared release artifacts + uses: actions/upload-artifact@v4 + with: + name: stable-diffusion-native-${{ inputs.tag }} + path: dist/ + if-no-files-found: error + retention-days: 14 + + release: + needs: package + if: ${{ inputs.publish }} + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/download-artifact@v4 + with: + name: stable-diffusion-native-${{ inputs.tag }} + path: dist - uses: softprops/action-gh-release@v2 with: tag_name: ${{ inputs.tag }} diff --git a/README.md b/README.md index 45169be..869d545 100644 --- a/README.md +++ b/README.md @@ -610,6 +610,13 @@ Run the `Native Build & Release` workflow with a tag such as `v0.1.0`. Tags are `vMAJOR.MINOR.PATCH`, with an optional `-N` rebuild counter starting at 1 (`v0.1.0-2`). Each release records the upstream commit in `manifest.json`. +Set `publish=false` to prepare and validate all platform archives and the Apple +XCFramework without creating a tag or GitHub release. The workflow uploads +`stable-diffusion-native-` as a run artifact retained for 14 days. Build +and packaging jobs have read-only repository permissions; only the separate +publication job has write permission, and it is skipped in preparation mode. +Normal release runs keep `publish=true` by default. + Archive names: - `stable-diffusion-native-runtime--.tar.gz` diff --git a/tests/test_release_workflow.py b/tests/test_release_workflow.py new file mode 100644 index 0000000..0c39158 --- /dev/null +++ b/tests/test_release_workflow.py @@ -0,0 +1,38 @@ +"""Keep preparation runs unable to enter the release-writing job.""" + +import unittest +from pathlib import Path + + +ROOT = Path(__file__).resolve().parent.parent + + +class ReleaseWorkflowTest(unittest.TestCase): + def test_preparation_has_no_release_write_path(self): + workflow = (ROOT / ".github/workflows/native_release.yml").read_text() + preparation, marker, release = workflow.partition("\n release:\n") + self.assertTrue(marker, "publication must remain a separate job") + self.assertIn("permissions:\n contents: read\n", preparation) + self.assertNotIn("contents: write", preparation) + self.assertNotIn("action-gh-release", preparation) + self.assertIn("name: stable-diffusion-native-${{ inputs.tag }}", preparation) + self.assertIn("retention-days: 14", preparation) + job_header = release.split(" steps:", 1)[0] + self.assertIn(" needs: package\n", job_header) + self.assertIn(" if: ${{ inputs.publish }}\n", job_header) + self.assertIn(" contents: write\n", job_header) + self.assertEqual(workflow.count("action-gh-release@"), 1) + + def test_normal_release_mode_remains_explicit_and_enabled(self): + workflow = (ROOT / ".github/workflows/native_release.yml").read_text() + self.assertIn( + " publish:\n" + " description: Publish the prepared artifacts as a GitHub release\n" + " type: boolean\n" + " default: true\n", + workflow, + ) + + +if __name__ == "__main__": + unittest.main()