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.
Files changed (35) hide show
  1. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.github/workflows/ci.yml +1 -0
  2. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.github/workflows/release.yml +2 -1
  3. src_py_lib-0.1.4/.github/workflows/validate.yml +280 -0
  4. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/AGENTS.md +4 -4
  5. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/PKG-INFO +1 -1
  6. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/pyproject.toml +1 -1
  7. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/__init__.py +1 -0
  8. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/sourcegraph.py +21 -5
  9. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/tests/test_logging_http_clients.py +46 -0
  10. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/uv.lock +1 -1
  11. src_py_lib-0.1.3/.github/workflows/validate.yml +0 -135
  12. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.gitignore +0 -0
  13. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.markdownlint-cli2.yaml +0 -0
  14. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/.python-version +0 -0
  15. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/LICENSE +0 -0
  16. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/README.md +0 -0
  17. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/SECURITY.md +0 -0
  18. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/renovate.json +0 -0
  19. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/__init__.py +0 -0
  20. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/github.py +0 -0
  21. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/google_sheets.py +0 -0
  22. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/graphql.py +0 -0
  23. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/linear.py +0 -0
  24. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/one_password.py +0 -0
  25. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/clients/slack.py +0 -0
  26. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/py.typed +0 -0
  27. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/__init__.py +0 -0
  28. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/config.py +0 -0
  29. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/http.py +0 -0
  30. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/json_cache.py +0 -0
  31. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/json_types.py +0 -0
  32. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/logging.py +0 -0
  33. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/src/src_py_lib/utils/tsv.py +0 -0
  34. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/tests/test_import.py +0 -0
  35. {src_py_lib-0.1.3 → src_py_lib-0.1.4}/tests/test_tsv.py +0 -0
@@ -5,6 +5,7 @@ on:
5
5
 
6
6
  permissions:
7
7
  contents: read
8
+ pull-requests: read
8
9
 
9
10
  concurrency:
10
11
  group: ci-${{ github.workflow }}-${{ github.ref }}
@@ -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.2
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.2
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.2
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.2
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
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
@@ -10,7 +10,7 @@ dev = [
10
10
 
11
11
  [project]
12
12
  name = "src-py-lib"
13
- version = "0.1.3"
13
+ version = "0.1.4"
14
14
  description = "Reusable libraries for Sourcegraph projects"
15
15
  readme = "README.md"
16
16
  requires-python = ">=3.11"
@@ -176,6 +176,7 @@ __all__ = [
176
176
  "load_json_cache",
177
177
  "load_json_subset",
178
178
  "logging",
179
+ "logging_context",
179
180
  "logging_settings_from_config",
180
181
  "log",
181
182
  "log_context",
@@ -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
- for trace in self.drain_traces() if traces is None else traces:
250
- yield self.fetch_jaeger_trace_summary(
251
- trace,
252
- retry_delays_seconds=retry_delays_seconds,
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
  [
@@ -254,7 +254,7 @@ wheels = [
254
254
 
255
255
  [[package]]
256
256
  name = "src-py-lib"
257
- version = "0.1.3"
257
+ version = "0.1.4"
258
258
  source = { editable = "." }
259
259
  dependencies = [
260
260
  { name = "httpx" },
@@ -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