From 6f61d897beb793999d5a49ca9b1d1e7497a8d75d Mon Sep 17 00:00:00 2001 From: 117503445 Date: Mon, 6 Jul 2026 14:38:50 +0800 Subject: [PATCH] fix(build): configure bundled CA for binary HTTPS Signed-off-by: 117503445 --- agentrun.spec | 2 +- pyproject.toml | 1 + src/agentrun_cli/_utils/certificates.py | 15 +++++++++ .../_utils/pyinstaller_certifi_hook.py | 5 +++ tests/unit/test_certificates.py | 31 +++++++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/agentrun_cli/_utils/certificates.py create mode 100644 src/agentrun_cli/_utils/pyinstaller_certifi_hook.py create mode 100644 tests/unit/test_certificates.py diff --git a/agentrun.spec b/agentrun.spec index b375f93..1bbcf76 100644 --- a/agentrun.spec +++ b/agentrun.spec @@ -57,7 +57,7 @@ a = Analysis( hiddenimports=[], hookspath=[], hooksconfig={}, - runtime_hooks=[], + runtime_hooks=['src/agentrun_cli/_utils/pyinstaller_certifi_hook.py'], excludes=EXCLUDES, noarchive=False, optimize=0, diff --git a/pyproject.toml b/pyproject.toml index c0058cb..896f2c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ classifiers = [ dependencies = [ "agentrun-sdk[core]>=0.0.37", + "certifi>=2024.0.0", "oss2>=2.19.1", "pyyaml>=6.0", "questionary>=2.0", diff --git a/src/agentrun_cli/_utils/certificates.py b/src/agentrun_cli/_utils/certificates.py new file mode 100644 index 0000000..413b478 --- /dev/null +++ b/src/agentrun_cli/_utils/certificates.py @@ -0,0 +1,15 @@ +"""Certificate bundle setup for frozen CLI binaries.""" + +import os +import sys + +import certifi + + +def configure_default_ca_bundle() -> None: + """Use the bundled certifi CA file when running as a frozen binary.""" + if not getattr(sys, "frozen", False): + return + if os.environ.get("SSL_CERT_FILE"): + return + os.environ["SSL_CERT_FILE"] = certifi.where() diff --git a/src/agentrun_cli/_utils/pyinstaller_certifi_hook.py b/src/agentrun_cli/_utils/pyinstaller_certifi_hook.py new file mode 100644 index 0000000..d0103cd --- /dev/null +++ b/src/agentrun_cli/_utils/pyinstaller_certifi_hook.py @@ -0,0 +1,5 @@ +"""PyInstaller runtime hook for bundled CA certificates.""" + +from agentrun_cli._utils.certificates import configure_default_ca_bundle + +configure_default_ca_bundle() diff --git a/tests/unit/test_certificates.py b/tests/unit/test_certificates.py new file mode 100644 index 0000000..8288fe8 --- /dev/null +++ b/tests/unit/test_certificates.py @@ -0,0 +1,31 @@ +"""Unit tests for frozen-binary certificate setup.""" + +from agentrun_cli._utils import certificates + + +class TestConfigureDefaultCaBundle: + def test_uses_certifi_for_frozen_binary(self, monkeypatch): + monkeypatch.setattr(certificates.sys, "frozen", True, raising=False) + monkeypatch.delenv("SSL_CERT_FILE", raising=False) + monkeypatch.setattr(certificates.certifi, "where", lambda: "/tmp/cacert.pem") + + certificates.configure_default_ca_bundle() + + assert certificates.os.environ["SSL_CERT_FILE"] == "/tmp/cacert.pem" + + def test_preserves_user_ssl_cert_file(self, monkeypatch): + monkeypatch.setattr(certificates.sys, "frozen", True, raising=False) + monkeypatch.setenv("SSL_CERT_FILE", "/custom/ca.pem") + monkeypatch.setattr(certificates.certifi, "where", lambda: "/tmp/cacert.pem") + + certificates.configure_default_ca_bundle() + + assert certificates.os.environ["SSL_CERT_FILE"] == "/custom/ca.pem" + + def test_skips_regular_python_runtime(self, monkeypatch): + monkeypatch.delattr(certificates.sys, "frozen", raising=False) + monkeypatch.delenv("SSL_CERT_FILE", raising=False) + + certificates.configure_default_ca_bundle() + + assert "SSL_CERT_FILE" not in certificates.os.environ