src-py-lib 0.1.3__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.github/workflows/ci.yml +1 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.github/workflows/release.yml +2 -1
- src_py_lib-0.1.4/.github/workflows/validate.yml +280 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/AGENTS.md +4 -4
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/PKG-INFO +1 -1
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/pyproject.toml +1 -1
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/__init__.py +1 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/sourcegraph.py +21 -5
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/tests/test_logging_http_clients.py +46 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/uv.lock +1 -1
- src_py_lib-0.1.3/.github/workflows/validate.yml +0 -135
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.gitignore +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.markdownlint-cli2.yaml +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.python-version +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/LICENSE +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/README.md +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/SECURITY.md +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/renovate.json +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/__init__.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/github.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/google_sheets.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/graphql.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/linear.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/one_password.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/slack.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/py.typed +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/__init__.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/config.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/http.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/json_cache.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/json_types.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/logging.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/tsv.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/tests/test_import.py +0 -0
- {src_py_lib-0.1.3 → src_py_lib-0.1.4}/tests/test_tsv.py +0 -0
|
@@ -13,6 +13,7 @@ on:
|
|
|
13
13
|
|
|
14
14
|
permissions:
|
|
15
15
|
contents: write
|
|
16
|
+
pull-requests: read
|
|
16
17
|
|
|
17
18
|
concurrency:
|
|
18
19
|
group: release-${{ github.event.inputs.tag || github.ref_name }}
|
|
@@ -50,7 +51,6 @@ jobs:
|
|
|
50
51
|
uses: actions/setup-python@v6
|
|
51
52
|
with:
|
|
52
53
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
53
|
-
cache: pip
|
|
54
54
|
|
|
55
55
|
- name: Cache uv
|
|
56
56
|
uses: actions/cache@v5
|
|
@@ -225,6 +225,7 @@ jobs:
|
|
|
225
225
|
- name: Publish GitHub release assets
|
|
226
226
|
env:
|
|
227
227
|
GH_TOKEN: ${{ github.token }}
|
|
228
|
+
GH_REPO: ${{ github.repository }}
|
|
228
229
|
run: |
|
|
229
230
|
release_tag="${{ github.event.inputs.tag || github.ref_name }}"
|
|
230
231
|
notes_path="$(find release-assets -name release-notes.md -print -quit)"
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
name: Validate
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
ref:
|
|
7
|
+
description: "Git ref to validate. Defaults to the caller's ref."
|
|
8
|
+
required: false
|
|
9
|
+
type: string
|
|
10
|
+
build-package:
|
|
11
|
+
description: "Build and smoke-test package artifacts. Release builds do this separately."
|
|
12
|
+
required: false
|
|
13
|
+
type: boolean
|
|
14
|
+
default: true
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
pull-requests: read
|
|
19
|
+
|
|
20
|
+
defaults:
|
|
21
|
+
run:
|
|
22
|
+
shell: bash
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
changes:
|
|
26
|
+
name: Detect changed paths
|
|
27
|
+
runs-on: ubuntu-24.04
|
|
28
|
+
outputs:
|
|
29
|
+
github_actions: ${{ steps.changed_paths.outputs.github_actions }}
|
|
30
|
+
markdown: ${{ steps.changed_paths.outputs.markdown }}
|
|
31
|
+
python: ${{ steps.changed_paths.outputs.python }}
|
|
32
|
+
package: ${{ steps.changed_paths.outputs.package }}
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Detect changed paths
|
|
36
|
+
id: changed_paths
|
|
37
|
+
env:
|
|
38
|
+
GH_TOKEN: ${{ github.token }}
|
|
39
|
+
PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
|
|
40
|
+
run: |
|
|
41
|
+
github_actions_changed=false
|
|
42
|
+
markdown_changed=false
|
|
43
|
+
python_changed=false
|
|
44
|
+
package_changed=false
|
|
45
|
+
|
|
46
|
+
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
|
|
47
|
+
github_actions_changed=true
|
|
48
|
+
markdown_changed=true
|
|
49
|
+
python_changed=true
|
|
50
|
+
package_changed=true
|
|
51
|
+
else
|
|
52
|
+
changed_files="$(mktemp)"
|
|
53
|
+
gh api --paginate \
|
|
54
|
+
"repos/${GITHUB_REPOSITORY}/pulls/${PULL_REQUEST_NUMBER}/files" \
|
|
55
|
+
--jq '.[].filename' > "${changed_files}"
|
|
56
|
+
|
|
57
|
+
while IFS= read -r changed_file; do
|
|
58
|
+
case "${changed_file}" in
|
|
59
|
+
.github/workflows/*)
|
|
60
|
+
github_actions_changed=true
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
|
|
64
|
+
case "${changed_file}" in
|
|
65
|
+
*.md|.markdownlint-cli2.yaml)
|
|
66
|
+
markdown_changed=true
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
|
|
70
|
+
case "${changed_file}" in
|
|
71
|
+
.python-version|pyproject.toml|uv.lock|src/*|tests/*)
|
|
72
|
+
python_changed=true
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
|
|
76
|
+
case "${changed_file}" in
|
|
77
|
+
.python-version|LICENSE|README.md|pyproject.toml|uv.lock|src/*)
|
|
78
|
+
package_changed=true
|
|
79
|
+
;;
|
|
80
|
+
esac
|
|
81
|
+
done < "${changed_files}"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
{
|
|
85
|
+
echo "github_actions=${github_actions_changed}"
|
|
86
|
+
echo "markdown=${markdown_changed}"
|
|
87
|
+
echo "python=${python_changed}"
|
|
88
|
+
echo "package=${package_changed}"
|
|
89
|
+
} >> "${GITHUB_OUTPUT}"
|
|
90
|
+
|
|
91
|
+
github_actions:
|
|
92
|
+
name: Lint GitHub Actions
|
|
93
|
+
needs: changes
|
|
94
|
+
if: needs.changes.outputs.github_actions == 'true'
|
|
95
|
+
runs-on: ubuntu-24.04
|
|
96
|
+
env:
|
|
97
|
+
ACTIONLINT_VERSION: "1.7.12"
|
|
98
|
+
|
|
99
|
+
steps:
|
|
100
|
+
- name: Check out code
|
|
101
|
+
uses: actions/checkout@v6
|
|
102
|
+
with:
|
|
103
|
+
persist-credentials: false
|
|
104
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
105
|
+
|
|
106
|
+
- name: Install actionlint
|
|
107
|
+
run: |
|
|
108
|
+
mkdir -p "${HOME}/.local/bin"
|
|
109
|
+
asset="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
|
|
110
|
+
checksums="actionlint_${ACTIONLINT_VERSION}_checksums.txt"
|
|
111
|
+
base_url="https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}"
|
|
112
|
+
|
|
113
|
+
curl -fsSLO "${base_url}/${asset}"
|
|
114
|
+
curl -fsSLO "${base_url}/${checksums}"
|
|
115
|
+
grep " ${asset}$" "${checksums}" | sha256sum --check
|
|
116
|
+
tar -xzf "${asset}" -C "${HOME}/.local/bin" actionlint
|
|
117
|
+
chmod 0755 "${HOME}/.local/bin/actionlint"
|
|
118
|
+
|
|
119
|
+
- name: Lint GitHub Actions
|
|
120
|
+
run: |
|
|
121
|
+
"${HOME}/.local/bin/actionlint"
|
|
122
|
+
|
|
123
|
+
markdown:
|
|
124
|
+
name: Lint Markdown
|
|
125
|
+
needs: changes
|
|
126
|
+
if: needs.changes.outputs.markdown == 'true'
|
|
127
|
+
runs-on: ubuntu-24.04
|
|
128
|
+
env:
|
|
129
|
+
MARKDOWNLINT_CLI2_VERSION: "0.22.1"
|
|
130
|
+
|
|
131
|
+
steps:
|
|
132
|
+
- name: Check out code
|
|
133
|
+
uses: actions/checkout@v6
|
|
134
|
+
with:
|
|
135
|
+
persist-credentials: false
|
|
136
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
137
|
+
|
|
138
|
+
- name: Cache npm
|
|
139
|
+
uses: actions/cache@v5
|
|
140
|
+
with:
|
|
141
|
+
path: ~/.npm
|
|
142
|
+
key: npm-${{ runner.os }}-markdownlint-cli2-${{ env.MARKDOWNLINT_CLI2_VERSION }}
|
|
143
|
+
|
|
144
|
+
- name: Lint Markdown
|
|
145
|
+
run: npx --yes "markdownlint-cli2@${MARKDOWNLINT_CLI2_VERSION}"
|
|
146
|
+
|
|
147
|
+
python:
|
|
148
|
+
name: Validate Python
|
|
149
|
+
needs: changes
|
|
150
|
+
if: needs.changes.outputs.python == 'true'
|
|
151
|
+
runs-on: ubuntu-24.04
|
|
152
|
+
env:
|
|
153
|
+
IMPORT_NAME: src_py_lib
|
|
154
|
+
PYTHON_VERSION: "3.11"
|
|
155
|
+
UV_VERSION: "0.11.7"
|
|
156
|
+
|
|
157
|
+
steps:
|
|
158
|
+
- name: Check out code
|
|
159
|
+
uses: actions/checkout@v6
|
|
160
|
+
with:
|
|
161
|
+
persist-credentials: false
|
|
162
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
163
|
+
|
|
164
|
+
- name: Set up Python
|
|
165
|
+
uses: actions/setup-python@v6
|
|
166
|
+
with:
|
|
167
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
168
|
+
|
|
169
|
+
- name: Cache uv
|
|
170
|
+
uses: actions/cache@v5
|
|
171
|
+
with:
|
|
172
|
+
path: ~/.cache/uv
|
|
173
|
+
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
174
|
+
restore-keys: |
|
|
175
|
+
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
176
|
+
|
|
177
|
+
- name: Install uv
|
|
178
|
+
run: python -m pip install "uv==${UV_VERSION}"
|
|
179
|
+
|
|
180
|
+
- name: Validate lockfile
|
|
181
|
+
run: uv lock --check
|
|
182
|
+
|
|
183
|
+
- name: Lint Python
|
|
184
|
+
run: uv run --frozen ruff check .
|
|
185
|
+
|
|
186
|
+
- name: Check Python formatting
|
|
187
|
+
run: uv run --frozen ruff format --check .
|
|
188
|
+
|
|
189
|
+
- name: Type check
|
|
190
|
+
run: uv run --frozen pyright
|
|
191
|
+
|
|
192
|
+
- name: Run tests
|
|
193
|
+
run: uv run --frozen python -m unittest discover -s tests
|
|
194
|
+
|
|
195
|
+
- name: Smoke test source checkout import
|
|
196
|
+
run: |
|
|
197
|
+
uv run --frozen python - <<'PY'
|
|
198
|
+
import os
|
|
199
|
+
|
|
200
|
+
import src_py_lib
|
|
201
|
+
|
|
202
|
+
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
203
|
+
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
204
|
+
PY
|
|
205
|
+
|
|
206
|
+
package_build:
|
|
207
|
+
name: Build and smoke-test package
|
|
208
|
+
needs: changes
|
|
209
|
+
if: inputs.build-package && needs.changes.outputs.package == 'true'
|
|
210
|
+
runs-on: ubuntu-24.04
|
|
211
|
+
env:
|
|
212
|
+
IMPORT_NAME: src_py_lib
|
|
213
|
+
PYTHON_VERSION: "3.11"
|
|
214
|
+
UV_VERSION: "0.11.7"
|
|
215
|
+
|
|
216
|
+
steps:
|
|
217
|
+
- name: Check out code
|
|
218
|
+
uses: actions/checkout@v6
|
|
219
|
+
with:
|
|
220
|
+
persist-credentials: false
|
|
221
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
222
|
+
|
|
223
|
+
- name: Set up Python
|
|
224
|
+
uses: actions/setup-python@v6
|
|
225
|
+
with:
|
|
226
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
227
|
+
|
|
228
|
+
- name: Cache uv
|
|
229
|
+
uses: actions/cache@v5
|
|
230
|
+
with:
|
|
231
|
+
path: ~/.cache/uv
|
|
232
|
+
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
233
|
+
restore-keys: |
|
|
234
|
+
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
235
|
+
|
|
236
|
+
- name: Install uv
|
|
237
|
+
run: python -m pip install "uv==${UV_VERSION}"
|
|
238
|
+
|
|
239
|
+
- name: Build wheel
|
|
240
|
+
run: uv build --wheel --out-dir dist --no-create-gitignore
|
|
241
|
+
|
|
242
|
+
- name: Smoke test installed wheel
|
|
243
|
+
run: |
|
|
244
|
+
python -m venv build/ci-venv
|
|
245
|
+
. build/ci-venv/bin/activate
|
|
246
|
+
python -m pip install dist/*.whl
|
|
247
|
+
python - <<'PY'
|
|
248
|
+
import os
|
|
249
|
+
|
|
250
|
+
import src_py_lib
|
|
251
|
+
|
|
252
|
+
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
253
|
+
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
254
|
+
PY
|
|
255
|
+
|
|
256
|
+
package:
|
|
257
|
+
name: Validate package
|
|
258
|
+
needs: [changes, github_actions, markdown, python, package_build]
|
|
259
|
+
if: always()
|
|
260
|
+
runs-on: ubuntu-24.04
|
|
261
|
+
|
|
262
|
+
steps:
|
|
263
|
+
- name: Confirm validation results
|
|
264
|
+
run: |
|
|
265
|
+
for validation_result in \
|
|
266
|
+
"${{ needs.changes.result }}" \
|
|
267
|
+
"${{ needs.github_actions.result }}" \
|
|
268
|
+
"${{ needs.markdown.result }}" \
|
|
269
|
+
"${{ needs.python.result }}" \
|
|
270
|
+
"${{ needs.package_build.result }}"
|
|
271
|
+
do
|
|
272
|
+
case "${validation_result}" in
|
|
273
|
+
success|skipped)
|
|
274
|
+
;;
|
|
275
|
+
*)
|
|
276
|
+
echo "::error title=Validation failed::At least one validation job ended with '${validation_result}'."
|
|
277
|
+
exit 1
|
|
278
|
+
;;
|
|
279
|
+
esac
|
|
280
|
+
done
|
|
@@ -64,7 +64,7 @@ uv run python -m unittest discover -s tests
|
|
|
64
64
|
```sh
|
|
65
65
|
set -euo pipefail
|
|
66
66
|
|
|
67
|
-
VERSION=0.1.
|
|
67
|
+
VERSION=0.1.4
|
|
68
68
|
BRANCH="release-v${VERSION}"
|
|
69
69
|
|
|
70
70
|
git fetch origin --tags --prune
|
|
@@ -116,7 +116,7 @@ rm -rf /tmp/src-py-lib-release-check
|
|
|
116
116
|
```sh
|
|
117
117
|
set -euo pipefail
|
|
118
118
|
|
|
119
|
-
VERSION=0.1.
|
|
119
|
+
VERSION=0.1.4
|
|
120
120
|
BRANCH="release-v${VERSION}"
|
|
121
121
|
GH_REPO="sourcegraph/src-py-lib"
|
|
122
122
|
|
|
@@ -140,7 +140,7 @@ gh pr merge "${BRANCH}" --repo "${GH_REPO}" --squash --delete-branch
|
|
|
140
140
|
```sh
|
|
141
141
|
set -euo pipefail
|
|
142
142
|
|
|
143
|
-
VERSION=0.1.
|
|
143
|
+
VERSION=0.1.4
|
|
144
144
|
|
|
145
145
|
git fetch origin --tags --prune
|
|
146
146
|
git switch main
|
|
@@ -154,7 +154,7 @@ git push origin "v${VERSION}"
|
|
|
154
154
|
```sh
|
|
155
155
|
set -euo pipefail
|
|
156
156
|
|
|
157
|
-
VERSION=0.1.
|
|
157
|
+
VERSION=0.1.4
|
|
158
158
|
GH_REPO="sourcegraph/src-py-lib"
|
|
159
159
|
|
|
160
160
|
RUN_ID="$(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: src-py-lib
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Reusable libraries for Sourcegraph projects
|
|
5
5
|
Project-URL: Homepage, https://github.com/sourcegraph/src-py-lib
|
|
6
6
|
Project-URL: Issues, https://github.com/sourcegraph/src-py-lib/issues
|
|
@@ -8,6 +8,7 @@ import json
|
|
|
8
8
|
import queue
|
|
9
9
|
import time
|
|
10
10
|
from collections.abc import Iterable, Iterator, Mapping, Sequence
|
|
11
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
11
12
|
from dataclasses import dataclass, field
|
|
12
13
|
from typing import Final, cast
|
|
13
14
|
from urllib.parse import urlsplit
|
|
@@ -19,6 +20,7 @@ from src_py_lib.utils.json_types import JSONDict, JSONValue, json_dict, json_lis
|
|
|
19
20
|
from src_py_lib.utils.logging import (
|
|
20
21
|
current_trace_context,
|
|
21
22
|
new_trace_context,
|
|
23
|
+
submit_with_log_context,
|
|
22
24
|
trace_context_from_traceparent,
|
|
23
25
|
traceparent_header,
|
|
24
26
|
)
|
|
@@ -244,13 +246,27 @@ class SourcegraphClient:
|
|
|
244
246
|
traces: Iterable[SourcegraphTrace] | None = None,
|
|
245
247
|
*,
|
|
246
248
|
retry_delays_seconds: Sequence[float] = JAEGER_TRACE_RETRY_DELAYS_SECONDS,
|
|
249
|
+
parallelism: int = 8,
|
|
247
250
|
) -> Iterator[SourcegraphJaegerTraceSummary]:
|
|
248
251
|
"""Yield compact Jaeger/debug summaries for traced Sourcegraph requests."""
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
if parallelism < 1:
|
|
253
|
+
raise ValueError("parallelism must be at least 1")
|
|
254
|
+
pending_traces = list(self.drain_traces() if traces is None else traces)
|
|
255
|
+
with ThreadPoolExecutor(
|
|
256
|
+
max_workers=parallelism,
|
|
257
|
+
thread_name_prefix="SourcegraphJaegerTrace",
|
|
258
|
+
) as executor:
|
|
259
|
+
futures = [
|
|
260
|
+
submit_with_log_context(
|
|
261
|
+
executor,
|
|
262
|
+
self.fetch_jaeger_trace_summary,
|
|
263
|
+
trace,
|
|
264
|
+
retry_delays_seconds=retry_delays_seconds,
|
|
265
|
+
)
|
|
266
|
+
for trace in pending_traces
|
|
267
|
+
]
|
|
268
|
+
for future in as_completed(futures):
|
|
269
|
+
yield future.result()
|
|
254
270
|
|
|
255
271
|
def fetch_jaeger_trace_summary(
|
|
256
272
|
self,
|
|
@@ -8,6 +8,7 @@ import json
|
|
|
8
8
|
import logging
|
|
9
9
|
import subprocess
|
|
10
10
|
import tempfile
|
|
11
|
+
import threading
|
|
11
12
|
import unittest
|
|
12
13
|
from collections.abc import Mapping
|
|
13
14
|
from contextlib import redirect_stderr, redirect_stdout
|
|
@@ -36,6 +37,7 @@ from src_py_lib.clients.slack import SlackClient
|
|
|
36
37
|
from src_py_lib.clients.sourcegraph import (
|
|
37
38
|
SourcegraphClient,
|
|
38
39
|
SourcegraphClientConfig,
|
|
40
|
+
SourcegraphTrace,
|
|
39
41
|
decode_external_service_id,
|
|
40
42
|
decode_repository_id,
|
|
41
43
|
encode_repository_id,
|
|
@@ -1535,6 +1537,50 @@ class ClientTest(unittest.TestCase):
|
|
|
1535
1537
|
self.assertEqual(summaries[0].graphql_operations[0]["operation"], "Viewer")
|
|
1536
1538
|
self.assertEqual(summaries[0].errored_spans[0]["description"], "boom")
|
|
1537
1539
|
|
|
1540
|
+
def test_sourcegraph_streams_jaeger_summaries_in_parallel(self) -> None:
|
|
1541
|
+
trace_ids = ("1" * 32, "2" * 32, "3" * 32)
|
|
1542
|
+
requested_trace_ids: list[str] = []
|
|
1543
|
+
first_batch_barrier = threading.Barrier(2, timeout=1)
|
|
1544
|
+
|
|
1545
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
1546
|
+
trace_id = request.url.path.rsplit("/", 1)[-1]
|
|
1547
|
+
requested_trace_ids.append(trace_id)
|
|
1548
|
+
if trace_id in trace_ids[:2]:
|
|
1549
|
+
first_batch_barrier.wait()
|
|
1550
|
+
return httpx.Response(
|
|
1551
|
+
200,
|
|
1552
|
+
json={
|
|
1553
|
+
"data": [
|
|
1554
|
+
{
|
|
1555
|
+
"spans": [
|
|
1556
|
+
{
|
|
1557
|
+
"operationName": f"trace {trace_id[0]}",
|
|
1558
|
+
"duration": 1_000,
|
|
1559
|
+
"tags": [],
|
|
1560
|
+
}
|
|
1561
|
+
]
|
|
1562
|
+
}
|
|
1563
|
+
]
|
|
1564
|
+
},
|
|
1565
|
+
)
|
|
1566
|
+
|
|
1567
|
+
client = SourcegraphClient(
|
|
1568
|
+
"https://sourcegraph.example.com/",
|
|
1569
|
+
"token",
|
|
1570
|
+
http=HTTPClient(max_attempts=1, transport=httpx.MockTransport(handler)),
|
|
1571
|
+
)
|
|
1572
|
+
|
|
1573
|
+
summaries = list(
|
|
1574
|
+
client.stream_jaeger_trace_summaries(
|
|
1575
|
+
[SourcegraphTrace(trace_id) for trace_id in trace_ids],
|
|
1576
|
+
retry_delays_seconds=(0,),
|
|
1577
|
+
parallelism=2,
|
|
1578
|
+
)
|
|
1579
|
+
)
|
|
1580
|
+
|
|
1581
|
+
self.assertCountEqual(requested_trace_ids, trace_ids)
|
|
1582
|
+
self.assertCountEqual([summary.trace.trace_id for summary in summaries], trace_ids)
|
|
1583
|
+
|
|
1538
1584
|
def test_graphql_client_paginates_cursor_results(self) -> None:
|
|
1539
1585
|
http = RecordingHTTP(
|
|
1540
1586
|
[
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
name: Validate
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_call:
|
|
5
|
-
inputs:
|
|
6
|
-
ref:
|
|
7
|
-
description: "Git ref to validate. Defaults to the caller's ref."
|
|
8
|
-
required: false
|
|
9
|
-
type: string
|
|
10
|
-
build-package:
|
|
11
|
-
description: "Build and smoke-test package artifacts. Release builds do this separately."
|
|
12
|
-
required: false
|
|
13
|
-
type: boolean
|
|
14
|
-
default: true
|
|
15
|
-
|
|
16
|
-
permissions:
|
|
17
|
-
contents: read
|
|
18
|
-
|
|
19
|
-
defaults:
|
|
20
|
-
run:
|
|
21
|
-
shell: bash
|
|
22
|
-
|
|
23
|
-
jobs:
|
|
24
|
-
package:
|
|
25
|
-
name: Validate package
|
|
26
|
-
runs-on: ubuntu-24.04
|
|
27
|
-
env:
|
|
28
|
-
ACTIONLINT_VERSION: "1.7.12"
|
|
29
|
-
IMPORT_NAME: src_py_lib
|
|
30
|
-
MARKDOWNLINT_CLI2_VERSION: "0.22.1"
|
|
31
|
-
PYTHON_VERSION: "3.11"
|
|
32
|
-
UV_VERSION: "0.11.7"
|
|
33
|
-
|
|
34
|
-
steps:
|
|
35
|
-
- name: Check out code
|
|
36
|
-
uses: actions/checkout@v6
|
|
37
|
-
with:
|
|
38
|
-
persist-credentials: false
|
|
39
|
-
ref: ${{ inputs.ref || github.ref }}
|
|
40
|
-
|
|
41
|
-
- name: Cache actionlint
|
|
42
|
-
id: cache-actionlint
|
|
43
|
-
uses: actions/cache@v5
|
|
44
|
-
with:
|
|
45
|
-
path: ~/.local/bin/actionlint
|
|
46
|
-
key: actionlint-${{ runner.os }}-${{ runner.arch }}-${{ env.ACTIONLINT_VERSION }}
|
|
47
|
-
|
|
48
|
-
- name: Install actionlint
|
|
49
|
-
if: steps.cache-actionlint.outputs.cache-hit != 'true'
|
|
50
|
-
run: |
|
|
51
|
-
mkdir -p "${HOME}/.local/bin"
|
|
52
|
-
asset="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
|
|
53
|
-
checksums="actionlint_${ACTIONLINT_VERSION}_checksums.txt"
|
|
54
|
-
base_url="https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}"
|
|
55
|
-
|
|
56
|
-
curl -fsSLO "${base_url}/${asset}"
|
|
57
|
-
curl -fsSLO "${base_url}/${checksums}"
|
|
58
|
-
grep " ${asset}$" "${checksums}" | sha256sum --check
|
|
59
|
-
tar -xzf "${asset}" -C "${HOME}/.local/bin" actionlint
|
|
60
|
-
chmod 0755 "${HOME}/.local/bin/actionlint"
|
|
61
|
-
|
|
62
|
-
- name: Lint GitHub Actions
|
|
63
|
-
run: |
|
|
64
|
-
"${HOME}/.local/bin/actionlint"
|
|
65
|
-
|
|
66
|
-
- name: Cache npm
|
|
67
|
-
uses: actions/cache@v5
|
|
68
|
-
with:
|
|
69
|
-
path: ~/.npm
|
|
70
|
-
key: npm-${{ runner.os }}-markdownlint-cli2-${{ env.MARKDOWNLINT_CLI2_VERSION }}
|
|
71
|
-
|
|
72
|
-
- name: Lint Markdown
|
|
73
|
-
run: npx --yes "markdownlint-cli2@${MARKDOWNLINT_CLI2_VERSION}"
|
|
74
|
-
|
|
75
|
-
- name: Set up Python
|
|
76
|
-
uses: actions/setup-python@v6
|
|
77
|
-
with:
|
|
78
|
-
python-version: ${{ env.PYTHON_VERSION }}
|
|
79
|
-
cache: pip
|
|
80
|
-
|
|
81
|
-
- name: Cache uv
|
|
82
|
-
uses: actions/cache@v5
|
|
83
|
-
with:
|
|
84
|
-
path: ~/.cache/uv
|
|
85
|
-
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
86
|
-
restore-keys: |
|
|
87
|
-
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
88
|
-
|
|
89
|
-
- name: Install uv
|
|
90
|
-
run: python -m pip install "uv==${UV_VERSION}"
|
|
91
|
-
|
|
92
|
-
- name: Validate lockfile
|
|
93
|
-
run: uv lock --check
|
|
94
|
-
|
|
95
|
-
- name: Lint Python
|
|
96
|
-
run: uv run --frozen ruff check .
|
|
97
|
-
|
|
98
|
-
- name: Check Python formatting
|
|
99
|
-
run: uv run --frozen ruff format --check .
|
|
100
|
-
|
|
101
|
-
- name: Type check
|
|
102
|
-
run: uv run --frozen pyright
|
|
103
|
-
|
|
104
|
-
- name: Run tests
|
|
105
|
-
run: uv run --frozen python -m unittest discover -s tests
|
|
106
|
-
|
|
107
|
-
- name: Smoke test source checkout import
|
|
108
|
-
run: |
|
|
109
|
-
uv run --frozen python - <<'PY'
|
|
110
|
-
import os
|
|
111
|
-
|
|
112
|
-
import src_py_lib
|
|
113
|
-
|
|
114
|
-
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
115
|
-
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
116
|
-
PY
|
|
117
|
-
|
|
118
|
-
- name: Build wheel
|
|
119
|
-
if: inputs.build-package
|
|
120
|
-
run: uv build --wheel --out-dir dist --no-create-gitignore
|
|
121
|
-
|
|
122
|
-
- name: Smoke test installed wheel
|
|
123
|
-
if: inputs.build-package
|
|
124
|
-
run: |
|
|
125
|
-
python -m venv build/ci-venv
|
|
126
|
-
. build/ci-venv/bin/activate
|
|
127
|
-
python -m pip install dist/*.whl
|
|
128
|
-
python - <<'PY'
|
|
129
|
-
import os
|
|
130
|
-
|
|
131
|
-
import src_py_lib
|
|
132
|
-
|
|
133
|
-
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
134
|
-
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
135
|
-
PY
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|