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
package/README.md CHANGED
@@ -1,43 +1,47 @@
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
9
- - **Monorepo support**: Stage multiple packages for deployment
10
- - **Cross-platform**: Works on Linux servers and Windows/Mac dev machines
7
+ - **Git-based deployment**: Push to bare repo, server hook handles install
8
+ - **PM2 integration**: Automatic process restarts with user isolation
9
+ - **Lazy initialization**: Deploy repo created on first `gpd stage`
10
+ - **SSH orchestration**: Server setup 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
  {
31
25
  "services": {
32
- "my-api": {
33
- "packages": ["my-api"],
34
- "mainPackage": "my-api",
35
- "deployRepo": "../deploy-my-api",
36
- "pm2Name": "my-api",
26
+ "my-api-staging": {
27
+ "sourceDir": "my-api",
28
+ "deployRepo": "deploy/staging",
29
+ "artifacts": ["dist/index.js", "package.json", "ecosystem.config.cjs"],
30
+ "processManager": "pm2",
31
+ "processName": "my-api-staging",
32
+ "pm2Home": "/opt/myapp/.pm2",
33
+ "pm2User": "myapp",
34
+ "environment": "staging",
35
+ "env": {
36
+ "PORT": 5000,
37
+ "NODE_ENV": "staging"
38
+ },
37
39
  "server": {
38
- "targetDir": "/opt/myapp/my-api",
39
- "bareRepo": "/git/deploy-my-api",
40
- "user": "myapp"
40
+ "host": "user@myserver",
41
+ "sshOptions": "-p 22",
42
+ "targetDir": "/opt/myapp/staging/my-api",
43
+ "bareRepo": "/git/deploy-myapp/staging/my-api",
44
+ "group": "deploy-myapp"
41
45
  }
42
46
  }
43
47
  }
@@ -47,140 +51,115 @@ Create `.git-deploy.json` in your workspace root:
47
51
  ### 2. Initialize server (once per service)
48
52
 
49
53
  ```bash
50
- # On the server
51
- sudo gpd init my-api
54
+ gpd init my-api-staging
52
55
  ```
53
56
 
54
- This creates:
55
- - 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
57
+ This creates via SSH:
58
+ - Bare git repository at `/git/deploy-myapp/staging/my-api`
59
+ - Target directory at `/opt/myapp/staging/my-api`
60
+ - Post-receive hook that calls `gpd install`
59
61
 
60
- ### 3. Deploy from dev machine
62
+ ### 3. Deploy
61
63
 
62
64
  ```bash
63
- # Build, stage, and push
64
- 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
65
+ gpd deploy my-api-staging
69
66
  ```
70
67
 
71
- ## Commands
68
+ This:
69
+ 1. Creates deploy repo (if needed) at `my-api/deploy/staging/`
70
+ 2. Copies build artifacts to deploy repo
71
+ 3. Commits and pushes to bare repo on server
72
+ 4. Server hook: `git checkout && npm install && pm2 restart`
72
73
 
73
- ### Development Commands
74
+ ## Commands
74
75
 
75
76
  | Command | Description |
76
77
  |---------|-------------|
78
+ | `gpd status` | Show all configured services |
77
79
  | `gpd stage <service>` | Copy build artifacts to deploy repo |
78
80
  | `gpd release <service>` | Commit and push deploy repo |
79
- | `gpd deploy <service>` | Stage + release in one step |
80
-
81
- ### Server Commands
81
+ | `gpd deploy <service>` | Stage + release (hook handles install) |
82
+ | `gpd init <service>` | Initialize server (bare repo, target dir, hook) |
83
+ | `gpd install <service>` | Server-side install (called by hook) |
84
+ | `gpd logs <service>` | Show PM2 logs from server via SSH |
82
85
 
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 |
86
+ ## Options
89
87
 
90
- ## Configuration
91
-
92
- ### .git-deploy.json
88
+ ```bash
89
+ gpd deploy my-api -m "custom commit message"
90
+ gpd deploy my-api --skip-push # Only stage, do not push
91
+ gpd logs my-api -f # Follow logs
92
+ gpd logs my-api -n 100 # Show last 100 lines
93
+ ```
93
94
 
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
- }
95
+ ## Config Reference
96
+
97
+ ```typescript
98
+ interface ServiceConfig {
99
+ sourceDir: string; // Project directory (e.g., "my-api")
100
+ deployRepo: string; // Deploy repo path, relative to sourceDir
101
+ artifacts: string[]; // Files/dirs to copy
102
+ processManager: 'pm2'; // Process manager type
103
+ processName: string; // PM2 process name
104
+ pm2Home?: string; // PM2_HOME on server
105
+ pm2User?: string; // User to run PM2 as (sudo -u)
106
+ environment?: string; // staging | production
107
+ env?: Record<string, any>; // Environment variables for .env file
108
+ server: {
109
+ host: string; // SSH host (user@hostname)
110
+ sshOptions?: string; // SSH options (e.g., "-p 6771 -4")
111
+ targetDir: string; // Target directory on server
112
+ bareRepo: string; // Bare repo path on server
113
+ group?: string; // Unix group for permissions
114
+ };
112
115
  }
113
116
  ```
114
117
 
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
118
+ ## Architecture
131
119
 
132
120
  ```
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
- └─────────────┘
121
+ Workspace Server
122
+ ───────── ──────
123
+ my-api/
124
+ ├── src/ /git/deploy-myapp/staging/my-api/
125
+ ├── dist/ └── hooks/post-receive
126
+ └── deploy/
127
+ └── staging/ /opt/myapp/staging/my-api/
128
+ ├── .git → ssh://... ├── dist/index.js
129
+ ├── dist/ ├── package.json
130
+ └── package.json ├── node_modules/
131
+ └── .env (generated)
165
132
  ```
166
133
 
167
- ## Integration with npm scripts
134
+ ## Workflow
168
135
 
169
- ```json
170
- {
171
- "scripts": {
172
- "predeploy": "npm version patch && npm run build",
173
- "deploy": "gpd deploy my-api"
174
- }
175
- }
136
+ ```
137
+ Dev Machine Server
138
+ ─────────── ──────
139
+ gpd deploy my-api-staging
140
+
141
+ ├─ gpd stage
142
+ │ └─ Copy artifacts → my-api/deploy/staging/
143
+
144
+ └─ gpd release
145
+ └─ git push ───────────────→ /git/deploy-myapp/staging/my-api
146
+
147
+ └─ post-receive hook:
148
+ gpd install my-api-staging
149
+
150
+ ├─ git checkout -f
151
+ ├─ .env generation
152
+ ├─ npm install --omit=dev
153
+ └─ pm2 restart
176
154
  ```
177
155
 
178
- ## Requirements
156
+ ## Server Prerequisites
179
157
 
180
- - Node.js >= 18
158
+ - Node.js + npm
159
+ - PM2 (`npm install -g pm2`)
160
+ - gpd CLI (`npm install -g git-push-deploy-cli`)
161
+ - SSH access from dev machine
181
162
  - Git
182
- - PM2 (on server)
183
- - Linux server (Debian, Ubuntu, Raspberry Pi OS, etc.)
184
163
 
185
164
  ## License
186
165
 
@@ -1,8 +1,16 @@
1
1
  interface DeployOptions {
2
2
  message?: string;
3
+ skipPush?: boolean;
3
4
  }
4
5
  /**
5
- * Deploy command - stage and release in one step
6
+ * Deploy command - stage artifacts and push to server
7
+ *
8
+ * New architecture:
9
+ * 1. Stage: Copy build artifacts to deploy repo (with lazy init)
10
+ * 2. Release: Commit and push to bare repo on server
11
+ * 3. Server hook handles: git checkout, npm install, pm2 restart
12
+ *
13
+ * No more SSH install from client - the post-receive hook does everything!
6
14
  */
7
15
  export declare function deployCommand(serviceName: string, options?: DeployOptions): Promise<void>;
8
16
  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":"AAKA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBnG"}
@@ -1,10 +1,37 @@
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';
3
5
  /**
4
- * Deploy command - stage and release in one step
6
+ * Deploy command - stage artifacts and push to server
7
+ *
8
+ * New architecture:
9
+ * 1. Stage: Copy build artifacts to deploy repo (with lazy init)
10
+ * 2. Release: Commit and push to bare repo on server
11
+ * 3. Server hook handles: git checkout, npm install, pm2 restart
12
+ *
13
+ * No more SSH install from client - the post-receive hook does everything!
5
14
  */
6
15
  export async function deployCommand(serviceName, options = {}) {
16
+ const config = getServiceConfig(serviceName);
17
+ console.log(chalk.blue.bold(`Deploying ${serviceName}...`));
18
+ console.log(chalk.gray(` Environment: ${config.environment || 'production'}`));
19
+ console.log(chalk.gray(` Server: ${config.server.host}`));
20
+ console.log('');
21
+ // 1. Stage artifacts to deploy repo
7
22
  await stageCommand(serviceName);
8
- await releaseCommand(serviceName, options);
23
+ console.log('');
24
+ // 2. Commit and push (triggers server-side hook)
25
+ if (!options.skipPush) {
26
+ await releaseCommand(serviceName, options);
27
+ console.log('');
28
+ console.log(chalk.green.bold(`✓ Deployed ${serviceName}`));
29
+ console.log(chalk.gray(' The server hook will handle: git checkout, npm install, pm2 restart'));
30
+ console.log(chalk.gray(` Check logs: gpd logs ${serviceName}`));
31
+ }
32
+ else {
33
+ console.log(chalk.yellow('Skipped push (--skip-push). Run manually:'));
34
+ console.log(chalk.white(` gpd release ${serviceName}`));
35
+ }
9
36
  }
10
37
  //# 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;AAOvD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,UAAyB,EAAE;IAClF,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAE7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,WAAW,KAAK,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,WAAW,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,oCAAoC;IACpC,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,iDAAiD;IACjD,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACtB,MAAM,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,WAAW,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC,CAAC;QACjG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -1,9 +1,13 @@
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 target directory on remote server via SSH
5
+ *
6
+ * Creates:
7
+ * 1. Bare repo at server.bareRepo (e.g., /git/sym/deploy-kairox/staging/kairox-api)
8
+ * 2. Target directory at server.targetDir (e.g., /opt/kairox/staging/kairox-api)
9
+ * 3. Post-receive hook that calls `gpd install <service>`
6
10
  */
7
- export declare function initCommand(serviceName: string, options?: InitOptions): Promise<void>;
11
+ export declare function initCommand(serviceName: string, _options?: InitOptions): Promise<void>;
8
12
  export {};
9
13
  //# 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;AA8DD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6EhG"}