Skip to content

Commit 11699ee

Browse files
PBS-style date-keyed releases + Node 24 actions (#14)
* Date-keyed releases (PBS-style): full version in filenames Restructures the publish step so that a manually triggered workflow_dispatch with a `release_date` input (YYYYMMDD) produces a single GitHub release tagged by that date, containing every per-platform tarball from every matrix entry. Mirrors what astral-sh/python-build-standalone already does and what we already consume in flet-dev/serious-python's package_command via _release.standaloneReleaseDate. Why move away from one-release-per-python-minor: * Re-cutting a release for a build fix (e.g. the Python.app strip we just landed) currently has to clobber an existing tag, which breaks reproducibility for any downstream that pinned to it. * Several platform fixes in the past month had to wait for a coordinated "all minor versions get a fresh tarball" moment; date tags decouple that — we just cut a new date once everything we care about builds. * Symmetric with how flet-dev/serious-python's package_command resolves its astral-sh CPython tarball: pin a date, not a minor. Changes: * build-python.yml: - workflow_dispatch gains a `release_date` input (YYYYMMDD). - New publish-release job downloads ALL matrix artifacts and publishes one release tagged ${release_date}. - Publish only fires on workflow_dispatch with a non-empty release_date; pushes still exercise the matrix (artifacts left for inspection) but don't touch releases. * build-python-version.yml: - Removed the per-version publish-release job (moved to parent). - Matrix artifact upload names now include the full Python version (e.g. python-darwin-3.14.6 instead of python-darwin-3.14) so the parent workflow can ingest multiple patch versions of the same minor without artifact-name collisions. - Darwin packagers receive the full version directly so their tarball filenames carry it verbatim. * Per-platform packagers (darwin/ios, android, linux, windows): - Tarball/zip filenames switch from $PYTHON_VERSION_SHORT to the full $PYTHON_VERSION (e.g. python-macos-dart-3.14.6.tar.gz). The internal lookups that need the short version derive it inline. - mobile-forge artifacts follow the same naming convention. Consumer side (serious-python's prepare_*.sh, build.gradle, CMakeLists) still needs a follow-up to: - Read a new PYTHON_BUILD_RELEASE (YYYYMMDD) env var instead of using "v$PYTHON_VERSION" as the release tag. - Reference tarballs by full Python version in the URL. - Lay them out as $FLET_CACHE_DIR/python-build/<release>/<file>. That migration is independent of this PR and will land separately. * ci: bump actions/{checkout,upload-artifact,download-artifact} v4 -> v5 The previous releases bundled Node.js 20 runtimes; GitHub deprecated Node 20 in actions on 2026-06-16 with full removal on 2026-09-16, and the workflow now emits a "Node.js 20 actions are deprecated" warning on every matrix entry. v5 ships on Node 24 across all three actions and is otherwise drop-in compatible with our usage. setup-python is already on v6 (Node 24 native). softprops/action-gh- release@v2 still runs on Node 20 — leaving it pending an upstream v3 since it only fires on the new workflow_dispatch publish path and won't add warning noise to push-driven runs. * ci: bump actions to latest majors (Node 24) The earlier v4->v5 bump didn't silence the Node 20 deprecation warnings: actions/upload-artifact@v5 and actions/download-artifact@v5 only have "preliminary" Node 24 support and still default to Node 20. The runtime default flips to Node 24 only at v6+. Move every action to its current latest major (all node24): actions/checkout v5 -> v6 actions/upload-artifact v5 -> v7 actions/download-artifact v5 -> v8 softprops/action-gh-release v2 -> v3 actions/setup-python v6 (already latest, node24) All inputs in use remain supported; artifacts stay zipped so upload v7 / download v8 (direct-upload/decompress changes) and download v8's default digest-mismatch=error don't affect this workflow.
1 parent 352b7fe commit 11699ee

6 files changed

Lines changed: 81 additions & 59 deletions

File tree

.github/workflows/build-python-version.yml

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
runs-on: macos-26
3535
steps:
3636
- name: Checkout
37-
uses: actions/checkout@v4
37+
uses: actions/checkout@v6
3838

3939
- name: Derive short Python version
4040
shell: bash
@@ -58,18 +58,23 @@ jobs:
5858
5959
# mobile-forge artifact: iOS-only install+support tree (same structure as before).
6060
# Captured before the macOS build also writes into ./support / ./install.
61-
tar -czf dist/python-ios-mobile-forge-$PYTHON_VERSION_SHORT.tar.gz install support
61+
tar -czf dist/python-ios-mobile-forge-$PYTHON_VERSION.tar.gz install support
6262
6363
# macOS: universal2 framework built from source (all versions).
6464
python build_macos.py "$PYTHON_VERSION"
6565
66-
bash ./package-ios-for-dart.sh . "$PYTHON_VERSION_SHORT"
67-
bash ./package-macos-for-dart.sh . "$PYTHON_VERSION_SHORT"
66+
# Package scripts receive the FULL Python version: the tarball name
67+
# carries it verbatim so a date-keyed release can host multiple
68+
# patches of the same minor (e.g. 3.14.5 + 3.14.6) side by side.
69+
# Internal lookups inside the scripts derive the short version
70+
# themselves where they need it.
71+
bash ./package-ios-for-dart.sh . "$PYTHON_VERSION"
72+
bash ./package-macos-for-dart.sh . "$PYTHON_VERSION"
6873
6974
- name: Upload Darwin build artifacts
70-
uses: actions/upload-artifact@v4
75+
uses: actions/upload-artifact@v7
7176
with:
72-
name: python-darwin-${{ env.PYTHON_VERSION_SHORT }}
77+
name: python-darwin-${{ env.PYTHON_VERSION }}
7378
path: darwin/dist/python-*.tar.gz
7479
if-no-files-found: error
7580

