git-push-deploy-cli 0.1.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.
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/commands/deploy.d.ts +9 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +10 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +212 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install.d.ts +10 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +67 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/logs.d.ts +10 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +42 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/release.d.ts +9 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +32 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/commands/stage.d.ts +5 -0
- package/dist/commands/stage.d.ts.map +1 -0
- package/dist/commands/stage.js +37 -0
- package/dist/commands/stage.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +61 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/loader.d.ts +22 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +66 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/types.d.ts +42 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +10 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/files.d.ts +25 -0
- package/dist/utils/files.d.ts.map +1 -0
- package/dist/utils/files.js +47 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/git.d.ts +33 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +63 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/pm2.d.ts +39 -0
- package/dist/utils/pm2.d.ts.map +1 -0
- package/dist/utils/pm2.js +83 -0
- package/dist/utils/pm2.js.map +1 -0
- package/dist/utils/process-manager.d.ts +37 -0
- package/dist/utils/process-manager.d.ts.map +1 -0
- package/dist/utils/process-manager.js +17 -0
- package/dist/utils/process-manager.js.map +1 -0
- package/dist/utils/shell.d.ts +24 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +51 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/systemd.d.ts +34 -0
- package/dist/utils/systemd.d.ts.map +1 -0
- package/dist/utils/systemd.js +79 -0
- package/dist/utils/systemd.js.map +1 -0
- package/package.json +60 -0
- package/templates/post-receive.sh +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Andreas Schulz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# git-push-deploy-cli (gpd)
|
|
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.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
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
|
|
11
|
+
- **Config-driven**: Define services in `.git-deploy.json`
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Global installation (recommended for servers)
|
|
17
|
+
npm install -g git-push-deploy-cli
|
|
18
|
+
|
|
19
|
+
# Or use npx
|
|
20
|
+
npx git-push-deploy-cli <command>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Create config file
|
|
26
|
+
|
|
27
|
+
Create `.git-deploy.json` in your workspace root:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"services": {
|
|
32
|
+
"my-api": {
|
|
33
|
+
"packages": ["my-api"],
|
|
34
|
+
"mainPackage": "my-api",
|
|
35
|
+
"deployRepo": "../deploy-my-api",
|
|
36
|
+
"pm2Name": "my-api",
|
|
37
|
+
"server": {
|
|
38
|
+
"targetDir": "/opt/myapp/my-api",
|
|
39
|
+
"bareRepo": "/git/deploy-my-api",
|
|
40
|
+
"user": "myapp"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Initialize server (once per service)
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# On the server
|
|
51
|
+
sudo gpd init my-api
|
|
52
|
+
```
|
|
53
|
+
|
|
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
|
|
59
|
+
|
|
60
|
+
### 3. Deploy from dev machine
|
|
61
|
+
|
|
62
|
+
```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
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Commands
|
|
72
|
+
|
|
73
|
+
### Development Commands
|
|
74
|
+
|
|
75
|
+
| Command | Description |
|
|
76
|
+
|---------|-------------|
|
|
77
|
+
| `gpd stage <service>` | Copy build artifacts to deploy repo |
|
|
78
|
+
| `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 |
|
|
89
|
+
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
### .git-deploy.json
|
|
93
|
+
|
|
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
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
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
|
|
131
|
+
|
|
132
|
+
```
|
|
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
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Requirements
|
|
179
|
+
|
|
180
|
+
- Node.js >= 18
|
|
181
|
+
- Git
|
|
182
|
+
- PM2 (on server)
|
|
183
|
+
- Linux server (Debian, Ubuntu, Raspberry Pi OS, etc.)
|
|
184
|
+
|
|
185
|
+
## License
|
|
186
|
+
|
|
187
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface DeployOptions {
|
|
2
|
+
message?: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Deploy command - stage and release in one step
|
|
6
|
+
*/
|
|
7
|
+
export declare function deployCommand(serviceName: string, options?: DeployOptions): Promise<void>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { stageCommand } from './stage.js';
|
|
2
|
+
import { releaseCommand } from './release.js';
|
|
3
|
+
/**
|
|
4
|
+
* Deploy command - stage and release in one step
|
|
5
|
+
*/
|
|
6
|
+
export async function deployCommand(serviceName, options = {}) {
|
|
7
|
+
await stageCommand(serviceName);
|
|
8
|
+
await releaseCommand(serviceName, options);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface InitOptions {
|
|
2
|
+
users?: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Init command - initialize bare repo, hook, and permissions on server
|
|
6
|
+
*/
|
|
7
|
+
export declare function initCommand(serviceName: string, options?: InitOptions): Promise<void>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { writeFileSync, chmodSync } from 'fs';
|
|
3
|
+
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';
|
|
7
|
+
/**
|
|
8
|
+
* Generate post-receive hook content
|
|
9
|
+
*/
|
|
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 = {}) {
|
|
134
|
+
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
|
+
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 });
|
|
204
|
+
console.log(chalk.green(`✓ Initialized ${serviceName}`));
|
|
205
|
+
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`));
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface InstallOptions {
|
|
2
|
+
ref?: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Install command - extract, npm install, restart process
|
|
6
|
+
* This is called by the post-receive hook
|
|
7
|
+
*/
|
|
8
|
+
export declare function installCommand(serviceName: string, options?: InstallOptions): Promise<void>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
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';
|
|
7
|
+
/**
|
|
8
|
+
* Install command - extract, npm install, restart process
|
|
9
|
+
* This is called by the post-receive hook
|
|
10
|
+
*/
|
|
11
|
+
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
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
console.log(chalk.yellow(` Warning: Could not extract ${pkg}`));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Set ownership
|
|
32
|
+
if (server.user) {
|
|
33
|
+
exec(`chown -R ${server.user}:${server.user} ${server.targetDir}`, { silent: true });
|
|
34
|
+
}
|
|
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 });
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
exec('npm install --omit=dev', { cwd: mainPkgPath });
|
|
43
|
+
}
|
|
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 });
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
pm.restart(processName, { home: pm2Home });
|
|
51
|
+
}
|
|
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
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
console.log(chalk.green(`✓ Installed ${serviceName}`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface LogsOptions {
|
|
2
|
+
lines?: string;
|
|
3
|
+
follow?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Logs command - show deployment logs
|
|
7
|
+
*/
|
|
8
|
+
export declare function logsCommand(serviceName: string, options?: LogsOptions): Promise<void>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import { getServiceConfig } from '../config/loader.js';
|
|
4
|
+
import { exec } from '../utils/shell.js';
|
|
5
|
+
import { exists } from '../utils/files.js';
|
|
6
|
+
/**
|
|
7
|
+
* Logs command - show deployment logs
|
|
8
|
+
*/
|
|
9
|
+
export async function logsCommand(serviceName, options = {}) {
|
|
10
|
+
const lines = options.lines || '50';
|
|
11
|
+
const logFile = `/var/log/deploy-${serviceName}.log`;
|
|
12
|
+
// Check if log file exists
|
|
13
|
+
if (!exists(logFile)) {
|
|
14
|
+
// Try to get config to show better error message
|
|
15
|
+
try {
|
|
16
|
+
getServiceConfig(serviceName);
|
|
17
|
+
console.log(chalk.yellow(`Log file not found: ${logFile}`));
|
|
18
|
+
console.log(chalk.gray('The service may not have been deployed yet.'));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
console.log(chalk.red(`Unknown service: ${serviceName}`));
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (options.follow) {
|
|
26
|
+
console.log(chalk.blue(`Following logs for ${serviceName} (Ctrl+C to exit)...`));
|
|
27
|
+
console.log('');
|
|
28
|
+
// Use spawn for follow mode
|
|
29
|
+
const tail = spawn('tail', ['-f', '-n', lines, logFile], {
|
|
30
|
+
stdio: 'inherit'
|
|
31
|
+
});
|
|
32
|
+
tail.on('error', (error) => {
|
|
33
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(chalk.blue(`Deployment logs for ${serviceName} (last ${lines} lines):`));
|
|
38
|
+
console.log('');
|
|
39
|
+
exec(`tail -n ${lines} ${logFile}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAO3C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,WAAmB,EAAE,UAAuB,EAAE;IAC9E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;IACpC,MAAM,OAAO,GAAG,mBAAmB,WAAW,MAAM,CAAC;IAErD,2BAA2B;IAC3B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACrB,iDAAiD;QACjD,IAAI,CAAC;YACH,gBAAgB,CAAC,WAAW,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,WAAW,sBAAsB,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,4BAA4B;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE;YACvD,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,WAAW,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,CAAC,WAAW,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface ReleaseOptions {
|
|
2
|
+
message?: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Release command - commit and push deploy repository
|
|
6
|
+
*/
|
|
7
|
+
export declare function releaseCommand(serviceName: string, options?: ReleaseOptions): Promise<void>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=release.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../src/commands/release.ts"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BrG"}
|