src-py-lib 0.1.2__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.2 → src_py_lib-0.1.4}/.github/workflows/ci.yml +1 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/.github/workflows/release.yml +30 -20
- src_py_lib-0.1.4/.github/workflows/validate.yml +280 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/AGENTS.md +4 -4
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/PKG-INFO +1 -1
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/pyproject.toml +1 -1
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/__init__.py +1 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/sourcegraph.py +21 -5
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/tests/test_logging_http_clients.py +46 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/uv.lock +1 -1
- src_py_lib-0.1.2/.github/workflows/validate.yml +0 -124
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/.gitignore +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/.markdownlint-cli2.yaml +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/.python-version +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/LICENSE +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/README.md +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/SECURITY.md +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/renovate.json +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/__init__.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/github.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/google_sheets.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/graphql.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/linear.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/one_password.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/clients/slack.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/py.typed +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/utils/__init__.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/utils/config.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/utils/http.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/utils/json_cache.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/utils/json_types.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/utils/logging.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/src/src_py_lib/utils/tsv.py +0 -0
- {src_py_lib-0.1.2 → src_py_lib-0.1.4}/tests/test_import.py +0 -0
- {src_py_lib-0.1.2 → 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 }}
|
|
@@ -28,10 +29,10 @@ jobs:
|
|
|
28
29
|
uses: ./.github/workflows/validate.yml
|
|
29
30
|
with:
|
|
30
31
|
ref: ${{ github.event.inputs.tag || github.ref }}
|
|
32
|
+
build-package: false
|
|
31
33
|
|
|
32
34
|
wheel:
|
|
33
35
|
name: Build wheel
|
|
34
|
-
needs: validate
|
|
35
36
|
runs-on: ubuntu-24.04
|
|
36
37
|
env:
|
|
37
38
|
IMPORT_NAME: src_py_lib
|
|
@@ -50,10 +51,9 @@ 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
|
-
uses: actions/cache@
|
|
56
|
+
uses: actions/cache@v5
|
|
57
57
|
with:
|
|
58
58
|
path: ~/.cache/uv
|
|
59
59
|
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
@@ -61,9 +61,7 @@ jobs:
|
|
|
61
61
|
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
62
62
|
|
|
63
63
|
- name: Install build tools
|
|
64
|
-
run:
|
|
65
|
-
python -m pip install --upgrade pip
|
|
66
|
-
python -m pip install "uv==${UV_VERSION}"
|
|
64
|
+
run: python -m pip install "uv==${UV_VERSION}"
|
|
67
65
|
|
|
68
66
|
- name: Validate release inputs
|
|
69
67
|
id: release
|
|
@@ -145,7 +143,6 @@ jobs:
|
|
|
145
143
|
run: |
|
|
146
144
|
python -m venv build/release/install-venv
|
|
147
145
|
. build/release/install-venv/bin/activate
|
|
148
|
-
python -m pip install --upgrade pip
|
|
149
146
|
python -m pip install "${{ steps.build.outputs.wheel_path }}"
|
|
150
147
|
python - <<'PY'
|
|
151
148
|
import os
|
|
@@ -213,22 +210,35 @@ jobs:
|
|
|
213
210
|
${{ steps.build.outputs.wheel_path }}
|
|
214
211
|
${{ steps.build.outputs.source_distribution_path }}
|
|
215
212
|
|
|
213
|
+
github-release:
|
|
214
|
+
name: Publish GitHub release assets
|
|
215
|
+
needs: [validate, wheel]
|
|
216
|
+
runs-on: ubuntu-24.04
|
|
217
|
+
|
|
218
|
+
steps:
|
|
219
|
+
- name: Download release assets
|
|
220
|
+
uses: actions/download-artifact@v7
|
|
221
|
+
with:
|
|
222
|
+
name: src-py-lib-release
|
|
223
|
+
path: release-assets
|
|
224
|
+
|
|
216
225
|
- name: Publish GitHub release assets
|
|
217
226
|
env:
|
|
218
227
|
GH_TOKEN: ${{ github.token }}
|
|
228
|
+
GH_REPO: ${{ github.repository }}
|
|
219
229
|
run: |
|
|
220
|
-
release_tag="${{
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
"
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
release_tag="${{ github.event.inputs.tag || github.ref_name }}"
|
|
231
|
+
notes_path="$(find release-assets -name release-notes.md -print -quit)"
|
|
232
|
+
mapfile -t release_assets < <(find release-assets -type f ! -name release-notes.md | sort)
|
|
233
|
+
|
|
234
|
+
if [[ -z "${notes_path}" ]]; then
|
|
235
|
+
echo "::error title=Missing release notes::release-notes.md was not found in release artifact."
|
|
236
|
+
exit 1
|
|
237
|
+
fi
|
|
238
|
+
if [[ "${#release_assets[@]}" -eq 0 ]]; then
|
|
239
|
+
echo "::error title=Missing release assets::No release assets were downloaded."
|
|
240
|
+
exit 1
|
|
241
|
+
fi
|
|
232
242
|
|
|
233
243
|
if gh release view "${release_tag}" >/dev/null 2>&1; then
|
|
234
244
|
gh release edit "${release_tag}" --title "${release_tag}" --notes-file "${notes_path}"
|
|
@@ -243,7 +253,7 @@ jobs:
|
|
|
243
253
|
|
|
244
254
|
pypi:
|
|
245
255
|
name: Publish PyPI package
|
|
246
|
-
needs: wheel
|
|
256
|
+
needs: [validate, wheel]
|
|
247
257
|
runs-on: ubuntu-24.04
|
|
248
258
|
permissions:
|
|
249
259
|
contents: read
|
|
@@ -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,124 +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
|
-
|
|
11
|
-
permissions:
|
|
12
|
-
contents: read
|
|
13
|
-
|
|
14
|
-
defaults:
|
|
15
|
-
run:
|
|
16
|
-
shell: bash
|
|
17
|
-
|
|
18
|
-
jobs:
|
|
19
|
-
package:
|
|
20
|
-
name: Validate package
|
|
21
|
-
runs-on: ubuntu-24.04
|
|
22
|
-
env:
|
|
23
|
-
ACTIONLINT_VERSION: "1.7.12"
|
|
24
|
-
IMPORT_NAME: src_py_lib
|
|
25
|
-
MARKDOWNLINT_CLI2_VERSION: "0.22.1"
|
|
26
|
-
PYTHON_VERSION: "3.11"
|
|
27
|
-
UV_VERSION: "0.11.7"
|
|
28
|
-
|
|
29
|
-
steps:
|
|
30
|
-
- name: Check out code
|
|
31
|
-
uses: actions/checkout@v6
|
|
32
|
-
with:
|
|
33
|
-
persist-credentials: false
|
|
34
|
-
ref: ${{ inputs.ref || github.ref }}
|
|
35
|
-
|
|
36
|
-
- name: Cache actionlint
|
|
37
|
-
id: cache-actionlint
|
|
38
|
-
uses: actions/cache@v4
|
|
39
|
-
with:
|
|
40
|
-
path: ~/.local/bin/actionlint
|
|
41
|
-
key: actionlint-${{ runner.os }}-${{ runner.arch }}-${{ env.ACTIONLINT_VERSION }}
|
|
42
|
-
|
|
43
|
-
- name: Install actionlint
|
|
44
|
-
if: steps.cache-actionlint.outputs.cache-hit != 'true'
|
|
45
|
-
run: |
|
|
46
|
-
mkdir -p "${HOME}/.local/bin"
|
|
47
|
-
go install "github.com/rhysd/actionlint/cmd/actionlint@v${ACTIONLINT_VERSION}"
|
|
48
|
-
install -m 0755 "${HOME}/go/bin/actionlint" "${HOME}/.local/bin/actionlint"
|
|
49
|
-
|
|
50
|
-
- name: Lint GitHub Actions
|
|
51
|
-
run: |
|
|
52
|
-
"${HOME}/.local/bin/actionlint"
|
|
53
|
-
|
|
54
|
-
- name: Cache npm
|
|
55
|
-
uses: actions/cache@v4
|
|
56
|
-
with:
|
|
57
|
-
path: ~/.npm
|
|
58
|
-
key: npm-${{ runner.os }}-markdownlint-cli2-${{ env.MARKDOWNLINT_CLI2_VERSION }}
|
|
59
|
-
|
|
60
|
-
- name: Lint Markdown
|
|
61
|
-
run: npx --yes "markdownlint-cli2@${MARKDOWNLINT_CLI2_VERSION}"
|
|
62
|
-
|
|
63
|
-
- name: Set up Python
|
|
64
|
-
uses: actions/setup-python@v6
|
|
65
|
-
with:
|
|
66
|
-
python-version: ${{ env.PYTHON_VERSION }}
|
|
67
|
-
cache: pip
|
|
68
|
-
|
|
69
|
-
- name: Cache uv
|
|
70
|
-
uses: actions/cache@v4
|
|
71
|
-
with:
|
|
72
|
-
path: ~/.cache/uv
|
|
73
|
-
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
74
|
-
restore-keys: |
|
|
75
|
-
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
76
|
-
|
|
77
|
-
- name: Install uv
|
|
78
|
-
run: |
|
|
79
|
-
python -m pip install --upgrade pip
|
|
80
|
-
python -m pip install "uv==${UV_VERSION}"
|
|
81
|
-
|
|
82
|
-
- name: Validate lockfile
|
|
83
|
-
run: uv lock --check
|
|
84
|
-
|
|
85
|
-
- name: Lint Python
|
|
86
|
-
run: uv run --frozen ruff check .
|
|
87
|
-
|
|
88
|
-
- name: Check Python formatting
|
|
89
|
-
run: uv run --frozen ruff format --check .
|
|
90
|
-
|
|
91
|
-
- name: Type check
|
|
92
|
-
run: uv run --frozen pyright
|
|
93
|
-
|
|
94
|
-
- name: Run tests
|
|
95
|
-
run: uv run --frozen python -m unittest discover -s tests
|
|
96
|
-
|
|
97
|
-
- name: Smoke test source checkout import
|
|
98
|
-
run: |
|
|
99
|
-
uv run --frozen python - <<'PY'
|
|
100
|
-
import os
|
|
101
|
-
|
|
102
|
-
import src_py_lib
|
|
103
|
-
|
|
104
|
-
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
105
|
-
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
106
|
-
PY
|
|
107
|
-
|
|
108
|
-
- name: Build wheel
|
|
109
|
-
run: uv build --wheel --out-dir dist --no-create-gitignore
|
|
110
|
-
|
|
111
|
-
- name: Smoke test installed wheel
|
|
112
|
-
run: |
|
|
113
|
-
python -m venv build/ci-venv
|
|
114
|
-
. build/ci-venv/bin/activate
|
|
115
|
-
python -m pip install --upgrade pip
|
|
116
|
-
python -m pip install dist/*.whl
|
|
117
|
-
python - <<'PY'
|
|
118
|
-
import os
|
|
119
|
-
|
|
120
|
-
import src_py_lib
|
|
121
|
-
|
|
122
|
-
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
123
|
-
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
124
|
-
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
|