diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c28b929c4b..455934c0cd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,10 +35,14 @@ concurrency: jobs: prepare: + # The workflow_run branches filter matches the head branch name, which a + # fork PR opened from its own `main` shares; only a push here may publish. if: >- github.repository == 'Tracer-Cloud/opensre' && (github.event_name != 'workflow_run' || - github.event.workflow_run.conclusion == 'success') + (github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event == 'push' && + github.event.workflow_run.head_repository.full_name == github.repository)) runs-on: ubuntu-24.04 outputs: channel: ${{ steps.meta.outputs.channel }} @@ -81,6 +85,10 @@ jobs: fi if [ "$EVENT_NAME" = "workflow_run" ]; then + if ! git merge-base --is-ancestor "$source_sha" refs/remotes/origin/main; then + echo "Release source commit is not on main: ${source_sha}" >&2 + exit 1 + fi released_sha="$(git rev-parse -q --verify "refs/tags/main-build^{commit}" || true)" if [ -n "$released_sha" ]; then if ! git merge-base --is-ancestor "$released_sha" "$source_sha"; then diff --git a/integrations/neon/client.py b/integrations/neon/client.py index 4ce5e6ce19..6954527584 100644 --- a/integrations/neon/client.py +++ b/integrations/neon/client.py @@ -8,7 +8,6 @@ from __future__ import annotations -import logging import re from http import HTTPStatus from typing import Any @@ -19,8 +18,6 @@ from integrations.neon.config import NeonConfig from integrations.probes import ProbeResult -logger = logging.getLogger(__name__) - _MAX_PATH_SEGMENT_LEN = 128 # Neon project/branch IDs and bucket names are lowercase slugs: letters, # digits, hyphens (bucket names may also hold dots). Reject anything else so a diff --git a/pyproject.toml b/pyproject.toml index 379765c053..0eccc094c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -265,6 +265,8 @@ constraint-dependencies = [ "setuptools>=84.1.0", # GHSA-45c3-73f7-pv4m (via pymongo). "dnspython>=2.9.0", + # GHSA-3jp2-3mrg-2vxc (via kubernetes). + "oauthlib>=4.0.1", ] # litellm caps filelock below 4, and GHSA-v4x8-3wr5-3wq8 (high), GHSA-9vhv-jxww-xfm5 # and GHSA-567q-5qvw-pf92 have no 3.x fix. 4.0 changed only SoftReadWriteLock's diff --git a/tests/packaging/test_release_manifest.py b/tests/packaging/test_release_manifest.py index 38a99c66c9..2a0f767a7e 100644 --- a/tests/packaging/test_release_manifest.py +++ b/tests/packaging/test_release_manifest.py @@ -168,6 +168,13 @@ def test_release_workflow_does_not_run_on_pull_requests() -> None: assert 'echo "channel=pr" >> "$GITHUB_OUTPUT"' not in workflow assert "opensre_pr_" not in workflow + # A fork PR from its own `main` passes the branches filter, so the CI run + # must also be a push to this repository and the commit must be on main. + prepare_if = yaml.load(workflow, Loader=yaml.BaseLoader)["jobs"]["prepare"]["if"] + assert "github.event.workflow_run.event == 'push'" in prepare_if + assert "github.event.workflow_run.head_repository.full_name == github.repository" in prepare_if + assert 'git merge-base --is-ancestor "$source_sha" refs/remotes/origin/main' in workflow + def test_release_workflow_does_not_publish_python_distributions_to_pypi() -> None: raw = _RELEASE_WORKFLOW.read_text(encoding="utf-8") diff --git a/uv.lock b/uv.lock index 7e44e45c6b..35305fd9cb 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 5 +revision = 3 requires-python = ">=3.12" resolution-markers = [ "python_full_version >= '3.15' and sys_platform == 'win32'", @@ -20,6 +20,7 @@ resolution-markers = [ constraints = [ { name = "certifi", specifier = ">=2026.10.19" }, { name = "dnspython", specifier = ">=2.9.0" }, + { name = "oauthlib", specifier = ">=4.0.1" }, { name = "setuptools", specifier = ">=84.1.0" }, { name = "virtualenv", specifier = ">=21.14.12" }, ] @@ -1426,8 +1427,8 @@ name = "httpcore2" version = "2.12.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "h11" }, - { name = "truststore" }, + { name = "h11", marker = "sys_platform != 'emscripten'" }, + { name = "truststore", marker = "sys_platform != 'emscripten'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/be/ad/f4f0e57345f1870f3e8cb624e058d7eca6e5a27d33bcc3311d9b618734cd/httpcore2-2.12.0.tar.gz", hash = "sha256:9293522bba0aa7c4c8e9e3f040c16575bd8868e155a77fa30c7a9085a5eae648", size = 67548, upload-time = "2026-08-18T13:22:08.211Z" } wheels = [ @@ -2002,7 +2003,7 @@ name = "macholib" version = "1.16.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "altgraph" }, + { name = "altgraph", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/10/2f/97589876ea967487978071c9042518d28b958d87b17dceb7cdc1d881f963/macholib-1.16.4.tar.gz", hash = "sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362", size = 59427, upload-time = "2025-11-22T08:28:38.373Z" } wheels = [ @@ -2539,11 +2540,11 @@ wheels = [ [[package]] name = "oauthlib" -version = "4.0.0" +version = "4.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7a/d8/a1bcc8ba112a627f8ffbdc212a78ce18d3ac07e91a5ca65d27918eee25a1/oauthlib-4.0.0.tar.gz", hash = "sha256:efb274799819440f95b4ab3b818869f1ce9ae26c5beacba0201d1a1b76b54f86", size = 187232, upload-time = "2026-09-28T06:01:18.77Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/17/2bb072de0b990303c985f26869fd47bb179024a051f47e7f9d208eb92f8e/oauthlib-4.0.1.tar.gz", hash = "sha256:3d73febdb6faa00f277c81fb04be7b7586fb96fc3b7f0b9c772dada69a25ede7", size = 191219, upload-time = "2026-10-31T09:52:58.008Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/f4/78229a1066068ca14fc60fb26cf7381cabe4382261392b90e5f9552722d4/oauthlib-4.0.0-py3-none-any.whl", hash = "sha256:624c28c13a0a59cabf9747dfa52af63be3e512a7f2714df16e91b5b3a145e6cd", size = 159715, upload-time = "2026-09-28T06:01:17.008Z" }, + { url = "https://files.pythonhosted.org/packages/df/ef/3b8adde1b32a6f540758bff734d3442c621734c83708e5f02b0ba2f43b84/oauthlib-4.0.1-py3-none-any.whl", hash = "sha256:498a298876e996301950a5b053d12c31628bb7b895db03666430c69ce182eb61", size = 161934, upload-time = "2026-10-31T09:52:56.206Z" }, ] [[package]] @@ -4201,8 +4202,8 @@ name = "secretstorage" version = "3.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cryptography" }, - { name = "jeepney" }, + { name = "cryptography", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "jeepney", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } wheels = [