11name : PyAuto Release
22
33on :
4- # --- PAUSED 2026-07-06: routine cron disabled org-wide; re-enable by uncommenting ---
5- # schedule:
6- # - cron: '0 2 * * 1-5' # 2 AM UTC weekdays
4+ schedule :
5+ # 2 AM UTC weekdays. Scheduled runs REHEARSE (TestPyPI-only) until the repo
6+ # variable RELEASE_MODE is set to 'live' — see the resolve_mode job.
7+ - cron : ' 0 2 * * 1-5'
78 workflow_dispatch :
89 inputs :
910 minor_version :
2425 default : ' false'
2526
2627jobs :
28+ # Single source of truth for rehearsal-vs-live. workflow_dispatch passes the
29+ # `rehearsal` input through unchanged; scheduled runs REHEARSE (TestPyPI-only)
30+ # until the PyAutoBuild repo variable RELEASE_MODE is set to 'live' — flipping
31+ # the daily release to real PyPI is a one-variable change, no commit needed.
32+ # The `needs` context is direct-only in GitHub Actions, so every job gating on
33+ # this output must list resolve_mode in its own needs.
34+ resolve_mode :
35+ runs-on : ubuntu-latest
36+ outputs :
37+ rehearsal : ${{ steps.mode.outputs.rehearsal }}
38+ steps :
39+ - name : Resolve rehearsal vs live
40+ id : mode
41+ run : |
42+ if [ "${{ github.event_name }}" = "schedule" ]; then
43+ if [ "${{ vars.RELEASE_MODE }}" = "live" ]; then
44+ REHEARSAL=false
45+ else
46+ REHEARSAL=true
47+ fi
48+ else
49+ REHEARSAL="${{ github.event.inputs.rehearsal || 'false' }}"
50+ fi
51+ echo "rehearsal=${REHEARSAL}" >> "$GITHUB_OUTPUT"
52+ echo "event=\`${{ github.event_name }}\` RELEASE_MODE=\`${{ vars.RELEASE_MODE }}\` → rehearsal=\`${REHEARSAL}\`" >> "$GITHUB_STEP_SUMMARY"
53+
2754 version_number :
2855 runs-on : ubuntu-latest
56+ needs : resolve_mode
2957 outputs :
3058 version_number : ${{ steps.version_number.outputs.version_number }}
3159 steps :
4674 # source of *this* run — a bare `--skip-existing` would silently leave
4775 # stale wheels from a prior rehearsal of the same date/minor in place.
4876 # run_number*100+run_attempt is unique per dispatch and per re-run attempt.
49- if [ "${{ github.event.inputs .rehearsal }}" = "true" ]
77+ if [ "${{ needs.resolve_mode.outputs .rehearsal }}" = "true" ]
5078 then
5179 DEV_SEGMENT=$(( ${{ github.run_number }} * 100 + RUN_ATTEMPT ))
5280 VERSION="${DATE_FORMATTED}.${MINOR_VERSION:-${{ github.run_number }}}.dev${DEV_SEGMENT}"
@@ -235,11 +263,12 @@ jobs:
235263 run_smoke_tests :
236264 runs-on : ubuntu-latest
237265 needs :
266+ - resolve_mode
238267 - release_test_pypi
239268 - version_number
240269 # Skipped in rehearsal mode: rehearsal halts after the TestPyPI publish; the
241270 # workspace integration surface is validated downstream by Heart, not here.
242- if : " ${{ github.event.inputs .rehearsal != 'true' }}"
271+ if : " ${{ needs.resolve_mode.outputs .rehearsal != 'true' }}"
243272 strategy :
244273 fail-fast : false
245274 matrix :
@@ -320,7 +349,7 @@ jobs:
320349 # release_workspaces, bump_library_colab_urls, and (via release_workspaces)
321350 # wiki_currency_check / wiki_drift_issue. The full-release path is unchanged
322351 # when rehearsal is not 'true'.
323- if : " ${{ github.event.inputs .rehearsal != 'true' }}"
352+ if : " ${{ needs.resolve_mode.outputs .rehearsal != 'true' }}"
324353 env :
325354 TWINE_REPOSITORY : pypi
326355 TWINE_USERNAME : __token__
@@ -330,6 +359,7 @@ jobs:
330359 # (workspace-validation.yml). Build is a pure executor: it gates only on
331360 # the TestPyPI build + version. Release readiness is enforced upstream by
332361 # the release agent via `pyauto-heart readiness`.
362+ - resolve_mode
333363 - release_test_pypi
334364 - version_number
335365 strategy :
@@ -402,9 +432,10 @@ jobs:
402432 publish_release_notes :
403433 runs-on : ubuntu-latest
404434 needs :
435+ - resolve_mode
405436 - release
406437 - version_number
407- if : " ${{ github.event.inputs .rehearsal != 'true' }}"
438+ if : " ${{ needs.resolve_mode.outputs .rehearsal != 'true' }}"
408439 strategy :
409440 fail-fast : false
410441 matrix :
@@ -613,9 +644,10 @@ jobs:
613644 env :
614645 PAT : ${{ secrets.PAT_PYAUTOLABS }}
615646 needs :
647+ - resolve_mode
616648 - release
617649 - version_number
618- if : " ${{ github.event.inputs .rehearsal != 'true' }}"
650+ if : " ${{ needs.resolve_mode.outputs .rehearsal != 'true' }}"
619651 strategy :
620652 fail-fast : false
621653 matrix :
@@ -658,9 +690,10 @@ jobs:
658690 # ---------------------------------------------------------------------------
659691 wiki_currency_check :
660692 needs :
693+ - resolve_mode
661694 - version_number
662695 - release_workspaces
663- if : " ${{ github.event.inputs .rehearsal != 'true' }}"
696+ if : " ${{ needs.resolve_mode.outputs .rehearsal != 'true' }}"
664697 uses : PyAutoLabs/autolens_assistant/.github/workflows/wiki-currency.yml@main
665698 with :
666699 stack_version : ${{ needs.version_number.outputs.version_number }}
@@ -711,9 +744,10 @@ jobs:
711744 rehearsal_version :
712745 runs-on : ubuntu-latest
713746 needs :
747+ - resolve_mode
714748 - version_number
715749 - release_test_pypi
716- if : " ${{ github.event.inputs .rehearsal == 'true' }}"
750+ if : " ${{ needs.resolve_mode.outputs .rehearsal == 'true' }}"
717751 steps :
718752 - name : Record resolved TestPyPI version
719753 run : |
0 commit comments