git-push-deploy-cli 0.1.0 → 0.1.1

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.
Files changed (43) hide show
  1. package/README.md +66 -121
  2. package/dist/commands/deploy.d.ts +2 -1
  3. package/dist/commands/deploy.d.ts.map +1 -1
  4. package/dist/commands/deploy.js +23 -1
  5. package/dist/commands/deploy.js.map +1 -1
  6. package/dist/commands/init.d.ts +6 -3
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +23 -202
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/logs.d.ts +1 -1
  11. package/dist/commands/logs.d.ts.map +1 -1
  12. package/dist/commands/logs.js +19 -25
  13. package/dist/commands/logs.js.map +1 -1
  14. package/dist/commands/status.d.ts +1 -1
  15. package/dist/commands/status.d.ts.map +1 -1
  16. package/dist/commands/status.js +3 -35
  17. package/dist/commands/status.js.map +1 -1
  18. package/dist/config/types.d.ts +7 -6
  19. package/dist/config/types.d.ts.map +1 -1
  20. package/dist/index.js +6 -12
  21. package/dist/index.js.map +1 -1
  22. package/dist/utils/shell.d.ts +6 -0
  23. package/dist/utils/shell.d.ts.map +1 -1
  24. package/dist/utils/shell.js +9 -0
  25. package/dist/utils/shell.js.map +1 -1
  26. package/package.json +1 -1
  27. package/dist/commands/install.d.ts +0 -10
  28. package/dist/commands/install.d.ts.map +0 -1
  29. package/dist/commands/install.js +0 -67
  30. package/dist/commands/install.js.map +0 -1
  31. package/dist/utils/pm2.d.ts +0 -39
  32. package/dist/utils/pm2.d.ts.map +0 -1
  33. package/dist/utils/pm2.js +0 -83
  34. package/dist/utils/pm2.js.map +0 -1
  35. package/dist/utils/process-manager.d.ts +0 -37
  36. package/dist/utils/process-manager.d.ts.map +0 -1
  37. package/dist/utils/process-manager.js +0 -17
  38. package/dist/utils/process-manager.js.map +0 -1
  39. package/dist/utils/systemd.d.ts +0 -34
  40. package/dist/utils/systemd.d.ts.map +0 -1
  41. package/dist/utils/systemd.js +0 -79
  42. package/dist/utils/systemd.js.map +0 -1
  43. package/templates/post-receive.sh +0 -55
package/README.md CHANGED
@@ -1,30 +1,24 @@
1
1
  # git-push-deploy-cli (gpd)
2
2
 
3
- Git Push Deploy - A CLI for git-based deployments with PM2/systemd support. Push to deploy Node.js applications using bare git repositories and post-receive hooks.
3
+ Git Push Deploy - A CLI for git-based deployments with PM2 support. Push to deploy Node.js applications via SSH.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Git-based deployment**: Push to deploy using bare repositories
8
- - **PM2 integration**: Automatic process management and restarts
7
+ - **Git-based deployment**: Push to bare repo, SSH triggers install
8
+ - **PM2 integration**: Automatic process restarts
9
9
  - **Monorepo support**: Stage multiple packages for deployment
10
- - **Cross-platform**: Works on Linux servers and Windows/Mac dev machines
10
+ - **SSH orchestration**: Everything runs from your dev machine
11
11
  - **Config-driven**: Define services in `.git-deploy.json`
12
12
 
13
13
  ## Installation
14
14
 
15
15
  ```bash
16
- # Global installation (recommended for servers)
17
16
  npm install -g git-push-deploy-cli
18
-
19
- # Or use npx
20
- npx git-push-deploy-cli <command>
21
17
  ```
22
18
 
23
19
  ## Quick Start
24
20
 
25
- ### 1. Create config file
26
-
27
- Create `.git-deploy.json` in your workspace root:
21
+ ### 1. Create `.git-deploy.json` in your workspace root:
28
22
 
