Skip to content

Commit e848685

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/async-client-search-api
# Conflicts: # pyproject.toml
2 parents 72eb662 + 95e9a80 commit e848685

13 files changed

Lines changed: 257 additions & 74 deletions
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
# Check if the ci:per-commit label is present.
3+
#
4+
# For pull_request events, checks labels from the event payload.
5+
# For push events, looks up the originating PR via the GitHub API.
6+
#
7+
# Usage:
8+
# check-ci-per-commit-label.sh <event_name> <repository> <sha> [labels_json]
9+
#
10+
# Arguments:
11+
# event_name - "pull_request" or "push"
12+
# repository - e.g. "owner/repo"
13+
# sha - commit SHA
14+
# labels_json - JSON array of label names (required for pull_request)
15+
#
16+
# Output:
17+
# Prints has_label=true or has_label=false (for GITHUB_OUTPUT)
18+
set -euo pipefail
19+
20+
event_name="${1:?Usage: check-ci-per-commit-label.sh <event_name> <repository> <sha> [labels_json]}"
21+
repository="${2:?Missing repository}"
22+
sha="${3:?Missing sha}"
23+
labels_json="${4:-}"
24+
25+
HAS_LABEL="false"
26+
27+
if [ "$event_name" = "pull_request" ]; then
28+
if echo "$labels_json" | grep -q "ci:per-commit"; then
29+
HAS_LABEL="true"
30+
fi
31+
else
32+
PRS=$(gh api \
33+
"repos/${repository}/commits/${sha}/pulls" \
34+
--jq '.[].number')
35+
for pr in $PRS; do
36+
LABELS=$(gh api \
37+
"repos/${repository}/pulls/${pr}" \
38+
--jq '.labels[].name')
39+
if echo "$LABELS" | grep -q "^ci:per-commit$"; then
40+
HAS_LABEL="true"
41+
break
42+
fi
43+
done
44+
fi
45+
46+
echo "has_label=${HAS_LABEL}"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env bash
2+
# Run the full CI checks on each commit in the given range, sequentially.
3+
# Stops at the first commit that fails.
4+
#
5+
# Usage:
6+
# run-ci-per-commit.sh <base_sha> <head_sha>
7+
#
8+
# Arguments:
9+
# base_sha - the base commit (exclusive)
10+
# head_sha - the head commit (inclusive)
11+
set -euo pipefail
12+
13+
base="${1:?Usage: run-ci-per-commit.sh <base_sha> <head_sha>}"
14+
head="${2:?Missing head_sha}"
15+
16+
commits=$(git rev-list --reverse "${base}..${head}")
17+
total=$(echo "$commits" | wc -l | tr -d ' ')
18+
current=0
19+
20+
for commit in $commits; do
21+
current=$((current + 1))
22+
short=$(git rev-parse --short "$commit")
23+
subject=$(git log -1 --format=%s "$commit")
24+
echo ""
25+
echo "=== [$current/$total] Testing ${short}: ${subject} ==="
26+
echo ""
27+
28+
git checkout --quiet "$commit"
29+
make install
30+
make lint
31+
make check-format
32+
make test
33+
34+
echo ""
35+
echo "=== [$current/$total] PASSED: ${short} ==="
36+
done
37+
38+
echo ""
39+
echo "All ${total} commit(s) passed CI checks."

.github/workflows/actions.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,18 @@ jobs:
66
strategy:
77
fail-fast: false
88
matrix:
9-
python-version: ["3.13"]
10-
poetry-version: ["2.3.1"]
9+
python-version: ["3.11", "3.12", "3.13", "3.14"]
1110
os: [ubuntu-latest, macos-latest]
1211
runs-on: ${{ matrix.os }}
1312
steps:
1413
- uses: actions/checkout@v6
15-
- uses: actions/setup-python@v6
14+
- name: Install uv
15+
uses: astral-sh/setup-uv@v6
1616
with:
1717
python-version: ${{ matrix.python-version }}
1818
- name: Install GNU sed on macOS
1919
if: runner.os == 'macOS'
2020
run: brew install gnu-sed
21-
- name: Install poetry
22-
run: pip install poetry==${{ matrix.poetry-version}}
2321
- name: Install deps
2422
run: make install
2523
- name: Run tests
@@ -28,30 +26,32 @@ jobs:
2826
run: make check-format
2927
- name: Run linter
3028
run: make lint
29+
- name: Type check
30+
run: make typecheck
3131
- name: Security audit
3232
run: make audit
3333

