Skip to content

Commit e0a4f26

Browse files
committed
docs: add server auto deploy design spec
1 parent 7e0f1f1 commit e0a4f26

1 file changed

Lines changed: 204 additions & 0 deletions

File tree

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# ClipSync Server Auto Deploy Design
2+
3+
## Context
4+
5+
ClipSync currently has a Go server in `clipSync-server` and no repository-level CI/CD assets for automated deployment. The deployment target is an existing Linux host at `8.141.100.238`, accessed as `root` over SSH. The current server deployment directory is `/opt/clipSync-server-src`, and the server has already been deployed manually at least once.
6+
7+
The goal of this design is to automate deployment for the server only. Windows and Android delivery remain out of scope. The authoritative runtime behavior of the server remains unchanged: it still reads `configs/config.yaml`, stores SQLite data under `data/`, exposes WebSocket on `8080`, and exposes HTTP API and health checks on `8081`.
8+
9+
## Goal
10+
11+
Create a GitHub Actions based deployment pipeline that automatically deploys `clipSync-server` when code is pushed to the `main` branch. The pipeline must build a Linux binary, upload a release bundle to the target host, replace the deployed server files under `/opt/clipSync-server-src`, overwrite `configs/config.yaml` with the repository version, preserve runtime data under `data/`, restart the existing service, and fail loudly if post-deploy health checks do not pass.
12+
13+
## Non-Goals
14+
15+
- Automating Windows or Android build and release flows
16+
- Introducing Docker or container orchestration
17+
- Redesigning the server runtime layout beyond what is necessary for safe deployment
18+
- Replacing the current server host, deployment path, or service manager
19+
- Changing protocol schemas or application behavior unrelated to deployment
20+
21+
## Deployment Approach
22+
23+
The recommended deployment path is:
24+
25+
1. Trigger on pushes to `main`
26+
2. Run server tests in GitHub Actions from `clipSync-server`
27+
3. Build a Linux `amd64` server binary in GitHub Actions
28+
4. Package the binary, repository deployment script, and repository `configs/config.yaml`
29+
5. Upload the bundle to the target server over SSH/SCP
30+
6. Run a remote deployment script that stages the release, copies updated artifacts into `/opt/clipSync-server-src`, preserves `data/`, overwrites `configs/config.yaml`, restarts the existing service, and performs a health check
31+
32+
This keeps the build environment in GitHub Actions rather than on the production host, which reduces deployment drift and avoids depending on the server to maintain a full Go/CGO toolchain for each release.
33+
34+
## Architecture
35+
36+
### Workflow Trigger and Responsibilities
37+
38+
A GitHub Actions workflow at `.github/workflows/deploy-server.yml` will own the automation entrypoint. It will:
39+
40+
- Trigger on pushes to `main`
41+
- Check out the repository
42+
- Set up Go on Ubuntu
43+
- Run `go test ./... -v -count=1` inside `clipSync-server`
44+
- Build a Linux `amd64` binary for the server
45+
- Assemble a deployment bundle
46+
- Authenticate to the host using repository secrets
47+
- Upload the bundle and execute the deployment script on the host
48+
- Verify deployment success with an HTTP health request
49+
50+
### Release Bundle Contents
51+
52+
The release bundle should be minimal and explicit. It should include:
53+
54+
- The compiled Linux server binary
55+
- The repository version of `clipSync-server/configs/config.yaml`
56+
- The remote deployment script from `scripts/deploy/server-release.sh`
57+
- Release metadata containing the commit SHA and build timestamp for deployment logging
58+
59+
The bundle should not include `data/`, since the server’s runtime data must survive deployments.
60+
61+
### Remote Deployment Script Responsibilities
62+
63+
The remote script will be executed on the target host after upload. It will:
64+
65+
- Extract the bundle into a temporary staging directory
66+
- Validate that required files exist before touching the live directory
67+
- Ensure target subdirectories such as `bin/` and `configs/` exist
68+
- Back up the currently deployed server binary to a previous-version file
69+
- Copy the new server binary into the live deployment directory
70+
- Copy the new `configs/config.yaml` into the live deployment directory
71+
- Leave `data/` untouched
72+
- Restart the configured systemd service
73+
- Run a post-restart health check against `http://127.0.0.1:8081/api/v1/health`
74+
75+
### Health Validation
76+
77+
The deployment is considered successful only if the server comes back healthy after restart. Health validation should happen in two layers:
78+
79+
- On the server, the remote script checks the local health endpoint to confirm the service is up
80+
- In GitHub Actions, the workflow repeats the check against `http://8.141.100.238:8081/api/v1/health` for clear CI visibility after the remote script finishes
81+
82+
If the service fails to restart or the health endpoint does not return success, the workflow must fail.
83+
84+
## Secrets and Environment Contract
85+
86+
The workflow should read deployment-specific values from GitHub Secrets rather than hard-coding them into the repository.
87+
88+
Required secrets:
89+
90+
- `DEPLOY_HOST`: `8.141.100.238`
91+
- `DEPLOY_USER`: `root`
92+
- `DEPLOY_SSH_KEY`: private key contents from `C:\Users\20562\.ssh\id_ed25519`
93+
- `DEPLOY_PATH`: `/opt/clipSync-server-src`
94+
- `DEPLOY_SERVICE_NAME`: existing systemd service name for the server
95+
- `DEPLOY_KNOWN_HOSTS`: server host key entry used for SSH host verification
96+
97+
The workflow may also use non-secret environment variables for values like the local package name or artifact paths.
98+
99+
## Failure Handling and Rollback
100+
101+
The deployment should be fail-fast and minimally recoverable.
102+
103+
### Failure Rules
104+
105+
- If tests fail, deployment does not start
106+
- If the build fails, deployment does not start
107+
- If upload fails, deployment does not modify the target host
108+
- If required bundle files are missing, the remote script exits before touching the live directory
109+
- If service restart fails, the remote script exits with a non-zero code
110+
- If the health check fails after restart, the deployment is marked failed
111+
112+
### Lightweight Rollback
113+
114+
The first version of rollback should focus on the executable rather than full release versioning.
115+
116+
Before replacing the active binary, the remote script should copy the current binary to a backup filename such as `bin/clipsync-server.prev`. If the new binary fails to restart cleanly or health checks fail, the script should attempt to restore the previous binary and restart the service once more.
117+
118+
This keeps the implementation small while still giving the deployment path a practical recovery mechanism.
119+
120+
## Testing Strategy
121+
122+
Testing should validate both code correctness and deployment script safety.
123+
124+
### CI Validation
125+
126+
- Run the existing Go test suite with `go test ./... -v -count=1`
127+
- Build the Linux binary in the same workflow job or in a dependent deploy job
128+
- Validate release bundle assembly before upload
129+
130+
### Script Validation
131+
132+
The remote deployment script should be written defensively so that the most important behaviors are testable by inspection:
133+
134+
- It must use strict shell flags such as `set -euo pipefail`
135+
- It must validate required environment variables and files
136+
- It must not delete `data/`
137+
- It must restart only the configured service name
138+
- It must fail clearly when health checks do not succeed
139+
140+
If time permits during implementation, a repository-local shell check step can be added to catch basic script issues before deployment.
141+
142+
## Files and Responsibilities
143+
144+
### New Files
145+
146+
- `.github/workflows/deploy-server.yml`
147+
- Defines the CI/CD pipeline for test, build, package, upload, and deploy
148+
- `scripts/deploy/server-release.sh`
149+
- Executes the remote staging, copy, restart, rollback, and health check flow
150+
- `docs/deployment/github-actions-server.md`
151+
- Documents required GitHub secrets, first-time server setup expectations, and how to operate the deployment pipeline
152+
153+
### Existing Files Touched
154+
155+
- `clipSync-server/configs/config.yaml`
156+
- Not structurally changed by the deployment feature, but explicitly included in the release bundle and overwritten on the server during deployment
157+
158+
## Operational Assumptions
159+
160+
- The target host is Linux and reachable from GitHub Actions over SSH
161+
- `/opt/clipSync-server-src` already exists on the server
162+
- The existing server is managed by systemd
163+
- The systemd service already runs from `/opt/clipSync-server-src`
164+
- The service has permission to read `configs/config.yaml` and write under `data/`
165+
- The health endpoint remains available at `/api/v1/health` on port `8081`
166+
167+
## Risks and Mitigations
168+
169+
### Unknown systemd service name
170+
171+
Risk: the repository currently does not document the actual service name.
172+
173+
Mitigation: treat the service name as a required GitHub Secret and document it clearly.
174+
175+
### Overwriting repository config into production
176+
177+
Risk: production settings can be unintentionally replaced by a development-oriented config file.
178+
179+
Mitigation: document this behavior explicitly and require the repository `config.yaml` to be production-safe before enabling automatic deployment.
180+
181+
### SQLite runtime continuity
182+
183+
Risk: accidental removal of `data/` would destroy runtime state.
184+
185+
Mitigation: the deployment script must never delete or replace `data/`, and the spec makes that preservation requirement explicit.
186+
187+
### CGO build reliability
188+
189+
Risk: `go-sqlite3` requires CGO support and can fail in mismatched build setups.
190+
191+
Mitigation: build on `ubuntu-latest` with a native Linux environment rather than relying on Windows cross-compilation shortcuts.
192+
193+
## Success Criteria
194+
195+
The deployment feature is successful when all of the following are true:
196+
197+
- Pushing to `main` triggers the workflow automatically
198+
- The workflow runs server tests before deployment
199+
- The workflow produces a Linux server binary and uploads a release bundle to the server
200+
- The server deployment updates the binary and `configs/config.yaml` under `/opt/clipSync-server-src`
201+
- The `data/` directory remains intact after deployment
202+
- The existing systemd service restarts successfully
203+
- The post-deploy health endpoint responds successfully
204+
- Setup and maintenance steps are documented in the repository

0 commit comments

Comments
 (0)