Skip to content

Commit da04dfe

Browse files
vdavezclaude
andcommitted
Add justfile with op integration, restrict workflow permissions
Adds a justfile wrapping common tasks, with 1Password CLI injecting secrets for integration tests. Adds explicit permissions blocks to all GitHub Actions workflows to restrict GITHUB_TOKEN scope. Updates README development docs to reflect just-based workflow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4741c2f commit da04dfe

6 files changed

Lines changed: 96 additions & 28 deletions

File tree

.github/workflows/lint.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ on:
99
# pull_request:
1010
# branches: [ main, develop ]
1111

12+
permissions:
13+
contents: read
14+
1215
jobs:
1316
lint:
1417
runs-on: ubuntu-latest

.github/workflows/publish.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
types: [published]
66
workflow_dispatch:
77

8+
permissions:
9+
contents: read
10+
id-token: write
11+
812
jobs:
913
build-and-publish:
1014
runs-on: ubuntu-latest

.github/workflows/security.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
pull_request:
77
branches: [ main, develop ]
88

9+
permissions:
10+
contents: read
11+
912
jobs:
1013
bandit:
1114
runs-on: ubuntu-latest

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
pull_request:
77
branches: [ main, develop ]
88

9+
permissions:
10+
contents: read
11+
912
jobs:
1013
test:
1114
runs-on: ${{ matrix.os }}

README.md

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ print(contract["recipient"]["display_name"]) # Nested fields too
346346

347347
## Development
348348

349-
This project uses [uv](https://docs.astral.sh/uv/) for dependency management and tooling.
349+
This project uses [uv](https://docs.astral.sh/uv/) for dependency management and [just](https://github.com/casey/just) as a task runner. Integration tests use [1Password CLI](https://developer.1password.com/docs/cli/) (`op`) to inject the API key at runtime.
350350

351351
### Setup
352352

@@ -357,11 +357,19 @@ cd tango-python
357357

358358
# Install dependencies with uv
359359
uv sync --all-extras
360+
```
361+
362+
### Secrets Management
363+
364+
API keys are stored in 1Password and injected at runtime via `op run`. The `.env` file uses secret references instead of real values:
360365

361-
# Or install dev dependencies only
362-
uv sync --group dev
366+
```bash
367+
# .env
368+
TANGO_API_KEY=op://Vault/tango-api/credential
363369
```
364370

371+
Recipes that need the API key (integration tests, live tests, cassette refresh) handle this automatically through `just`.
372+
365373
### Testing
366374

367375
The SDK includes a comprehensive test suite with:
@@ -370,23 +378,19 @@ The SDK includes a comprehensive test suite with:
370378

371379
```bash
372380
# Run all tests
373-
uv run pytest
381+
just test
374382

375383
# Run only unit tests
376-
uv run pytest tests/ -m "not integration"
384+
just test-unit
377385

378-
# Run only integration tests
379-
uv run pytest tests/integration/
386+
# Run integration tests (API key injected via 1Password)
387+
just test-integration
380388

381-
# Run integration tests with live API (requires TANGO_API_KEY)
382-
export TANGO_API_KEY=your-api-key
383-
export TANGO_USE_LIVE_API=true
384-
uv run pytest tests/integration/
389+
# Run integration tests with live API
390+
just test-live
385391

386392
# Refresh cassettes with fresh API responses
387-
export TANGO_API_KEY=your-api-key
388-
export TANGO_REFRESH_CASSETTES=true
389-
uv run pytest tests/integration/
393+
just refresh-cassettes
390394
```
391395

392396
See [tests/integration/README.md](tests/integration/README.md) for detailed testing documentation.
@@ -395,16 +399,19 @@ See [tests/integration/README.md](tests/integration/README.md) for detailed test
395399

396400
```bash
397401
# Format code
398-
uv run ruff format tango/
402+
just fmt
399403

400404
# Lint code
401-
uv run ruff check tango/
405+
just lint
402406

403407
# Type checking
404-
uv run mypy tango/
408+
just typecheck
409+
410+
# Security scan
411+
just bandit
405412

406-
# Run all checks
407-
uv run ruff format tango/ && uv run ruff check tango/ && uv run mypy tango/
413+
# Run all checks (format, lint, typecheck, bandit)
414+
just check
408415
```
409416

410417
### Project Structure
@@ -482,6 +489,8 @@ tango-python/
482489

483490
- Python 3.12 or higher
484491
- httpx >= 0.27.0
492+
- [just](https://github.com/casey/just) (for development task runner)
493+
- [1Password CLI](https://developer.1password.com/docs/cli/) (for integration tests)
485494

486495
## License
487496

@@ -501,12 +510,9 @@ Contributions are welcome! Please feel free to submit a Pull Request.
501510

502511
1. Fork the repository
503512
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
504-
3. Run lint and format: `uv run ruff format tango/ && uv run ruff check tango/`
505-
4. Run type checking: `uv run mypy tango/`
506-
5. Run tests: `uv run pytest`
507-
6. (Optional) Run [filter and shape conformance](scripts/README.md#filter-and-shape-conformance) if you have the tango API manifest; CI will run it on push/PR
508-
7. Commit your changes (`git commit -m 'Add amazing feature'`)
509-
8. Push to the branch (`git push origin feature/amazing-feature`)
510-
9. Open a Pull Request
511-
512-
For a single command that runs formatting, linting, type checking, and tests (and conformance when the manifest is present), use: `uv run python scripts/pr_review.py --mode full`
513+
3. Run all checks: `just check`
514+
4. Run tests: `just test`
515+
5. (Optional) Run full PR review: `just pr-review`
516+
6. Commit your changes (`git commit -m 'Add amazing feature'`)
517+
7. Push to the branch (`git push origin feature/amazing-feature`)
518+
8. Open a Pull Request

justfile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Tango Python SDK task runner
2+
# Requires: just (https://github.com/casey/just), uv, op (1Password CLI)
3+
4+
# Default: list available recipes
5+
default:
6+
@just --list
7+
8+
# Run all tests
9+
test *args:
10+
uv run pytest {{ args }}
11+
12+
# Run unit tests only
13+
test-unit *args:
14+
uv run pytest tests/ -m "not integration" {{ args }}
15+
16+
# Run integration tests (requires API key in 1Password)
17+
test-integration *args:
18+
op run --env-file .env -- uv run pytest tests/integration/ {{ args }}
19+
20+
# Run integration tests with live API
21+
test-live *args:
22+
TANGO_USE_LIVE_API=true op run --env-file .env -- uv run pytest tests/integration/ {{ args }}
23+
24+
# Refresh VCR cassettes with fresh API responses
25+
refresh-cassettes *args:
26+
TANGO_REFRESH_CASSETTES=true op run --env-file .env -- uv run pytest tests/integration/ {{ args }}
27+
28+
# Format code
29+
fmt:
30+
uv run ruff format tango/
31+
32+
# Lint code
33+
lint:
34+
uv run ruff check tango/
35+
36+
# Type checking
37+
typecheck:
38+
uv run mypy tango/
39+
40+
# Security scan with bandit
41+
bandit:
42+
uv run bandit -r tango/ -c pyproject.toml
43+
44+
# Run all code quality checks
45+
check: fmt lint typecheck bandit
46+
47+
# Full PR review (format, lint, types, tests, conformance)
48+
pr-review *args:
49+
uv run python scripts/pr_review.py --mode full {{ args }}

0 commit comments

Comments
 (0)