repomatic.release.binary module¶
Binary build targets and the names of their release assets.
Defines the Nuitka compilation targets for all supported platforms, the
executable format each one compiles to, and the naming of the binaries a
release publishes. The header parsing that verifies a compiled binary lives in
repomatic.release.verify.
- repomatic.release.binary.BINARY_ASSET_SUFFIXES = ('.bin', '.exe')¶
File extensions identifying compiled binaries among release assets.
The one definition of “a compiled release asset”:
scan-virustotaluploads this set, the release workflow downloads it (--patternflags in_release-engine.yaml),docs/binaries.mdlists it, and the dev-release asset globs derive from it.
- repomatic.release.binary.PYTHON_DIST_SUFFIXES = ('.tar.gz', '.whl')¶
File extensions identifying Python distributions among release assets.
The counterpart of
BINARY_ASSET_SUFFIXES, and the same kind of single definition:pack_binary_assets()excludes this set from the binary upload list (create-releasealready attached those), and the dev-release asset globs add it on top of the compiled binaries.
- repomatic.release.binary.NUITKA_DISABLE_CCACHE_FLAG: Final[str] = '--disable-ccache'¶
The Nuitka option that keeps its ccache wrapper out of a build.
- repomatic.release.binary.MACHO_MAGIC_64: Final[int] = 4277009103¶
Magic of a 64-bit Mach-O header, in the file’s own (little) endianness.
- repomatic.release.binary.MACHO_FAT_MAGICS: Final[frozenset[int]] = frozenset({3405691582, 3405691583})¶
Big-endian magics of universal (fat) Mach-O containers, 32- and 64-bit.
- class repomatic.release.binary.BinaryFormat(label, extension, floor_label)[source]¶
Bases:
EnumExecutable container format a compiled binary uses.
Each member owns what varies by format: the name messages print, the file extension its executables take, and what a target’s floor measures. The floor label doubles as the enforceability flag, since a format recording no measurable floor has nothing to label. The header parser for each format is
read_header().Note
Members carry no magic bytes of their own:
detect()needs to read them in a fixed order (a fat Mach-O and a PE both fail an equality test on the first four bytes), so the probe stays one method rather than a table.- ELF = ('elf', 'bin', 'glibc')¶
- MACHO = ('macho', 'bin', 'macOS')¶
- PE = ('pe', 'exe', None)¶
- label¶
Lowercase format name, as printed in verification messages.
- extension¶
File extension executables of this format take.
- floor_label¶
What a target’s floor measures for this format, or
None.Nonemarks a format whose headers record nothing a scan can check, soBuildTarget.enforced_floorreports no floor to enforce. Only PE is in that case: its version headers are nominal, and the Windows floor is CPython’s own support policy, not a linker artifact.
- repomatic.release.binary.PLATFORM_FORMATS: Final[dict[Platform | Group, BinaryFormat]] = {Group(id='linux', name='Linux distributions'): BinaryFormat.ELF, Platform(id='macos', name='macOS'): BinaryFormat.MACHO, Platform(id='windows', name='Windows'): BinaryFormat.PE}¶
Executable format each build platform compiles to.
Read through
BuildTarget.binary_format, which is how every caller reaches it.
- repomatic.release.binary.MACHINE_IDS: Final[dict[tuple[BinaryFormat, Architecture], int]] = {(BinaryFormat.ELF, Architecture(id='aarch64', name='ARM64 (AArch64)')): 183, (BinaryFormat.ELF, Architecture(id='x86_64', name='x86-64 (AMD64)')): 62, (BinaryFormat.MACHO, Architecture(id='aarch64', name='ARM64 (AArch64)')): 16777228, (BinaryFormat.MACHO, Architecture(id='x86_64', name='x86-64 (AMD64)')): 16777223, (BinaryFormat.PE, Architecture(id='aarch64', name='ARM64 (AArch64)')): 43620, (BinaryFormat.PE, Architecture(id='x86_64', name='x86-64 (AMD64)')): 34404}¶
Machine identifier a binary’s header carries, per format and architecture.
One table rather than three, keyed the way
PlatformKeykeys the tool registry: the value is the raw header integer of each format, so a caller compares it against whatever the matching parser returns.
- class repomatic.release.binary.BuildTarget(id, runner, platform, arch, floor, container=None)[source]¶
Bases:
objectOne Nuitka compile target: a runner image, a platform and an architecture.
Carries the metadata every consumer branches on, and the methods that interpret it, so a caller asks the target what its binaries must look like instead of re-deriving it from a platform name.
Platform and architecture are Extra Platforms traits rather than free strings, which is the same vocabulary
PlatformKeykeys the downloaded-binary registry on.as_matrix_entry()renders both back to their ids for the workflow matrix.Every field is irreducible: anything a format decides (the file extension, what the floor measures, which header field to read) lives on
BinaryFormatinstead.- id: str¶
Short target identifier, chosen for user-friendliness.
It names the published release asset, so it must stay stable: download URLs,
docs/install.mdand thebinaries.csvcatalog all match on it.Note
It is deliberately not derived from
platformandarch, even though all six targets currently read{platform}-{short arch}. The asset names froze on the shortx64andarm64spellings while those fields carry the canonical extra-platforms ids, and a future target splitting an existing pair (a musl Linux, say) would need a name the derivation cannot produce.tests/test_binary.pypins the pairing.
- runner: str¶
Runner image, as named in GitHub-hosted runners.
Named for what it holds, not for the
osmatrix key it renders to:ubuntu-26.04-armis an image, andplatformis the operating system.Hint
One compile job per target, each on one of the six runners the test matrix already covers, so a published binary is built on an image the suite is validated against. The targets are exactly
KNOWN_RUNNERS, not a separate selection: an image is added here by widening the test axes, never on its own.
- arch: Architecture¶
CPU architecture the binary is compiled for.
- floor: str¶
Oldest runtime the binary is built to run on.
What the version counts is the format’s business, named by
BinaryFormat.floor_label: a glibc symbol version on ELF, a macOS deployment target on Mach-O, a Windows release on PE. The first two are measured out of the compiled files byverify_binary_floor(); the third is documentation, since PE version headers record nothing to measure.On macOS,
build_envalso exports it asMACOSX_DEPLOYMENT_TARGETfor the compile.
- container: str | None = None¶
OCI image the Linux compile and self-test jobs run in.
Passed to the
container:key of the release workflow. Compiling insidemanylinux_2_28caps the toolchain at glibc 2.28, so binaries stop inheriting the floor of whatever glibc the current runner image ships.Declared per target rather than derived from
platform, which would assume every Linux target is a manylinux one. Absent on macOS and Windows: GitHub Actions containers do not exist for those runners.
- property binary_format: BinaryFormat¶
Executable format the compiler emits for this target.
- property nuitka_flags: tuple[str, ...]¶
Nuitka options the compile of this target adds to the shared ones.
macOS turns ccache off. Nuitka downloads its own ccache binary there, with no checksum at the call site (Nuitka#3997), and runs it under Rosetta on arm at a measured cost. The download is supply-chain surface for no gain: see
compile_cache.docs/nuitka.mdsays what re-enabling it would take.
- property compile_cache: bool¶
Whether a persisted Nuitka compile cache speeds up this target.
A target compiling with ccache off writes no object a later run could reuse, so the release workflow neither restores nor saves its cache.
- property build_env: dict[str, str]¶
Environment variables the compile of this target needs.
macOS pins
MACOSX_DEPLOYMENT_TARGETtofloor. Without it, compiled objects and processed dylibs inherit the build runner’s own macOS version as their minimum.
- as_matrix_entry()[source]¶
Flat, JSON-safe mapping of this target, for GitHub matrix inclusion.
Renders
platformandarchback to their extra-platforms ids, the spelling the workflow expressions (matrix.platform_id) andtests.yaml’s runner check compare against, andrunnerback to theoskeyruns-on:reads. A target with no container omits the key, so an entry carries only what applies to it.
- repomatic.release.binary.NUITKA_BUILD_TARGETS: Final[dict[str, BuildTarget]] = {'linux-arm64': BuildTarget(id='linux-arm64', runner='ubuntu-26.04-arm', platform=Group(id='linux', name='Linux distributions'), arch=Architecture(id='aarch64', name='ARM64 (AArch64)'), floor='2.28', container='quay.io/pypa/manylinux_2_28_aarch64@sha256:e7035406e58d96b7407246af1f6514a3cbd753a0025b42b9adfbeadd3b29ba80'), 'linux-x64': BuildTarget(id='linux-x64', runner='ubuntu-26.04', platform=Group(id='linux', name='Linux distributions'), arch=Architecture(id='x86_64', name='x86-64 (AMD64)'), floor='2.28', container='quay.io/pypa/manylinux_2_28_x86_64@sha256:fdb9a9c223b215604dc7b6f7e8fff4b39bfea5fbaa7777a2e5544a60dfa437f8'), 'macos-arm64': BuildTarget(id='macos-arm64', runner='macos-26', platform=Platform(id='macos', name='macOS'), arch=Architecture(id='aarch64', name='ARM64 (AArch64)'), floor='11.0', container=None), 'macos-x64': BuildTarget(id='macos-x64', runner='macos-26-intel', platform=Platform(id='macos', name='macOS'), arch=Architecture(id='x86_64', name='x86-64 (AMD64)'), floor='10.15', container=None), 'windows-arm64': BuildTarget(id='windows-arm64', runner='windows-11-arm', platform=Platform(id='windows', name='Windows'), arch=Architecture(id='aarch64', name='ARM64 (AArch64)'), floor='11', container=None), 'windows-x64': BuildTarget(id='windows-x64', runner='windows-2025', platform=Platform(id='windows', name='Windows'), arch=Architecture(id='x86_64', name='x86-64 (AMD64)'), floor='10', container=None)}¶
GitHub-hosted runner matrix for Nuitka builds, keyed by target name.
The roster is closed: every entry compiles on a runner the test matrix already covers, and the key doubles as the compiled binary’s published identifier. See
BuildTargetfor what each field means and which of them are frozen.Note
A target leaves the roster when its runner image does
A published binary needs a runner to compile on, so GitHub’s Available Images table sets how long an architecture lives here.
macos-x64therefore ships for as long as that table offers an Intel macOS label, on GitHub’s schedule rather than Apple’s. The two diverge: Apple lets Mac App Store apps go arm64-only and drops Intel in macOS 27, while an Intel Mac stays on macOS 26 Tahoe and keeps running it, so those users still want the binary.Drop the target once
sync-runner-imagesreports the image deprecated, and not before. Removing one is a single change across two files: this roster andTEST_RUNNERS_FULLare held equal bytests/test_workflows.py::test_binary_build_targets_are_the_test_axes. A retirement onto a successor image needs no edit here: each target reads its runner from a slot constant ofrepomatic.matrix.axes, which is whatsync-runner-imagesrewrites.
- repomatic.release.binary.FLAT_BUILD_TARGETS: Final[list[dict[str, str]]] = [{'arch': 'aarch64', 'container': 'quay.io/pypa/manylinux_2_28_aarch64@sha256:e7035406e58d96b7407246af1f6514a3cbd753a0025b42b9adfbeadd3b29ba80', 'extension': 'bin', 'floor': '2.28', 'os': 'ubuntu-26.04-arm', 'platform_id': 'linux', 'target': 'linux-arm64'}, {'arch': 'x86_64', 'container': 'quay.io/pypa/manylinux_2_28_x86_64@sha256:fdb9a9c223b215604dc7b6f7e8fff4b39bfea5fbaa7777a2e5544a60dfa437f8', 'extension': 'bin', 'floor': '2.28', 'os': 'ubuntu-26.04', 'platform_id': 'linux', 'target': 'linux-x64'}, {'arch': 'aarch64', 'extension': 'bin', 'floor': '11.0', 'os': 'macos-26', 'platform_id': 'macos', 'target': 'macos-arm64'}, {'arch': 'x86_64', 'extension': 'bin', 'floor': '10.15', 'os': 'macos-26-intel', 'platform_id': 'macos', 'target': 'macos-x64'}, {'arch': 'aarch64', 'extension': 'exe', 'floor': '11', 'os': 'windows-11-arm', 'platform_id': 'windows', 'target': 'windows-arm64'}, {'arch': 'x86_64', 'extension': 'exe', 'floor': '10', 'os': 'windows-2025', 'platform_id': 'windows', 'target': 'windows-x64'}]¶
List of build targets in a flat format, suitable for matrix inclusion.
- repomatic.release.binary.current_build_target()[source]¶
The build target of the machine this runs on.
Matches the running platform and architecture against
NUITKA_BUILD_TARGETS. A Linux distribution extra-platforms cannot name still matches the Linux targets, as the tool registry treats it.- Return type:
- Returns:
The target, or
Nonewhen no target builds on this machine.
- repomatic.release.binary.binary_name(package, target, version=None)[source]¶
Compose a compiled binary’s release-asset filename.
The one definition of the naming convention:
{package}-{version}-{target}.{ext}for the versioned upload, and with no version the stable alias ({package}-{target}.{ext}) backing thereleases/latest/downloadURLs. The extension comes fromNUITKA_BUILD_TARGETS.- Return type:
- repomatic.release.binary.versionless_alias(filename, version)[source]¶
Map a versioned binary filename to its stable alias, or
None.Strips the
-{version}-segment (papaya-1.2.3-linux-arm64.binbecomespapaya-linux-arm64.bin). ReturnsNonefor filenames that carry no such segment or are not compiled binaries, so callers can filter and map in one pass.
- repomatic.release.binary.binary_filename_re(package)[source]¶
Match a package binary filename, versioned or versionless.
Captures
targetandext, both alternations derived fromNUITKA_BUILD_TARGETSso a new build target extends the pattern without anyone editing a regex. The release freeze rewrites both spellings onto the versioned form through this;tests/test_platform_keys.pypins the pattern against every target.
- repomatic.release.binary.pack_binary_assets(dist_dir, version)[source]¶
Pack a release’s upload list, materializing the versionless aliases.
Mirrors what the release engine’s upload step needs: every file in dist_dir except the Python distributions (
create-releasealready uploaded those), plus a byte-identical versionless alias copied beside each versioned binary so the stablereleases/latest/downloadURLs always resolve. Aliases share their sibling’s digest, which is what lets artifact attestations verify them unchanged and the binaries catalog collapse them (seebinaries_page._binary_assets).Idempotent: re-running overwrites the same aliases with the same bytes.
