redeploy 0.2.4__tar.gz → 0.2.5__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.
- {redeploy-0.2.4 → redeploy-0.2.5}/PKG-INFO +6 -6
- {redeploy-0.2.4 → redeploy-0.2.5}/README.md +5 -5
- {redeploy-0.2.4 → redeploy-0.2.5}/pyproject.toml +1 -1
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/__init__.py +1 -1
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/cli.py +97 -1
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_version_cli.py +90 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy.egg-info/PKG-INFO +6 -6
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/apply/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/apply/executor.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/data_sync.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/detect/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/detect/detector.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/detect/probes.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/detect/remote.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/detect/templates.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/detect/workflow.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/discovery.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/dsl/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/dsl/loader.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/dsl/parser.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/fleet.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/iac/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/iac/base.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/iac/docker_compose.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/iac/parsers/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/iac/parsers/compose.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/iac/registry.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/models.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/observe.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/parse.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/patterns.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/plan/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/plan/planner.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/plugins/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/plugins/builtin/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/plugins/builtin/browser_reload.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/plugins/builtin/notify.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/plugins/builtin/systemd_reload.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/ssh.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/steps.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_cli.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_data_sync.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_discovery.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_dsl.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_examples.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_executor.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_fleet.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_git_integration.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_iac.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_manifest.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_models.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_observe.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_parse.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_patterns.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_planner_edge.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_plugins.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_probes.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_public_api.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_ssh.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_templates.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_verify.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_version.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_version_changelog.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_version_manifest.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_version_sources.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/tests/test_workflow.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/verify.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/bump.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/changelog.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/commits.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/diff.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/git_integration.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/git_transaction.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/manifest.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/sources/__init__.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/sources/base.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/sources/json_.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/sources/plain.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/sources/regex.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/sources/toml_.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/sources/yaml_.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version/transaction.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy/version.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy.egg-info/SOURCES.txt +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy.egg-info/dependency_links.txt +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy.egg-info/entry_points.txt +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy.egg-info/requires.txt +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/redeploy.egg-info/top_level.txt +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/setup.cfg +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/tests/test_iac.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/tests/test_parse.py +0 -0
- {redeploy-0.2.4 → redeploy-0.2.5}/tests/test_redeploy.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redeploy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -26,17 +26,17 @@ Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
|
26
26
|
|
|
27
27
|
## AI Cost Tracking
|
|
28
28
|
|
|
29
|
-
    
|
|
30
|
+
  
|
|
31
31
|
|
|
32
|
-
- 🤖 **LLM usage:** $3.
|
|
33
|
-
- 👤 **Human dev:** ~$
|
|
32
|
+
- 🤖 **LLM usage:** $3.4500 (23 commits)
|
|
33
|
+
- 👤 **Human dev:** ~$563 (5.6h @ $100/h, 30min dedup)
|
|
34
34
|
|
|
35
35
|
Generated on 2026-04-20 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
39
|
-
    
|
|
40
40
|
|
|
41
41
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
42
42
|
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
|
|
4
4
|
## AI Cost Tracking
|
|
5
5
|
|
|
6
|
-
    
|
|
7
|
+
  
|
|
8
8
|
|
|
9
|
-
- 🤖 **LLM usage:** $3.
|
|
10
|
-
- 👤 **Human dev:** ~$
|
|
9
|
+
- 🤖 **LLM usage:** $3.4500 (23 commits)
|
|
10
|
+
- 👤 **Human dev:** ~$563 (5.6h @ $100/h, 30min dedup)
|
|
11
11
|
|
|
12
12
|
Generated on 2026-04-20 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
    
|
|
17
17
|
|
|
18
18
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
19
19
|
|
|
@@ -7,7 +7,7 @@ Public API (stable from 0.2.0, semver guaranteed)::
|
|
|
7
7
|
|
|
8
8
|
Everything not listed in ``__all__`` is internal and may change without notice.
|
|
9
9
|
"""
|
|
10
|
-
__version__ = "0.2.
|
|
10
|
+
__version__ = "0.2.5"
|
|
11
11
|
|
|
12
12
|
# ── Core models ───────────────────────────────────────────────────────────────
|
|
13
13
|
from .models import ( # noqa: F401
|
|
@@ -2347,6 +2347,8 @@ def _calculate_bump(current: str, bump_type: str) -> str:
|
|
|
2347
2347
|
@click.argument("version")
|
|
2348
2348
|
@click.option("--manifest", "manifest_path_str", default=".redeploy/version.yaml",
|
|
2349
2349
|
help="Path to version manifest")
|
|
2350
|
+
@click.option("--package", "package_name", "-p", help="Set version for a specific package (for monorepo)")
|
|
2351
|
+
@click.option("--all-packages", is_flag=True, help="Set version for all packages (for monorepo)")
|
|
2350
2352
|
@click.option("--dry-run", is_flag=True, help="Preview changes without applying")
|
|
2351
2353
|
@click.option("--commit", is_flag=True, help="Create git commit with changes")
|
|
2352
2354
|
@click.option("--tag", is_flag=True, help="Create git tag for new version")
|
|
@@ -2354,10 +2356,13 @@ def _calculate_bump(current: str, bump_type: str) -> str:
|
|
|
2354
2356
|
@click.option("--sign", is_flag=True, help="Sign tag with GPG")
|
|
2355
2357
|
@click.option("--allow-dirty", is_flag=True, help="Allow version change with dirty working directory")
|
|
2356
2358
|
@click.option("--changelog", is_flag=True, help="Update CHANGELOG.md")
|
|
2357
|
-
def version_set(version, manifest_path_str, dry_run, commit, tag, push, sign, allow_dirty, changelog):
|
|
2359
|
+
def version_set(version, manifest_path_str, package_name, all_packages, dry_run, commit, tag, push, sign, allow_dirty, changelog):
|
|
2358
2360
|
"""Set an explicit version across all manifest sources."""
|
|
2359
2361
|
from rich.console import Console
|
|
2360
2362
|
from .version import VersionManifest
|
|
2363
|
+
from .version.bump import bump_package
|
|
2364
|
+
from .version.changelog import ChangelogManager, get_commits_since_tag
|
|
2365
|
+
from .version.git_integration import GitIntegration, GitIntegrationError
|
|
2361
2366
|
|
|
2362
2367
|
console = Console()
|
|
2363
2368
|
manifest_path = Path(manifest_path_str)
|
|
@@ -2368,6 +2373,97 @@ def version_set(version, manifest_path_str, dry_run, commit, tag, push, sign, al
|
|
|
2368
2373
|
sys.exit(1)
|
|
2369
2374
|
|
|
2370
2375
|
manifest_model = VersionManifest.load(manifest_path)
|
|
2376
|
+
|
|
2377
|
+
if package_name and all_packages:
|
|
2378
|
+
console.print("[red]✗ Use either --package NAME or --all-packages, not both.[/red]")
|
|
2379
|
+
sys.exit(1)
|
|
2380
|
+
|
|
2381
|
+
if package_name or all_packages:
|
|
2382
|
+
if not manifest_model.is_monorepo():
|
|
2383
|
+
console.print("[red]✗ Manifest has no packages defined. Add 'packages:' section for monorepo support.[/red]")
|
|
2384
|
+
sys.exit(1)
|
|
2385
|
+
|
|
2386
|
+
if package_name:
|
|
2387
|
+
targets = [package_name]
|
|
2388
|
+
pkg = manifest_model.get_package(package_name)
|
|
2389
|
+
if pkg is None:
|
|
2390
|
+
console.print(f"[red]✗ Package '{package_name}' not found in manifest[/red]")
|
|
2391
|
+
console.print(f" Available: {manifest_model.list_packages()}")
|
|
2392
|
+
sys.exit(1)
|
|
2393
|
+
else:
|
|
2394
|
+
targets = manifest_model.list_packages()
|
|
2395
|
+
|
|
2396
|
+
repo_path = manifest_path.parent.parent
|
|
2397
|
+
|
|
2398
|
+
if dry_run:
|
|
2399
|
+
for pkg_name in targets:
|
|
2400
|
+
pkg = manifest_model.get_package(pkg_name)
|
|
2401
|
+
console.print(f"[DRY RUN] Would set {pkg_name}: {pkg.version} → {version}")
|
|
2402
|
+
console.print(f" Sources: {len(pkg.sources)}")
|
|
2403
|
+
for source in pkg.sources:
|
|
2404
|
+
console.print(f" - {source.path} ({source.format})")
|
|
2405
|
+
return
|
|
2406
|
+
|
|
2407
|
+
try:
|
|
2408
|
+
git = None
|
|
2409
|
+
if commit or tag or push:
|
|
2410
|
+
git_config = manifest_model.get_package(package_name).git if package_name and manifest_model.get_package(package_name) and manifest_model.get_package(package_name).git else manifest_model.git
|
|
2411
|
+
git = GitIntegration(git_config, repo_path)
|
|
2412
|
+
if git_config.require_clean and not allow_dirty:
|
|
2413
|
+
git.require_clean()
|
|
2414
|
+
|
|
2415
|
+
touched_files = []
|
|
2416
|
+
if changelog:
|
|
2417
|
+
changelog_path = manifest_model.changelog.path if manifest_model.changelog else Path("CHANGELOG.md")
|
|
2418
|
+
changelog_mgr = ChangelogManager(repo_path / changelog_path)
|
|
2419
|
+
commits = get_commits_since_tag(repo_path, manifest_model.git.tag_format.format(version=manifest_model.version))
|
|
2420
|
+
new_content = changelog_mgr.prepare_release(version, commit_messages=commits)
|
|
2421
|
+
changelog_mgr.write(new_content)
|
|
2422
|
+
console.print(f"[green]✓ Updated {changelog_path}[/green]")
|
|
2423
|
+
touched_files.append(changelog_path)
|
|
2424
|
+
|
|
2425
|
+
for pkg_name in targets:
|
|
2426
|
+
pkg = manifest_model.get_package(pkg_name)
|
|
2427
|
+
result = bump_package(manifest_model, pkg_name, "patch", new_version=version)
|
|
2428
|
+
touched_files.extend(source.path for source in pkg.sources)
|
|
2429
|
+
console.print(f"[green]✓[/green] {pkg_name}: {result['old']} → {result['new_version']} ({result['success']}/{result['total']} sources)")
|
|
2430
|
+
|
|
2431
|
+
manifest_model.save(manifest_path)
|
|
2432
|
+
touched_files.append(manifest_path)
|
|
2433
|
+
|
|
2434
|
+
if git:
|
|
2435
|
+
unique_files = []
|
|
2436
|
+
for file_path in touched_files:
|
|
2437
|
+
if file_path not in unique_files:
|
|
2438
|
+
unique_files.append(file_path)
|
|
2439
|
+
|
|
2440
|
+
commit_hash = None
|
|
2441
|
+
tag_name = None
|
|
2442
|
+
if commit or push:
|
|
2443
|
+
commit_hash = git.commit(version, unique_files)
|
|
2444
|
+
if tag or push:
|
|
2445
|
+
tag_name = git.tag(version, sign=sign)
|
|
2446
|
+
if push:
|
|
2447
|
+
git.push(follow_tags=True)
|
|
2448
|
+
|
|
2449
|
+
console.print(f"[green]✓ Set version to {version} for {len(targets)} package(s)[/green]")
|
|
2450
|
+
if commit_hash:
|
|
2451
|
+
console.print(f" Commit: {commit_hash[:8]}")
|
|
2452
|
+
if tag_name:
|
|
2453
|
+
console.print(f" Tag: {tag_name}")
|
|
2454
|
+
if push:
|
|
2455
|
+
console.print(" Pushed to origin")
|
|
2456
|
+
|
|
2457
|
+
return
|
|
2458
|
+
except GitIntegrationError as e:
|
|
2459
|
+
console.print(f"[red]✗ Git error: {e}[/red]")
|
|
2460
|
+
sys.exit(1)
|
|
2461
|
+
except Exception as e:
|
|
2462
|
+
console.print(f"[red]✗ Version set failed: {e}[/red]")
|
|
2463
|
+
import traceback
|
|
2464
|
+
console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
2465
|
+
sys.exit(1)
|
|
2466
|
+
|
|
2371
2467
|
_bump_single(
|
|
2372
2468
|
manifest_model,
|
|
2373
2469
|
"patch",
|
|
@@ -32,6 +32,41 @@ def _write_version_workspace(base: Path, version: str = "1.0.0") -> None:
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
def _write_monorepo_version_workspace(base: Path) -> None:
|
|
36
|
+
(base / ".redeploy").mkdir(parents=True, exist_ok=True)
|
|
37
|
+
(base / "backend").mkdir(parents=True, exist_ok=True)
|
|
38
|
+
(base / "frontend").mkdir(parents=True, exist_ok=True)
|
|
39
|
+
(base / "backend" / "VERSION").write_text("1.0.0\n", encoding="utf-8")
|
|
40
|
+
(base / "frontend" / "VERSION").write_text("2.0.0\n", encoding="utf-8")
|
|
41
|
+
|
|
42
|
+
manifest = {
|
|
43
|
+
"version": {
|
|
44
|
+
"version": "0.0.0",
|
|
45
|
+
"scheme": "semver",
|
|
46
|
+
"policy": "independent",
|
|
47
|
+
"sources": [],
|
|
48
|
+
"packages": {
|
|
49
|
+
"backend": {
|
|
50
|
+
"version": "1.0.0",
|
|
51
|
+
"sources": [
|
|
52
|
+
{"path": "backend/VERSION", "format": "plain"},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
"frontend": {
|
|
56
|
+
"version": "2.0.0",
|
|
57
|
+
"sources": [
|
|
58
|
+
{"path": "frontend/VERSION", "format": "plain"},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
(base / ".redeploy" / "version.yaml").write_text(
|
|
65
|
+
yaml.dump(manifest, sort_keys=False),
|
|
66
|
+
encoding="utf-8",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
35
70
|
class TestVersionSet:
|
|
36
71
|
def test_set_updates_manifest_and_sources(self, tmp_path):
|
|
37
72
|
runner = _runner()
|
|
@@ -61,6 +96,61 @@ class TestVersionSet:
|
|
|
61
96
|
assert "DRY RUN" in result.output
|
|
62
97
|
assert Path("VERSION").read_text(encoding="utf-8").strip() == "1.0.0"
|
|
63
98
|
|
|
99
|
+
def test_set_package_updates_only_selected_package(self, tmp_path):
|
|
100
|
+
runner = _runner()
|
|
101
|
+
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
102
|
+
_write_monorepo_version_workspace(Path.cwd())
|
|
103
|
+
|
|
104
|
+
result = runner.invoke(
|
|
105
|
+
cli,
|
|
106
|
+
["version", "set", "3.3.3", "--package", "backend"],
|
|
107
|
+
catch_exceptions=False,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
assert result.exit_code == 0, result.output
|
|
111
|
+
assert Path("backend/VERSION").read_text(encoding="utf-8").strip() == "3.3.3"
|
|
112
|
+
assert Path("frontend/VERSION").read_text(encoding="utf-8").strip() == "2.0.0"
|
|
113
|
+
|
|
114
|
+
manifest = yaml.safe_load(Path(".redeploy/version.yaml").read_text(encoding="utf-8"))
|
|
115
|
+
assert manifest["version"]["packages"]["backend"]["version"] == "3.3.3"
|
|
116
|
+
assert manifest["version"]["packages"]["frontend"]["version"] == "2.0.0"
|
|
117
|
+
assert manifest["version"]["version"] == "0.0.0"
|
|
118
|
+
|
|
119
|
+
def test_set_all_packages_updates_all_packages(self, tmp_path):
|
|
120
|
+
runner = _runner()
|
|
121
|
+
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
122
|
+
_write_monorepo_version_workspace(Path.cwd())
|
|
123
|
+
|
|
124
|
+
result = runner.invoke(
|
|
125
|
+
cli,
|
|
126
|
+
["version", "set", "4.4.4", "--all-packages"],
|
|
127
|
+
catch_exceptions=False,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
assert result.exit_code == 0, result.output
|
|
131
|
+
assert Path("backend/VERSION").read_text(encoding="utf-8").strip() == "4.4.4"
|
|
132
|
+
assert Path("frontend/VERSION").read_text(encoding="utf-8").strip() == "4.4.4"
|
|
133
|
+
|
|
134
|
+
manifest = yaml.safe_load(Path(".redeploy/version.yaml").read_text(encoding="utf-8"))
|
|
135
|
+
assert manifest["version"]["packages"]["backend"]["version"] == "4.4.4"
|
|
136
|
+
assert manifest["version"]["packages"]["frontend"]["version"] == "4.4.4"
|
|
137
|
+
|
|
138
|
+
def test_set_package_dry_run_does_not_modify_monorepo(self, tmp_path):
|
|
139
|
+
runner = _runner()
|
|
140
|
+
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
141
|
+
_write_monorepo_version_workspace(Path.cwd())
|
|
142
|
+
|
|
143
|
+
result = runner.invoke(
|
|
144
|
+
cli,
|
|
145
|
+
["version", "set", "5.5.5", "--package", "backend", "--dry-run"],
|
|
146
|
+
catch_exceptions=False,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
assert result.exit_code == 0, result.output
|
|
150
|
+
assert "Would set backend: 1.0.0 → 5.5.5" in result.output
|
|
151
|
+
assert Path("backend/VERSION").read_text(encoding="utf-8").strip() == "1.0.0"
|
|
152
|
+
assert Path("frontend/VERSION").read_text(encoding="utf-8").strip() == "2.0.0"
|
|
153
|
+
|
|
64
154
|
|
|
65
155
|
class TestVersionDiff:
|
|
66
156
|
def test_diff_spec_match_returns_zero(self, tmp_path):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redeploy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -26,17 +26,17 @@ Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
|
26
26
|
|
|
27
27
|
## AI Cost Tracking
|
|
28
28
|
|
|
29
|
-
    
|
|
30
|
+
  
|
|
31
31
|
|
|
32
|
-
- 🤖 **LLM usage:** $3.
|
|
33
|
-
- 👤 **Human dev:** ~$
|
|
32
|
+
- 🤖 **LLM usage:** $3.4500 (23 commits)
|
|
33
|
+
- 👤 **Human dev:** ~$563 (5.6h @ $100/h, 30min dedup)
|
|
34
34
|
|
|
35
35
|
Generated on 2026-04-20 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
39
|
-
    
|
|
40
40
|
|
|
41
41
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
42
42
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|