portly 0.1.0__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.
- portly-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
- portly-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- portly-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +30 -0
- portly-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- portly-0.1.0/.github/dependabot.yml +19 -0
- portly-0.1.0/.github/workflows/CI.yml +110 -0
- portly-0.1.0/.github/workflows/release-please.yml +34 -0
- portly-0.1.0/.github/workflows/release.yml +183 -0
- portly-0.1.0/.gitignore +32 -0
- portly-0.1.0/.pre-commit-config.yaml +36 -0
- portly-0.1.0/.release-please-manifest.json +1 -0
- portly-0.1.0/CHANGELOG.md +43 -0
- portly-0.1.0/CODE_OF_CONDUCT.md +122 -0
- portly-0.1.0/CONTRIBUTING.md +90 -0
- portly-0.1.0/Cargo.lock +763 -0
- portly-0.1.0/Cargo.toml +47 -0
- portly-0.1.0/LICENSE +21 -0
- portly-0.1.0/PKG-INFO +146 -0
- portly-0.1.0/README.md +120 -0
- portly-0.1.0/SECURITY.md +46 -0
- portly-0.1.0/examples/main.py +166 -0
- portly-0.1.0/examples/requirements.txt +2 -0
- portly-0.1.0/examples/static/index.html +381 -0
- portly-0.1.0/pyproject.toml +80 -0
- portly-0.1.0/python/portly/__init__.py +32 -0
- portly-0.1.0/python/portly/__init__.pyi +35 -0
- portly-0.1.0/python/portly/_lib.pyi +68 -0
- portly-0.1.0/python/portly/py.typed +0 -0
- portly-0.1.0/release-please-config.json +10 -0
- portly-0.1.0/src/lib.rs +825 -0
- portly-0.1.0/tests/conftest.py +79 -0
- portly-0.1.0/tests/stubtest-allowlist.txt +9 -0
- portly-0.1.0/tests/test_portly.py +199 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a problem with portly
|
|
3
|
+
labels: [bug]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for taking the time to report a bug! Please fill in as much
|
|
9
|
+
information as you can.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: what-happened
|
|
12
|
+
attributes:
|
|
13
|
+
label: What happened?
|
|
14
|
+
description: A clear and concise description of the bug.
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: expected
|
|
19
|
+
attributes:
|
|
20
|
+
label: Expected behavior
|
|
21
|
+
description: What did you expect to happen?
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: repro
|
|
24
|
+
attributes:
|
|
25
|
+
label: Steps to reproduce
|
|
26
|
+
description: Minimal code or commands that trigger the bug.
|
|
27
|
+
placeholder: |
|
|
28
|
+
```python
|
|
29
|
+
import portly
|
|
30
|
+
portly.kill(8000)
|
|
31
|
+
```
|
|
32
|
+
validations:
|
|
33
|
+
required: true
|
|
34
|
+
- type: input
|
|
35
|
+
id: version
|
|
36
|
+
attributes:
|
|
37
|
+
label: portly version
|
|
38
|
+
description: e.g. 0.1.0 (check `python -c "import portly; print(portly.__version__)"`)
|
|
39
|
+
validations:
|
|
40
|
+
required: true
|
|
41
|
+
- type: dropdown
|
|
42
|
+
id: platform
|
|
43
|
+
attributes:
|
|
44
|
+
label: Platform
|
|
45
|
+
options:
|
|
46
|
+
- Linux
|
|
47
|
+
- macOS
|
|
48
|
+
- Windows
|
|
49
|
+
- Other
|
|
50
|
+
validations:
|
|
51
|
+
required: true
|
|
52
|
+
- type: input
|
|
53
|
+
id: python
|
|
54
|
+
attributes:
|
|
55
|
+
label: Python version
|
|
56
|
+
description: e.g. 3.12, 3.14t (free-threaded)
|
|
57
|
+
- type: textarea
|
|
58
|
+
id: logs
|
|
59
|
+
attributes:
|
|
60
|
+
label: Relevant output / traceback
|
|
61
|
+
description: Paste any error messages or tracebacks.
|
|
62
|
+
render: shell
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security issues
|
|
4
|
+
url: https://github.com/PatrykBochenek/portly/security/policy
|
|
5
|
+
about: Please report security vulnerabilities privately — see SECURITY.md.
|
|
6
|
+
- name: Discussions
|
|
7
|
+
url: https://github.com/PatrykBochenek/portly/discussions
|
|
8
|
+
about: Ask questions, discuss ideas, and get help.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new feature or improvement for portly
|
|
3
|
+
labels: [enhancement]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for suggesting an idea! Please describe the problem you're
|
|
9
|
+
solving and the shape of the solution you have in mind.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: problem
|
|
12
|
+
attributes:
|
|
13
|
+
label: Problem
|
|
14
|
+
description: What problem would this feature solve?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: solution
|
|
19
|
+
attributes:
|
|
20
|
+
label: Proposed solution
|
|
21
|
+
description: How should the feature work? API sketches welcome.
|
|
22
|
+
placeholder: |
|
|
23
|
+
```python
|
|
24
|
+
portly.wait_until_free(5432, interval=0.2)
|
|
25
|
+
```
|
|
26
|
+
- type: textarea
|
|
27
|
+
id: alternatives
|
|
28
|
+
attributes:
|
|
29
|
+
label: Alternatives considered
|
|
30
|
+
description: Any workarounds or alternative designs you've thought of.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this PR do, and why? -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- Bullet list of the concrete changes. -->
|
|
8
|
+
|
|
9
|
+
## Testing
|
|
10
|
+
|
|
11
|
+
<!-- How was this verified? e.g. "pytest tests/", "cargo test", "maturin build". -->
|
|
12
|
+
|
|
13
|
+
## Checklist
|
|
14
|
+
|
|
15
|
+
- [ ] `cargo fmt --check` and `cargo clippy -- -D warnings` pass
|
|
16
|
+
- [ ] `ruff check` and `ruff format --check` pass
|
|
17
|
+
- [ ] `mypy python/portly tests` passes
|
|
18
|
+
- [ ] `pytest tests/` passes
|
|
19
|
+
- [ ] Stub changes (`.pyi`) are validated by `mypy.stubtest`
|
|
20
|
+
- [ ] CHANGELOG updated (if user-facing change)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "github-actions"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
|
|
8
|
+
- package-ecosystem: "cargo"
|
|
9
|
+
directory: "/"
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "weekly"
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "pip"
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
17
|
+
groups:
|
|
18
|
+
dev-dependencies:
|
|
19
|
+
patterns: ["maturin", "pytest", "pytest-cov", "ruff", "mypy"]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint & typecheck
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
18
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.13"
|
|
21
|
+
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
|
|
22
|
+
with:
|
|
23
|
+
components: rustfmt, clippy
|
|
24
|
+
- name: Install Python tooling
|
|
25
|
+
run: pip install ruff mypy maturin pytest
|
|
26
|
+
- name: Ruff check
|
|
27
|
+
run: ruff check python/ tests/ examples/
|
|
28
|
+
- name: Ruff format
|
|
29
|
+
run: ruff format --check python/ tests/ examples/
|
|
30
|
+
- name: Mypy (strict)
|
|
31
|
+
run: mypy python/portly tests
|
|
32
|
+
- name: Stubtest (stubs vs runtime)
|
|
33
|
+
run: |
|
|
34
|
+
maturin build --out dist
|
|
35
|
+
pip install dist/*.whl
|
|
36
|
+
python -m mypy.stubtest portly._lib --allowlist tests/stubtest-allowlist.txt
|
|
37
|
+
- name: Cargo fmt
|
|
38
|
+
run: cargo fmt -- --check
|
|
39
|
+
- name: Cargo clippy
|
|
40
|
+
run: cargo clippy --all-targets -- -D warnings
|
|
41
|
+
- name: Cargo test
|
|
42
|
+
run: cargo test
|
|
43
|
+
- name: Zizmor (GitHub Actions security audit)
|
|
44
|
+
run: |
|
|
45
|
+
pip install zizmor
|
|
46
|
+
zizmor --min-severity high .github/workflows/
|
|
47
|
+
|
|
48
|
+
test:
|
|
49
|
+
name: Test (${{ matrix.os }} / ${{ matrix.python-version }})
|
|
50
|
+
runs-on: ${{ matrix.os }}
|
|
51
|
+
strategy:
|
|
52
|
+
fail-fast: false
|
|
53
|
+
matrix:
|
|
54
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
55
|
+
python-version: ["3.10", "3.14"]
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
58
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
59
|
+
with:
|
|
60
|
+
python-version: ${{ matrix.python-version }}
|
|
61
|
+
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
|
|
62
|
+
- name: Install maturin
|
|
63
|
+
run: pip install maturin pytest
|
|
64
|
+
- name: Build extension
|
|
65
|
+
run: maturin build --out dist
|
|
66
|
+
- name: Install extension
|
|
67
|
+
shell: bash
|
|
68
|
+
run: pip install dist/*.whl
|
|
69
|
+
- name: Run tests
|
|
70
|
+
run: pytest tests/ -v
|
|
71
|
+
|
|
72
|
+
freethreaded:
|
|
73
|
+
name: Test (free-threaded 3.14t)
|
|
74
|
+
runs-on: ubuntu-latest
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
77
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
78
|
+
with:
|
|
79
|
+
python-version: "3.14t"
|
|
80
|
+
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
|
|
81
|
+
- name: Install maturin
|
|
82
|
+
run: pip install maturin pytest
|
|
83
|
+
- name: Build extension
|
|
84
|
+
run: maturin build --out dist
|
|
85
|
+
- name: Install extension
|
|
86
|
+
run: pip install dist/*.whl
|
|
87
|
+
- name: Run tests
|
|
88
|
+
run: pytest tests/ -v
|
|
89
|
+
|
|
90
|
+
wheel:
|
|
91
|
+
name: Wheel & sdist install test
|
|
92
|
+
runs-on: ubuntu-latest
|
|
93
|
+
steps:
|
|
94
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
95
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
96
|
+
with:
|
|
97
|
+
python-version: "3.13"
|
|
98
|
+
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
|
|
99
|
+
- name: Install maturin
|
|
100
|
+
run: pip install maturin pytest
|
|
101
|
+
- name: Build and test wheel
|
|
102
|
+
run: |
|
|
103
|
+
maturin build --release --locked --out dist
|
|
104
|
+
pip install dist/*.whl
|
|
105
|
+
python -m pytest tests/ -q
|
|
106
|
+
- name: Build and test sdist
|
|
107
|
+
run: |
|
|
108
|
+
maturin sdist --out dist
|
|
109
|
+
pip install dist/*.tar.gz
|
|
110
|
+
python -m pytest tests/ -q
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Release Please
|
|
2
|
+
|
|
3
|
+
# release-please opens a "chore(main): release vX.Y.Z" PR whenever conventional
|
|
4
|
+
# commits land on main. Merging that PR bumps Cargo.toml/Cargo.lock and
|
|
5
|
+
# CHANGELOG.md, then release-please creates the vX.Y.Z tag + GitHub Release.
|
|
6
|
+
#
|
|
7
|
+
# Because the tag is created with GITHUB_TOKEN, the tag-push event does NOT
|
|
8
|
+
# trigger our release.yml (GitHub suppresses events caused by GITHUB_TOKEN).
|
|
9
|
+
# Instead we dispatch release.yml on the tag via workflow_dispatch, which is
|
|
10
|
+
# allowed for GITHUB_TOKEN.
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
branches: [main]
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
pull-requests: write
|
|
18
|
+
issues: write
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
release-please:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: googleapis/release-please-action@d1a8f221d7723166f48a584aebba00ef3f6febec # v4
|
|
25
|
+
id: release
|
|
26
|
+
with:
|
|
27
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
28
|
+
target-branch: main
|
|
29
|
+
|
|
30
|
+
- name: Trigger release build
|
|
31
|
+
if: ${{ steps.release.outputs.release_created == 'true' }}
|
|
32
|
+
run: gh workflow run release.yml --ref "${{ steps.release.outputs.tag_name }}"
|
|
33
|
+
env:
|
|
34
|
+
GH_TOKEN: ${{ github.token }}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Builds wheels + sdist for every supported platform and publishes them to
|
|
4
|
+
# PyPI using Trusted Publishing (OIDC). Triggered by `v*` tags.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
linux:
|
|
16
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
platform:
|
|
20
|
+
- runner: ubuntu-22.04
|
|
21
|
+
target: x86_64
|
|
22
|
+
- runner: ubuntu-22.04
|
|
23
|
+
target: aarch64
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.10"
|
|
29
|
+
- name: Build wheels
|
|
30
|
+
uses: PyO3/maturin-action@423a6347767a8b16e65c2a7a7042e4a921528da8 # v1
|
|
31
|
+
with:
|
|
32
|
+
target: ${{ matrix.platform.target }}
|
|
33
|
+
args: --release --out dist --find-interpreter --locked
|
|
34
|
+
sccache: false
|
|
35
|
+
manylinux: auto
|
|
36
|
+
- name: Upload wheels
|
|
37
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
38
|
+
with:
|
|
39
|
+
name: wheels-linux-${{ matrix.platform.target }}
|
|
40
|
+
path: dist
|
|
41
|
+
|
|
42
|
+
musllinux:
|
|
43
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
44
|
+
strategy:
|
|
45
|
+
matrix:
|
|
46
|
+
platform:
|
|
47
|
+
- runner: ubuntu-22.04
|
|
48
|
+
target: x86_64
|
|
49
|
+
- runner: ubuntu-22.04
|
|
50
|
+
target: aarch64
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
53
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
54
|
+
with:
|
|
55
|
+
python-version: "3.10"
|
|
56
|
+
- name: Build wheels
|
|
57
|
+
uses: PyO3/maturin-action@423a6347767a8b16e65c2a7a7042e4a921528da8 # v1
|
|
58
|
+
with:
|
|
59
|
+
target: ${{ matrix.platform.target }}
|
|
60
|
+
args: --release --out dist --find-interpreter --locked
|
|
61
|
+
sccache: false
|
|
62
|
+
manylinux: musllinux_1_2
|
|
63
|
+
- name: Upload wheels
|
|
64
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
65
|
+
with:
|
|
66
|
+
name: wheels-musllinux-${{ matrix.platform.target }}
|
|
67
|
+
path: dist
|
|
68
|
+
|
|
69
|
+
windows:
|
|
70
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
71
|
+
strategy:
|
|
72
|
+
matrix:
|
|
73
|
+
platform:
|
|
74
|
+
- runner: windows-latest
|
|
75
|
+
target: x64
|
|
76
|
+
python_arch: x64
|
|
77
|
+
- runner: windows-11-arm
|
|
78
|
+
target: aarch64
|
|
79
|
+
python_arch: arm64
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
82
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
83
|
+
with:
|
|
84
|
+
python-version: "3.13"
|
|
85
|
+
architecture: ${{ matrix.platform.python_arch }}
|
|
86
|
+
- name: Build wheels
|
|
87
|
+
uses: PyO3/maturin-action@423a6347767a8b16e65c2a7a7042e4a921528da8 # v1
|
|
88
|
+
with:
|
|
89
|
+
target: ${{ matrix.platform.target }}
|
|
90
|
+
args: --release --out dist --find-interpreter --locked
|
|
91
|
+
sccache: false
|
|
92
|
+
- name: Upload wheels
|
|
93
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
94
|
+
with:
|
|
95
|
+
name: wheels-windows-${{ matrix.platform.target }}
|
|
96
|
+
path: dist
|
|
97
|
+
|
|
98
|
+
macos:
|
|
99
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
100
|
+
strategy:
|
|
101
|
+
matrix:
|
|
102
|
+
platform:
|
|
103
|
+
- runner: macos-15-intel
|
|
104
|
+
target: x86_64
|
|
105
|
+
- runner: macos-latest
|
|
106
|
+
target: aarch64
|
|
107
|
+
steps:
|
|
108
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
109
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
110
|
+
with:
|
|
111
|
+
python-version: "3.10"
|
|
112
|
+
- name: Build wheels
|
|
113
|
+
uses: PyO3/maturin-action@423a6347767a8b16e65c2a7a7042e4a921528da8 # v1
|
|
114
|
+
with:
|
|
115
|
+
target: ${{ matrix.platform.target }}
|
|
116
|
+
args: --release --out dist --find-interpreter --locked
|
|
117
|
+
sccache: false
|
|
118
|
+
- name: Upload wheels
|
|
119
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
120
|
+
with:
|
|
121
|
+
name: wheels-macos-${{ matrix.platform.target }}
|
|
122
|
+
path: dist
|
|
123
|
+
|
|
124
|
+
sdist:
|
|
125
|
+
runs-on: ubuntu-latest
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
128
|
+
- name: Build sdist
|
|
129
|
+
uses: PyO3/maturin-action@423a6347767a8b16e65c2a7a7042e4a921528da8 # v1
|
|
130
|
+
with:
|
|
131
|
+
command: sdist
|
|
132
|
+
args: --out dist
|
|
133
|
+
- name: Upload sdist
|
|
134
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
135
|
+
with:
|
|
136
|
+
name: wheels-sdist
|
|
137
|
+
path: dist
|
|
138
|
+
|
|
139
|
+
release:
|
|
140
|
+
name: Release
|
|
141
|
+
runs-on: ubuntu-latest
|
|
142
|
+
needs: [linux, musllinux, windows, macos, sdist]
|
|
143
|
+
permissions:
|
|
144
|
+
# For artifact attestation and trusted publishing.
|
|
145
|
+
id-token: write
|
|
146
|
+
# For creating the GitHub Release.
|
|
147
|
+
contents: write
|
|
148
|
+
# For generating PEP 740 attestations.
|
|
149
|
+
attestations: write
|
|
150
|
+
steps:
|
|
151
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
152
|
+
- name: Verify tag matches Cargo.toml version
|
|
153
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
154
|
+
run: |
|
|
155
|
+
version="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)"
|
|
156
|
+
if [ "v${version}" != "${GITHUB_REF_NAME}" ]; then
|
|
157
|
+
echo "::error::Tag ${GITHUB_REF_NAME} does not match Cargo.toml version v${version}"
|
|
158
|
+
exit 1
|
|
159
|
+
fi
|
|
160
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
161
|
+
- name: Generate artifact attestation
|
|
162
|
+
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4
|
|
163
|
+
with:
|
|
164
|
+
subject-path: 'wheels-*/*'
|
|
165
|
+
- name: Create or update GitHub Release
|
|
166
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
167
|
+
run: |
|
|
168
|
+
if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
|
|
169
|
+
# release-please already created the release (with changelog notes);
|
|
170
|
+
# attach the wheels to it.
|
|
171
|
+
gh release upload "${GITHUB_REF_NAME}" wheels-*/* --clobber
|
|
172
|
+
else
|
|
173
|
+
gh release create "${GITHUB_REF_NAME}" wheels-*/* --generate-notes
|
|
174
|
+
fi
|
|
175
|
+
env:
|
|
176
|
+
GH_TOKEN: ${{ github.token }}
|
|
177
|
+
- name: Install uv
|
|
178
|
+
uses: astral-sh/setup-uv@94527f2e458b27549849d47d273a16bec83a01e9 # v7
|
|
179
|
+
with:
|
|
180
|
+
enable-cache: false
|
|
181
|
+
- name: Publish to PyPI
|
|
182
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
183
|
+
run: uv publish --trusted-publishing always 'wheels-*/*'
|
portly-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Rust
|
|
2
|
+
/target
|
|
3
|
+
**/*.rs.bk
|
|
4
|
+
# Cargo.lock is committed intentionally (reproducible wheel/sdist builds).
|
|
5
|
+
|
|
6
|
+
# Python
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*$py.class
|
|
10
|
+
*.so
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
dist/
|
|
15
|
+
build/
|
|
16
|
+
.eggs/
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.mypy_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
|
|
21
|
+
# IDE
|
|
22
|
+
.vscode/
|
|
23
|
+
.idea/
|
|
24
|
+
*.swp
|
|
25
|
+
*.swo
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Maturin
|
|
32
|
+
wheelhouse/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-toml
|
|
9
|
+
- id: check-added-large-files
|
|
10
|
+
- id: check-merge-conflict
|
|
11
|
+
|
|
12
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
13
|
+
rev: v0.16.3
|
|
14
|
+
hooks:
|
|
15
|
+
- id: ruff
|
|
16
|
+
args: [--fix]
|
|
17
|
+
- id: ruff-format
|
|
18
|
+
|
|
19
|
+
- repo: local
|
|
20
|
+
hooks:
|
|
21
|
+
- id: mypy
|
|
22
|
+
name: mypy (strict)
|
|
23
|
+
entry: mypy python/portly tests
|
|
24
|
+
language: system
|
|
25
|
+
pass_filenames: false
|
|
26
|
+
types: [python]
|
|
27
|
+
- id: cargo-fmt
|
|
28
|
+
name: cargo fmt
|
|
29
|
+
entry: cargo fmt -- --check
|
|
30
|
+
language: system
|
|
31
|
+
pass_filenames: false
|
|
32
|
+
- id: cargo-clippy
|
|
33
|
+
name: cargo clippy
|
|
34
|
+
entry: cargo clippy --all-targets -- -D warnings
|
|
35
|
+
language: system
|
|
36
|
+
pass_filenames: false
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{".":"0.1.0"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## 0.1.0 (2026-08-16)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* rename python package and add typed stubs ([cfbcd68](https://github.com/PatrykBochenek/portly/commit/cfbcd68b18a2b7751837ed2d226caafb68cb2cda))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* clippy flatten lint and Windows wheel install glob ([66c90dc](https://github.com/PatrykBochenek/portly/commit/66c90dce62e7259d935026cc26d4f9f1c1eb36a6))
|
|
19
|
+
* clippy manual-flatten on the Linux socket table loops ([061c010](https://github.com/PatrykBochenek/portly/commit/061c010ca90f53c6d3efc8e21c8a40709ab3678f))
|
|
20
|
+
* compile on Linux and Windows ([e300527](https://github.com/PatrykBochenek/portly/commit/e300527d5172146b0561a4bd47c127ee28c37d92))
|
|
21
|
+
|
|
22
|
+
## [Unreleased]
|
|
23
|
+
|
|
24
|
+
## [0.1.0] - 2026-08-16
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Initial release of **portly**: a cross-platform, Rust-powered library
|
|
29
|
+
for checking, finding, scanning, waiting on, and freeing TCP/UDP ports.
|
|
30
|
+
- API: `is_available`, `find_free`, `wait_until_free`, `get_info`, `kill`,
|
|
31
|
+
`scan`, `__version__`.
|
|
32
|
+
- Native (subprocess-free) process lookup on all platforms:
|
|
33
|
+
- Linux: `/proc/net/{tcp,tcp6,udp,udp6}` + `/proc/<pid>/fd` via `procfs`.
|
|
34
|
+
- macOS: `libproc` (`proc_pidinfo`).
|
|
35
|
+
- Windows: `GetExtended{Tcp,Udp}Table` + ToolHelp32 via `windows-sys`
|
|
36
|
+
(no dependency on the deprecated `wmic`).
|
|
37
|
+
- Type stubs (`_lib.pyi`) validated by `mypy.stubtest`; `py.typed` marker.
|
|
38
|
+
- CI: lint/typecheck gates, cross-platform test matrix (incl. free-threaded
|
|
39
|
+
3.14t), wheel + sdist install tests, and a release workflow using PyPI
|
|
40
|
+
Trusted Publishing with PEP 740 attestations.
|
|
41
|
+
|
|
42
|
+
[Unreleased]: https://github.com/PatrykBochenek/portly/compare/v0.1.0...HEAD
|
|
43
|
+
[0.1.0]: https://github.com/PatrykBochenek/portly/releases/tag/v0.1.0
|