git-push-deploy-cli 0.1.0 → 0.2.0

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 (57) hide show
  1. package/README.md +105 -126
  2. package/dist/commands/deploy.d.ts +9 -1
  3. package/dist/commands/deploy.d.ts.map +1 -1
  4. package/dist/commands/deploy.js +29 -2
  5. package/dist/commands/deploy.js.map +1 -1
  6. package/dist/commands/init.d.ts +7 -3
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +90 -166
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/install.d.ts +14 -3
  11. package/dist/commands/install.d.ts.map +1 -1
  12. package/dist/commands/install.js +156 -49
  13. package/dist/commands/install.js.map +1 -1
  14. package/dist/commands/logs.d.ts +1 -1
  15. package/dist/commands/logs.d.ts.map +1 -1
  16. package/dist/commands/logs.js +21 -25
  17. package/dist/commands/logs.js.map +1 -1
  18. package/dist/commands/release.d.ts +2 -0
  19. package/dist/commands/release.d.ts.map +1 -1
  20. package/dist/commands/release.js +7 -5
  21. package/dist/commands/release.js.map +1 -1
  22. package/dist/commands/stage.d.ts +5 -0
  23. package/dist/commands/stage.d.ts.map +1 -1
  24. package/dist/commands/stage.js +58 -22
  25. package/dist/commands/stage.js.map +1 -1
  26. package/dist/commands/status.d.ts +1 -1
  27. package/dist/commands/status.d.ts.map +1 -1
  28. package/dist/commands/status.js +8 -36
  29. package/dist/commands/status.js.map +1 -1
  30. package/dist/config/loader.d.ts +14 -0
  31. package/dist/config/loader.d.ts.map +1 -1
  32. package/dist/config/loader.js +18 -0
  33. package/dist/config/loader.js.map +1 -1
  34. package/dist/config/types.d.ts +52 -13
  35. package/dist/config/types.d.ts.map +1 -1
  36. package/dist/config/types.js +24 -1
  37. package/dist/config/types.js.map +1 -1
  38. package/dist/index.js +17 -16
  39. package/dist/index.js.map +1 -1
  40. package/dist/utils/shell.d.ts +7 -0
  41. package/dist/utils/shell.d.ts.map +1 -1
  42. package/dist/utils/shell.js +10 -0
  43. package/dist/utils/shell.js.map +1 -1
  44. package/package.json +2 -2
  45. package/dist/utils/pm2.d.ts +0 -39
  46. package/dist/utils/pm2.d.ts.map +0 -1
  47. package/dist/utils/pm2.js +0 -83
  48. package/dist/utils/pm2.js.map +0 -1
  49. package/dist/utils/process-manager.d.ts +0 -37
  50. package/dist/utils/process-manager.d.ts.map +0 -1
  51. package/dist/utils/process-manager.js +0 -17
  52. package/dist/utils/process-manager.js.map +0 -1
  53. package/dist/utils/systemd.d.ts +0 -34
  54. package/dist/utils/systemd.d.ts.map +0 -1
  55. package/dist/utils/systemd.js +0 -79
  56. package/dist/utils/systemd.js.map +0 -1
  57. package/templates/post-receive.sh +0 -55
@@ -1,212 +1,136 @@
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
5
  * Generate post-receive hook content
