summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErmoshkin Artem <[email protected]>2026-07-03 15:27:57 +0300
committerGitHub <[email protected]>2026-07-03 15:27:57 +0300
commite844854ba6d72bbdc3af36e45ede13f2e0de0edd (patch)
treefa1053cec85053f7cbb433471e7e9018f5b859c8
parent64b4c17eb0799092b9bee23247fafee0800f57e7 (diff)
create a dependency leak check helper (#45139)
Co-authored-by: Artem Ermoshkin <[email protected]>
-rw-r--r--.github/workflows/cpp_sdk_peerdirs_check.yml68
-rw-r--r--ydb/public/sdk/cpp/allowed_peerdirs.txt6
-rw-r--r--ydb/public/sdk/cpp/scripts/check_peerdirs.py85
-rw-r--r--ydb/public/sdk/cpp/src/client/topic/impl/ya.make1
4 files changed, 159 insertions, 1 deletions
diff --git a/.github/workflows/cpp_sdk_peerdirs_check.yml b/.github/workflows/cpp_sdk_peerdirs_check.yml
new file mode 100644
index 00000000000..ad124c0c8fc
--- /dev/null
+++ b/.github/workflows/cpp_sdk_peerdirs_check.yml
@@ -0,0 +1,68 @@
+name: Check CPP SDK PEERDIRs
+
+on:
+ pull_request_target:
+ branches: [main, stable-*]
+ paths: ['ydb/public/sdk/cpp/**', '.github/workflows/cpp_sdk_peerdirs_check.yml']
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ check:
+ if: >-
+ github.event_name == 'workflow_dispatch' ||
+ (vars.CHECKS_SWITCH != '' && fromJSON(vars.CHECKS_SWITCH).cpp_sdk_peerdirs_check == true)
+ runs-on: [self-hosted, tiny-worker]
+ steps:
+ - uses: actions/github-script@v8
+ if: github.event_name == 'pull_request_target'
+ id: gate
+ with:
+ github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
+ script: |
+ const pr = context.payload.pull_request;
+ if (pr.labels.some(l => l.name === 'ok-to-test')) return true;
+ if (pr.user.login === context.repo.owner) return true;
+ try {
+ await github.rest.repos.checkCollaborator({
+ owner: context.repo.owner, repo: context.repo.repo, username: pr.user.login,
+ });
+ return true;
+ } catch (e) {
+ if (e.status === 404) return false;
+ throw e;
+ }
+
+ - name: Comment if waiting on ok-to-test
+ if: steps.gate.outputs.result == 'false' && github.event.action == 'opened'
+ uses: actions/github-script@v8
+ with:
+ script: |
+ await github.rest.issues.createComment({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: 'Hi! The C++ SDK PEERDIRs check will run after a maintainer adds an `ok-to-test` label to this PR. Thank you for your patience!'
+ });
+
+ - uses: actions/checkout@v5
+ if: github.event_name != 'pull_request_target' || steps.gate.outputs.result == 'true'
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.ref }}
+ fetch-depth: 0
+
+ - if: github.event_name != 'pull_request_target' || steps.gate.outputs.result == 'true'
+ env:
+ BASE_REF: ${{ github.event.pull_request.base.ref }}
+ run: |
+ set -euo pipefail
+ if [ "${{ github.event_name }}" = pull_request_target ]; then
+ git fetch --no-tags origin "$BASE_REF"
+ git diff --name-only --diff-filter=ACMRT "origin/$BASE_REF...HEAD" > changed.txt
+ python3 ydb/public/sdk/cpp/scripts/check_peerdirs.py changed.txt
+ else
+ python3 ydb/public/sdk/cpp/scripts/check_peerdirs.py
+ fi
diff --git a/ydb/public/sdk/cpp/allowed_peerdirs.txt b/ydb/public/sdk/cpp/allowed_peerdirs.txt
new file mode 100644
index 00000000000..49259c99a74
--- /dev/null
+++ b/ydb/public/sdk/cpp/allowed_peerdirs.txt
@@ -0,0 +1,6 @@
+# Mirrors ydb-cpp-sdk/.github/scripts/copy_sources.sh.
+ydb/public/sdk/cpp/
+ydb/public/api/
+library/cpp/
+contrib/
+util/
diff --git a/ydb/public/sdk/cpp/scripts/check_peerdirs.py b/ydb/public/sdk/cpp/scripts/check_peerdirs.py
new file mode 100644
index 00000000000..0ec91d0b4c6
--- /dev/null
+++ b/ydb/public/sdk/cpp/scripts/check_peerdirs.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+import sys
+from pathlib import Path
+
+SDK = Path(__file__).resolve().parent.parent
+PREFIX = Path("ydb/public/sdk/cpp")
+ALLOWLIST = SDK / "allowed_peerdirs.txt"
+ALLOWED = [
+ line.split("#", 1)[0].strip()
+ for line in ALLOWLIST.read_text(encoding="utf-8").splitlines()
+ if line.split("#", 1)[0].strip()
+]
+IN_SCOPE = {"src", "include", "plugins", "examples"}
+
+
+def ok(rel):
+ parts = Path(rel).parts
+ return (
+ parts
+ and parts[0] in IN_SCOPE
+ and "ut" not in parts
+ and "ut_utils" not in parts
+ )
+
+
+def peerdirs(text):
+ in_block = False
+ for i, line in enumerate(text.splitlines(), 1):
+ s = line.split("#", 1)[0].strip()
+ if s.startswith("PEERDIR("):
+ if s.endswith(")"):
+ dep = s[len("PEERDIR("):-1].strip()
+ if dep:
+ yield i, dep
+ else:
+ in_block = True
+ continue
+ if in_block:
+ if s == ")":
+ in_block = False
+ elif s:
+ yield i, s
+
+
+def targets(changed_path):
+ all_targets = [
+ p for p in sorted(SDK.rglob("ya.make")) if ok(p.relative_to(SDK))
+ ]
+ if not changed_path:
+ return all_targets
+ changed = [
+ Path(line.strip())
+ for line in Path(changed_path).read_text(encoding="utf-8").splitlines()
+ if line.strip()
+ ]
+ if PREFIX / "allowed_peerdirs.txt" in changed or PREFIX / "scripts/check_peerdirs.py" in changed:
+ return all_targets
+ out = []
+ for path in changed:
+ try:
+ rel = path.relative_to(PREFIX)
+ except ValueError:
+ continue
+ if path.name != "ya.make" or not ok(rel):
+ continue
+ out.append(SDK / rel)
+ return out
+
+
+def main():
+ files = targets(sys.argv[1] if len(sys.argv) > 1 else None)
+ bad = []
+ for ya_make in files:
+ for line_no, dep in peerdirs(ya_make.read_text(encoding="utf-8")):
+ if not any(dep.startswith(p) for p in ALLOWED):
+ rel = PREFIX / ya_make.relative_to(SDK)
+ bad.append(f"{rel}:{line_no}: forbidden PEERDIR {dep!r}")
+ if bad:
+ print("\n".join(bad), file=sys.stderr)
+ raise SystemExit(1)
+ print(f"ok ({len(files)} ya.make)")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ydb/public/sdk/cpp/src/client/topic/impl/ya.make b/ydb/public/sdk/cpp/src/client/topic/impl/ya.make
index cac04e3c63a..0cf913bf647 100644
--- a/ydb/public/sdk/cpp/src/client/topic/impl/ya.make
+++ b/ydb/public/sdk/cpp/src/client/topic/impl/ya.make
@@ -33,7 +33,6 @@ PEERDIR(
library/cpp/threading/future/subscription
library/cpp/monlib/metrics
library/cpp/string_utils/url
- ydb/library/persqueue
ydb/public/sdk/cpp/src/library/persqueue/obfuscate
ydb/public/api/grpc/draft
ydb/public/api/grpc