29
23
  ```json
30
24
  {
@@ -33,11 +27,13 @@ Create `.git-deploy.json` in your workspace root:
33
27
  "packages": ["my-api"],
34
28
  "mainPackage": "my-api",
35
29
  "deployRepo": "../deploy-my-api",
36
- "pm2Name": "my-api",
30
+ "processName": "my-api",
31
+ "pm2Home": "/opt/myapp/.pm2",
32
+ "artifacts": ["dist", "package.json", "package-lock.json", "ecosystem.config.cjs"],
37
33
  "server": {
34
+ "host": "user@myserver",
38
35
  "targetDir": "/opt/myapp/my-api",
39
- "bareRepo": "/git/deploy-my-api",
40
- "user": "myapp"
36
+ "bareRepo": "/git/deploy-my-api"
41
37
  }
42
38
  }
43
39
  }
@@ -47,140 +43,89 @@ Create `.git-deploy.json` in your workspace root:
47
43
  ### 2. Initialize server (once per service)
48
44
 
49
45
  ```bash
50
- # On the server
51
- sudo gpd init my-api
46
+ gpd init my-api
52
47
  ```
53
48
 
54
- This creates:
49
+ This creates via SSH:
55
50
  - Bare git repository at `/git/deploy-my-api`
56
- - Post-receive hook for automatic deployment
57
- - Log file at `/var/log/deploy-my-api.log`
58
- - Unix group `deploy-my-api` with appropriate permissions
51
+ - Clone at `/opt/myapp/my-api`
59
52
 
60
- ### 3. Deploy from dev machine
53
+ ### 3. Deploy
61
54
 
62
55
  ```bash
63
- # Build, stage, and push
64
56
  gpd deploy my-api