6
+ * The hook simply calls `gpd install <service>` which handles all the logic
9
7
  */
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);
8
+ function generatePostReceiveHook(serviceName, config) {
9
+ const { targetDir, bareRepo, pm2User, pm2Home } = config;
10
+ // Build the install command with sudo if pm2User is specified
11
+ let installCmd = 'gpd install ' + serviceName;
12
+ if (pm2User) {
13
+ // Run gpd as the pm2User
14
+ installCmd = `sudo -u ${pm2User} ${installCmd}`;
15
15
  }
16
- // Default: PM2 hook
17
- const pm2Env = pm2Home ? `PM2_HOME=${pm2Home} ` : '';
18
16
  return `#!/bin/bash
19
- # Post-receive hook for ${serviceName}
20
- # Generated by git-deploy-cli
21
- # Process Manager: pm2
22
-
23
17
  set -e
24
18
 
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
19
+ # GPD post-receive hook for ${serviceName}
20
+ # Generated by: gpd init ${serviceName}
81
21
 
82
22
  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'}"
23
+ TARGET_DIR="${targetDir}"
24
+ GIT_DIR="${bareRepo}"
25
+ LOG_FILE="/var/log/gpd-${serviceName}.log"
89
26
 
90
27
  log() {
91
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | sudo tee -a "$LOG_FILE"
28
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
92
29
  }
93
30
 
94
- log "=== Deployment started ==="
31
+ log "=== Deployment started for $SERVICE ==="
95
32
 
96
33
  while read oldrev newrev refname; do
97
34
  BRANCH=$(echo "$refname" | sed 's|refs/heads/||')
98
35
  log "Received push to branch: $BRANCH"
99
36
 
100
37
  if [ "$BRANCH" != "main" ] && [ "$BRANCH" != "master" ]; then
101
- log "Ignoring non-main branch"
38
+ log "Ignoring branch $BRANCH (only main/master triggers deploy)"
102
39
  continue
103
40
  fi
104
41
 
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
42
+ # Export variables for gpd install
43
+ export GPD_TARGET_DIR="$TARGET_DIR"
44
+ export GPD_GIT_DIR="$GIT_DIR"
45
+ export GPD_SERVICE="$SERVICE"
46
+ ${pm2Home ? `export PM2_HOME="${pm2Home}"` : ''}
110
47
 
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
48
+ # Run gpd install (handles checkout, npm install, pm2 restart)
49
+ log "Running: ${installCmd}"
50
+ ${installCmd} 2>&1 | tee -a "$LOG_FILE"
125
51
  done
126
52
 
127
53
  log "=== Deployment completed ==="
128
54
  `;
129
55
  }
130
56
  /**
131
- * Init command - initialize bare repo, hook, and permissions on server
57
+ * Init command - initialize bare repo and target directory on remote server via SSH
58
+ *
59
+ * Creates:
60
+ * 1. Bare repo at server.bareRepo (e.g., /git/sym/deploy-kairox/staging/kairox-api)
61
+ * 2. Target directory at server.targetDir (e.g., /opt/kairox/staging/kairox-api)
62
+ * 3. Post-receive hook that calls `gpd install <service>`
132
63
  */
133
- export async function initCommand(serviceName, options = {}) {
64
+ export async function initCommand(serviceName, _options = {}) {
134
65
  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
66
  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 });
67
+ const { host, bareRepo, targetDir, sshOptions, group } = config.server;
68
+ const { pm2User, pm2Home } = config;
69
+ console.log(chalk.gray(` Host: ${host}`));
70
+ console.log(chalk.gray(` Bare repo: ${bareRepo}`));
71
+ console.log(chalk.gray(` Target dir: ${targetDir}`));
72
+ if (group)
73
+ console.log(chalk.gray(` Group: ${group}`));
74
+ if (pm2User)
75
+ console.log(chalk.gray(` PM2 user: ${pm2User}`));
76
+ // 1. Create group if specified
77
+ if (group) {
78
+ console.log(chalk.gray(` Creating group ${group}...`));
79
+ const createGroupCmd = `sudo groupadd -f ${group} && sudo usermod -aG ${group} $(whoami)`;
80
+ sshExec(host, createGroupCmd, { sshOptions });
148
81
  }
