Skip to content

add linux release binaries for ci consumers#2

Merged
anmorgunov merged 1 commit into
masterfrom
build/linux-release-binary
May 13, 2026
Merged

add linux release binaries for ci consumers#2
anmorgunov merged 1 commit into
masterfrom
build/linux-release-binary

Conversation

@anmorgunov

@anmorgunov anmorgunov commented May 13, 2026

Copy link
Copy Markdown
Contributor

summary

  • bump cooldown-guard to 0.1.2
  • add a linux x86_64 standalone release binary build based on pyinstaller
  • upload wheel, sdist, binary, and sha256 checksum to github releases
  • update example workflows to consume the pinned github release binary instead of resolving the tool from pypi at runtime
  • add binary smoke coverage in ci

verification

  • uv lock
  • uv run pytest
  • uv sync --group dev --group release
  • uv run python scripts/build_release_binary.py
  • COOLDOWN_GUARD_BINARY=dist/cooldown-guard-darwin-arm64 uv run pytest tests/smoke_binary_test.py

notes

  • release automation still publishes to pypi for humans, but ci consumers should prefer the github release binary plus pinned sha256
  • the release workflow uploads cooldown-guard-linux-x86_64 and cooldown-guard-linux-x86_64.sha256

View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

Summary by CodeRabbit

  • New Features

    • Prebuilt release binaries now available for Linux x86_64 with SHA-256 verification support.
  • Documentation

    • Updated guidance to use prebuilt binaries with pinned checksums instead of package installation.
  • Tests

    • Added smoke tests for binary artifacts to validate functionality.
  • Chores

    • Version bumped to 0.1.2.
    • Added release automation workflows for generating and publishing artifacts.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Free

Run ID: b305416e-53d8-488b-a2f9-23f37d94640b

📥 Commits

Reviewing files that changed from the base of the PR and between 1043bda and 04e2fdd.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • .github/workflows/ci.yml
  • .github/workflows/publish-pypi.yml
  • .github/workflows/publish-release.yml
  • README.md
  • examples/github-actions/reconcile.yml
  • examples/github-actions/validate.yml
  • pyproject.toml
  • scripts/build_release_binary.py
  • scripts/verify_release_tag.py
  • src/cooldown_guard/__init__.py
  • tests/smoke_binary_test.py

📝 Walkthrough

Walkthrough

This PR introduces a release binary distribution pipeline for version 0.1.2. It adds infrastructure to build, verify, test, and publish prebuilt PyInstaller binaries alongside PyPI packages, updates GitHub Actions workflows to perform these steps, and changes example workflows to consume prebuilt binaries instead of installing from PyPI.

Changes

Release Binary Distribution Pipeline

Layer / File(s) Summary
Version and Release Dependencies
pyproject.toml, src/cooldown_guard/__init__.py
Package version is bumped to 0.1.2 and a new [dependency-groups].release group adds pyinstaller>=6.16 to enable binary builds.
Release Tag Verification Script
scripts/verify_release_tag.py
New utility script reads the package version from pyproject.toml, constructs the expected release tag in v<version> format, and validates it against the RELEASE_TAG environment variable with a clear error on mismatch.
Binary Build Script
scripts/build_release_binary.py
New build script maps OS and CPU architecture to platform-specific binary names, runs PyInstaller to create one-file executables, computes SHA-256 checksums, and outputs both the binary and checksum file to dist/.
Binary Smoke Tests
tests/smoke_binary_test.py
Smoke tests verify that the built binary responds correctly to --help and validate --project commands, with helper fixtures that set up temporary projects matching the expected configuration; tests are skipped if COOLDOWN_GUARD_BINARY environment variable is not set.
Publish Release Workflow
.github/workflows/publish-release.yml
New GitHub Actions workflow triggered on release publication that verifies the release tag, builds Python wheel and sdist artifacts with smoke tests, builds the Linux x86_64 binary, and uploads all assets (wheels, sdists, binary, SHA-256 checksum) to the GitHub Release.
PyPI Workflow Verification Update
.github/workflows/publish-pypi.yml
PyPI publish workflow now uses the dedicated scripts/verify_release_tag.py script instead of inline Python logic, keeping the same validation check that the GitHub release tag matches v<project.version>.
CI Pipeline Binary Testing
.github/workflows/ci.yml
New binary-smoke job added to the CI pipeline that builds the release binary and runs smoke tests against it, executing after the existing test job.
Example Workflow Updates
examples/github-actions/reconcile.yml, examples/github-actions/validate.yml
Example workflows now download and verify prebuilt binaries from GitHub releases (version 0.1.2) instead of installing via PyPI, using pinned version and SHA-256 checksums to ensure authenticity and reproducibility.
Documentation Updates
README.md
README is updated to document the new publish-release.yml workflow, explain that example workflows download and verify the Linux x86_64 release binary via SHA-256 checksum, clarify that the PyPI publish workflow requires the GitHub release tag to match the package version, and recommend pinning both COOLDOWN_GUARD_VERSION and COOLDOWN_GUARD_SHA256 for binary downloads.

