Skip PyPI publishing for GitHub pre-releases#2800
Conversation
When creating a GitHub release with the 'Set as a pre-release' checkbox checked, the pypi-release workflow will now skip the publish job. This allows cutting release candidates or test releases on GitHub without pushing packages to PyPI. The version-bump-prs workflow already guards on workflow_run.conclusion == 'success', so it naturally won't create version-bump PRs when pypi-release is skipped. Manual workflow_dispatch is unaffected and always publishes. Co-authored-by: openhands <openhands@all-hands.dev>
Python API breakage checks — ✅ PASSEDResult: ✅ PASSED |
REST API breakage checks (OpenAPI) — ✅ PASSEDResult: ✅ PASSED |
all-hands-bot
left a comment
There was a problem hiding this comment.
🟢 Good taste - Simple, elegant solution that eliminates the special case of testing releases.
all-hands-bot
left a comment
There was a problem hiding this comment.
QA Report: Skip PyPI Publishing for GitHub Pre-releases
Verdict:
Summary
The workflow change correctly implements the ability to skip PyPI publishing for pre-releases. The conditional logic works as designed for all three scenarios (workflow_dispatch, regular release, pre-release). One minor suggestion for improved robustness.
Environment Setup
✅ YAML syntax validation: Valid (yamllint)
✅ Workflow validation: No errors (actionlint)
✅ Repository context: Successfully checked out PR branch at commit bb5461d
CI & Test Status
✅ All CI checks PASSING:
- pre-commit: SUCCESS
- Python API: SUCCESS
- REST API (OpenAPI): SUCCESS
- sdk-tests: SUCCESS
- tools-tests: SUCCESS
- agent-server-tests: SUCCESS
- cross-tests: SUCCESS
Functional Verification
✅ Conditional Logic Analysis
Verified the workflow conditional handles all three scenarios correctly:
1. Manual workflow_dispatch trigger:
github.event_name == 'workflow_dispatch'→ true!github.event.release.prerelease→ true (undefined → truthy)- Result: Publish runs ✓
2. Regular release (prerelease=false):
github.event_name == 'workflow_dispatch'→ false!github.event.release.prerelease→ !false → true- Result: Publish runs ✓
3. Pre-release (prerelease=true):
github.event_name == 'workflow_dispatch'→ false!github.event.release.prerelease→ !true → false- Result: Publish is skipped ✓
✅ Downstream Effects Verification
Verified the claim about version-bump-prs workflow:
# Checked .github/workflows/version-bump-prs.yml line 22-25:
if: >
github.event_name == 'workflow_dispatch' ||
(github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'release')Confirmed: When the publish job is skipped due to a pre-release, the workflow conclusion will not be 'success', so version-bump-prs will correctly NOT trigger. No changes needed there.
Unable to Verify
❌ Functional testing with actual GitHub releases: Cannot trigger real GitHub releases in this QA environment to verify:
- Creating a pre-release actually skips PyPI publish
- Creating a regular release actually publishes to PyPI
- Manual workflow_dispatch trigger works correctly
Suggested AGENTS.md guidance for future workflow QA:
## Verifying GitHub Actions Workflow Changes
For workflow changes that cannot be fully tested in the QA environment:
1. Validate YAML/workflow syntax with actionlint
2. Verify conditional logic through scenario analysis
3. Check CI passes on the PR
4. After merge: Monitor actual workflow runs in the Actions tab
5. For critical workflows: Test in a fork or test repository firstIssues Found
🟡 Minor: Conditional expression could be more explicit and defensive (see inline comment)
Verdict
Recommendation: Consider applying the suggested change for improved code clarity, or merge as-is if you're confident in GitHub Actions' handling of undefined properties.
This QA report was generated by an AI assistant (OpenHands) following the /qa-changes methodology.
| # pushing packages to PyPI. Manual workflow_dispatch always runs. | ||
| if: > | ||
| github.event_name == 'workflow_dispatch' || | ||
| !github.event.release.prerelease |
There was a problem hiding this comment.
🟡 Suggestion: Consider making the conditional more explicit to avoid relying on undefined property handling:
| !github.event.release.prerelease | |
| (github.event_name == 'release' && !github.event.release.prerelease) |
The current version works but accesses github.event.release.prerelease even when the release object doesn't exist (during workflow_dispatch). While GitHub Actions handles this gracefully by treating undefined as falsy, being explicit about the event type makes the logic clearer and more defensive.
Alternatively, keep the current version if you prefer brevity and are confident in GitHub Actions' undefined handling.
Summary
When creating a GitHub release with the "Set as a pre-release" checkbox checked, the
pypi-releaseworkflow will now skip the publish job. This allows cutting release candidates or test releases on GitHub without pushing packages to PyPI.How it works
ifcondition to thepublishjob inpypi-release.ymlthat checksgithub.event.release.prereleaseworkflow_dispatchis unaffected and always publishesDownstream effects
The
version-bump-prsworkflow already guards onworkflow_run.conclusion == 'success', so it naturally won't create version-bump PRs whenpypi-releaseis skipped due to a pre-release. No changes needed there.Usage
To create a pre-release that doesn't push to PyPI:
The release will be created on GitHub (visible to the team, with artifacts) but nothing will be published to PyPI.
This PR was created by an AI assistant (OpenHands).
Agent Server images for this PR
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.13-nodejs22-slimgolang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:49f5c84-pythonRun
All tags pushed for this build
About Multi-Architecture Support
49f5c84-python) is a multi-arch manifest supporting both amd64 and arm6449f5c84-python-amd64) are also available if needed