pltr-cli 0.5.1__tar.gz → 0.6.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.
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/PKG-INFO +1 -1
- pltr_cli-0.6.0/RELEASE.md +163 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/pyproject.toml +19 -6
- pltr_cli-0.6.0/scripts/release.py +371 -0
- pltr_cli-0.6.0/src/pltr/__init__.py +1 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/dataset.py +34 -129
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_dataset_transactions.py +31 -29
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/uv.lock +1 -1
- pltr_cli-0.5.1/scripts/release.py +0 -211
- pltr_cli-0.5.1/src/pltr/__init__.py +0 -1
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/.github/workflows/ci.yml +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/.github/workflows/publish.yml +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/.github/workflows/test-publish.yml +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/.gitignore +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/.pre-commit-config.yaml +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/CHANGELOG.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/CLAUDE.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/LICENSE +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/README.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/children.csv +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/README.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/api/wrapper.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/examples/csv-upload.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/examples/gallery.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/features/dataset-transactions.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/user-guide/aliases.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/user-guide/authentication.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/user-guide/commands.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/user-guide/quick-start.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/user-guide/troubleshooting.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/docs/user-guide/workflows.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/folder_info.json +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/folders.json +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/mypy.ini +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/__main__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/auth/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/auth/base.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/auth/manager.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/auth/oauth.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/auth/storage.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/auth/token.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/cli.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/admin.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/alias.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/completion.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/configure.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/connectivity.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/dataset.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/folder.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/mediasets.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/ontology.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/orchestration.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/project.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/resource.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/resource_role.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/shell.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/space.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/sql.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/commands/verify.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/config/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/config/aliases.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/config/profiles.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/config/settings.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/admin.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/base.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/connectivity.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/folder.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/mediasets.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/ontology.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/orchestration.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/project.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/resource.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/resource_role.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/space.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/services/sql.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/utils/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/utils/alias_resolver.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/utils/completion.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/utils/formatting.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/src/pltr/utils/progress.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/conftest.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/README.md +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/conftest.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/test_auth_flow.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/test_cli_integration.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/test_data_workflows.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/test_data_workflows_simple.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/integration/test_simple_integration.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_auth/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_auth/test_base.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_auth/test_manager.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_auth/test_oauth.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_auth/test_storage.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_auth/test_token.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_admin.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_alias.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_completion.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_connectivity.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_dataset.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_folder.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_ontology.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_orchestration.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_shell.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_sql.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_commands/test_verify_simple.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_config/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_config/test_aliases.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_config/test_profiles.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_config/test_settings.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_admin.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_base.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_connectivity.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_dataset.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_folder.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_ontology.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_orchestration.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_project.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_resource.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_resource_role.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_space.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_services/test_sql.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_utils/__init__.py +0 -0
- {pltr_cli-0.5.1 → pltr_cli-0.6.0}/tests/test_utils/test_alias_resolver.py +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Release Process
|
|
2
|
+
|
|
3
|
+
This document describes how to create releases for pltr-cli using the automated release script.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The release script (`scripts/release.py`) supports both interactive and non-interactive modes to accommodate different use cases:
|
|
8
|
+
- **Interactive mode**: For human developers who want to review and confirm each step
|
|
9
|
+
- **Non-interactive mode**: For AI agents and automated systems that need to create releases programmatically
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### For Humans (Interactive Mode)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Patch release (0.5.1 → 0.5.2)
|
|
17
|
+
python scripts/release.py --type patch
|
|
18
|
+
|
|
19
|
+
# Minor release (0.5.1 → 0.6.0)
|
|
20
|
+
python scripts/release.py --type minor
|
|
21
|
+
|
|
22
|
+
# Major release (0.5.1 → 1.0.0)
|
|
23
|
+
python scripts/release.py --type major
|
|
24
|
+
|
|
25
|
+
# Specific version
|
|
26
|
+
python scripts/release.py --version 0.6.0
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### For AI Agents/Automation (Non-Interactive Mode)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Create release without prompts, don't push
|
|
33
|
+
python scripts/release.py --version 0.5.2 --yes --no-push
|
|
34
|
+
|
|
35
|
+
# Create release and push automatically
|
|
36
|
+
python scripts/release.py --type patch --yes --push
|
|
37
|
+
|
|
38
|
+
# Test what would happen (dry run)
|
|
39
|
+
python scripts/release.py --version 0.5.2 --dry-run
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Command-Line Arguments
|
|
43
|
+
|
|
44
|
+
| Argument | Description |
|
|
45
|
+
|----------|-------------|
|
|
46
|
+
| `--version X.Y.Z` | Specify exact version to release |
|
|
47
|
+
| `--type {major\|minor\|patch}` | Bump version automatically |
|
|
48
|
+
| `--yes`, `-y` | Skip all confirmation prompts (non-interactive mode) |
|
|
49
|
+
| `--push` | Push to origin without asking (requires `--yes`) |
|
|
50
|
+
| `--no-push` | Don't push to origin (useful for testing) |
|
|
51
|
+
| `--dry-run` | Show what would be done without making changes |
|
|
52
|
+
|
|
53
|
+
## What the Script Does
|
|
54
|
+
|
|
55
|
+
1. **Validates environment**:
|
|
56
|
+
- Checks that you're in a git repository
|
|
57
|
+
- Ensures working directory is clean (no uncommitted changes)
|
|
58
|
+
- Validates version format
|
|
59
|
+
|
|
60
|
+
2. **Version handling**:
|
|
61
|
+
- Gets current version from `pyproject.toml`
|
|
62
|
+
- Calculates or validates new version
|
|
63
|
+
- Warns if version already exists or is the same as current
|
|
64
|
+
|
|
65
|
+
3. **Creates release**:
|
|
66
|
+
- Updates version in `pyproject.toml`
|
|
67
|
+
- Creates git commit with message like "patch: Release version 0.5.2"
|
|
68
|
+
- Creates git tag like "v0.5.2"
|
|
69
|
+
|
|
70
|
+
4. **Optional push**:
|
|
71
|
+
- Pushes commit and tag to origin (triggers GitHub Actions)
|
|
72
|
+
- Can be automatic (`--push`), skipped (`--no-push`), or prompted (default)
|
|
73
|
+
|
|
74
|
+
## Usage Examples
|
|
75
|
+
|
|
76
|
+
### Interactive Development Workflow
|
|
77
|
+
```bash
|
|
78
|
+
# Make your changes
|
|
79
|
+
git add .
|
|
80
|
+
git commit -m "feat: add new feature"
|
|
81
|
+
|
|
82
|
+
# Create a patch release interactively
|
|
83
|
+
python scripts/release.py --type patch
|
|
84
|
+
# → Script will prompt for confirmation
|
|
85
|
+
# → Script will ask if you want to push
|
|
86
|
+
|
|
87
|
+
# The script will:
|
|
88
|
+
# 1. Update pyproject.toml (0.5.1 → 0.5.2)
|
|
89
|
+
# 2. Create commit "patch: Release version 0.5.2"
|
|
90
|
+
# 3. Create tag "v0.5.2"
|
|
91
|
+
# 4. Ask if you want to push to trigger publishing
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### AI Agent Workflow
|
|
95
|
+
```bash
|
|
96
|
+
# AI agent creates a release without any prompts
|
|
97
|
+
python scripts/release.py --version 0.5.2 --yes --no-push
|
|
98
|
+
|
|
99
|
+
# The script will:
|
|
100
|
+
# 1. Update pyproject.toml to version 0.5.2
|
|
101
|
+
# 2. Create commit "release: Release version 0.5.2"
|
|
102
|
+
# 3. Create tag "v0.5.2"
|
|
103
|
+
# 4. NOT push (--no-push specified)
|
|
104
|
+
# 5. Print instructions for manual push if needed
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Testing/Validation Workflow
|
|
108
|
+
```bash
|
|
109
|
+
# See what would happen without making changes
|
|
110
|
+
python scripts/release.py --version 0.6.0 --dry-run
|
|
111
|
+
|
|
112
|
+
# Create release locally but don't push (for testing)
|
|
113
|
+
python scripts/release.py --version 0.6.0 --yes --no-push
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## GitHub Actions Integration
|
|
117
|
+
|
|
118
|
+
When commits and tags are pushed to the repository, GitHub Actions will automatically:
|
|
119
|
+
1. Build the package
|
|
120
|
+
2. Run tests
|
|
121
|
+
3. Publish to PyPI (for tagged releases)
|
|
122
|
+
4. Create GitHub release with release notes
|
|
123
|
+
|
|
124
|
+
Monitor the workflow at: https://github.com/anjor/pltr-cli/actions
|
|
125
|
+
|
|
126
|
+
## Error Handling
|
|
127
|
+
|
|
128
|
+
The script handles several common error scenarios:
|
|
129
|
+
|
|
130
|
+
- **Dirty working directory**: Script will fail if there are uncommitted changes
|
|
131
|
+
- **Duplicate versions**: Warns if trying to release the same version as current
|
|
132
|
+
- **Existing tags**: Warns if git tag already exists locally or remotely
|
|
133
|
+
- **Invalid versions**: Validates semantic version format (X.Y.Z)
|
|
134
|
+
- **Missing arguments**: Requires either `--version` or `--type`
|
|
135
|
+
- **Invalid combinations**: Prevents conflicting flags like `--push` and `--no-push`
|
|
136
|
+
|
|
137
|
+
## Troubleshooting
|
|
138
|
+
|
|
139
|
+
### "EOFError: EOF when reading a line"
|
|
140
|
+
This happens when running the script in non-interactive mode without the `--yes` flag. Add `--yes` to skip prompts.
|
|
141
|
+
|
|
142
|
+
### "Tag already exists"
|
|
143
|
+
The script will warn you and ask for confirmation. You can:
|
|
144
|
+
- Delete the existing tag: `git tag -d v0.5.2`
|
|
145
|
+
- Use a different version number
|
|
146
|
+
- Continue anyway (not recommended)
|
|
147
|
+
|
|
148
|
+
### "Working directory is not clean"
|
|
149
|
+
Commit or stash your changes before running the release script:
|
|
150
|
+
```bash
|
|
151
|
+
git add .
|
|
152
|
+
git commit -m "your changes"
|
|
153
|
+
# OR
|
|
154
|
+
git stash
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Best Practices
|
|
158
|
+
|
|
159
|
+
1. **Always test with `--dry-run` first** when trying new version numbers
|
|
160
|
+
2. **Use `--no-push` for testing** to avoid accidental pushes
|
|
161
|
+
3. **Follow semantic versioning**: patch for bug fixes, minor for features, major for breaking changes
|
|
162
|
+
4. **Keep working directory clean** before creating releases
|
|
163
|
+
5. **Monitor GitHub Actions** after pushing to ensure successful publishing
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pltr-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
4
4
|
description = "Command-line interface for Palantir Foundry APIs"
|
|
5
5
|
authors = [
|
|
6
|
-
{ name = "anjor", email = "anjor@umd.edu" }
|
|
6
|
+
{ name = "anjor", email = "anjor@umd.edu" },
|
|
7
7
|
]
|
|
8
8
|
readme = "README.md"
|
|
9
|
-
license = { text = "MIT" }
|
|
10
9
|
requires-python = ">=3.9"
|
|
11
10
|
dependencies = [
|
|
12
11
|
"click-repl>=0.3.0",
|
|
@@ -17,7 +16,14 @@ dependencies = [
|
|
|
17
16
|
"rich>=14.1.0",
|
|
18
17
|
"typer>=0.16.0",
|
|
19
18
|
]
|
|
20
|
-
keywords = [
|
|
19
|
+
keywords = [
|
|
20
|
+
"palantir",
|
|
21
|
+
"foundry",
|
|
22
|
+
"cli",
|
|
23
|
+
"api",
|
|
24
|
+
"data",
|
|
25
|
+
"ontology",
|
|
26
|
+
]
|
|
21
27
|
classifiers = [
|
|
22
28
|
"Development Status :: 3 - Alpha",
|
|
23
29
|
"Environment :: Console",
|
|
@@ -35,6 +41,9 @@ classifiers = [
|
|
|
35
41
|
"Topic :: Utilities",
|
|
36
42
|
]
|
|
37
43
|
|
|
44
|
+
[project.license]
|
|
45
|
+
text = "MIT"
|
|
46
|
+
|
|
38
47
|
[project.urls]
|
|
39
48
|
Homepage = "https://github.com/anjor/pltr-cli"
|
|
40
49
|
Repository = "https://github.com/anjor/pltr-cli"
|
|
@@ -46,11 +55,15 @@ Documentation = "https://github.com/anjor/pltr-cli/blob/main/README.md"
|
|
|
46
55
|
pltr = "pltr.cli:app"
|
|
47
56
|
|
|
48
57
|
[build-system]
|
|
49
|
-
requires = [
|
|
58
|
+
requires = [
|
|
59
|
+
"hatchling",
|
|
60
|
+
]
|
|
50
61
|
build-backend = "hatchling.build"
|
|
51
62
|
|
|
52
63
|
[tool.hatch.build.targets.wheel]
|
|
53
|
-
packages = [
|
|
64
|
+
packages = [
|
|
65
|
+
"src/pltr",
|
|
66
|
+
]
|
|
54
67
|
|
|
55
68
|
[dependency-groups]
|
|
56
69
|
dev = [
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Release script for pltr-cli
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
# Interactive mode (for humans)
|
|
7
|
+
python scripts/release.py --version 0.1.1
|
|
8
|
+
python scripts/release.py --type patch
|
|
9
|
+
|
|
10
|
+
# Non-interactive mode (for AI agents/automation)
|
|
11
|
+
python scripts/release.py --version 0.1.1 --yes --no-push
|
|
12
|
+
python scripts/release.py --type patch --yes --push
|
|
13
|
+
|
|
14
|
+
# Dry run to see what would happen
|
|
15
|
+
python scripts/release.py --version 0.1.1 --dry-run
|
|
16
|
+
|
|
17
|
+
Flags:
|
|
18
|
+
--yes, -y Skip all confirmation prompts (non-interactive mode)
|
|
19
|
+
--push Push to origin without asking (requires --yes)
|
|
20
|
+
--no-push Don't push to origin (useful for testing)
|
|
21
|
+
--dry-run Show what would be done without making changes
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
import re
|
|
26
|
+
import subprocess
|
|
27
|
+
import sys
|
|
28
|
+
import tomllib
|
|
29
|
+
import tomli_w
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_current_version():
|
|
34
|
+
"""Get the current version from pyproject.toml"""
|
|
35
|
+
pyproject_path = Path("pyproject.toml")
|
|
36
|
+
if not pyproject_path.exists():
|
|
37
|
+
print("Error: pyproject.toml not found")
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
|
|
40
|
+
with open(pyproject_path, "rb") as f:
|
|
41
|
+
config = tomllib.load(f)
|
|
42
|
+
|
|
43
|
+
return config["project"]["version"]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def update_version_in_pyproject(new_version):
|
|
47
|
+
"""Update version in pyproject.toml"""
|
|
48
|
+
pyproject_path = Path("pyproject.toml")
|
|
49
|
+
|
|
50
|
+
with open(pyproject_path, "rb") as f:
|
|
51
|
+
config = tomllib.load(f)
|
|
52
|
+
|
|
53
|
+
config["project"]["version"] = new_version
|
|
54
|
+
|
|
55
|
+
with open(pyproject_path, "wb") as f:
|
|
56
|
+
tomli_w.dump(config, f)
|
|
57
|
+
|
|
58
|
+
print(f"Updated pyproject.toml version to {new_version}")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def update_version_in_init_py(new_version):
|
|
62
|
+
"""Update __version__ in src/pltr/__init__.py"""
|
|
63
|
+
init_py_path = Path("src/pltr/__init__.py")
|
|
64
|
+
|
|
65
|
+
if not init_py_path.exists():
|
|
66
|
+
print("Error: src/pltr/__init__.py not found")
|
|
67
|
+
sys.exit(1)
|
|
68
|
+
|
|
69
|
+
# Read the current content
|
|
70
|
+
content = init_py_path.read_text()
|
|
71
|
+
|
|
72
|
+
# Update the version using regex
|
|
73
|
+
import re
|
|
74
|
+
|
|
75
|
+
pattern = r'__version__ = "[^"]+"'
|
|
76
|
+
replacement = f'__version__ = "{new_version}"'
|
|
77
|
+
|
|
78
|
+
if not re.search(pattern, content):
|
|
79
|
+
print("Error: Could not find __version__ in src/pltr/__init__.py")
|
|
80
|
+
sys.exit(1)
|
|
81
|
+
|
|
82
|
+
updated_content = re.sub(pattern, replacement, content)
|
|
83
|
+
init_py_path.write_text(updated_content)
|
|
84
|
+
|
|
85
|
+
print(f"Updated src/pltr/__init__.py __version__ to {new_version}")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def validate_version(version):
|
|
89
|
+
"""Validate semantic version format"""
|
|
90
|
+
pattern = r"^\d+\.\d+\.\d+(?:-[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*)?$"
|
|
91
|
+
if not re.match(pattern, version):
|
|
92
|
+
print(
|
|
93
|
+
f"Error: Invalid version format '{version}'. Use semantic versioning (e.g., 1.0.0)"
|
|
94
|
+
)
|
|
95
|
+
sys.exit(1)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def run_git_command(cmd):
|
|
99
|
+
"""Run git command and return result"""
|
|
100
|
+
try:
|
|
101
|
+
result = subprocess.run(
|
|
102
|
+
cmd, shell=True, check=True, capture_output=True, text=True
|
|
103
|
+
)
|
|
104
|
+
return result.stdout.strip()
|
|
105
|
+
except subprocess.CalledProcessError as e:
|
|
106
|
+
print(f"Error running git command: {cmd}")
|
|
107
|
+
print(f"Error output: {e.stderr}")
|
|
108
|
+
sys.exit(1)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def check_git_status():
|
|
112
|
+
"""Check if git working directory is clean"""
|
|
113
|
+
status = run_git_command("git status --porcelain")
|
|
114
|
+
if status:
|
|
115
|
+
print(
|
|
116
|
+
"Error: Working directory is not clean. Please commit or stash changes first."
|
|
117
|
+
)
|
|
118
|
+
print("Uncommitted changes:")
|
|
119
|
+
print(status)
|
|
120
|
+
sys.exit(1)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def check_tag_exists(version):
|
|
124
|
+
"""Check if a git tag already exists for this version"""
|
|
125
|
+
tag_name = f"v{version}"
|
|
126
|
+
try:
|
|
127
|
+
# Check if tag exists locally
|
|
128
|
+
result = subprocess.run(
|
|
129
|
+
["git", "tag", "-l", tag_name], capture_output=True, text=True, check=True
|
|
130
|
+
)
|
|
131
|
+
if result.stdout.strip():
|
|
132
|
+
print(f"Warning: Tag {tag_name} already exists locally.")
|
|
133
|
+
return True
|
|
134
|
+
except subprocess.CalledProcessError:
|
|
135
|
+
pass
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
# Check if tag exists on remote
|
|
139
|
+
result = subprocess.run(
|
|
140
|
+
["git", "ls-remote", "--tags", "origin", tag_name],
|
|
141
|
+
capture_output=True,
|
|
142
|
+
text=True,
|
|
143
|
+
check=True,
|
|
144
|
+
)
|
|
145
|
+
if result.stdout.strip():
|
|
146
|
+
print(f"Warning: Tag {tag_name} already exists on remote.")
|
|
147
|
+
return True
|
|
148
|
+
except subprocess.CalledProcessError:
|
|
149
|
+
# Remote might not exist or be accessible, continue
|
|
150
|
+
pass
|
|
151
|
+
|
|
152
|
+
return False
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def create_release_commit_and_tag(version, release_type, push_mode="ask"):
|
|
156
|
+
"""Create release commit and tag"""
|
|
157
|
+
# Stage the version file changes
|
|
158
|
+
run_git_command("git add pyproject.toml src/pltr/__init__.py")
|
|
159
|
+
|
|
160
|
+
# Create release commit
|
|
161
|
+
commit_message = f"{release_type}: Release version {version}"
|
|
162
|
+
run_git_command(f'git commit -m "{commit_message}"')
|
|
163
|
+
print(f"Created release commit: {commit_message}")
|
|
164
|
+
|
|
165
|
+
# Create and push tag
|
|
166
|
+
tag_name = f"v{version}"
|
|
167
|
+
try:
|
|
168
|
+
run_git_command(f'git tag -a {tag_name} -m "Release {version}"')
|
|
169
|
+
print(f"Created tag: {tag_name}")
|
|
170
|
+
except SystemExit:
|
|
171
|
+
print(f"Error: Failed to create tag {tag_name}. It may already exist.")
|
|
172
|
+
print(f"To delete the existing tag: git tag -d {tag_name}")
|
|
173
|
+
print(f"To delete from remote: git push origin :refs/tags/{tag_name}")
|
|
174
|
+
raise
|
|
175
|
+
|
|
176
|
+
# Handle push based on mode
|
|
177
|
+
if push_mode == "force":
|
|
178
|
+
run_git_command("git push origin HEAD")
|
|
179
|
+
run_git_command(f"git push origin {tag_name}")
|
|
180
|
+
print("Pushed commit and tag to origin")
|
|
181
|
+
print("GitHub Actions will now build and publish the release automatically")
|
|
182
|
+
print("Monitor the workflow at: https://github.com/anjor/pltr-cli/actions")
|
|
183
|
+
elif push_mode == "no":
|
|
184
|
+
print("Not pushing to origin (--no-push specified).")
|
|
185
|
+
print("You can push manually later with:")
|
|
186
|
+
print(" git push origin HEAD")
|
|
187
|
+
print(f" git push origin {tag_name}")
|
|
188
|
+
else: # push_mode == "ask"
|
|
189
|
+
push_choice = (
|
|
190
|
+
input(f"Push commit and tag '{tag_name}' to origin? (y/N): ")
|
|
191
|
+
.strip()
|
|
192
|
+
.lower()
|
|
193
|
+
)
|
|
194
|
+
if push_choice in ["y", "yes"]:
|
|
195
|
+
run_git_command("git push origin HEAD")
|
|
196
|
+
run_git_command(f"git push origin {tag_name}")
|
|
197
|
+
print("Pushed commit and tag to origin")
|
|
198
|
+
print("GitHub Actions will now build and publish the release automatically")
|
|
199
|
+
print("Monitor the workflow at: https://github.com/anjor/pltr-cli/actions")
|
|
200
|
+
else:
|
|
201
|
+
print("Not pushing to origin. You can push manually later with:")
|
|
202
|
+
print(" git push origin HEAD")
|
|
203
|
+
print(f" git push origin {tag_name}")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def bump_version(current_version, bump_type):
|
|
207
|
+
"""Bump version based on type"""
|
|
208
|
+
parts = current_version.split(".")
|
|
209
|
+
if len(parts) != 3:
|
|
210
|
+
print(
|
|
211
|
+
f"Error: Current version '{current_version}' is not in semantic version format"
|
|
212
|
+
)
|
|
213
|
+
sys.exit(1)
|
|
214
|
+
|
|
215
|
+
major, minor, patch = map(int, parts)
|
|
216
|
+
|
|
217
|
+
if bump_type == "major":
|
|
218
|
+
return f"{major + 1}.0.0"
|
|
219
|
+
elif bump_type == "minor":
|
|
220
|
+
return f"{major}.{minor + 1}.0"
|
|
221
|
+
elif bump_type == "patch":
|
|
222
|
+
return f"{major}.{minor}.{patch + 1}"
|
|
223
|
+
else:
|
|
224
|
+
print(f"Error: Invalid bump type '{bump_type}'. Use: major, minor, or patch")
|
|
225
|
+
sys.exit(1)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def main():
|
|
229
|
+
parser = argparse.ArgumentParser(description="Create a release for pltr-cli")
|
|
230
|
+
parser.add_argument("--version", help="Specific version to release (e.g., 1.0.0)")
|
|
231
|
+
parser.add_argument(
|
|
232
|
+
"--type",
|
|
233
|
+
choices=["major", "minor", "patch"],
|
|
234
|
+
help="Version bump type (alternative to --version)",
|
|
235
|
+
)
|
|
236
|
+
parser.add_argument(
|
|
237
|
+
"--dry-run",
|
|
238
|
+
action="store_true",
|
|
239
|
+
help="Show what would be done without making changes",
|
|
240
|
+
)
|
|
241
|
+
parser.add_argument(
|
|
242
|
+
"--yes",
|
|
243
|
+
"-y",
|
|
244
|
+
action="store_true",
|
|
245
|
+
help="Skip all confirmation prompts (non-interactive mode)",
|
|
246
|
+
)
|
|
247
|
+
parser.add_argument(
|
|
248
|
+
"--push",
|
|
249
|
+
action="store_true",
|
|
250
|
+
help="Push to origin without asking (requires --yes)",
|
|
251
|
+
)
|
|
252
|
+
parser.add_argument(
|
|
253
|
+
"--no-push",
|
|
254
|
+
action="store_true",
|
|
255
|
+
help="Don't push to origin (useful for testing)",
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
args = parser.parse_args()
|
|
259
|
+
|
|
260
|
+
# Validate argument combinations
|
|
261
|
+
if args.push and args.no_push:
|
|
262
|
+
print("Error: Cannot specify both --push and --no-push")
|
|
263
|
+
sys.exit(1)
|
|
264
|
+
|
|
265
|
+
if args.push and not args.yes:
|
|
266
|
+
print("Error: --push requires --yes (non-interactive mode)")
|
|
267
|
+
sys.exit(1)
|
|
268
|
+
|
|
269
|
+
# Ensure we're in a git repository
|
|
270
|
+
try:
|
|
271
|
+
run_git_command("git rev-parse --git-dir")
|
|
272
|
+
except subprocess.CalledProcessError:
|
|
273
|
+
print("Error: Not in a git repository")
|
|
274
|
+
sys.exit(1)
|
|
275
|
+
|
|
276
|
+
# Get current version
|
|
277
|
+
current_version = get_current_version()
|
|
278
|
+
print(f"Current version: {current_version}")
|
|
279
|
+
|
|
280
|
+
# Determine new version
|
|
281
|
+
if args.version and args.type:
|
|
282
|
+
print("Error: Cannot specify both --version and --type")
|
|
283
|
+
sys.exit(1)
|
|
284
|
+
elif args.version:
|
|
285
|
+
new_version = args.version
|
|
286
|
+
validate_version(new_version)
|
|
287
|
+
release_type = "release"
|
|
288
|
+
elif args.type:
|
|
289
|
+
new_version = bump_version(current_version, args.type)
|
|
290
|
+
release_type = args.type
|
|
291
|
+
else:
|
|
292
|
+
print("Error: Must specify either --version or --type")
|
|
293
|
+
sys.exit(1)
|
|
294
|
+
|
|
295
|
+
print(f"New version: {new_version}")
|
|
296
|
+
|
|
297
|
+
# Check if we're trying to release the same version
|
|
298
|
+
if new_version == current_version:
|
|
299
|
+
print(f"\nWarning: Version {new_version} is the same as current version.")
|
|
300
|
+
print("This will create a new commit and tag for the same version.")
|
|
301
|
+
if not args.yes:
|
|
302
|
+
confirm_same = input("Continue anyway? (y/N): ").strip().lower()
|
|
303
|
+
if confirm_same not in ["y", "yes"]:
|
|
304
|
+
print("Release cancelled")
|
|
305
|
+
sys.exit(0)
|
|
306
|
+
|
|
307
|
+
if args.dry_run:
|
|
308
|
+
print("\nDry run mode - would perform these actions:")
|
|
309
|
+
print(f"1. Update pyproject.toml version to {new_version}")
|
|
310
|
+
print(f"2. Update src/pltr/__init__.py __version__ to {new_version}")
|
|
311
|
+
print(f"3. Create git commit: '{release_type}: Release version {new_version}'")
|
|
312
|
+
print(f"4. Create git tag: v{new_version}")
|
|
313
|
+
print("5. Optionally push to origin")
|
|
314
|
+
return
|
|
315
|
+
|
|
316
|
+
# Check git status
|
|
317
|
+
check_git_status()
|
|
318
|
+
|
|
319
|
+
# Check if tag already exists
|
|
320
|
+
if check_tag_exists(new_version):
|
|
321
|
+
if not args.yes:
|
|
322
|
+
confirm_tag = (
|
|
323
|
+
input(f"Tag v{new_version} already exists. Continue anyway? (y/N): ")
|
|
324
|
+
.strip()
|
|
325
|
+
.lower()
|
|
326
|
+
)
|
|
327
|
+
if confirm_tag not in ["y", "yes"]:
|
|
328
|
+
print("Release cancelled")
|
|
329
|
+
sys.exit(0)
|
|
330
|
+
else:
|
|
331
|
+
print(f"Continuing despite existing tag v{new_version} (--yes specified)")
|
|
332
|
+
|
|
333
|
+
# Confirm release
|
|
334
|
+
print(f"\nAbout to create release {new_version}")
|
|
335
|
+
print("This will:")
|
|
336
|
+
print(f"1. Update pyproject.toml version to {new_version}")
|
|
337
|
+
print(f"2. Update src/pltr/__init__.py __version__ to {new_version}")
|
|
338
|
+
print(f"3. Create git commit and tag v{new_version}")
|
|
339
|
+
if args.push:
|
|
340
|
+
print("4. Push to origin to trigger GitHub Actions publishing")
|
|
341
|
+
elif args.no_push:
|
|
342
|
+
print("4. NOT push to origin (--no-push specified)")
|
|
343
|
+
else:
|
|
344
|
+
print("4. Optionally push to trigger GitHub Actions publishing")
|
|
345
|
+
|
|
346
|
+
if not args.yes:
|
|
347
|
+
confirm = input("\nProceed with release? (y/N): ").strip().lower()
|
|
348
|
+
if confirm not in ["y", "yes"]:
|
|
349
|
+
print("Release cancelled")
|
|
350
|
+
sys.exit(0)
|
|
351
|
+
else:
|
|
352
|
+
print("\nProceeding with release (--yes specified)...")
|
|
353
|
+
|
|
354
|
+
# Determine push mode
|
|
355
|
+
if args.push:
|
|
356
|
+
push_mode = "force"
|
|
357
|
+
elif args.no_push:
|
|
358
|
+
push_mode = "no"
|
|
359
|
+
else:
|
|
360
|
+
push_mode = "ask"
|
|
361
|
+
|
|
362
|
+
# Perform release
|
|
363
|
+
update_version_in_pyproject(new_version)
|
|
364
|
+
update_version_in_init_py(new_version)
|
|
365
|
+
create_release_commit_and_tag(new_version, release_type, push_mode)
|
|
366
|
+
|
|
367
|
+
print(f"\n✅ Release {new_version} created successfully!")
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
if __name__ == "__main__":
|
|
371
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.0"
|