@@ -78,7 +83,7 @@ jobs:
7883
runs-on: ubuntu-latest
7984
steps:
8085
- name: Checkout
81-
uses: actions/checkout@v4
86+
uses: actions/checkout@v6
8287

8388
- name: Derive short Python version
8489
shell: bash
@@ -102,7 +107,7 @@ jobs:
102107
run: |
103108
bash ./build-all.sh "$PYTHON_VERSION"
104109
mkdir -p dist
105-
tar -czf dist/python-android-mobile-forge-$PYTHON_VERSION_SHORT.tar.gz install support
110+
tar -czf dist/python-android-mobile-forge-$PYTHON_VERSION.tar.gz install support
106111
bash ./package-for-dart.sh install "$PYTHON_VERSION" arm64-v8a
107112
bash ./package-for-dart.sh install "$PYTHON_VERSION" x86_64
108113
read version_major version_minor < <(echo "$PYTHON_VERSION" | sed -E 's/^([0-9]+)\.([0-9]+).*/\1 \2/')
@@ -120,9 +125,9 @@ jobs:
120125
run: python3 -m unittest discover -s android/tests -t android/tests -v
121126

122127
- name: Upload build artifacts
123-
uses: actions/upload-artifact@v4
128+
uses: actions/upload-artifact@v7
124129
with:
125-
name: python-android-${{ env.PYTHON_VERSION_SHORT }}
130+
name: python-android-${{ env.PYTHON_VERSION }}
126131
path: android/dist/python-android-*.tar.gz
127132
if-no-files-found: error
128133

@@ -131,7 +136,7 @@ jobs:
131136
runs-on: ubuntu-latest
132137
steps:
133138
- name: Checkout
134-
uses: actions/checkout@v4
139+
uses: actions/checkout@v6
135140

136141
- name: Derive short Python version
137142
shell: bash
@@ -153,17 +158,17 @@ jobs:
153158
bash ./package-for-linux.sh aarch64 ""
154159
155160
- name: Upload build artifacts
156-
uses: actions/upload-artifact@v4
161+
uses: actions/upload-artifact@v7
157162
with:
158-
name: python-linux-${{ env.PYTHON_VERSION_SHORT }}
163+
name: python-linux-${{ env.PYTHON_VERSION }}
159164
path: linux/python-linux-dart-*.tar.gz
160165
if-no-files-found: error
161166

162167
build-windows:
163168
name: Build Python for Windows
164169
runs-on: windows-2022
165170
steps:
166-
- uses: actions/checkout@v4
171+
- uses: actions/checkout@v6
167172

168173
- name: Derive short Python version
169174
shell: pwsh
@@ -184,44 +189,12 @@ jobs:
184189
-PythonVersionShort "${{ env.PYTHON_VERSION_SHORT }}"
185190
186191
- name: Upload build artifacts
187-
uses: actions/upload-artifact@v4
192+
uses: actions/upload-artifact@v7
188193
with:
189-
name: python-windows-${{ env.PYTHON_VERSION_SHORT }}
194+
name: python-windows-${{ env.PYTHON_VERSION }}
190195
path: windows/python-windows-for-dart-*.zip
191196
if-no-files-found: error
192197