Sequence Diagrams

sequenceDiagram
  participant GitHub as GitHub Release
  participant Checkout as Checkout Repo
  participant Verify as Verify Tag
  participant Build as Build Artifacts
  participant Test as Run Tests
  participant Binary as Build Binary
  participant Upload as Upload Assets
  GitHub->>Checkout: on: published
  Checkout->>Verify: verify RELEASE_TAG matches version
  Verify->>Build: tag is valid
  Build->>Test: wheel/sdist artifacts
  Test->>Binary: tests passed
  Binary->>Upload: binary + .sha256
  Upload->>GitHub: upload to release
Loading
sequenceDiagram
  participant Example as Example Workflow
  participant Release as GitHub Release
  participant Verify as sha256sum
  participant Binary as ./cooldown-guard
  Example->>Release: download cooldown-guard-linux-x86_64
  Release->>Verify: provide binary + COOLDOWN_GUARD_SHA256
  Verify->>Binary: checksum valid
  Binary->>Example: executable ready
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A binary awaits in GitHub's release,
No Python install—just download and run!
SHA-256 checksums grant peace,
While workflows orchestrate the fun—
From PyInstaller's magic, version bumped to 0.1.2!


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the type/feature a new capability or enhancement for the user label May 13, 2026
@anmorgunov anmorgunov added the scope/ci-cd affects github actions, deployment, or build processes label May 13, 2026
@anmorgunov anmorgunov merged commit b68bfe6 into master May 13, 2026
6 checks passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the release process for cooldown-guard by introducing standalone binary builds using PyInstaller. It includes new scripts for building binaries and verifying release tags, updates example workflows to use these binaries with SHA256 verification, and bumps the project version to 0.1.2. The reviewer provided feedback on improving robustness in the release scripts by suggesting the use of .get() for environment variables to avoid KeyErrors and ensuring the distribution directory exists before writing checksum files.

pyproject = pathlib.Path("pyproject.toml")
version = tomllib.loads(pyproject.read_text())["project"]["version"]
expected_tag = f"v{version}"
release_tag = os.environ["RELEASE_TAG"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Accessing os.environ["RELEASE_TAG"] directly will raise a KeyError if the environment variable is missing. It is better to handle this gracefully with a clear error message to help debug CI configuration issues.

    release_tag = os.environ.get("RELEASE_TAG")
    if not release_tag:
        raise SystemExit("RELEASE_TAG environment variable is required")

Comment on lines +15 to +22
def main() -> None:
binary_name = get_binary_name()
build_binary(binary_name)
binary_path = DIST_DIR / binary_name
checksum_path = DIST_DIR / f"{binary_name}.sha256"
checksum_path.write_text(f"{sha256(binary_path)} {binary_name}\n")
print(binary_path)
print(checksum_path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The script writes the checksum file to DIST_DIR (line 20), but it doesn't explicitly ensure that this directory exists. While PyInstaller usually creates dist/ during the build process, if the build fails or if PyInstaller is configured differently in the future, the write_text call might fail with a FileNotFoundError. It's safer to ensure the directory exists before writing to it.

Suggested change
def main() -> None:
binary_name = get_binary_name()
build_binary(binary_name)
binary_path = DIST_DIR / binary_name
checksum_path = DIST_DIR / f"{binary_name}.sha256"
checksum_path.write_text(f"{sha256(binary_path)} {binary_name}\n")
print(binary_path)
print(checksum_path)
def main() -> None:
binary_name = get_binary_name()
build_binary(binary_name)
binary_path = DIST_DIR / binary_name
checksum_path = DIST_DIR / f"{binary_name}.sha256"
DIST_DIR.mkdir(parents=True, exist_ok=True)
checksum_path.write_text(f"{sha256(binary_path)} {binary_name}\n")
print(binary_path)
print(checksum_path)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope/ci-cd affects github actions, deployment, or build processes type/feature a new capability or enhancement for the user

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant