Initial commit: add AutoDeploy project
This commit is contained in:
63
docs/superpowers/plans/2026-07-02-deploy-tool-workbench.md
Normal file
63
docs/superpowers/plans/2026-07-02-deploy-tool-workbench.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Deploy Tool Workbench Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Build a Python tkinter workbench for detecting and deploying Spring Boot + Vue separated projects.
|
||||
|
||||
**Architecture:** Core logic lives in testable modules for scanning, environment checks, and deployment planning. The GUI imports those modules and presents their results in a left-nav workbench with dashboard cards, settings, and logs.
|
||||
|
||||
**Tech Stack:** Python 3 standard library, tkinter/ttk, unittest.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Core Project Scanner
|
||||
|
||||
**Files:**
|
||||
- Create: `deploy_tool/scanner.py`
|
||||
- Test: `tests/test_scanner.py`
|
||||
|
||||
- [ ] Write tests for detecting backend, frontend, and SQL files from temporary folders.
|
||||
- [ ] Run `python -m unittest tests.test_scanner` and verify tests fail because the module does not exist.
|
||||
- [ ] Implement scanner dataclasses and `scan_project`.
|
||||
- [ ] Run `python -m unittest tests.test_scanner` and verify pass.
|
||||
|
||||
### Task 2: Environment Checks
|
||||
|
||||
**Files:**
|
||||
- Create: `deploy_tool/environment.py`
|
||||
- Test: `tests/test_environment.py`
|
||||
|
||||
- [ ] Write tests using an injected command runner for installed and missing commands.
|
||||
- [ ] Run `python -m unittest tests.test_environment` and verify tests fail because the module does not exist.
|
||||
- [ ] Implement environment check result types and command checks.
|
||||
- [ ] Run `python -m unittest tests.test_environment` and verify pass.
|
||||
|
||||
### Task 3: Deployment Plan
|
||||
|
||||
**Files:**
|
||||
- Create: `deploy_tool/deployer.py`
|
||||
- Test: `tests/test_deployer.py`
|
||||
|
||||
- [ ] Write tests that generate backend, frontend, and SQL deployment command steps.
|
||||
- [ ] Run `python -m unittest tests.test_deployer` and verify tests fail because the module does not exist.
|
||||
- [ ] Implement `build_deployment_plan`.
|
||||
- [ ] Run `python -m unittest tests.test_deployer` and verify pass.
|
||||
|
||||
### Task 4: Workbench GUI
|
||||
|
||||
**Files:**
|
||||
- Create: `deploy_tool/gui.py`
|
||||
- Create: `main.py`
|
||||
|
||||
- [ ] Implement tkinter layout with sidebar, top action bar, dashboard cards, config form, and log output.
|
||||
- [ ] Wire folder selection, scan, environment check, and deployment plan preview.
|
||||
- [ ] Keep long operations on background threads and push messages to the UI queue.
|
||||
|
||||
### Task 5: Documentation and Verification
|
||||
|
||||
**Files:**
|
||||
- Create: `README.md`
|
||||
|
||||
- [ ] Document usage, features, and current local-only deployment scope.
|
||||
- [ ] Run `python -m unittest`.
|
||||
- [ ] Run `python -m py_compile main.py deploy_tool/*.py`.
|
||||
44
docs/superpowers/plans/2026-07-03-local-auto-deploy.md
Normal file
44
docs/superpowers/plans/2026-07-03-local-auto-deploy.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Local Auto Deploy Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Turn the local deployment flow from a partly executable command preview into an automatic local deploy runner.
|
||||
|
||||
**Architecture:** Keep plan generation in `deploy_tool/deployer.py`, but make deployment steps typed so commands that need runtime context can run without shell placeholders. The runner will build backend and frontend, copy frontend artifacts to the output directory, import SQL through stdin, locate the built jar, and start the backend process.
|
||||
|
||||
**Tech Stack:** Python standard library, `unittest`, `subprocess`, `pathlib`, `shutil`.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Deployment Step Model
|
||||
|
||||
**Files:**
|
||||
- Modify: `deploy_tool/deployer.py`
|
||||
- Test: `tests/test_deployer.py`
|
||||
|
||||
- [x] Add tests showing SQL import steps no longer contain shell redirection and backend start no longer contains jar placeholders.
|
||||
- [x] Add fields to `DeploymentStep` for `kind` and optional artifact metadata.
|
||||
- [x] Update `build_deployment_plan` to emit executable step metadata.
|
||||
- [x] Run `python -m unittest tests.test_deployer`.
|
||||
|
||||
### Task 2: Automatic Runner
|
||||
|
||||
**Files:**
|
||||
- Modify: `deploy_tool/deployer.py`
|
||||
- Test: `tests/test_deployer.py`
|
||||
|
||||
- [x] Add tests for latest jar discovery under `target` or `build/libs`.
|
||||
- [x] Add tests for frontend artifact copy from `dist` or `build`.
|
||||
- [x] Add tests with an injected process runner to verify SQL stdin and backend startup command.
|
||||
- [x] Implement helper functions and dependency injection points for process execution.
|
||||
- [x] Run `python -m unittest tests.test_deployer`.
|
||||
|
||||
### Task 3: GUI Wording and Verification
|
||||
|
||||
**Files:**
|
||||
- Modify: `deploy_tool/gui.py`
|
||||
- Test: `python -m unittest discover -s tests`
|
||||
|
||||
- [x] Update the confirmation text from partial execution to automatic local deployment.
|
||||
- [x] Run `python -m unittest discover -s tests`.
|
||||
- [x] Run `python -m py_compile main.py @((Get-ChildItem -LiteralPath .\deploy_tool -Filter *.py).FullName)`.
|
||||
@@ -0,0 +1,62 @@
|
||||
# Backend Restart and Health Check Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Restart the process occupying the configured backend port and report deployment success only after the replacement backend is listening.
|
||||
|
||||
**Architecture:** Add testable process/port helpers to `deploy_tool/deployer.py`, then compose them in the existing background runner. Add a main-thread deployment state guard to `deploy_tool/gui.py` so both deploy buttons share one running state.
|
||||
|
||||
**Tech Stack:** Python standard library, `unittest`, Tkinter, Windows `netstat` and `taskkill`.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Listener discovery and process replacement
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/test_deployer.py`
|
||||
- Modify: `deploy_tool/deployer.py`
|
||||
|
||||
- [ ] Add failing tests for server-port extraction and parsing IPv4/IPv6 `netstat` listener rows.
|
||||
- [ ] Run the targeted tests and confirm they fail because the helpers do not exist.
|
||||
- [ ] Implement `_extract_server_port()` and `_parse_windows_listening_pids()`.
|
||||
- [ ] Run the targeted tests and confirm they pass.
|
||||
- [ ] Add a failing test proving listener PIDs are terminated and the port must become free before launch.
|
||||
- [ ] Implement listener lookup, process-tree termination, and bounded port-release polling.
|
||||
- [ ] Run all deployer tests.
|
||||
|
||||
### Task 2: Backend startup readiness
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/test_deployer.py`
|
||||
- Modify: `deploy_tool/deployer.py`
|
||||
|
||||
- [ ] Add failing tests for early child exit, startup timeout cleanup, and successful readiness.
|
||||
- [ ] Run the targeted tests and confirm the current immediate-success behavior fails them.
|
||||
- [ ] Refactor the background runner behind injectable `_restart_backend()` dependencies.
|
||||
- [ ] Add Windows detached-process creation flags and a timestamped log separator.
|
||||
- [ ] Poll child state and TCP readiness; return non-zero on early exit or timeout.
|
||||
- [ ] Run all deployer tests.
|
||||
|
||||
### Task 3: Duplicate GUI deployment guard
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/test_gui_navigation.py`
|
||||
- Modify: `deploy_tool/gui.py`
|
||||
|
||||
- [ ] Add failing tests that a running deployment ignores another invocation and that button state is updated together.
|
||||
- [ ] Run the targeted tests and confirm failure.
|
||||
- [ ] Store both deployment button instances, add `deployment_running`, and centralize button state changes.
|
||||
- [ ] Set the guard before the worker starts and clear it when `deploy_done` is handled.
|
||||
- [ ] Run GUI tests.
|
||||
|
||||
### Task 4: Verification
|
||||
|
||||
**Files:**
|
||||
- Verify: `deploy_tool/deployer.py`
|
||||
- Verify: `deploy_tool/gui.py`
|
||||
- Verify: `tests/test_deployer.py`
|
||||
- Verify: `tests/test_gui_navigation.py`
|
||||
|
||||
- [ ] Run `python -m unittest discover -s tests -p 'test_*.py' -v` and require zero failures.
|
||||
- [ ] Run `python -m compileall -q deploy_tool main.py tests` and require exit code 0.
|
||||
- [ ] Inspect `git diff --check` and the final diff for unrelated changes.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Workbench Deploy Tool Design
|
||||
|
||||
## Goal
|
||||
|
||||
Build a Python desktop tool that helps deploy separated Spring Boot + Vue projects. The user selects one folder, then the tool detects backend, frontend, SQL files, required local environments, configurable deployment settings, and deployment command steps.
|
||||
|
||||
## Interface
|
||||
|
||||
Use a workbench layout:
|
||||
|
||||
- Left navigation for Project, Environment, Database, Deployment, Logs.
|
||||
- Top action bar with folder selection, scan, environment check, and deploy actions.
|
||||
- Main dashboard cards for backend, frontend, SQL, and environment status.
|
||||
- Configuration fields for backend port, frontend build directory, MySQL connection, and deployment output directory.
|
||||
- Log panel for command output and status messages.
|
||||
|
||||
## Architecture
|
||||
|
||||
Use Python standard library only for the first version. Keep business logic outside the GUI:
|
||||
|
||||
- `deploy_tool/scanner.py` detects Spring Boot, Vue, and SQL files.
|
||||
- `deploy_tool/environment.py` checks commands such as Java, Maven, Gradle, Node, npm, Vue CLI, and MySQL.
|
||||
- `deploy_tool/deployer.py` builds deployment steps and can run shell commands with streamed output.
|
||||
- `deploy_tool/gui.py` implements the tkinter/ttk workbench.
|
||||
- `main.py` starts the application.
|
||||
|
||||
## Behavior
|
||||
|
||||
The scanner walks the selected folder and recognizes:
|
||||
|
||||
- Spring Boot backend by `pom.xml`, `build.gradle`, `src/main/java`, and Spring Boot dependency text.
|
||||
- Vue frontend by `package.json` containing Vue dependencies or scripts plus common Vue config files.
|
||||
- SQL files by `.sql` extension.
|
||||
|
||||
Environment checks run non-destructive version commands and report installed/missing states.
|
||||
|
||||
Deployment starts with a dry, visible command plan. The first version focuses on local build/import/start orchestration and clear logs rather than remote server provisioning.
|
||||
|
||||
## Testing
|
||||
|
||||
Use `unittest` from the standard library. Tests cover scanner detection, environment command handling with injected runners, and deployment plan generation.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Backend Restart and Health Check Design
|
||||
|
||||
## Goal
|
||||
|
||||
Make backend deployment deterministic on Windows: replace any process listening on the configured backend port, prevent duplicate GUI deployments, keep the launched Java process alive independently of the deployment window, and report success only after the new backend is actually listening.
|
||||
|
||||
## Confirmed Behavior
|
||||
|
||||
- Before starting the backend, find every process listening on the configured backend port.
|
||||
- Terminate each listener and its child process tree, including listeners not created by this tool.
|
||||
- Log every PID that is terminated and fail the deployment if the port cannot be released.
|
||||
- Do not allow another deployment to start while one is already running.
|
||||
- Report exit code `0` only after the new process remains alive and the configured port accepts TCP connections.
|
||||
- If the process exits early or startup times out, report failure and retain the backend log for diagnosis.
|
||||
|
||||
## Architecture
|
||||
|
||||
Keep process orchestration in `deploy_tool/deployer.py` and GUI state in `deploy_tool/gui.py`. Use only the Python standard library and Windows commands already available on the target machine; do not add a package dependency.
|
||||
|
||||
`deployer.py` will contain small helpers with focused responsibilities:
|
||||
|
||||
- Extract the configured server port from the Java command.
|
||||
- Parse Windows `netstat -ano -p tcp` output to identify listening PIDs.
|
||||
- Terminate a PID tree with `taskkill /PID <pid> /T /F`.
|
||||
- Poll the port until it is released before launch.
|
||||
- Poll the child process and port during startup.
|
||||
- Build Windows creation flags that detach the Java process from the GUI console.
|
||||
|
||||
The existing deployment runner contract remains unchanged: each step returns an integer exit code. A background backend step may wait for readiness, but after readiness it returns while the detached Java process continues running.
|
||||
|
||||
## Deployment Flow
|
||||
|
||||
1. Resolve the backend JAR and configured port as today.
|
||||
2. Query listeners for that port.
|
||||
3. Log and terminate each listener process tree.
|
||||
4. Wait up to 10 seconds for the port to become free. Failure to release the port stops deployment.
|
||||
5. Append a clear deployment separator to `backend.log` and start Java with stdout/stderr redirected to that log.
|
||||
6. On Windows, use `CREATE_NEW_PROCESS_GROUP` and `DETACHED_PROCESS` so closing the GUI does not close the backend console process.
|
||||
7. For up to 60 seconds, poll both `process.poll()` and a TCP connection to `127.0.0.1:<port>`.
|
||||
8. If the process exits before listening, return its non-zero code, or `1` if it exited with code `0` without becoming ready.
|
||||
9. If the port begins accepting connections while the child is alive, log the PID and return `0`.
|
||||
10. If startup times out, terminate the new process tree and return `1`.
|
||||
|
||||
## GUI Behavior
|
||||
|
||||
Both visible deployment buttons will be retained, but both refer to the same deployment-running state.
|
||||
|
||||
- After confirmation and before starting the worker thread, set `deployment_running = True` and disable both buttons.
|
||||
- If deployment is already running, ignore another invocation and add an explanatory log message.
|
||||
- When the `deploy_done` event is handled, clear the flag, restore both buttons, and display the real exit code.
|
||||
|
||||
This state transition occurs on the Tk main thread, so rapid clicks cannot enqueue multiple deployment workers.
|
||||
|
||||
## Error Handling and Logs
|
||||
|
||||
- Failure to enumerate listeners, terminate a listener, release the port, create the Java process, or reach readiness produces a non-zero deployment result.
|
||||
- Log messages identify the affected port and PID without hiding the original backend log.
|
||||
- Historical `backend.log` content is preserved; a timestamped separator distinguishes runs.
|
||||
- The existing MyBatis warning is not treated as a startup failure because readiness is based on process state and TCP availability.
|
||||
|
||||
## Testing
|
||||
|
||||
Use `unittest` and dependency injection or pure helpers so tests do not terminate real processes or occupy real user ports.
|
||||
|
||||
Regression coverage will include:
|
||||
|
||||
- Parsing IPv4 and IPv6 listener rows while ignoring unrelated ports and states.
|
||||
- Terminating all listener PIDs before spawning Java.
|
||||
- Returning failure when the old listener cannot be stopped.
|
||||
- Returning failure when Java exits before opening the port.
|
||||
- Returning failure and cleaning up when startup times out.
|
||||
- Returning success only when Java is alive and the configured port becomes reachable.
|
||||
- Applying Windows detached-process flags.
|
||||
- Ignoring a second GUI deployment while one is active.
|
||||
- Disabling and restoring both GUI deployment buttons around a deployment.
|
||||
|
||||
The full existing test suite must continue to pass.
|
||||
Reference in New Issue
Block a user