mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
# Description of Changes This PR modernizes the project's Python tooling across GitHub Actions by migrating CI workflows from pip-based dependency management to `uv` and aligning Python execution with the engine project's managed environment. ### What was changed - Replaced `actions/setup-python` and ad-hoc `pip install` steps with `astral-sh/setup-uv` across CI workflows. - Configured shared `uv` dependency caching using `engine/pyproject.toml` and `engine/uv.lock`. - Updated Python script execution to use `uv run --project engine --locked` for a consistent runtime environment. - Replaced package installation steps with `uv sync` for the required dependency groups (e.g. `tools` and `cucumber`). - Added Docker image build validation for both production and development AI engine images. - Updated workflow cache configuration and Docker build context where required. - Removed obsolete Python requirements files that are no longer needed after the migration. - Applied minor Python code modernizations, including import cleanup, modern built-in generic type annotations (`list[...]`, `tuple[...]`, `float | None`), and small style improvements. - Removed unnecessary Python formatter/linter extensions from the development container configuration. ### Why the change was made - Standardize Python dependency management across the repository. - Reduce duplicated dependency installation logic in CI. - Improve workflow performance through shared dependency caching. - Ensure all Python utilities execute against the same locked dependency set managed by the engine project. - Simplify long-term maintenance by eliminating legacy requirements files and pip-specific workflow steps. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have run `task check` to verify linters, typechecks, and tests pass - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing) for more details. --------- Signed-off-by: Carsten Drewes <c.drewes@stud.uni-hannover.de> Co-authored-by: albanobattistella <34811668+albanobattistella@users.noreply.github.com> Co-authored-by: kastenherri <116314318+kastenherri@users.noreply.github.com> Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: James Brunton <jbrunton96@gmail.com>
106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Download the pinned gitleaks binary into .task/bin, verifying its checksum.
|
|
|
|
gitleaks is a Go binary with no PyPI package, so it can't be locked like the
|
|
other tools (ruff/codespell/toml-sort live in engine/pyproject.toml).
|
|
This script is the single source of truth for the gitleaks version and the
|
|
SHA-256 of each release asset. It is cross-platform (stdlib only) and idempotent:
|
|
if the cached binary already reports the pinned version it does nothing, so
|
|
`task pre-commit` can call it every run.
|
|
|
|
Bump the version by editing VERSION and the SHA256 map (values come from the
|
|
release's gitleaks_<version>_checksums.txt).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import platform
|
|
import subprocess
|
|
import sys
|
|
import tarfile
|
|
import urllib.request
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
VERSION = "8.30.0"
|
|
|
|
# SHA-256 of each release asset, keyed by "<os>_<arch>" (gitleaks' own naming).
|
|
SHA256 = {
|
|
"linux_x64": "79a3ab579b53f71efd634f3aaf7e04a0fa0cf206b7ed434638d1547a2470a66e",
|
|
"linux_arm64": "b4cbbb6ddf7d1b2a603088cd03a4e3f7ce48ee7fd449b51f7de6ee2906f5fa2f",
|
|
"darwin_x64": "ca221d012d247080c2f6f61f4b7a83bffa2453806b0c195c795bbe9a8c775ed5",
|
|
"darwin_arm64": "b251ab2bcd4cd8ba9e56ff37698c033ebf38582b477d21ebd86586d927cf87e7",
|
|
"windows_x64": "54fe94f644b832dd08e8c3a5915efb3bfa862386d59fb27ca0792cb687a83573",
|
|
}
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
IS_WINDOWS = platform.system() == "Windows"
|
|
BIN = REPO_ROOT / ".task" / "bin" / ("gitleaks.exe" if IS_WINDOWS else "gitleaks")
|
|
|
|
|
|
def platform_key() -> str:
|
|
os_name = {"Linux": "linux", "Darwin": "darwin", "Windows": "windows"}.get(platform.system())
|
|
arch = {
|
|
"x86_64": "x64",
|
|
"amd64": "x64",
|
|
"arm64": "arm64",
|
|
"aarch64": "arm64",
|
|
"i386": "x32",
|
|
"i686": "x32",
|
|
"x86": "x32",
|
|
"armv7l": "armv7",
|
|
"armv6l": "armv6",
|
|
}.get(platform.machine().lower())
|
|
if not os_name or not arch:
|
|
raise SystemExit(f"Unsupported platform for gitleaks: {platform.system()}/{platform.machine()}")
|
|
return f"{os_name}_{arch}"
|
|
|
|
|
|
def cached_version() -> str | None:
|
|
if not BIN.exists():
|
|
return None
|
|
try:
|
|
return subprocess.run([str(BIN), "version"], capture_output=True, text=True).stdout.strip()
|
|
except OSError:
|
|
return None
|
|
|
|
|
|
def main() -> int:
|
|
if cached_version() == VERSION:
|
|
return 0
|
|
|
|
key = platform_key()
|
|
expected = SHA256.get(key)
|
|
if expected is None:
|
|
raise SystemExit(f"No pinned gitleaks checksum for {key}")
|
|
|
|
suffix = "zip" if key.startswith("windows") else "tar.gz"
|
|
asset = f"gitleaks_{VERSION}_{key}.{suffix}"
|
|
url = f"https://github.com/gitleaks/gitleaks/releases/download/v{VERSION}/{asset}"
|
|
print(f"Downloading gitleaks {VERSION} ({asset})", flush=True)
|
|
|
|
BIN.parent.mkdir(parents=True, exist_ok=True)
|
|
archive, _ = urllib.request.urlretrieve(url)
|
|
digest = hashlib.sha256(Path(archive).read_bytes()).hexdigest()
|
|
if digest != expected:
|
|
raise SystemExit(f"gitleaks checksum mismatch: expected {expected}, got {digest}")
|
|
|
|
member = "gitleaks.exe" if IS_WINDOWS else "gitleaks"
|
|
if suffix == "zip":
|
|
with zipfile.ZipFile(archive) as zf:
|
|
data = zf.read(member)
|
|
else:
|
|
with tarfile.open(archive) as tf:
|
|
extracted = tf.extractfile(member)
|
|
if extracted is None:
|
|
raise SystemExit(f"{member} not found in {asset}")
|
|
data = extracted.read()
|
|
BIN.write_bytes(data)
|
|
BIN.chmod(0o755)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|