193-
publish-release:
194-
name: Publish Release Assets
195-
runs-on: ubuntu-latest
196-
# Only publish GitHub release assets from the main branch; other branches still
197-
# build (and upload per-job artifacts) but don't touch releases.
198-
if: github.ref == 'refs/heads/main'
199-
needs:
200-
- build-darwin
201-
- build-android
202-
- build-linux
203-
- build-windows
204-
permissions:
205-
contents: write
206-
steps:
207-
- name: Derive short Python version
208-
shell: bash
209-
run: |
210-
echo "PYTHON_VERSION_SHORT=$(echo "$PYTHON_VERSION" | cut -d. -f1,2)" >> "$GITHUB_ENV"
211-
212-
- name: Download all build artifacts
213-
uses: actions/download-artifact@v4
214-
with:
215-
pattern: python-*-${{ env.PYTHON_VERSION_SHORT }}
216-
path: release-artifacts
217-
merge-multiple: true
218-
219-
- name: Publish all artifacts to release
220-
uses: softprops/action-gh-release@v2
221-
with:
222-
tag_name: v${{ env.PYTHON_VERSION_SHORT }}
223-
files: release-artifacts/*
224-
fail_on_unmatched_files: true
225-
generate_release_notes: false
226-
draft: false
227-
prerelease: false
198+
# The publish-release job lives in the parent workflow (build-python.yml):
199+
# date-keyed releases collect tarballs from every matrix entry into one
200+
# release, so the publish step has to run after the full matrix completes.

.github/workflows/build-python.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ on:
44
push:
55
pull_request:
66
workflow_dispatch:
7+
inputs:
8+
release_date:
9+
description: >
10+
Release tag (YYYYMMDD). When set, a single GitHub release with that
11+
tag is created and all per-platform tarballs from every matrix entry
12+
are published as assets. Leave empty for a build-only run that uploads
13+
per-job artifacts but does not publish a release.
14+
required: false
15+
type: string
16+
default: ""
717

818
# Cancel in-flight runs when a newer event arrives for the same logical branch.
919
concurrency:
@@ -24,3 +34,34 @@ jobs:
2434
with:
2535
python_version: ${{ matrix.python_version }}
2636
secrets: inherit
37+
38+
publish-release:
39+
name: Publish Release Assets
40+
runs-on: ubuntu-latest
41+
# Date-keyed releases (PBS-style): only publish when an operator explicitly
42+
# triggers via workflow_dispatch with a `release_date` input. Pushes still
43+
# exercise the matrix but leave per-job artifacts for inspection and do
44+
# not touch GitHub releases.
45+
if: github.event_name == 'workflow_dispatch' && inputs.release_date != ''
46+
needs:
47+
- build-matrix
48+
permissions:
49+
contents: write
50+
steps:
51+
- name: Download all build artifacts
52+
uses: actions/download-artifact@v8
53+
with:
54+
pattern: python-*
55+
path: release-artifacts
56+
merge-multiple: true
57+
58+
- name: Publish all artifacts to release
59+
uses: softprops/action-gh-release@v3
60+
with:
61+
tag_name: ${{ inputs.release_date }}
62+
name: ${{ inputs.release_date }}
63+
files: release-artifacts/*
64+
fail_on_unmatched_files: true
65+
generate_release_notes: false
66+
draft: false
67+
prerelease: false

android/package-for-dart.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,7 @@ done
121121

122122
rm -rf $build_dir/lib
123123

124-
# final archive
125-
tar -czf dist/python-android-dart-$python_version_short-$abi.tar.gz -C $build_dir .
124+
# final archive — filename uses the FULL python version (e.g. 3.14.6, not
125+
# 3.14) so a single date-keyed release can host multiple patches of the
126+
# same minor side by side.
127+
tar -czf dist/python-android-dart-$python_version-$abi.tar.gz -C $build_dir .

darwin/package-ios-for-dart.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,7 @@ rm -rf __pycache__
8282
rm -rf **/__pycache__
8383
cd -
8484

85-
# final archive
86-
tar -czf dist/python-ios-dart-$python_version_short.tar.gz -C $build_dir .
85+
# final archive — filename uses the FULL python version (e.g. 3.14.6, not
86+
# 3.14) so a single date-keyed release can host multiple patches of the
87+
# same minor side by side.
88+
tar -czf dist/python-ios-dart-$python_version.tar.gz -C $build_dir .

linux/package-for-linux.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,7 @@ fi
4747
mkdir -p $PYTHON_ARCH/dist
4848
rsync -av --exclude-from=python-linux-dart.exclude $PYTHON_ARCH/build/python/* $PYTHON_ARCH/dist
4949

50-
# archive
51-
tar -czf "python-linux-dart-$PYTHON_VERSION_SHORT-$PYTHON_ARCH.tar.gz" -C "$PYTHON_ARCH/dist" .
50+
# archive — filename uses the FULL python version (e.g. 3.14.6, not 3.14)
51+
# so a single date-keyed release can host multiple patches of the same
52+
# minor side by side.
53+
tar -czf "python-linux-dart-$PYTHON_VERSION-$PYTHON_ARCH.tar.gz" -C "$PYTHON_ARCH/dist" .

windows/package-for-dart.ps1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ $srcDir = Join-Path $srcRoot "Python-$PythonVersion"
2020
$pcbuildDir = Join-Path $srcDir "PCbuild\amd64"
2121
$pythonTag = $PythonVersionShort -replace '\.', ''
2222

23-
$packageRoot = Join-Path $workspace "windows\python-windows-for-dart-$PythonVersionShort"
24-
$zipPath = Join-Path $workspace "windows\python-windows-for-dart-$PythonVersionShort.zip"
23+
# Filename uses the FULL python version (e.g. 3.14.6, not 3.14) so a single
24+
# date-keyed release can host multiple patches of the same minor side by side.
25+
$packageRoot = Join-Path $workspace "windows\python-windows-for-dart-$PythonVersion"
26+
$zipPath = Join-Path $workspace "windows\python-windows-for-dart-$PythonVersion.zip"
2527
$excludeListPath = Join-Path $workspace "windows\python-windows-dart.exclude"
2628
$keepImportLibs = @("python3.lib", "python3_d.lib", "python$pythonTag.lib", "python${pythonTag}_d.lib")
2729

0 commit comments

Comments
 (0)