65
-
66
- # Or step by step:
67
- gpd stage my-api # Copy build artifacts to deploy repo
68
- gpd release my-api # Commit and push
69
57
  ```
70
58
 
71
- ## Commands
59
+ This:
60
+ 1. Copies build artifacts to local deploy repo
61
+ 2. Commits and pushes to bare repo on server
62
+ 3. SSH: `git pull && npm install && pm2 restart`
72
63
 
73
- ### Development Commands
64
+ ## Commands
74
65
 
75
66
  | Command | Description |
76
67
  |---------|-------------|
68
+ | `gpd status` | Show all configured services |
77
69
  | `gpd stage <service>` | Copy build artifacts to deploy repo |
78
70
  | `gpd release <service>` | Commit and push deploy repo |
79
- | `gpd deploy <service>` | Stage + release in one step |
80
-
81
- ### Server Commands
82
-
83
- | Command | Description |
84
- |---------|-------------|
85
- | `gpd init <service>` | Initialize bare repo, hook, and permissions |
86
- | `gpd install <service>` | Extract, npm install, pm2 restart (used by hook) |
87
- | `gpd status` | Show all services and PM2 status |
88
- | `gpd logs <service>` | Show deployment logs |
71
+ | `gpd deploy <service>` | Stage + release + SSH install |
72
+ | `gpd init <service>` | Initialize bare repo and clone on server |
73
+ | `gpd logs <service>` | Show PM2 logs from server via SSH |
89
74
 
90
- ## Configuration
75
+ ## Options
91
76
 
92
- ### .git-deploy.json
77
+ ```bash
78
+ gpd deploy my-api -m "custom commit message"
79
+ gpd deploy my-api --skip-remote # Only stage and release, no SSH
80
+ gpd logs my-api -f # Follow logs
81
+ gpd logs my-api -n 100 # Show last 100 lines
82
+ ```
93
83
 
94
- ```json
95
- {
96
- "services": {
97
- "<service-name>": {
98
- "packages": ["pkg1", "pkg2"],
99
- "mainPackage": "pkg1",
100
- "deployRepo": "../deploy-<service>",
101
- "pm2Name": "<pm2-process-name>",
102
- "pm2Home": "/opt/myapp/.pm2",
103
- "artifacts": ["dist", "package.json", "package-lock.json"],
104
- "server": {
105
- "targetDir": "/opt/myapp/<service>",
106
- "bareRepo": "/git/deploy-<service>",
107
- "user": "myapp",
108
- "group": "deploy-<service>"
109
- }
110
- }
111
- }
84
+ ## Config Reference
85
+
86
+ ```typescript
87
+ interface ServiceConfig {
88
+ packages: string[]; // Packages to deploy (monorepo)
89
+ mainPackage: string; // Package with ecosystem.config.cjs
90
+ deployRepo: string; // Local deploy repo path
91
+ processName: string; // PM2 process name
92
+ pm2Home?: string; // PM2_HOME on server
93
+ artifacts?: string[]; // Files to copy (default: dist, package.json, etc.)
94
+ server: {
95
+ host: string; // SSH host (user@hostname)
96
+ targetDir: string; // Clone directory on server
97
+ bareRepo: string; // Bare repo path on server
98
+ };
112
99
  }
113
100
  ```
114
101
 
115
- ### Configuration Options
116
-
117
- | Option | Required | Description |
118
- |--------|----------|-------------|
119
- | `packages` | Yes | Packages to deploy (monorepo support) |
120
- | `mainPackage` | Yes | Package with package.json for npm install |
121
- | `deployRepo` | Yes | Path to local deploy repository |
122
- | `pm2Name` | Yes | PM2 process name |
123
- | `pm2Home` | No | PM2 home directory (default: ~/.pm2) |
124
- | `artifacts` | No | Files/dirs to copy (default: dist, package.json, package-lock.json) |
125
- | `server.targetDir` | Yes | Where to install on server |
126
- | `server.bareRepo` | Yes | Path to bare git repo on server |
127
- | `server.user` | No | Unix user for file ownership |
128
- | `server.group` | No | Unix group (default: deploy-<service>) |
129
-
130
- ## How It Works
102
+ ## Workflow
131
103
 
132
104
  ```
133
- [Dev Machine] [Server]
134
- │ │
135
- │ npm run build │
136
-
137
- ┌─────────────┐ │
138
- dist/ │ │
139
- package.json│ │
140
- └─────────────┘ │
141
-
142
- git-deploy stage
143
- ▼ │
144
- ┌─────────────┐ │
145
- deploy-repo/│ │
146
- │ └─ my-api/ │ │
147
- └─────────────┘ │
148
- │ │
149
- │ git-deploy release │
150
- │ (git push) │
151
- ▼ ▼
152
- ─────────────────────►
153
- ┌─────────────┐
154
- │ bare repo │
155
- │ post-receive│
156
- └─────────────┘
157
-
158
- │ git-deploy install
159
-
160
- ┌─────────────┐
161
- │ /opt/myapp/ │
162
- │ npm install │
163
- │ pm2 restart │
164
- └─────────────┘
165
- ```
166
-
167
- ## Integration with npm scripts
168
-
169
- ```json
170
- {
171
- "scripts": {
172
- "predeploy": "npm version patch && npm run build",
173
- "deploy": "gpd deploy my-api"
174
- }
175
- }
105
+ Dev Machine Server
106
+ ─────────── ──────
107
+ gpd deploy my-api
108
+
109
+ ├─ gpd stage
110
+ └─ Copy artifacts → ../deploy-my-api/
111
+
112
+ ├─ gpd release
113
+ └─ git push ──────────────────→ /git/deploy-my-api (bare)
114
+
115
+ └─ SSH ────────────────────────────→ cd /opt/myapp/my-api
116
+ git pull
117
+ npm install --omit=dev
118
+ pm2 restart my-api
176
119
  ```
177
120
 
178
- ## Requirements
121
+ ## Server Prerequisites
179
122
 
180
- - Node.js >= 18
123
+ - Node.js + npm
124
+ - PM2 (`npm install -g pm2`)
125
+ - SSH access from dev machine
181
126
  - Git
182
- - PM2 (on server)
183
- - Linux server (Debian, Ubuntu, Raspberry Pi OS, etc.)
127
+
128
+ No gpd installation needed on the server!
184
129
 
185
130
  ## License
186
131
 
@@ -1,8 +1,9 @@
1
1
  interface DeployOptions {
2
2
  message?: string;
3
+ skipRemote?: boolean;
3
4
  }
4
5
  /**
5
- * Deploy command - stage and release in one step
6
+ * Deploy command - stage, release, and trigger remote install
6
7
  */
7
8
  export declare function deployCommand(serviceName: string, options?: DeployOptions): Promise<void>;
8
9
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnG"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAMA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BnG"}
@@ -1,10 +1,32 @@
1
+ import chalk from 'chalk';
1
2
  import { stageCommand } from './stage.js';
