src-py-lib 0.1.1__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.1/.github/workflows/ci.yml +93 -0
- src_py_lib-0.1.1/.github/workflows/release.yml +235 -0
- src_py_lib-0.1.1/.gitignore +20 -0
- src_py_lib-0.1.1/.markdownlint-cli2.yaml +9 -0
- src_py_lib-0.1.1/.python-version +1 -0
- src_py_lib-0.1.1/AGENTS.md +179 -0
- src_py_lib-0.1.1/LICENSE +21 -0
- src_py_lib-0.1.1/PKG-INFO +103 -0
- src_py_lib-0.1.1/README.md +80 -0
- src_py_lib-0.1.1/SECURITY.md +3 -0
- src_py_lib-0.1.1/pyproject.toml +61 -0
- src_py_lib-0.1.1/renovate.json +14 -0
- src_py_lib-0.1.1/src/src_py_lib/__init__.py +170 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/__init__.py +3 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/github.py +157 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/google_sheets.py +131 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/graphql.py +476 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/linear.py +101 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/one_password.py +95 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/slack.py +146 -0
- src_py_lib-0.1.1/src/src_py_lib/clients/sourcegraph.py +127 -0
- src_py_lib-0.1.1/src/src_py_lib/py.typed +0 -0
- src_py_lib-0.1.1/src/src_py_lib/utils/__init__.py +3 -0
- src_py_lib-0.1.1/src/src_py_lib/utils/config.py +603 -0
- src_py_lib-0.1.1/src/src_py_lib/utils/http.py +279 -0
- src_py_lib-0.1.1/src/src_py_lib/utils/json_cache.py +42 -0
- src_py_lib-0.1.1/src/src_py_lib/utils/json_types.py +54 -0
- src_py_lib-0.1.1/src/src_py_lib/utils/logging.py +950 -0
- src_py_lib-0.1.1/src/src_py_lib/utils/tsv.py +95 -0
- src_py_lib-0.1.1/tests/test_import.py +51 -0
- src_py_lib-0.1.1/tests/test_logging_http_clients.py +1981 -0
- src_py_lib-0.1.1/tests/test_tsv.py +65 -0
- src_py_lib-0.1.1/uv.lock +303 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
defaults:
|
|
13
|
+
run:
|
|
14
|
+
shell: bash
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
name: Build and test
|
|
19
|
+
runs-on: ubuntu-24.04
|
|
20
|
+
env:
|
|
21
|
+
IMPORT_NAME: src_py_lib
|
|
22
|
+
PYTHON_VERSION: "3.11"
|
|
23
|
+
UV_VERSION: "0.11.7"
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- name: Check out code
|
|
27
|
+
uses: actions/checkout@v6
|
|
28
|
+
with:
|
|
29
|
+
persist-credentials: false
|
|
30
|
+
|
|
31
|
+
- name: Set up Python
|
|
32
|
+
uses: actions/setup-python@v6
|
|
33
|
+
with:
|
|
34
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
35
|
+
cache: pip
|
|
36
|
+
|
|
37
|
+
- name: Install uv
|
|
38
|
+
run: |
|
|
39
|
+
python -m pip install --upgrade pip
|
|
40
|
+
python -m pip install "uv==${UV_VERSION}"
|
|
41
|
+
|
|
42
|
+
- name: Validate lockfile
|
|
43
|
+
run: uv lock --check
|
|
44
|
+
|
|
45
|
+
- name: Lint Markdown
|
|
46
|
+
run: npx --yes markdownlint-cli2
|
|
47
|
+
|
|
48
|
+
- name: Lint Python
|
|
49
|
+
run: uv run --frozen ruff check .
|
|
50
|
+
|
|
51
|
+
- name: Check Python formatting
|
|
52
|
+
run: uv run --frozen ruff format --check .
|
|
53
|
+
|
|
54
|
+
- name: Type check
|
|
55
|
+
run: uv run --frozen pyright
|
|
56
|
+
|
|
57
|
+
- name: Run tests
|
|
58
|
+
run: uv run --frozen python -m unittest discover -s tests
|
|
59
|
+
|
|
60
|
+
- name: Smoke test source checkout import
|
|
61
|
+
run: |
|
|
62
|
+
uv run --frozen python - <<'PY'
|
|
63
|
+
import os
|
|
64
|
+
|
|
65
|
+
import src_py_lib
|
|
66
|
+
|
|
67
|
+
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
68
|
+
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
69
|
+
PY
|
|
70
|
+
|
|
71
|
+
- name: Build wheel
|
|
72
|
+
run: uv build --wheel --out-dir dist --no-create-gitignore
|
|
73
|
+
|
|
74
|
+
- name: Smoke test installed wheel
|
|
75
|
+
run: |
|
|
76
|
+
python -m venv build/ci-venv
|
|
77
|
+
. build/ci-venv/bin/activate
|
|
78
|
+
python -m pip install --upgrade pip
|
|
79
|
+
python -m pip install dist/*.whl
|
|
80
|
+
python - <<'PY'
|
|
81
|
+
import os
|
|
82
|
+
|
|
83
|
+
import src_py_lib
|
|
84
|
+
|
|
85
|
+
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
86
|
+
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
87
|
+
PY
|
|
88
|
+
|
|
89
|
+
- name: Upload wheel artifact
|
|
90
|
+
uses: actions/upload-artifact@v7
|
|
91
|
+
with:
|
|
92
|
+
name: src-py-lib-wheel
|
|
93
|
+
path: dist/*.whl
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
name: Build release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
tag:
|
|
10
|
+
description: "Existing release tag to publish, for example v0.1.0"
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
group: release-${{ github.event.inputs.tag || github.ref_name }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
|
|
21
|
+
defaults:
|
|
22
|
+
run:
|
|
23
|
+
shell: bash
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
wheel:
|
|
27
|
+
name: Build wheel
|
|
28
|
+
runs-on: ubuntu-24.04
|
|
29
|
+
env:
|
|
30
|
+
IMPORT_NAME: src_py_lib
|
|
31
|
+
PYTHON_VERSION: "3.11"
|
|
32
|
+
UV_VERSION: "0.11.7"
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Check out release ref
|
|
36
|
+
uses: actions/checkout@v6
|
|
37
|
+
with:
|
|
38
|
+
fetch-depth: 0
|
|
39
|
+
persist-credentials: false
|
|
40
|
+
ref: ${{ github.event.inputs.tag || github.ref }}
|
|
41
|
+
|
|
42
|
+
- name: Set up Python
|
|
43
|
+
uses: actions/setup-python@v6
|
|
44
|
+
with:
|
|
45
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
46
|
+
cache: pip
|
|
47
|
+
|
|
48
|
+
- name: Install build tools
|
|
49
|
+
run: |
|
|
50
|
+
python -m pip install --upgrade pip
|
|
51
|
+
python -m pip install "uv==${UV_VERSION}"
|
|
52
|
+
|
|
53
|
+
- name: Validate release inputs
|
|
54
|
+
id: release
|
|
55
|
+
run: |
|
|
56
|
+
release_tag="${{ github.event.inputs.tag || github.ref_name }}"
|
|
57
|
+
if [[ ! "${release_tag}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
58
|
+
echo "::error title=Invalid release tag::Use a vMAJOR.MINOR.PATCH tag, got '${release_tag}'."
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
if ! git rev-parse --verify --quiet "refs/tags/${release_tag}" >/dev/null; then
|
|
62
|
+
echo "::error title=Missing tag::Tag '${release_tag}' was not fetched. Create and push it before running this workflow."
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
project_version=$(uv run --frozen python - <<'PY'
|
|
67
|
+
import tomllib
|
|
68
|
+
|
|
69
|
+
with open("pyproject.toml", "rb") as pyproject_file:
|
|
70
|
+
print(tomllib.load(pyproject_file)["project"]["version"])
|
|
71
|
+
PY
|
|
72
|
+
)
|
|
73
|
+
if [[ "v${project_version}" != "${release_tag}" ]]; then
|
|
74
|
+
echo "::error title=Version mismatch::pyproject.toml version '${project_version}' does not match tag '${release_tag}'."
|
|
75
|
+
exit 1
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo "tag=${release_tag}" >> "${GITHUB_OUTPUT}"
|
|
79
|
+
|
|
80
|
+
- name: Validate package
|
|
81
|
+
run: |
|
|
82
|
+
uv lock --check
|
|
83
|
+
uv run --frozen ruff check .
|
|
84
|
+
uv run --frozen ruff format --check .
|
|
85
|
+
uv run --frozen pyright
|
|
86
|
+
uv run --frozen python -m unittest discover -s tests
|
|
87
|
+
uv run --frozen python - <<'PY'
|
|
88
|
+
import os
|
|
89
|
+
|
|
90
|
+
import src_py_lib
|
|
91
|
+
|
|
92
|
+
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
93
|
+
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
94
|
+
PY
|
|
95
|
+
|
|
96
|
+
- name: Build distributions
|
|
97
|
+
id: build
|
|
98
|
+
run: |
|
|
99
|
+
dist_dir="build/release/dist"
|
|
100
|
+
rm -rf build/release
|
|
101
|
+
mkdir -p "${dist_dir}"
|
|
102
|
+
shopt -s nullglob
|
|
103
|
+
|
|
104
|
+
uv build --wheel --sdist --out-dir "${dist_dir}" --no-create-gitignore
|
|
105
|
+
project_wheels=("${dist_dir}"/*.whl)
|
|
106
|
+
if [[ "${#project_wheels[@]}" -ne 1 ]]; then
|
|
107
|
+
echo "::error title=Unexpected wheel count::Expected one project wheel, found ${#project_wheels[@]}."
|
|
108
|
+
exit 1
|
|
109
|
+
fi
|
|
110
|
+
source_distributions=("${dist_dir}"/*.tar.gz)
|
|
111
|
+
if [[ "${#source_distributions[@]}" -ne 1 ]]; then
|
|
112
|
+
echo "::error title=Unexpected source distribution count::Expected one source distribution, found ${#source_distributions[@]}."
|
|
113
|
+
exit 1
|
|
114
|
+
fi
|
|
115
|
+
wheel_path="${project_wheels[0]}"
|
|
116
|
+
wheel_name="$(basename "${wheel_path}")"
|
|
117
|
+
source_distribution_path="${source_distributions[0]}"
|
|
118
|
+
checksum_path="${wheel_path}.sha256"
|
|
119
|
+
|
|
120
|
+
(
|
|
121
|
+
cd "$(dirname "${wheel_path}")"
|
|
122
|
+
shasum -a 256 "${wheel_name}" > "$(basename "${checksum_path}")"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
echo "wheel_path=${wheel_path}" >> "${GITHUB_OUTPUT}"
|
|
126
|
+
echo "wheel_name=${wheel_name}" >> "${GITHUB_OUTPUT}"
|
|
127
|
+
echo "source_distribution_path=${source_distribution_path}" >> "${GITHUB_OUTPUT}"
|
|
128
|
+
echo "checksum_path=${checksum_path}" >> "${GITHUB_OUTPUT}"
|
|
129
|
+
|
|
130
|
+
- name: Smoke test installed wheel
|
|
131
|
+
run: |
|
|
132
|
+
python -m venv build/release/install-venv
|
|
133
|
+
. build/release/install-venv/bin/activate
|
|
134
|
+
python -m pip install --upgrade pip
|
|
135
|
+
python -m pip install "${{ steps.build.outputs.wheel_path }}"
|
|
136
|
+
python - <<'PY'
|
|
137
|
+
import os
|
|
138
|
+
|
|
139
|
+
import src_py_lib
|
|
140
|
+
|
|
141
|
+
if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
|
|
142
|
+
raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
|
|
143
|
+
PY
|
|
144
|
+
|
|
145
|
+
- name: Write release notes
|
|
146
|
+
id: notes
|
|
147
|
+
run: |
|
|
148
|
+
release_tag="${{ steps.release.outputs.tag }}"
|
|
149
|
+
wheel_name="${{ steps.build.outputs.wheel_name }}"
|
|
150
|
+
notes_path="build/release/release-notes.md"
|
|
151
|
+
cat > "${notes_path}" <<EOF
|
|
152
|
+
## Install
|
|
153
|
+
|
|
154
|
+
Install from PyPI:
|
|
155
|
+
|
|
156
|
+
\`\`\`sh
|
|
157
|
+
pip install src-py-lib
|
|
158
|
+
\`\`\`
|
|
159
|
+
|
|
160
|
+
Install from the release wheel:
|
|
161
|
+
|
|
162
|
+
\`\`\`sh
|
|
163
|
+
pip install "https://github.com/sourcegraph/src-py-lib/releases/download/${release_tag}/${wheel_name}"
|
|
164
|
+
\`\`\`
|
|
165
|
+
|
|
166
|
+
Or install this tag with uv:
|
|
167
|
+
|
|
168
|
+
\`\`\`sh
|
|
169
|
+
uv add "git+https://github.com/sourcegraph/src-py-lib.git@${release_tag}"
|
|
170
|
+
\`\`\`
|
|
171
|
+
|
|
172
|
+
Verify downloaded wheel assets with the matching \`.sha256\` file.
|
|
173
|
+
EOF
|
|
174
|
+
echo "path=${notes_path}" >> "${GITHUB_OUTPUT}"
|
|
175
|
+
|
|
176
|
+
- name: Upload workflow artifact
|
|
177
|
+
uses: actions/upload-artifact@v7
|
|
178
|
+
with:
|
|
179
|
+
name: src-py-lib-release
|
|
180
|
+
path: |
|
|
181
|
+
${{ steps.build.outputs.wheel_path }}
|
|
182
|
+
${{ steps.build.outputs.checksum_path }}
|
|
183
|
+
${{ steps.notes.outputs.path }}
|
|
184
|
+
|
|
185
|
+
- name: Upload PyPI artifact
|
|
186
|
+
uses: actions/upload-artifact@v7
|
|
187
|
+
with:
|
|
188
|
+
name: pypi-distributions
|
|
189
|
+
path: |
|
|
190
|
+
${{ steps.build.outputs.wheel_path }}
|
|
191
|
+
${{ steps.build.outputs.source_distribution_path }}
|
|
192
|
+
|
|
193
|
+
- name: Publish GitHub release assets
|
|
194
|
+
env:
|
|
195
|
+
GH_TOKEN: ${{ github.token }}
|
|
196
|
+
run: |
|
|
197
|
+
release_tag="${{ steps.release.outputs.tag }}"
|
|
198
|
+
wheel_path="${{ steps.build.outputs.wheel_path }}"
|
|
199
|
+
checksum_path="${{ steps.build.outputs.checksum_path }}"
|
|
200
|
+
notes_path="${{ steps.notes.outputs.path }}"
|
|
201
|
+
|
|
202
|
+
if gh release view "${release_tag}" >/dev/null 2>&1; then
|
|
203
|
+
gh release edit "${release_tag}" --title "${release_tag}" --notes-file "${notes_path}"
|
|
204
|
+
gh release upload "${release_tag}" "${wheel_path}" "${checksum_path}" --clobber
|
|
205
|
+
else
|
|
206
|
+
gh release create "${release_tag}" \
|
|
207
|
+
"${wheel_path}" \
|
|
208
|
+
"${checksum_path}" \
|
|
209
|
+
--title "${release_tag}" \
|
|
210
|
+
--notes-file "${notes_path}" \
|
|
211
|
+
--verify-tag
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
pypi:
|
|
215
|
+
name: Publish PyPI package
|
|
216
|
+
needs: wheel
|
|
217
|
+
runs-on: ubuntu-24.04
|
|
218
|
+
permissions:
|
|
219
|
+
contents: read
|
|
220
|
+
id-token: write
|
|
221
|
+
environment:
|
|
222
|
+
name: pypi
|
|
223
|
+
url: https://pypi.org/project/src-py-lib/
|
|
224
|
+
|
|
225
|
+
steps:
|
|
226
|
+
- name: Download built distribution
|
|
227
|
+
uses: actions/download-artifact@v7
|
|
228
|
+
with:
|
|
229
|
+
name: pypi-distributions
|
|
230
|
+
path: dist
|
|
231
|
+
|
|
232
|
+
- name: Publish PyPI package
|
|
233
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
234
|
+
with:
|
|
235
|
+
packages-dir: dist
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Agents
|
|
2
|
+
|
|
3
|
+
<!-- HUMAN-MAINTAINED - START -->
|
|
4
|
+
|
|
5
|
+
## Project principles
|
|
6
|
+
|
|
7
|
+
- This repo is public, never write non-public information in this repo
|
|
8
|
+
- Keep code and docs brief, for humans to read / understand / audit quickly
|
|
9
|
+
- Reuse and improve existing solutions / approaches / designs / helpers / tools / patterns,
|
|
10
|
+
before adding new / similar ones
|
|
11
|
+
- Keep runtime dependencies minimal; justify new dependencies in code review
|
|
12
|
+
- Preserve unrelated user or agent edits in the worktree
|
|
13
|
+
|
|
14
|
+
## Standard commands
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npx --yes markdownlint-cli2
|
|
18
|
+
uv sync
|
|
19
|
+
uv run ruff format .
|
|
20
|
+
uv run ruff check .
|
|
21
|
+
uv run pyright
|
|
22
|
+
uv run python -m unittest discover -s tests
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
<!-- HUMAN-MAINTAINED - END -->
|
|
26
|
+
|
|
27
|
+
<!-- AGENT-MAINTAINED - START -->
|
|
28
|
+
|
|
29
|
+
## Toolchain
|
|
30
|
+
|
|
31
|
+
- Use `uv` for dependency management, virtualenv creation, and command running
|
|
32
|
+
- Use pyright in strict mode; fix linting / typing issues instead of suppressing them
|
|
33
|
+
- Use ruff for formatting, import sorting, and linting
|
|
34
|
+
|
|
35
|
+
## Runtime standards
|
|
36
|
+
|
|
37
|
+
- Configure the root logger by default (`logger_name=""`) so project modules
|
|
38
|
+
and shared `src_py_lib` modules are captured by the same handlers
|
|
39
|
+
- Startup logs should include command, sanitized runtime config, commit when
|
|
40
|
+
available, and log file path when applicable
|
|
41
|
+
- Use shared HTTP/client helpers for timeout policy, API error wrapping, and
|
|
42
|
+
rate-limit handling
|
|
43
|
+
|
|
44
|
+
## Code organization
|
|
45
|
+
|
|
46
|
+
- Put importable package code under `src/`
|
|
47
|
+
- Put tests under `tests/`
|
|
48
|
+
- Keep module-level constants near the top of each module, after imports
|
|
49
|
+
- Prefer specific package/module names over broad `helpers` or `utils` modules
|
|
50
|
+
|
|
51
|
+
## Release process
|
|
52
|
+
|
|
53
|
+
- The tagged source commit must already contain the package version it
|
|
54
|
+
releases. Do not make the release workflow edit `pyproject.toml`.
|
|
55
|
+
- The tag must be `vMAJOR.MINOR.PATCH`, and `.github/workflows/release.yml`
|
|
56
|
+
verifies that it matches `project.version` before building GitHub release
|
|
57
|
+
assets and publishing to PyPI.
|
|
58
|
+
- Prepare releases on a branch from current `main`. Set `VERSION`, then run:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
set -euo pipefail
|
|
62
|
+
|
|
63
|
+
VERSION=0.1.1
|
|
64
|
+
BRANCH="release-v${VERSION}"
|
|
65
|
+
|
|
66
|
+
git fetch origin --tags --prune
|
|
67
|
+
git switch main
|
|
68
|
+
git pull --ff-only
|
|
69
|
+
git switch -c "${BRANCH}"
|
|
70
|
+
|
|
71
|
+
uv run python - "${VERSION}" <<'PY'
|
|
72
|
+
from pathlib import Path
|
|
73
|
+
import re
|
|
74
|
+
import sys
|
|
75
|
+
|
|
76
|
+
version = sys.argv[1]
|
|
77
|
+
path = Path("pyproject.toml")
|
|
78
|
+
text = path.read_text()
|
|
79
|
+
new_text = re.sub(
|
|
80
|
+
r'(?m)^version = "[^"]+"$',
|
|
81
|
+
f'version = "{version}"',
|
|
82
|
+
text,
|
|
83
|
+
count=1,
|
|
84
|
+
)
|
|
85
|
+
if new_text == text:
|
|
86
|
+
raise SystemExit("pyproject.toml version was not updated")
|
|
87
|
+
path.write_text(new_text)
|
|
88
|
+
PY
|
|
89
|
+
|
|
90
|
+
uv lock
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- Validate before opening the PR:
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
set -euo pipefail
|
|
97
|
+
|
|
98
|
+
uv lock --check
|
|
99
|
+
npx --yes markdownlint-cli2
|
|
100
|
+
uv run ruff check .
|
|
101
|
+
uv run ruff format --check .
|
|
102
|
+
uv run pyright
|
|
103
|
+
uv run python -m unittest discover -s tests
|
|
104
|
+
uv build --wheel --sdist --out-dir /tmp/src-py-lib-release-check --no-create-gitignore
|
|
105
|
+
rm -rf /tmp/src-py-lib-release-check
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- Commit, push, open the PR, wait for checks, then merge it. If review is
|
|
109
|
+
required, stop after `gh pr checks` and ask for review before merging.
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
set -euo pipefail
|
|
113
|
+
|
|
114
|
+
VERSION=0.1.1
|
|
115
|
+
BRANCH="release-v${VERSION}"
|
|
116
|
+
GH_REPO="sourcegraph/src-py-lib"
|
|
117
|
+
|
|
118
|
+
git add pyproject.toml uv.lock
|
|
119
|
+
git commit -m "Release v${VERSION}"
|
|
120
|
+
git push -u origin "${BRANCH}"
|
|
121
|
+
|
|
122
|
+
gh pr create \
|
|
123
|
+
--repo "${GH_REPO}" \
|
|
124
|
+
--base main \
|
|
125
|
+
--head "${BRANCH}" \
|
|
126
|
+
--title "Release v${VERSION}" \
|
|
127
|
+
--body "Bump src-py-lib package metadata to ${VERSION}."
|
|
128
|
+
|
|
129
|
+
gh pr checks "${BRANCH}" --repo "${GH_REPO}" --watch --fail-fast
|
|
130
|
+
gh pr merge "${BRANCH}" --repo "${GH_REPO}" --squash --delete-branch
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- Tag the merged `main` commit. Do not tag a branch commit.
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
set -euo pipefail
|
|
137
|
+
|
|
138
|
+
VERSION=0.1.1
|
|
139
|
+
|
|
140
|
+
git fetch origin --tags --prune
|
|
141
|
+
git switch main
|
|
142
|
+
git pull --ff-only
|
|
143
|
+
git tag "v${VERSION}"
|
|
144
|
+
git push origin "v${VERSION}"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- Watch the release workflow and confirm the GitHub release and PyPI project.
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
set -euo pipefail
|
|
151
|
+
|
|
152
|
+
VERSION=0.1.1
|
|
153
|
+
GH_REPO="sourcegraph/src-py-lib"
|
|
154
|
+
|
|
155
|
+
RUN_ID="$(
|
|
156
|
+
gh run list \
|
|
157
|
+
--repo "${GH_REPO}" \
|
|
158
|
+
--workflow release.yml \
|
|
159
|
+
--branch "v${VERSION}" \
|
|
160
|
+
--limit 1 \
|
|
161
|
+
--json databaseId \
|
|
162
|
+
--jq '.[0].databaseId // empty'
|
|
163
|
+
)"
|
|
164
|
+
test -n "${RUN_ID}"
|
|
165
|
+
gh run watch "${RUN_ID}" --repo "${GH_REPO}" --exit-status
|
|
166
|
+
gh release view "v${VERSION}" --repo "${GH_REPO}"
|
|
167
|
+
uvx --from pip pip index versions src-py-lib
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
- If a pushed tag points at the wrong commit, move it only after explicit
|
|
171
|
+
human approval.
|
|
172
|
+
|
|
173
|
+
## Before finishing changes
|
|
174
|
+
|
|
175
|
+
- Re-read edited files for organization and stale comments
|
|
176
|
+
- Update `README.md` when setup or user-facing behavior changes
|
|
177
|
+
- Update this `AGENTS.md` only with durable project-specific discoveries
|
|
178
|
+
|
|
179
|
+
<!-- AGENT-MAINTAINED - END -->
|
src_py_lib-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sourcegraph
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: src-py-lib
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Reusable libraries for Sourcegraph projects
|
|
5
|
+
Project-URL: Homepage, https://github.com/sourcegraph/src-py-lib
|
|
6
|
+
Project-URL: Issues, https://github.com/sourcegraph/src-py-lib/issues
|
|
7
|
+
Author: Sourcegraph
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: Sourcegraph
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: httpx<1,>=0.28
|
|
20
|
+
Requires-Dist: pydantic<3,>=2
|
|
21
|
+
Requires-Dist: python-dotenv<2,>=1.2
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# src-py-lib
|
|
25
|
+
|
|
26
|
+
Reusable libraries for Sourcegraph projects
|
|
27
|
+
|
|
28
|
+
## Experimental - This is not a supported Sourcegraph product
|
|
29
|
+
|
|
30
|
+
This repo was created for Sourcegraph Implementation Engineering deployments,
|
|
31
|
+
and is not intended, designed, built, or supported for use in any other scenario.
|
|
32
|
+
Feel free to open issues or PRs, but responses are best effort.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
From PyPI:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
uv add src-py-lib
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
From this repository:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
uv add git+https://github.com/sourcegraph/src-py-lib.git
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Use it for
|
|
49
|
+
|
|
50
|
+
- Typed config models loaded from defaults, `.env`, environment variables, and CLI flags
|
|
51
|
+
- Root logger setup with terminal output, optional JSONL events, timing, and run metadata
|
|
52
|
+
- A shared `httpx` JSON client with timeouts, retries, `Retry-After`, and contextual errors
|
|
53
|
+
- Small helpers for TSV output, JSON caches, GraphQL pagination, and batched GraphQL queries
|
|
54
|
+
- Thin clients for Sourcegraph, Linear, Slack, GitHub, Google Sheets, and 1Password
|
|
55
|
+
|
|
56
|
+
Prefer vendor SDKs when they handle complex auth, token refresh, quota behavior,
|
|
57
|
+
pagination, retries, or request models better than a thin wrapper
|
|
58
|
+
|
|
59
|
+
## Quick example
|
|
60
|
+
|
|
61
|
+
Define a project config, parse it once, and configure logging at startup:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from pathlib import Path
|
|
65
|
+
|
|
66
|
+
import src_py_lib as src
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class LinearExportConfig(src.LinearClientConfig):
|
|
70
|
+
output_dir: Path = src.config_field(
|
|
71
|
+
default=Path("."),
|
|
72
|
+
env_var="LINEAR_EXPORT_OUTPUT_DIR",
|
|
73
|
+
cli_flag="--output-dir",
|
|
74
|
+
metavar="PATH",
|
|
75
|
+
help="Directory for generated files.",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
config = src.parse_args(LinearExportConfig, description="Export Linear data")
|
|
79
|
+
|
|
80
|
+
with src.logging(config):
|
|
81
|
+
client = src.linear_client_from_config(config)
|
|
82
|
+
client.validate()
|
|
83
|
+
src.info("Starting export", output_dir=str(config.output_dir))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- Config precedence is code defaults, `.env`, shell environment, then CLI overrides
|
|
87
|
+
- `parse_args` resolves `op://...` references by default
|
|
88
|
+
- Mark sensitive fields with `secret=True` so config snapshots redact resolved values
|
|
89
|
+
- `src.logging()` configures the root logger by default so project code and `src_py_lib` internals
|
|
90
|
+
share the same handlers
|
|
91
|
+
- Use `event()` for timed work, `stage()` for workflow context, and
|
|
92
|
+
`info()` / `warning()` / `error()` for structured one-off events
|
|
93
|
+
|
|
94
|
+
## Development
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
uv sync
|
|
98
|
+
uv run ruff format .
|
|
99
|
+
uv run ruff check .
|
|
100
|
+
uv run pyright
|
|
101
|
+
uv run python -m unittest discover -s tests
|
|
102
|
+
npx --yes markdownlint-cli2
|
|
103
|
+
```
|