datalegion-cli 1.2.1__tar.gz → 1.2.2__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.
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/PKG-INFO +1 -1
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/pyproject.toml +5 -1
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/client.py +1 -1
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/config.py +2 -1
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/test_config.py +16 -0
- datalegion_cli-1.2.2/tests/test_package_contents.py +56 -0
- datalegion_cli-1.2.1/.github/actionlint.yaml +0 -5
- datalegion_cli-1.2.1/.github/dependabot.yml +0 -42
- datalegion_cli-1.2.1/.github/workflows/ci.yml +0 -77
- datalegion_cli-1.2.1/.github/workflows/release.yml +0 -236
- datalegion_cli-1.2.1/.python-version +0 -1
- datalegion_cli-1.2.1/uv.lock +0 -658
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/.gitignore +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/README.md +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/__init__.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/async_typer.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/commands/__init__.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/commands/company.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/commands/credits.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/commands/person.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/commands/utility.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/logging.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/main.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/output.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/src/datalegion_cli/update.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/__init__.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/conftest.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/test_client.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/test_commands.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/test_logging.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/test_output.py +0 -0
- {datalegion_cli-1.2.1 → datalegion_cli-1.2.2}/tests/test_update.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "datalegion-cli"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.2"
|
|
4
4
|
description = "CLI for the Data Legion API — agent-friendly, fully async"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -57,6 +57,10 @@ build-backend = "hatchling.build"
|
|
|
57
57
|
[tool.hatch.build.targets.wheel]
|
|
58
58
|
packages = ["src/datalegion_cli"]
|
|
59
59
|
|
|
60
|
+
# The sdist carries the source and tests, never repo tooling (.github/, .claude/, lefthook.yml).
|
|
61
|
+
[tool.hatch.build.targets.sdist]
|
|
62
|
+
only-include = ["src/datalegion_cli", "tests"]
|
|
63
|
+
|
|
60
64
|
[dependency-groups]
|
|
61
65
|
dev = [
|
|
62
66
|
"pytest>=8.3.0",
|
|
@@ -43,7 +43,7 @@ class LegionClient:
|
|
|
43
43
|
timeout: float = 60.0,
|
|
44
44
|
):
|
|
45
45
|
self._base_url = base_url or get_base_url()
|
|
46
|
-
self._api_key = api_key or get_api_key()
|
|
46
|
+
self._api_key = (api_key or "").strip() or get_api_key()
|
|
47
47
|
self._timeout = timeout
|
|
48
48
|
self._client: httpx.AsyncClient | None = None
|
|
49
49
|
self.last_credits_used: str | None = None
|
|
@@ -114,7 +114,8 @@ def save_config(cfg: dict[str, object]) -> None:
|
|
|
114
114
|
|
|
115
115
|
def get_api_key() -> str:
|
|
116
116
|
"""Return the configured API key or raise."""
|
|
117
|
-
key
|
|
117
|
+
# Trimmed: a key from a file or a paste with a trailing newline is otherwise refused by httpx.
|
|
118
|
+
key = str(load_config().get("api_key", "")).strip()
|
|
118
119
|
if not key:
|
|
119
120
|
raise SystemExit(
|
|
120
121
|
"No API key configured. Run `datalegion-cli config set api_key <your-key>` "
|
|
@@ -49,6 +49,22 @@ class TestSaveAndLoad:
|
|
|
49
49
|
cfg = load_config()
|
|
50
50
|
assert cfg["api_key"] == "legion_roundtrip"
|
|
51
51
|
|
|
52
|
+
def test_api_key_is_trimmed(self, tmp_config_dir, monkeypatch):
|
|
53
|
+
from datalegion_cli.config import get_api_key, save_config
|
|
54
|
+
|
|
55
|
+
monkeypatch.setenv("LEGION_API_KEY", "legion_fromenv\n")
|
|
56
|
+
assert get_api_key() == "legion_fromenv"
|
|
57
|
+
monkeypatch.delenv("LEGION_API_KEY")
|
|
58
|
+
save_config({"api_key": " legion_fromfile "})
|
|
59
|
+
assert get_api_key() == "legion_fromfile"
|
|
60
|
+
|
|
61
|
+
def test_whitespace_only_api_key_is_missing(self, tmp_config_dir, monkeypatch):
|
|
62
|
+
from datalegion_cli.config import get_api_key
|
|
63
|
+
|
|
64
|
+
monkeypatch.setenv("LEGION_API_KEY", " \n")
|
|
65
|
+
with pytest.raises(SystemExit):
|
|
66
|
+
get_api_key()
|
|
67
|
+
|
|
52
68
|
def test_save_sets_file_permissions_600(self, tmp_config_dir):
|
|
53
69
|
from datalegion_cli.config import CONFIG_FILE, save_config
|
|
54
70
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""What the published wheel and sdist contain.
|
|
2
|
+
|
|
3
|
+
Customers install the wheel: it must hold only the ``datalegion_cli`` package, and its only
|
|
4
|
+
command is ``datalegion-cli``. The sdist carries the source and tests, never repo tooling.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import subprocess
|
|
8
|
+
import tarfile
|
|
9
|
+
import zipfile
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
|
|
14
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture(scope="module")
|
|
18
|
+
def dist(tmp_path_factory: pytest.TempPathFactory) -> Path:
|
|
19
|
+
out = tmp_path_factory.mktemp("dist")
|
|
20
|
+
# Each straight from the source tree: a default build makes the wheel from the sdist, which
|
|
21
|
+
# would hide a wheel misconfiguration behind the sdist's own include list.
|
|
22
|
+
for target in ("--sdist", "--wheel"):
|
|
23
|
+
subprocess.run(
|
|
24
|
+
["uv", "build", target, "--quiet", "--out-dir", str(out)], cwd=ROOT, check=True
|
|
25
|
+
)
|
|
26
|
+
return out
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_wheel_ships_only_the_cli(dist: Path) -> None:
|
|
30
|
+
(wheel,) = dist.glob("*.whl")
|
|
31
|
+
with zipfile.ZipFile(wheel) as archive:
|
|
32
|
+
names = archive.namelist()
|
|
33
|
+
commands = next(
|
|
34
|
+
(archive.read(n).decode() for n in names if n.endswith("entry_points.txt")), ""
|
|
35
|
+
)
|
|
36
|
+
top_level = {n.split("/")[0] for n in names if not n.split("/")[0].endswith(".dist-info")}
|
|
37
|
+
assert top_level == {"datalegion_cli"}
|
|
38
|
+
assert commands.split() == [
|
|
39
|
+
"[console_scripts]",
|
|
40
|
+
"datalegion-cli",
|
|
41
|
+
"=",
|
|
42
|
+
"datalegion_cli.main:run",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_sdist_carries_no_repo_tooling(dist: Path) -> None:
|
|
47
|
+
(sdist,) = dist.glob("*.tar.gz")
|
|
48
|
+
with tarfile.open(sdist) as archive:
|
|
49
|
+
names = archive.getnames()
|
|
50
|
+
leaked = [
|
|
51
|
+
n
|
|
52
|
+
for n in names
|
|
53
|
+
if any(part in n.split("/") for part in (".claude", ".github", "scripts", "lefthook.yml"))
|
|
54
|
+
]
|
|
55
|
+
assert leaked == []
|
|
56
|
+
assert any(n.endswith("src/datalegion_cli/main.py") for n in names)
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
updates:
|
|
3
|
-
- package-ecosystem: "uv"
|
|
4
|
-
directory: "/"
|
|
5
|
-
schedule:
|
|
6
|
-
interval: "weekly"
|
|
7
|
-
day: "sunday"
|
|
8
|
-
time: "09:00"
|
|
9
|
-
timezone: "America/Los_Angeles"
|
|
10
|
-
cooldown:
|
|
11
|
-
default-days: 1
|
|
12
|
-
labels:
|
|
13
|
-
- "dependencies"
|
|
14
|
-
- "python"
|
|
15
|
-
commit-message:
|
|
16
|
-
prefix: "chore(deps)"
|
|
17
|
-
groups:
|
|
18
|
-
minor-patch:
|
|
19
|
-
patterns:
|
|
20
|
-
- "*"
|
|
21
|
-
update-types:
|
|
22
|
-
- "minor"
|
|
23
|
-
- "patch"
|
|
24
|
-
|
|
25
|
-
- package-ecosystem: "github-actions"
|
|
26
|
-
directory: "/"
|
|
27
|
-
schedule:
|
|
28
|
-
interval: "weekly"
|
|
29
|
-
day: "sunday"
|
|
30
|
-
time: "09:00"
|
|
31
|
-
timezone: "America/Los_Angeles"
|
|
32
|
-
cooldown:
|
|
33
|
-
default-days: 1
|
|
34
|
-
labels:
|
|
35
|
-
- "dependencies"
|
|
36
|
-
- "github-actions"
|
|
37
|
-
commit-message:
|
|
38
|
-
prefix: "chore(deps)"
|
|
39
|
-
groups:
|
|
40
|
-
actions:
|
|
41
|
-
patterns:
|
|
42
|
-
- "*"
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches: [main]
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
lint:
|
|
9
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
10
|
-
steps:
|
|
11
|
-
- uses: actions/checkout@v7
|
|
12
|
-
- uses: astral-sh/setup-uv@v10.2.0
|
|
13
|
-
with:
|
|
14
|
-
enable-cache: true
|
|
15
|
-
# .python-version: the 3.11 floor
|
|
16
|
-
- run: uv sync --frozen --group dev
|
|
17
|
-
- run: uv run ruff check src/ tests/
|
|
18
|
-
- run: uv run ruff format --check src/ tests/
|
|
19
|
-
|
|
20
|
-
test-python:
|
|
21
|
-
name: test (Python ${{ matrix.python-version }})
|
|
22
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
23
|
-
strategy:
|
|
24
|
-
fail-fast: false
|
|
25
|
-
matrix:
|
|
26
|
-
# Every version pyproject.toml's classifiers claim.
|
|
27
|
-
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
28
|
-
# Without this uv takes the interpreter from .python-version (the 3.11 floor)
|
|
29
|
-
# for every leg.
|
|
30
|
-
env:
|
|
31
|
-
UV_PYTHON: ${{ matrix.python-version }}
|
|
32
|
-
steps:
|
|
33
|
-
- uses: actions/checkout@v7
|
|
34
|
-
- uses: astral-sh/setup-uv@v10.2.0
|
|
35
|
-
with:
|
|
36
|
-
enable-cache: true
|
|
37
|
-
- run: uv python install ${{ matrix.python-version }}
|
|
38
|
-
- run: uv sync --frozen --group dev
|
|
39
|
-
- name: Check the interpreter is the matrix version
|
|
40
|
-
run: uv run python -c "import sys; v = '%d.%d' % sys.version_info[:2]; assert v == '${{ matrix.python-version }}', f'ran {sys.version}, matrix says ${{ matrix.python-version }}'; print(sys.version)"
|
|
41
|
-
- run: uv run pytest
|
|
42
|
-
|
|
43
|
-
# The main ruleset requires a check named `test`; it passes only when every
|
|
44
|
-
# Python leg did.
|
|
45
|
-
test:
|
|
46
|
-
needs: test-python
|
|
47
|
-
if: always()
|
|
48
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
49
|
-
steps:
|
|
50
|
-
- run: '[ "${{ needs.test-python.result }}" = "success" ]'
|
|
51
|
-
|
|
52
|
-
actionlint:
|
|
53
|
-
name: actionlint
|
|
54
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
55
|
-
timeout-minutes: 5
|
|
56
|
-
permissions:
|
|
57
|
-
contents: read
|
|
58
|
-
steps:
|
|
59
|
-
- uses: actions/checkout@v7
|
|
60
|
-
# Pinned and checksum-verified (the upgrade sweep moves the version and both digests).
|
|
61
|
-
# actionlint runs shellcheck on every `run:` script when shellcheck is on PATH, so
|
|
62
|
-
# install it rather than let those checks skip silently.
|
|
63
|
-
- name: Lint workflows (actionlint + shellcheck)
|
|
64
|
-
env:
|
|
65
|
-
ACTIONLINT_VERSION: 1.7.12
|
|
66
|
-
run: |
|
|
67
|
-
case "$(uname -m)" in
|
|
68
|
-
x86_64) arch=amd64; sha=8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 ;;
|
|
69
|
-
aarch64) arch=arm64; sha=325e971b6ba9bfa504672e29be93c24981eeb1c07576d730e9f7c8805afff0c6 ;;
|
|
70
|
-
*) echo "unsupported arch $(uname -m)"; exit 1 ;;
|
|
71
|
-
esac
|
|
72
|
-
f="actionlint_${ACTIONLINT_VERSION}_linux_${arch}.tar.gz"
|
|
73
|
-
curl -fsSL -o "/tmp/$f" "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/$f"
|
|
74
|
-
echo "$sha /tmp/$f" | sha256sum -c -
|
|
75
|
-
tar -xzf "/tmp/$f" -C /tmp actionlint
|
|
76
|
-
command -v shellcheck >/dev/null || { sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck; }
|
|
77
|
-
/tmp/actionlint -color
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
name: Release
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- "v*"
|
|
7
|
-
|
|
8
|
-
concurrency:
|
|
9
|
-
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
-
cancel-in-progress: true
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
lint:
|
|
14
|
-
name: Lint & Build
|
|
15
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
16
|
-
timeout-minutes: 5
|
|
17
|
-
permissions:
|
|
18
|
-
contents: read
|
|
19
|
-
steps:
|
|
20
|
-
- name: Checkout
|
|
21
|
-
uses: actions/checkout@v7
|
|
22
|
-
|
|
23
|
-
- name: Install uv
|
|
24
|
-
uses: astral-sh/setup-uv@v10.2.0
|
|
25
|
-
with:
|
|
26
|
-
enable-cache: true
|
|
27
|
-
cache-dependency-glob: "uv.lock"
|
|
28
|
-
|
|
29
|
-
- name: Set up Python
|
|
30
|
-
run: uv python install 3.11
|
|
31
|
-
|
|
32
|
-
- name: Install dependencies
|
|
33
|
-
run: uv sync --frozen --group dev
|
|
34
|
-
|
|
35
|
-
- name: Run lint
|
|
36
|
-
run: uv run ruff check src/ tests/
|
|
37
|
-
|
|
38
|
-
- name: Check formatting
|
|
39
|
-
run: uv run ruff format --check src/ tests/
|
|
40
|
-
|
|
41
|
-
- name: Build
|
|
42
|
-
run: uv build
|
|
43
|
-
|
|
44
|
-
- name: Prune uv cache
|
|
45
|
-
if: always()
|
|
46
|
-
run: uv cache prune --ci
|
|
47
|
-
|
|
48
|
-
test:
|
|
49
|
-
name: Test (Python ${{ matrix.python-version }})
|
|
50
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
51
|
-
timeout-minutes: 10
|
|
52
|
-
permissions:
|
|
53
|
-
contents: read
|
|
54
|
-
# Without this uv takes the interpreter from .python-version (the 3.11 floor)
|
|
55
|
-
# for every leg.
|
|
56
|
-
env:
|
|
57
|
-
UV_PYTHON: ${{ matrix.python-version }}
|
|
58
|
-
strategy:
|
|
59
|
-
fail-fast: false
|
|
60
|
-
matrix:
|
|
61
|
-
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
62
|
-
steps:
|
|
63
|
-
- name: Checkout
|
|
64
|
-
uses: actions/checkout@v7
|
|
65
|
-
|
|
66
|
-
- name: Install uv
|
|
67
|
-
uses: astral-sh/setup-uv@v10.2.0
|
|
68
|
-
with:
|
|
69
|
-
enable-cache: true
|
|
70
|
-
cache-dependency-glob: "uv.lock"
|
|
71
|
-
|
|
72
|
-
- name: Set up Python ${{ matrix.python-version }}
|
|
73
|
-
run: uv python install ${{ matrix.python-version }}
|
|
74
|
-
|
|
75
|
-
- name: Install dependencies
|
|
76
|
-
run: uv sync --frozen --group dev
|
|
77
|
-
|
|
78
|
-
- name: Check the interpreter is the matrix version
|
|
79
|
-
run: uv run python -c "import sys; v = '%d.%d' % sys.version_info[:2]; assert v == '${{ matrix.python-version }}', f'ran {sys.version}, matrix says ${{ matrix.python-version }}'; print(sys.version)"
|
|
80
|
-
|
|
81
|
-
- name: Run tests
|
|
82
|
-
run: uv run pytest tests/ -v --tb=short
|
|
83
|
-
|
|
84
|
-
- name: Prune uv cache
|
|
85
|
-
if: always()
|
|
86
|
-
run: uv cache prune --ci
|
|
87
|
-
|
|
88
|
-
publish-pypi:
|
|
89
|
-
name: Publish to PyPI
|
|
90
|
-
needs: [lint, test]
|
|
91
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
92
|
-
timeout-minutes: 5
|
|
93
|
-
permissions:
|
|
94
|
-
contents: read
|
|
95
|
-
id-token: write
|
|
96
|
-
steps:
|
|
97
|
-
- name: Checkout
|
|
98
|
-
uses: actions/checkout@v7
|
|
99
|
-
|
|
100
|
-
- name: Install uv
|
|
101
|
-
uses: astral-sh/setup-uv@v10.2.0
|
|
102
|
-
|
|
103
|
-
- name: Set up Python
|
|
104
|
-
run: uv python install 3.11
|
|
105
|
-
|
|
106
|
-
- name: Set version from tag
|
|
107
|
-
run: |
|
|
108
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
109
|
-
sed -i "s/^version = .*/version = \"${VERSION}\"/" pyproject.toml
|
|
110
|
-
|
|
111
|
-
- name: Build
|
|
112
|
-
run: uv build
|
|
113
|
-
|
|
114
|
-
- name: Check if version exists on PyPI
|
|
115
|
-
id: pypi-check
|
|
116
|
-
run: |
|
|
117
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
118
|
-
if curl -sSf "https://pypi.org/pypi/datalegion-cli/${VERSION}/json" > /dev/null 2>&1; then
|
|
119
|
-
echo "Version ${VERSION} already exists on PyPI, skipping publish"
|
|
120
|
-
echo "exists=true" >> "$GITHUB_OUTPUT"
|
|
121
|
-
else
|
|
122
|
-
echo "exists=false" >> "$GITHUB_OUTPUT"
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
- name: Publish to PyPI
|
|
126
|
-
if: steps.pypi-check.outputs.exists != 'true'
|
|
127
|
-
run: uv publish --trusted-publishing always
|
|
128
|
-
|
|
129
|
-
update-homebrew:
|
|
130
|
-
name: Update Homebrew Tap
|
|
131
|
-
needs: [publish-pypi]
|
|
132
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
133
|
-
timeout-minutes: 10
|
|
134
|
-
permissions:
|
|
135
|
-
contents: read
|
|
136
|
-
steps:
|
|
137
|
-
- name: Wait for PyPI availability
|
|
138
|
-
run: |
|
|
139
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
140
|
-
for i in $(seq 1 30); do
|
|
141
|
-
if curl -sSf "https://pypi.org/pypi/datalegion-cli/${VERSION}/json" > /dev/null 2>&1; then
|
|
142
|
-
echo "Version ${VERSION} available on PyPI"
|
|
143
|
-
exit 0
|
|
144
|
-
fi
|
|
145
|
-
echo "Waiting for PyPI... (attempt $i/30)"
|
|
146
|
-
sleep 10
|
|
147
|
-
done
|
|
148
|
-
echo "::error::Timed out waiting for PyPI availability"
|
|
149
|
-
exit 1
|
|
150
|
-
|
|
151
|
-
- name: Generate Homebrew formula
|
|
152
|
-
run: |
|
|
153
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
154
|
-
|
|
155
|
-
# Get the actual sdist URL and digest from PyPI JSON API
|
|
156
|
-
PYPI_JSON=$(curl -sSf "https://pypi.org/pypi/datalegion-cli/${VERSION}/json")
|
|
157
|
-
URL=$(echo "$PYPI_JSON" | python3 -c "import sys,json; urls=json.load(sys.stdin)['urls']; print(next(u['url'] for u in urls if u['packagetype']=='sdist'))")
|
|
158
|
-
SHA256=$(echo "$PYPI_JSON" | python3 -c "import sys,json; urls=json.load(sys.stdin)['urls']; print(next(u['digests']['sha256'] for u in urls if u['packagetype']=='sdist'))")
|
|
159
|
-
|
|
160
|
-
cat > datalegion-cli.rb <<FORMULA
|
|
161
|
-
class DatalegionCli < Formula
|
|
162
|
-
desc "CLI for the Data Legion API - agent-friendly, fully async"
|
|
163
|
-
homepage "https://www.datalegion.ai"
|
|
164
|
-
url "${URL}"
|
|
165
|
-
sha256 "${SHA256}"
|
|
166
|
-
license "MIT"
|
|
167
|
-
|
|
168
|
-
depends_on "python@3.13"
|
|
169
|
-
|
|
170
|
-
def install
|
|
171
|
-
venv = libexec/"venv"
|
|
172
|
-
system Formula["python@3.13"].opt_bin/"python3.13", "-m", "venv", venv
|
|
173
|
-
system venv/"bin/pip", "install", "datalegion-cli==#{version}"
|
|
174
|
-
bin.install_symlink Dir[venv/"bin/datalegion-cli"]
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
test do
|
|
178
|
-
assert_match version.to_s, shell_output("#{bin}/datalegion-cli version")
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
FORMULA
|
|
182
|
-
|
|
183
|
-
# Remove leading whitespace from heredoc indentation
|
|
184
|
-
sed -i 's/^ //' datalegion-cli.rb
|
|
185
|
-
|
|
186
|
-
- name: Push formula to tap
|
|
187
|
-
env:
|
|
188
|
-
GH_PAT: ${{ secrets.GH_PAT }}
|
|
189
|
-
run: |
|
|
190
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
191
|
-
git clone "https://x-access-token:${GH_PAT}@github.com/datalegion-ai/homebrew-tap.git" tap
|
|
192
|
-
mkdir -p tap/Formula
|
|
193
|
-
cp datalegion-cli.rb tap/Formula/datalegion-cli.rb
|
|
194
|
-
cd tap
|
|
195
|
-
git config user.name "github-actions[bot]"
|
|
196
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
197
|
-
git add Formula/datalegion-cli.rb
|
|
198
|
-
git diff --staged --quiet || git commit -m "datalegion-cli ${VERSION}"
|
|
199
|
-
git push
|
|
200
|
-
|
|
201
|
-
github-release:
|
|
202
|
-
name: Create GitHub Release
|
|
203
|
-
needs: [publish-pypi]
|
|
204
|
-
runs-on: blacksmith-2vcpu-ubuntu-2404
|
|
205
|
-
timeout-minutes: 5
|
|
206
|
-
permissions:
|
|
207
|
-
contents: write
|
|
208
|
-
steps:
|
|
209
|
-
- name: Checkout
|
|
210
|
-
uses: actions/checkout@v7
|
|
211
|
-
with:
|
|
212
|
-
ref: main
|
|
213
|
-
token: ${{ secrets.GH_PAT }}
|
|
214
|
-
|
|
215
|
-
- name: Update version in pyproject.toml
|
|
216
|
-
run: |
|
|
217
|
-
VERSION="${GITHUB_REF_NAME#v}"
|
|
218
|
-
sed -i "s/^version = .*/version = \"${VERSION}\"/" pyproject.toml
|
|
219
|
-
git config user.name "github-actions[bot]"
|
|
220
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
221
|
-
git add pyproject.toml
|
|
222
|
-
git diff --staged --quiet || git commit -m "chore: bump version to ${VERSION} [skip ci]"
|
|
223
|
-
git push
|
|
224
|
-
|
|
225
|
-
- name: Create Release
|
|
226
|
-
uses: actions/github-script@v9
|
|
227
|
-
with:
|
|
228
|
-
script: |
|
|
229
|
-
const tag = context.ref.replace('refs/tags/', '');
|
|
230
|
-
await github.rest.repos.createRelease({
|
|
231
|
-
owner: context.repo.owner,
|
|
232
|
-
repo: context.repo.repo,
|
|
233
|
-
tag_name: tag,
|
|
234
|
-
name: tag,
|
|
235
|
-
generate_release_notes: true,
|
|
236
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3.11
|