2
3
  import { releaseCommand } from './release.js';
4
+ import { getServiceConfig } from '../config/loader.js';
5
+ import { sshExec } from '../utils/shell.js';
3
6
  /**
4
- * Deploy command - stage and release in one step
7
+ * Deploy command - stage, release, and trigger remote install
5
8
  */
6
9
  export async function deployCommand(serviceName, options = {}) {
10
+ // 1. Stage artifacts
7
11
  await stageCommand(serviceName);
12
+ // 2. Commit and push
8
13
  await releaseCommand(serviceName, options);
14
+ // 3. Trigger remote install via SSH
15
+ if (!options.skipRemote) {
16
+ const config = getServiceConfig(serviceName);
17
+ const { host, targetDir } = config.server;
18
+ const { mainPackage, processName, pm2Home } = config;
19
+ console.log(chalk.blue(`Installing on ${host}...`));
20
+ const pm2Env = pm2Home ? `PM2_HOME=${pm2Home} ` : '';
21
+ const remoteCmd = [
22
+ `cd ${targetDir}`,
23
+ 'git pull --ff-only',
24
+ `cd ${mainPackage}`,
25
+ 'npm install --omit=dev',
26
+ `${pm2Env}pm2 restart ecosystem.config.cjs`
27
+ ].join(' && ');
28
+ sshExec(host, remoteCmd);
29
+ console.log(chalk.green(`✓ Deployed ${serviceName} to ${host}`));
30
+ }
9
31
  }
10
32
  //# sourceMappingURL=deploy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM9C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,UAAyB,EAAE;IAClF,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;IAChC,MAAM,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAO5C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,UAAyB,EAAE;IAClF,qBAAqB;IACrB,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;IAEhC,qBAAqB;IACrB,MAAM,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAE3C,oCAAoC;IACpC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC;QAC1C,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAErD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG;YAChB,MAAM,SAAS,EAAE;YACjB,oBAAoB;YACpB,MAAM,WAAW,EAAE;YACnB,wBAAwB;YACxB,GAAG,MAAM,kCAAkC;SAC5C,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEf,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,WAAW,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;AACH,CAAC"}
@@ -1,9 +1,12 @@
1
1
  interface InitOptions {
2
- users?: string;
3
2
  }
4
3
  /**
5
- * Init command - initialize bare repo, hook, and permissions on server
4
+ * Init command - initialize bare repo and clone on remote server via SSH
5
+ *
6
+ * Creates:
7
+ * 1. Bare repo at server.bareRepo (e.g., /git/sym/deploy-kairox-api)
8
+ * 2. Clone at server.targetDir (e.g., /opt/kairox/kairox-api)
6
9
  */
7
- export declare function initCommand(serviceName: string, options?: InitOptions): Promise<void>;
10
+ export declare function initCommand(serviceName: string, _options?: InitOptions): Promise<void>;
8
11
  export {};
9
12
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmID;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqF/F"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;CAEpB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhG"}
@@ -1,212 +1,33 @@
1
1
  import chalk from 'chalk';
2
- import { writeFileSync, chmodSync } from 'fs';
3
2
  import { getServiceConfig } from '../config/loader.js';