3434
ci-windows:
3535
strategy:
3636
fail-fast: false
3737
matrix:
38-
python-version: ["3.13"]
39-
poetry-version: ["2.3.1"]
38+
python-version: ["3.11", "3.12", "3.13", "3.14"]
4039
runs-on: windows-latest
4140
steps:
4241
- uses: actions/checkout@v6
43-
- uses: actions/setup-python@v6
42+
- name: Install uv
43+
uses: astral-sh/setup-uv@v6
4444
with:
4545
python-version: ${{ matrix.python-version }}
46-
- name: Install poetry
47-
run: pip install poetry==${{ matrix.poetry-version}}
4846
- name: Install deps
49-
run: poetry install
47+
run: make install
5048
- name: Run tests
51-
run: poetry run pytest tests
49+
run: make test
5250
- name: Check formatting
53-
run: poetry run ruff format --check leakix/ tests/ example/ executable/
51+
run: make check-format
5452
- name: Run linter
55-
run: poetry run ruff check leakix/ tests/ example/ executable/
53+
run: make lint
54+
- name: Type check
55+
run: make typecheck
5656
- name: Security audit
57-
run: poetry run pip-audit
57+
run: make audit
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: CI per commit
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
types: [labeled]
8+
branches:
9+
- main
10+
11+
jobs:
12+
check-label:
13+
name: Check for ci:per-commit label
14+
runs-on: ubuntu-latest
15+
outputs:
16+
has_label: ${{ steps.check.outputs.has_label }}
17+
steps:
18+
- uses: actions/checkout@v6
19+
- name: Check for label
20+
id: check
21+
env:
22+
GH_TOKEN: ${{ github.token }}
23+
run: |
24+
.github/scripts/check-ci-per-commit-label.sh \
25+
"${{ github.event_name }}" \
26+
"${{ github.repository }}" \
27+
"${{ github.sha }}" \
28+
'${{ toJSON(github.event.pull_request.labels.*.name) }}' \
29+
>> "$GITHUB_OUTPUT"
30+
31+
ci-per-commit:
32+
name: CI per commit
33+
needs: check-label
34+
if: needs.check-label.outputs.has_label == 'true'
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v6
38+
with:
39+
fetch-depth: 0
40+
- name: Install uv
41+
uses: astral-sh/setup-uv@v6
42+
with:
43+
python-version: "3.13"
44+
- name: Install GNU sed (macOS)
45+
if: runner.os == 'macOS'
46+
run: brew install gnu-sed
47+
- name: Determine commit range
48+
id: range
49+
env:
50+
GH_TOKEN: ${{ github.token }}
51+
run: |
52+
if [ "${{ github.event_name }}" = "pull_request" ]; then
53+
BASE="${{ github.event.pull_request.base.sha }}"
54+
HEAD="${{ github.event.pull_request.head.sha }}"
55+
else
56+
BASE="${{ github.event.before }}"
57+
HEAD="${{ github.sha }}"
58+
fi
59+
echo "base=${BASE}" >> "$GITHUB_OUTPUT"
60+
echo "head=${HEAD}" >> "$GITHUB_OUTPUT"
61+
- name: Run CI on each commit
62+
run: |
63+
.github/scripts/run-ci-per-commit.sh \
64+
"${{ steps.range.outputs.base }}" \
65+
"${{ steps.range.outputs.head }}"

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ profile_default/
8282
ipython_config.py
8383

8484
# pyenv
85-
.python-version
85+
# .python-version is tracked for uv
8686

8787
# pipenv
8888
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
@@ -128,4 +128,4 @@ dmypy.json
128128
# Pyre type checker
129129
.pyre/
130130