149
- catch {
150
- console.log(chalk.gray(` Group ${groupName} already exists`));
82
+ // 2. Create bare repo with shared group access
83
+ console.log(chalk.gray(` Creating bare repo...`));
84
+ const bareRepoParent = bareRepo.split('/').slice(0, -1).join('/');
85
+ let createBareCmd = `sudo mkdir -p ${bareRepoParent}`;
86
+ if (group) {
87
+ createBareCmd += ` && sudo chgrp ${group} ${bareRepoParent} && sudo chmod g+rwxs ${bareRepoParent}`;
151
88
  }
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
- }
89
+ createBareCmd += ` && cd ${bareRepoParent} && git init --bare --shared=group ${bareRepo.split('/').pop()}`;
90
+ if (group) {
91
+ createBareCmd += ` && sudo chgrp -R ${group} ${bareRepo}`;
164
92
  }
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
- }
93
+ sshExec(host, createBareCmd, { sshOptions });
94
+ // 3. Create target directory
95
+ console.log(chalk.gray(` Creating target directory...`));
96
+ const targetParent = targetDir.split('/').slice(0, -1).join('/');
97
+ let createTargetCmd = `sudo mkdir -p ${targetDir}`;
98
+ if (pm2User) {
99
+ createTargetCmd += ` && sudo chown ${pm2User}:${group || pm2User} ${targetDir}`;
174
100
  }
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`));
101
+ if (group) {
102
+ createTargetCmd += ` && sudo chgrp -R ${group} ${targetParent} && sudo chmod g+rwxs ${targetParent}`;
183
103
  }
104
+ sshExec(host, createTargetCmd, { sshOptions });
184
105
  // 4. Create post-receive hook
185
- const hookPath = joinPath(server.bareRepo, 'hooks', 'post-receive');
186
106
  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 });
107
+ const hookContent = generatePostReceiveHook(serviceName, {
108
+ targetDir,
109
+ bareRepo,
110
+ pm2User,
111
+ pm2Home
112
+ });
113
+ // Escape for shell (use base64 to avoid quote issues)
114
+ const hookBase64 = Buffer.from(hookContent).toString('base64');
115
+ const hookPath = `${bareRepo}/hooks/post-receive`;
116
+ const createHookCmd = `echo '${hookBase64}' | base64 -d | sudo tee ${hookPath} > /dev/null && sudo chmod +x ${hookPath}`;
117
+ if (group) {
118
+ sshExec(host, `${createHookCmd} && sudo chgrp ${group} ${hookPath}`, { sshOptions });
119
+ }
120
+ else {
121
+ sshExec(host, createHookCmd, { sshOptions });
122
+ }
123
+ // 5. Create log file
124
+ console.log(chalk.gray(` Creating log file...`));
125
+ const logFile = `/var/log/gpd-${serviceName}.log`;
126
+ let createLogCmd = `sudo touch ${logFile} && sudo chmod 666 ${logFile}`;
127
+ if (group) {
128
+ createLogCmd += ` && sudo chgrp ${group} ${logFile}`;
195
129
  }
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 });
130
+ sshExec(host, createLogCmd, { sshOptions });
204
131
  console.log(chalk.green(`✓ Initialized ${serviceName}`));
205
132
  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`));
133
+ console.log(chalk.gray('Server setup complete. Now you can deploy:'));
134
+ console.log(chalk.white(` gpd deploy ${serviceName}`));
211
135
  }
212
136
  //# 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":"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"}
@@ -1,9 +1,20 @@
1
1
  interface InstallOptions {
2
- ref?: string;
2
+ configPath?: string;
3
3
  }
4
4
  /**
5
- * Install command - extract, npm install, restart process
6
- * This is called by the post-receive hook
5
+ * Install command - runs on server after git push (called by post-receive hook)
6
+ *
7
+ * Environment variables from hook:
8
+ * - GPD_TARGET_DIR: Where to install (e.g., /opt/kairox/staging/kairox-api)
9
+ * - GPD_GIT_DIR: Bare repo path (e.g., /git/sym/deploy-kairox/staging/kairox-api)
10
+ * - GPD_SERVICE: Service name (e.g., kairox-api-staging)
11
+ * - PM2_HOME: PM2 home directory (optional)
12
+ *
13
+ * Steps:
14
+ * 1. git checkout from bare repo to target dir
15
+ * 2. Generate .env file from config
16
+ * 3. npm install --omit=dev
17
+ * 4. PM2 restart
7
18
  */