4
- import { exec, isRoot } from '../utils/shell.js';
5
- import { ensureDir, exists, joinPath } from '../utils/files.js';
6
- import { initBareRepo } from '../utils/git.js';
3
+ import { sshExec } from '../utils/shell.js';
7
4
  /**
8
- * Generate post-receive hook content
5
+ * Init command - initialize bare repo and clone on remote server via SSH
6
+ *
7
+ * Creates:
8
+ * 1. Bare repo at server.bareRepo (e.g., /git/sym/deploy-kairox-api)
9
+ * 2. Clone at server.targetDir (e.g., /opt/kairox/kairox-api)
9
10
  */
10
- function generateHook(serviceName, config) {
11
- const { server, packages, mainPackage, processName, processManager = 'pm2', pm2Home } = config;
12
- // Generate hook based on process manager type
13
- if (processManager === 'systemd') {
14
- return generateSystemdHook(serviceName, config);
15
- }
16
- // Default: PM2 hook
17
- const pm2Env = pm2Home ? `PM2_HOME=${pm2Home} ` : '';
18
- return `#!/bin/bash
19
- # Post-receive hook for ${serviceName}
20
- # Generated by git-deploy-cli
21
- # Process Manager: pm2
22
-
23
- set -e
24
-
25
- SERVICE="${serviceName}"
26
- TARGET_DIR="${server.targetDir}"
27
- LOG_FILE="/var/log/deploy-${serviceName}.log"
28
- PROCESS_NAME="${processName}"
29
- PACKAGES=(${packages.map(p => `"${p}"`).join(' ')})
30
- MAIN_PKG="${mainPackage}"
31
- USER="${server.user || 'root'}"
32
-
33
- log() {
34
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | sudo tee -a "$LOG_FILE"
35
- }
36
-
37
- log "=== Deployment started ==="
38
-
39
- while read oldrev newrev refname; do
40
- BRANCH=$(echo "$refname" | sed 's|refs/heads/||')
41
- log "Received push to branch: $BRANCH"
42
-
43
- if [ "$BRANCH" != "main" ] && [ "$BRANCH" != "master" ]; then
44
- log "Ignoring non-main branch"
45
- continue
46
- fi
47
-
48
- # Extract packages using git archive
49
- for pkg in "\${PACKAGES[@]}"; do
50
- log "Extracting $pkg..."
51
- git archive "$BRANCH" "$pkg/" 2>/dev/null | sudo tar -x -C "$TARGET_DIR/" || true
52
- done
53
-
54
- # Install dependencies
55
- log "Installing dependencies..."
56
- cd "$TARGET_DIR/$MAIN_PKG"
57
- sudo -u $USER npm install --omit=dev 2>&1 | sudo tee -a "$LOG_FILE"
58
-
59
- # Restart PM2
60
- log "Restarting $PROCESS_NAME..."
61
- sudo -u $USER ${pm2Env}pm2 restart "$PROCESS_NAME" --no-color 2>&1 | sudo tee -a "$LOG_FILE"
62
-
63
- log "Current status:"
64
- sudo -u $USER ${pm2Env}pm2 list --no-color 2>&1 | sudo tee -a "$LOG_FILE"
65
- done
66
-
67
- log "=== Deployment completed ==="
68
- `;
69
- }
70
- /**
71
- * Generate systemd-specific hook
72
- */
73
- function generateSystemdHook(serviceName, config) {
74
- const { server, packages, mainPackage, processName } = config;
75
- return `#!/bin/bash
76
- # Post-receive hook for ${serviceName}
77
- # Generated by git-deploy-cli
78
- # Process Manager: systemd
79
-
80
- set -e
81
-
82
- SERVICE="${serviceName}"
83
- TARGET_DIR="${server.targetDir}"
84
- LOG_FILE="/var/log/deploy-${serviceName}.log"
85
- PROCESS_NAME="${processName}"
86
- PACKAGES=(${packages.map(p => `"${p}"`).join(' ')})
87
- MAIN_PKG="${mainPackage}"
88
- USER="${server.user || 'root'}"
89
-
90
- log() {
91
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | sudo tee -a "$LOG_FILE"
92
- }
93
-
94
- log "=== Deployment started ==="
95
-
96
- while read oldrev newrev refname; do
97
- BRANCH=$(echo "$refname" | sed 's|refs/heads/||')
98
- log "Received push to branch: $BRANCH"
99
-
100
- if [ "$BRANCH" != "main" ] && [ "$BRANCH" != "master" ]; then
101
- log "Ignoring non-main branch"
102
- continue
103
- fi
104
-
105
- # Extract packages using git archive
106
- for pkg in "\${PACKAGES[@]}"; do
107
- log "Extracting $pkg..."
108
- git archive "$BRANCH" "$pkg/" 2>/dev/null | sudo tar -x -C "$TARGET_DIR/" || true
109
- done
110
-
111
- # Set ownership
112
- sudo chown -R $USER:$USER "$TARGET_DIR"
113
-
114
- # Install dependencies
115
- log "Installing dependencies..."
116
- cd "$TARGET_DIR/$MAIN_PKG"
117
- sudo -u $USER npm install --omit=dev 2>&1 | sudo tee -a "$LOG_FILE"
118
-
119
- # Restart systemd service
120
- log "Restarting $PROCESS_NAME..."
121
- sudo systemctl restart "$PROCESS_NAME" 2>&1 | sudo tee -a "$LOG_FILE"
122
-
123
- log "Current status:"
124
- sudo systemctl status "$PROCESS_NAME" --no-pager 2>&1 | sudo tee -a "$LOG_FILE" || true
125
- done
126
-
127
- log "=== Deployment completed ==="
128
- `;
129
- }
130
- /**
131
- * Init command - initialize bare repo, hook, and permissions on server
132
- */
133
- export async function initCommand(serviceName, options = {}) {
11
+ export async function initCommand(serviceName, _options = {}) {
134
12
  console.log(chalk.blue(`Initializing ${serviceName}...`));
135
- // Check root
136
- if (!isRoot()) {
137
- console.error(chalk.red('Error: init command requires root privileges. Run with sudo.'));
138
- process.exit(1);
139
- }
140
13
  const config = getServiceConfig(serviceName);
141
- const { server } = config;
142
- const groupName = server.group || `deploy-${serviceName}`;
143
- const logFile = `/var/log/deploy-${serviceName}.log`;
144
- // 1. Create group
145
- console.log(chalk.gray(` Creating group ${groupName}...`));
146
- try {
147
- exec(`groupadd ${groupName}`, { silent: true });
148
- }
149
- catch {
150
- console.log(chalk.gray(` Group ${groupName} already exists`));
151
- }
152
- // 2. Add users to group
153
- if (options.users) {
154
- const users = options.users.split(',').map(u => u.trim());
155
- for (const user of users) {
156
- console.log(chalk.gray(` Adding user ${user} to group...`));
157
- try {
158
- exec(`usermod -aG ${groupName} ${user}`, { silent: true });
159
- }
160
- catch {
161
- console.log(chalk.yellow(` Warning: Could not add user ${user}`));
162
- }
163
- }
164
- }
165
- // Add service user if configured
166
- if (server.user) {
167
- console.log(chalk.gray(` Adding service user ${server.user} to group...`));
168
- try {
169
- exec(`usermod -aG ${groupName} ${server.user}`, { silent: true });
170
- }
171
- catch {
172
- console.log(chalk.yellow(` Warning: Could not add user ${server.user}`));
173
- }
174
- }
175
- // 3. Create bare repo
176
- console.log(chalk.gray(` Creating bare repo at ${server.bareRepo}...`));
177
- if (!exists(server.bareRepo)) {
178
- ensureDir(server.bareRepo);
179
- initBareRepo(server.bareRepo);
180
- }
181
- else {
182
- console.log(chalk.gray(` Repo already exists`));
183
- }
184
- // 4. Create post-receive hook
185
- const hookPath = joinPath(server.bareRepo, 'hooks', 'post-receive');
186
- console.log(chalk.gray(` Creating post-receive hook...`));
187
- const hookContent = generateHook(serviceName, config);
188
- writeFileSync(hookPath, hookContent);
189
- chmodSync(hookPath, 0o755);
190
- // 5. Create target directory
191
- console.log(chalk.gray(` Creating target directory ${server.targetDir}...`));
192
- ensureDir(server.targetDir);
193
- if (server.user) {
194
- exec(`chown -R ${server.user}:${server.user} ${server.targetDir}`, { silent: true });
195
- }
196
- // 6. Create log file
197
- console.log(chalk.gray(` Creating log file ${logFile}...`));
198
- exec(`touch ${logFile}`, { silent: true });
199
- exec(`chown root:${groupName} ${logFile}`, { silent: true });
200
- exec(`chmod 664 ${logFile}`, { silent: true });
201
- // 7. Set repo permissions
202
- exec(`chown -R root:${groupName} ${server.bareRepo}`, { silent: true });
203
- exec(`chmod -R g+rwX ${server.bareRepo}`, { silent: true });
14
+ const { host, bareRepo, targetDir } = config.server;
15
+ console.log(chalk.gray(` Host: ${host}`));
16
+ console.log(chalk.gray(` Bare repo: ${bareRepo}`));
17
+ console.log(chalk.gray(` Target dir: ${targetDir}`));
18
+ // 1. Create bare repo
19
+ console.log(chalk.gray(` Creating bare repo...`));
20
+ const createBareCmd = `mkdir -p ${bareRepo} && cd ${bareRepo} && git init --bare`;
21
+ sshExec(host, createBareCmd);
22
+ // 2. Create target directory and clone
23
+ console.log(chalk.gray(` Creating clone at target...`));
24
+ const parentDir = targetDir.split('/').slice(0, -1).join('/');
25
+ const cloneName = targetDir.split('/').pop();
26
+ const cloneCmd = `mkdir -p ${parentDir} && cd ${parentDir} && git clone ${bareRepo} ${cloneName} 2>/dev/null || (cd ${targetDir} && git pull)`;
27
+ sshExec(host, cloneCmd);
204
28
  console.log(chalk.green(`✓ Initialized ${serviceName}`));
205
29
  console.log('');
206
- console.log(chalk.gray('Next steps:'));
207
- console.log(chalk.gray(` 1. On dev machine, add remote:`));
208
- console.log(chalk.white(` git remote add deploy ssh://server${server.bareRepo}`));
209
- console.log(chalk.gray(` 2. Push to trigger deployment:`));
210
- console.log(chalk.white(` git push deploy main`));
30
+ console.log(chalk.gray('Server setup complete. Now you can deploy:'));
31
+ console.log(chalk.white(` gpd deploy ${serviceName}`));
211
32
  }
212
33
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAM5C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,WAAmB,EAAE,WAAwB,EAAE;IAC/E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,KAAK,CAAC,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC;IAEpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,SAAS,EAAE,CAAC,CAAC,CAAC;IAEtD,sBAAsB;IACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,YAAY,QAAQ,UAAU,QAAQ,qBAAqB,CAAC;IAClF,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAE7B,uCAAuC;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,YAAY,SAAS,UAAU,SAAS,iBAAiB,QAAQ,IAAI,SAAS,uBAAuB,SAAS,eAAe,CAAC;IAC/I,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAExB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,WAAW,EAAE,CAAC,CAAC,CAAC;AAC1D,CAAC"}
@@ -3,7 +3,7 @@ interface LogsOptions {
3
3
  follow?: boolean;
4
4
  }
5
5
  /**
6
- * Logs command - show deployment logs
6
+ * Logs command - show PM2 logs from server via SSH
7
7
  */
8
8
  export declare function logsCommand(serviceName: string, options?: LogsOptions): Promise<void>;
9
9
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAMA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC/F"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC/F"}