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.
- package/README.md +66 -121
- package/dist/commands/deploy.d.ts +2 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +23 -1
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/init.d.ts +6 -3
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +23 -202
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/logs.d.ts +1 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +19 -25
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +3 -35
- package/dist/commands/status.js.map +1 -1
- package/dist/config/types.d.ts +7 -6
- package/dist/config/types.d.ts.map +1 -1
- package/dist/index.js +6 -12
- package/dist/index.js.map +1 -1
- package/dist/utils/shell.d.ts +6 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +9 -0
- package/dist/utils/shell.js.map +1 -1
- package/package.json +1 -1
- package/dist/commands/install.d.ts +0 -10
- package/dist/commands/install.d.ts.map +0 -1
- package/dist/commands/install.js +0 -67
- package/dist/commands/install.js.map +0 -1
- package/dist/utils/pm2.d.ts +0 -39
- package/dist/utils/pm2.d.ts.map +0 -1
- package/dist/utils/pm2.js +0 -83
- package/dist/utils/pm2.js.map +0 -1
- package/dist/utils/process-manager.d.ts +0 -37
- package/dist/utils/process-manager.d.ts.map +0 -1
- package/dist/utils/process-manager.js +0 -17
- package/dist/utils/process-manager.js.map +0 -1
- package/dist/utils/systemd.d.ts +0 -34
- package/dist/utils/systemd.d.ts.map +0 -1
- package/dist/utils/systemd.js +0 -79
- package/dist/utils/systemd.js.map +0 -1
- 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
|
|
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
|
|
8
|
-
- **PM2 integration**: Automatic process
|
|
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
|
-
- **
|
|
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
|
|
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
|
-
"
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
##
|
|
75
|
+
## Options
|
|
91
76
|
|
|
92
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
│
|
|
139
|
-
│
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
##
|
|
121
|
+
## Server Prerequisites
|
|
179
122
|
|
|
180
|
-
- Node.js
|
|
123
|
+
- Node.js + npm
|
|
124
|
+
- PM2 (`npm install -g pm2`)
|
|
125
|
+
- SSH access from dev machine
|
|
181
126
|
- Git
|
|
182
|
-
|
|
183
|
-
|
|
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
|
|
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":"
|
|
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"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -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
|
|
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;
|
|
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"}
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
interface InitOptions {
|
|
2
|
-
users?: string;
|
|
3
2
|
}
|
|
4
3
|
/**
|
|
5
|
-
* Init command - initialize bare repo
|
|
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,
|
|
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":"
|
|
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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -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 {
|
|
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
|
+
* 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
|
|
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 {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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('
|
|
207
|
-
console.log(chalk.
|
|
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":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,
|
|
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"}
|
package/dist/commands/logs.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"
|
|
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"}
|