131-
poetry.lock
131+
uv.lock

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ and this project adheres to
2323
- Lowered Python requirement from 3.13 to 3.11
2424
- Moved inline code examples from README to `example/` directory
2525
- Updated l9format requirement from =1.3.2 to =1.4.0 ([ae676d9])
26+
- Updated l9format requirement from =1.4.0 to =2.0.0 ([df916e5], [#68])
27+
28+
### Added
29+
30+
- Add Python 3.11, 3.12, and 3.14 support ([d111628])
31+
32+
### Removed
33+
34+
- Removed dependency on serde (unmaintained), replaced with dataclasses
35+
and l9format.l9format.Model ([df916e5], [#68])
36+
37+
### Infrastructure
38+
39+
- CI: use Makefile targets in Windows job and add sequential per-commit
40+
testing triggered by the ci:per-commit label ([3967e42], [#66])
41+
- Remove duplicated lint-shell target in Makefile ([a652654], [#67])
42+
- Add mypy type checking to CI workflow ([6b9a3db], [#42])
43+
- Migrate from Poetry to uv ([14bc55e], [#65])
2644

2745
## [0.1.10] - 2024-12-XX
2846

@@ -59,6 +77,12 @@ and this project adheres to
5977
[0.1.9]: https://github.com/LeakIX/LeakIXClient-Python/releases/tag/v0.1.9
6078

6179
<!-- Commit links -->
80+
[6b9a3db]: https://github.com/LeakIX/LeakIXClient-Python/commit/6b9a3db
81+
[d111628]: https://github.com/LeakIX/LeakIXClient-Python/commit/d111628
82+
[df916e5]: https://github.com/LeakIX/LeakIXClient-Python/commit/df916e5
83+
[14bc55e]: https://github.com/LeakIX/LeakIXClient-Python/commit/14bc55e
84+
[a652654]: https://github.com/LeakIX/LeakIXClient-Python/commit/a652654
85+
[3967e42]: https://github.com/LeakIX/LeakIXClient-Python/commit/3967e42
6286
[ae676d9]: https://github.com/LeakIX/LeakIXClient-Python/commit/ae676d9
6387
[65c5121]: https://github.com/LeakIX/LeakIXClient-Python/commit/65c5121
6488
[0975c1c]: https://github.com/LeakIX/LeakIXClient-Python/commit/0975c1c
@@ -67,3 +91,10 @@ and this project adheres to
6791
[6777ad9]: https://github.com/LeakIX/LeakIXClient-Python/commit/6777ad9
6892
[62550bc]: https://github.com/LeakIX/LeakIXClient-Python/commit/62550bc
6993
[4dd4948]: https://github.com/LeakIX/LeakIXClient-Python/commit/4dd4948
94+
95+
<!-- PR links -->
96+
[#66]: https://github.com/LeakIX/LeakIXClient-Python/pull/66
97+
[#65]: https://github.com/LeakIX/LeakIXClient-Python/issues/65
98+
[#67]: https://github.com/LeakIX/LeakIXClient-Python/issues/67
99+
[#42]: https://github.com/LeakIX/LeakIXClient-Python/issues/42
100+
[#68]: https://github.com/LeakIX/LeakIXClient-Python/pull/68

Makefile

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,58 +8,54 @@ help: ## Ask for help!
88

99
.PHONY: install
1010
install: ## Install dependencies
11-
poetry install
11+
uv sync
1212

1313
.PHONY: build
1414
build: ## Build the package
15-
poetry build
15+
uv build
1616

1717
.PHONY: test
1818
test: ## Run tests
19-
poetry run pytest
19+
uv run pytest
2020

2121
.PHONY: test-cov
2222
test-cov: ## Run tests with coverage
23-
poetry run pytest --cov=leakix --cov-report=term-missing
23+
uv run pytest --cov=leakix --cov-report=term-missing
2424

2525
.PHONY: format
2626
format: ## Format code with ruff
27-
poetry run ruff format leakix/ tests/ example/ executable/
27+
uv run ruff format leakix/ tests/ example/ executable/
2828

2929
.PHONY: check-format
3030
check-format: ## Check code formatting
31-
poetry run ruff format --check leakix/ tests/ example/ executable/
31+
uv run ruff format --check leakix/ tests/ example/ executable/
3232

3333
.PHONY: lint
3434
lint: ## Run ruff linter
35-
poetry run ruff check leakix/ tests/ example/ executable/
35+
uv run ruff check leakix/ tests/ example/ executable/
3636

3737
.PHONY: lint-fix
3838
lint-fix: ## Run ruff linter with auto-fix
39-
poetry run ruff check --fix leakix/ tests/ example/ executable/
39+
uv run ruff check --fix leakix/ tests/ example/ executable/
4040

4141
.PHONY: lint-shell
4242
lint-shell: ## Lint shell scripts using shellcheck
4343
shellcheck .github/scripts/*.sh
4444

4545
.PHONY: typecheck
4646
typecheck: ## Run mypy type checker
47-
poetry run mypy leakix/
47+
uv run mypy leakix/
4848

4949
.PHONY: audit
5050
audit: ## Run security audit
51-
poetry run pip-audit
51+
uv run pip-audit
5252

5353
.PHONY: check
5454
check: check-format lint typecheck test ## Run all checks
5555

5656
.PHONY: check-outdated
5757
check-outdated: ## Check for outdated dependencies
58-
poetry show --outdated || true
59-
60-
.PHONY: lint-shell
61-
lint-shell: ## Lint shell scripts using shellcheck
62-
shellcheck .github/scripts/*.sh
58+
uv pip list --outdated || true
6359

6460
.PHONY: clean
6561
clean: ## Clean build artifacts

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Official LeakIX python client
1111
pip install leakix
1212
```
1313

14-
To run tests, use `poetry run pytest`.
14+
To run tests, use `make test`.
1515

1616
## Documentation
1717

0 commit comments

Comments
 (0)