8
19
  export declare function installCommand(serviceName: string, options?: InstallOptions): Promise<void>;
9
20
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAOA,UAAU,cAAc;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DrG"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAMA,UAAU,cAAc;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAoDD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiHrG"}
@@ -1,67 +1,174 @@
1
1
  import chalk from 'chalk';
2
- import { readFileSync } from 'fs';
3
- import { getServiceConfig } from '../config/loader.js';
4
- import { exec } from '../utils/shell.js';
5
- import { exists, joinPath } from '../utils/files.js';
6
- import { createProcessManager } from '../utils/process-manager.js';
2
+ import { execSync } from 'child_process';
3
+ import { existsSync, writeFileSync, mkdirSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { getServiceConfig, findConfigFile } from '../config/loader.js';
7
6
  /**
8
- * Install command - extract, npm install, restart process
9
- * This is called by the post-receive hook
7
+ * Generate .env file content from config env object
8
+ */
9
+ function generateEnvContent(env) {
10
+ return Object.entries(env)
11
+ .map(([key, value]) => `${key}=${value}`)
12
+ .join('\n');
13
+ }
14
+ /**
15
+ * Execute shell command with logging
16
+ */
17
+ function exec(cmd, options = {}) {
18
+ if (!options.silent) {
19
+ console.log(chalk.gray(`$ ${cmd}`));
20
+ }
21
+ try {
22
+ execSync(cmd, {
23
+ cwd: options.cwd,
24
+ stdio: options.silent ? 'pipe' : 'inherit',
25
+ env: { ...process.env }
26
+ });
27
+ }
28
+ catch (error) {
29
+ throw new Error(`Command failed: ${cmd}`);
30
+ }
31
+ }
32
+ /**
33
+ * Execute command as a specific user via sudo
34
+ */
35
+ function execAsUser(cmd, user, options = {}) {
36
+ // Build environment exports
37
+ const envExports = options.env
38
+ ? Object.entries(options.env).map(([k, v]) => `export ${k}="${v}"`).join('; ') + '; '
39
+ : '';
40
+ const fullCmd = `sudo -u ${user} bash -c '${envExports}${cmd.replace(/'/g, "'\\''")}'`;
41
+ console.log(chalk.gray(`$ ${fullCmd}`));
42
+ try {
43
+ execSync(fullCmd, {
44
+ cwd: options.cwd,
45
+ stdio: 'inherit',
46
+ env: { ...process.env }
47
+ });
48
+ }
49
+ catch (error) {
50
+ throw new Error(`Command failed: ${fullCmd}`);
51
+ }
52
+ }
53
+ /**
54
+ * Install command - runs on server after git push (called by post-receive hook)
55
+ *
56
+ * Environment variables from hook:
57
+ * - GPD_TARGET_DIR: Where to install (e.g., /opt/kairox/staging/kairox-api)
58
+ * - GPD_GIT_DIR: Bare repo path (e.g., /git/sym/deploy-kairox/staging/kairox-api)
59
+ * - GPD_SERVICE: Service name (e.g., kairox-api-staging)
60
+ * - PM2_HOME: PM2 home directory (optional)
61
+ *
62
+ * Steps:
63
+ * 1. git checkout from bare repo to target dir
64
+ * 2. Generate .env file from config
65
+ * 3. npm install --omit=dev
66
+ * 4. PM2 restart
10
67
  */
11
68
  export async function installCommand(serviceName, options = {}) {
12
- const ref = options.ref || 'main';
13
- console.log(chalk.blue(`Installing ${serviceName} (ref: ${ref})...`));
14
- const config = getServiceConfig(serviceName);
15
- const { server, packages, mainPackage, processName, processManager: pmType = 'pm2', pm2Home } = config;
16
- // Create process manager instance
17
- const pm = createProcessManager(pmType);
18
- // Extract each package using git archive
19
- for (const pkg of packages) {
20
- console.log(chalk.gray(` Extracting ${pkg}...`));
21
- try {
22
- exec(`git archive ${ref} ${pkg}/ | tar -x -C ${server.targetDir}/`, {
23
- cwd: server.bareRepo,
24
- silent: true
25
- });
69
+ console.log(chalk.blue(`Installing ${serviceName}...`));
70
+ // Get paths from environment (set by hook) or use config
71
+ const targetDir = process.env.GPD_TARGET_DIR;
72
+ const gitDir = process.env.GPD_GIT_DIR;
73
+ if (!targetDir || !gitDir) {
74
+ throw new Error('GPD_TARGET_DIR and GPD_GIT_DIR must be set. This command should be run by the post-receive hook.');
75
+ }
76
+ // Find config - on server it should be at /etc/gpd/<service>.json or passed via -c
77
+ const configPath = options.configPath || findConfigFile();
78
+ if (!configPath) {
79
+ throw new Error('.git-deploy.json not found. Specify with -c option.');
80
+ }
81
+ const config = getServiceConfig(serviceName, configPath);
82
+ const { processName, pm2Home, pm2User, env } = config;
83
+ console.log(chalk.gray(` Target: ${targetDir}`));
84
+ console.log(chalk.gray(` Git dir: ${gitDir}`));
85
+ if (pm2User)
86
+ console.log(chalk.gray(` PM2 user: ${pm2User}`));
87
+ // Determine which user to run commands as
88
+ const runUser = pm2User || process.env.USER || 'root';
89
+ const userHome = pm2User ? `/home/${pm2User}` : process.env.HOME || '/root';
90
+ // Environment for npm/pm2 commands
91
+ const cmdEnv = {};
92
+ if (pm2Home)
93
+ cmdEnv.PM2_HOME = pm2Home;
94
+ if (pm2User) {
95
+ cmdEnv.HOME = `/opt/kairox`; // Use app directory as home for npm cache
96
+ }
97
+ // 1. Git checkout from bare repo to target dir
98
+ console.log(chalk.blue('Checking out files...'));
99
+ const checkoutCmd = `git --work-tree="${targetDir}" --git-dir="${gitDir}" checkout -f`;
100
+ if (pm2User) {
101
+ execAsUser(checkoutCmd, pm2User);
102
+ }
103
+ else {
104
+ exec(checkoutCmd);
105
+ }
106
+ // 2. Generate .env file from config
107
+ if (env && Object.keys(env).length > 0) {
108
+ console.log(chalk.blue('Generating .env file...'));
109
+ const envPath = join(targetDir, '.env');
110
+ const envContent = generateEnvContent(env);
111
+ writeFileSync(envPath, envContent + '\n');
112
+ console.log(chalk.gray(` Written to ${envPath}`));
113
+ // Fix ownership if running as different user
114
+ if (pm2User) {
115
+ exec(`sudo chown ${pm2User}:${pm2User} "${envPath}"`, { silent: true });
26
116
  }
27
- catch {
28
- console.log(chalk.yellow(` Warning: Could not extract ${pkg}`));
117
+ }
118
+ // 3. Create logs directory if needed
119
+ const logsDir = join(targetDir, 'logs');
120
+ if (!existsSync(logsDir)) {
121
+ mkdirSync(logsDir, { recursive: true });
122
+ if (pm2User) {
123
+ exec(`sudo chown ${pm2User}:${pm2User} "${logsDir}"`, { silent: true });
29
124
  }
125
+ console.log(chalk.gray(` Created ${logsDir}`));
126
+ }
127
+ // 4. npm install
128
+ console.log(chalk.blue('Installing dependencies...'));
129
+ const npmCmd = `npm install --omit=dev --cache=/opt/kairox/.npm`;
130
+ if (pm2User) {
131
+ execAsUser(npmCmd, pm2User, { cwd: targetDir, env: cmdEnv });
30
132
  }
31
- // Set ownership
32
- if (server.user) {
33
- exec(`chown -R ${server.user}:${server.user} ${server.targetDir}`, { silent: true });
133
+ else {
134
+ exec(npmCmd, { cwd: targetDir });
34
135
  }
35
- // Install dependencies
36
- const mainPkgPath = joinPath(server.targetDir, mainPackage);
37
- console.log(chalk.gray(` Installing dependencies in ${mainPackage}...`));
38
- if (server.user) {
39
- exec(`sudo -u ${server.user} npm install --omit=dev`, { cwd: mainPkgPath });
136
+ // 5. PM2 restart (or start if not running)
137
+ console.log(chalk.blue('Restarting PM2 process...'));
138
+ // Check if process exists and restart, otherwise start
139
+ const pm2RestartCmd = `pm2 describe ${processName} > /dev/null 2>&1 && pm2 restart ${processName} --update-env || pm2 start ecosystem.config.cjs --env ${config.environment || 'production'}`;
140
+ if (pm2User) {
141
+ execAsUser(pm2RestartCmd, pm2User, { cwd: targetDir, env: cmdEnv });
40
142
  }
41
143
  else {
42
- exec('npm install --omit=dev', { cwd: mainPkgPath });
144
+ let fullPm2Cmd = pm2RestartCmd;
145
+ if (pm2Home)
146
+ fullPm2Cmd = `PM2_HOME=${pm2Home} ${fullPm2Cmd}`;
147
+ exec(fullPm2Cmd, { cwd: targetDir });
43
148
  }
44
- // Restart process
45
- console.log(chalk.gray(` Restarting ${pm.name} process ${processName}...`));
46
- if (server.user) {
47
- pm.asUser(server.user, `restart ${processName}`, { home: pm2Home });
149
+ // 6. PM2 save
150
+ console.log(chalk.blue('Saving PM2 state...'));
151
+ const pm2SaveCmd = 'pm2 save';
152
+ if (pm2User) {
153
+ execAsUser(pm2SaveCmd, pm2User, { env: cmdEnv });
48
154
  }
49
155
  else {
50
- pm.restart(processName, { home: pm2Home });
156
+ let fullSaveCmd = pm2SaveCmd;
157
+ if (pm2Home)
158
+ fullSaveCmd = `PM2_HOME=${pm2Home} ${fullSaveCmd}`;
159
+ exec(fullSaveCmd);
51
160
  }
52
- // Get version from package.json
53
- try {
54
- const pkgJsonPath = joinPath(mainPkgPath, 'package.json');
55
- if (exists(pkgJsonPath)) {
56
- const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
57
- console.log(chalk.green(`✓ Installed ${serviceName} v${pkgJson.version}`));
58
- }
59
- else {
60
- console.log(chalk.green(`✓ Installed ${serviceName}`));
61
- }
161
+ console.log(chalk.green(`✓ Installed ${serviceName}`));
162
+ // Show status
163
+ const pm2StatusCmd = 'pm2 status';
164
+ if (pm2User) {
165
+ execAsUser(pm2StatusCmd, pm2User, { env: cmdEnv });
62
166
  }
63
- catch {
64
- console.log(chalk.green(`✓ Installed ${serviceName}`));
167
+ else {
168
+ let fullStatusCmd = pm2StatusCmd;
169
+ if (pm2Home)
170
+ fullStatusCmd = `PM2_HOME=${pm2Home} ${fullStatusCmd}`;
171
+ exec(fullStatusCmd);
65
172
  }
66
173
  }
67
174
  //# sourceMappingURL=install.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
@@ -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 {};