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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +187 -0
  3. package/dist/commands/deploy.d.ts +9 -0
  4. package/dist/commands/deploy.d.ts.map +1 -0
  5. package/dist/commands/deploy.js +10 -0
  6. package/dist/commands/deploy.js.map +1 -0
  7. package/dist/commands/init.d.ts +9 -0
  8. package/dist/commands/init.d.ts.map +1 -0
  9. package/dist/commands/init.js +212 -0
  10. package/dist/commands/init.js.map +1 -0
  11. package/dist/commands/install.d.ts +10 -0
  12. package/dist/commands/install.d.ts.map +1 -0
  13. package/dist/commands/install.js +67 -0
  14. package/dist/commands/install.js.map +1 -0
  15. package/dist/commands/logs.d.ts +10 -0
  16. package/dist/commands/logs.d.ts.map +1 -0
  17. package/dist/commands/logs.js +42 -0
  18. package/dist/commands/logs.js.map +1 -0
  19. package/dist/commands/release.d.ts +9 -0
  20. package/dist/commands/release.d.ts.map +1 -0
  21. package/dist/commands/release.js +32 -0
  22. package/dist/commands/release.js.map +1 -0
  23. package/dist/commands/stage.d.ts +5 -0
  24. package/dist/commands/stage.d.ts.map +1 -0
  25. package/dist/commands/stage.js +37 -0
  26. package/dist/commands/stage.js.map +1 -0
  27. package/dist/commands/status.d.ts +5 -0
  28. package/dist/commands/status.d.ts.map +1 -0
  29. package/dist/commands/status.js +61 -0
  30. package/dist/commands/status.js.map +1 -0
  31. package/dist/config/loader.d.ts +22 -0
  32. package/dist/config/loader.d.ts.map +1 -0
  33. package/dist/config/loader.js +66 -0
  34. package/dist/config/loader.js.map +1 -0
  35. package/dist/config/types.d.ts +42 -0
  36. package/dist/config/types.d.ts.map +1 -0
  37. package/dist/config/types.js +10 -0
  38. package/dist/config/types.js.map +1 -0
  39. package/dist/index.d.ts +3 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +52 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/utils/files.d.ts +25 -0
  44. package/dist/utils/files.d.ts.map +1 -0
  45. package/dist/utils/files.js +47 -0
  46. package/dist/utils/files.js.map +1 -0
  47. package/dist/utils/git.d.ts +33 -0
  48. package/dist/utils/git.d.ts.map +1 -0
  49. package/dist/utils/git.js +63 -0
  50. package/dist/utils/git.js.map +1 -0
  51. package/dist/utils/pm2.d.ts +39 -0
  52. package/dist/utils/pm2.d.ts.map +1 -0
  53. package/dist/utils/pm2.js +83 -0
  54. package/dist/utils/pm2.js.map +1 -0
  55. package/dist/utils/process-manager.d.ts +37 -0
  56. package/dist/utils/process-manager.d.ts.map +1 -0
  57. package/dist/utils/process-manager.js +17 -0
  58. package/dist/utils/process-manager.js.map +1 -0
  59. package/dist/utils/shell.d.ts +24 -0
  60. package/dist/utils/shell.d.ts.map +1 -0
  61. package/dist/utils/shell.js +51 -0
  62. package/dist/utils/shell.js.map +1 -0
  63. package/dist/utils/systemd.d.ts +34 -0
  64. package/dist/utils/systemd.d.ts.map +1 -0
  65. package/dist/utils/systemd.js +79 -0
  66. package/dist/utils/systemd.js.map +1 -0
  67. package/package.json +60 -0
  68. package/templates/post-receive.sh +55 -0
@@ -0,0 +1,83 @@
1
+ import { exec, execOutput } from './shell.js';
2
+ /**
3
+ * PM2 Process Manager implementation
4
+ */
5
+ export class PM2ProcessManager {
6
+ name = 'pm2';
7
+ buildEnv(options) {
8
+ return options?.home ? `PM2_HOME=${options.home} ` : '';
9
+ }
10
+ restart(processName, options) {
11
+ const env = this.buildEnv(options);
12
+ exec(`${env}pm2 restart ${processName} --no-color`, { silent: options?.silent });
13
+ }
14
+ list(options) {
15
+ const env = this.buildEnv(options);
16
+ return execOutput(`${env}pm2 list --no-color`);
17
+ }
18
+ save(options) {
19
+ const env = this.buildEnv(options);
20
+ exec(`${env}pm2 save`, { silent: true });
21
+ }
22
+ show(processName, options) {
23
+ const env = this.buildEnv(options);
24
+ return execOutput(`${env}pm2 show ${processName} --no-color`);
25
+ }
26
+ exists(processName, options) {
27
+ try {
28
+ this.show(processName, options);
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ asUser(user, command, options) {
36
+ const env = this.buildEnv(options);
37
+ exec(`sudo -u ${user} ${env}pm2 ${command} --no-color`, { silent: options?.silent });
38
+ }
39
+ }
40
+ // Legacy function exports for backward compatibility
41
+ /**
42
+ * Restart PM2 process
43
+ */
44
+ export function pm2Restart(processName, pm2Home) {
45
+ const pm2 = new PM2ProcessManager();
46
+ pm2.restart(processName, { home: pm2Home });
47
+ }
48
+ /**
49
+ * Get PM2 process list
50
+ */
51
+ export function pm2List(pm2Home) {
52
+ const pm2 = new PM2ProcessManager();
53
+ return pm2.list({ home: pm2Home });
54
+ }
55
+ /**
56
+ * Save PM2 process list
57
+ */
58
+ export function pm2Save(pm2Home) {
59
+ const pm2 = new PM2ProcessManager();
60
+ pm2.save({ home: pm2Home });
61
+ }
62
+ /**
63
+ * Get PM2 process info
64
+ */
65
+ export function pm2Show(processName, pm2Home) {
66
+ const pm2 = new PM2ProcessManager();
67
+ return pm2.show(processName, { home: pm2Home });
68
+ }
69
+ /**
70
+ * Check if PM2 process exists
71
+ */
72
+ export function pm2ProcessExists(processName, pm2Home) {
73
+ const pm2 = new PM2ProcessManager();
74
+ return pm2.exists(processName, { home: pm2Home });
75
+ }
76
+ /**
77
+ * Run PM2 command as specific user (for server-side)
78
+ */
79
+ export function pm2AsUser(user, command, pm2Home) {
80
+ const pm2 = new PM2ProcessManager();
81
+ pm2.asUser(user, command, { home: pm2Home });
82
+ }
83
+ //# sourceMappingURL=pm2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm2.js","sourceRoot":"","sources":["../../src/utils/pm2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Abstract interface for process managers (PM2, systemd, etc.)
3
+ */
4
+ export interface ProcessManager {
5
+ /** Name of the process manager */
6
+ readonly name: string;
7
+ /** Restart a process by name */
8
+ restart(processName: string, options?: ProcessManagerOptions): void;
9
+ /** Get status/list of processes */
10
+ list(options?: ProcessManagerOptions): string;
11
+ /** Save current process state (for resurrection after reboot) */
12
+ save(options?: ProcessManagerOptions): void;
13
+ /** Get info about a specific process */
14
+ show(processName: string, options?: ProcessManagerOptions): string;
15
+ /** Check if a process exists */
16
+ exists(processName: string, options?: ProcessManagerOptions): boolean;
17
+ /** Run command as specific user (for server-side) */
18
+ asUser(user: string, command: string, options?: ProcessManagerOptions): void;
19
+ }
20
+ /**
21
+ * Options for process manager commands
22
+ */
23
+ export interface ProcessManagerOptions {
24
+ /** Home directory for the process manager */
25
+ home?: string;
26
+ /** Run silently (no output) */
27
+ silent?: boolean;
28
+ }
29
+ /**
30
+ * Process manager types
31
+ */
32
+ export type ProcessManagerType = 'pm2' | 'systemd';
33
+ /**
34
+ * Factory function to create a process manager instance
35
+ */
36
+ export declare function createProcessManager(type: ProcessManagerType): ProcessManager;
37
+ //# sourceMappingURL=process-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/utils/process-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,gCAAgC;IAChC,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAEpE,mCAAmC;IACnC,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC;IAE9C,iEAAiE;IACjE,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAE5C,wCAAwC;IACxC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC;IAEnE,gCAAgC;IAChC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAEtE,qDAAqD;IACrD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC9E;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,SAAS,CAAC;AAEnD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAY7E"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Factory function to create a process manager instance
3
+ */
4
+ export function createProcessManager(type) {
5
+ switch (type) {
6
+ case 'pm2':
7
+ // Lazy import to avoid loading unused modules
8
+ const { PM2ProcessManager } = require('./pm2.js');
9
+ return new PM2ProcessManager();
10
+ case 'systemd':
11
+ const { SystemdProcessManager } = require('./systemd.js');
12
+ return new SystemdProcessManager();
13
+ default:
14
+ throw new Error(`Unknown process manager type: ${type}`);
15
+ }
16
+ }
17
+ //# sourceMappingURL=process-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../src/utils/process-manager.ts"],"names":[],"mappings":"AA0CA;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAwB;IAC3D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,8CAA8C;YAC9C,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;YAClD,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACjC,KAAK,SAAS;YACZ,MAAM,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;YAC1D,OAAO,IAAI,qBAAqB,EAAE,CAAC;QACrC;YACE,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Execute a shell command and return output
3
+ */
4
+ export declare function exec(command: string, options?: {
5
+ cwd?: string;
6
+ silent?: boolean;
7
+ }): string;
8
+ /**
9
+ * Execute command and return output (always silent)
10
+ */
11
+ export declare function execOutput(command: string, cwd?: string): string;
12
+ /**
13
+ * Check if a command exists
14
+ */
15
+ export declare function commandExists(command: string): boolean;
16
+ /**
17
+ * Check if running as root
18
+ */
19
+ export declare function isRoot(): boolean;
20
+ /**
21
+ * Get current username
22
+ */
23
+ export declare function getCurrentUser(): string;
24
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAc9F;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED;;GAEG;AACH,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -0,0 +1,51 @@
1
+ import { execSync } from 'child_process';
2
+ /**
3
+ * Execute a shell command and return output
4
+ */
5
+ export function exec(command, options = {}) {
6
+ try {
7
+ const result = execSync(command, {
8
+ cwd: options.cwd,
9
+ encoding: 'utf-8',
10
+ stdio: options.silent ? 'pipe' : 'inherit'
11
+ });
12
+ return result?.trim() || '';
13
+ }
14
+ catch (error) {
15
+ if (error instanceof Error && 'stdout' in error) {
16
+ return error.stdout?.trim() || '';
17
+ }
18
+ throw error;
19
+ }
20
+ }
21
+ /**
22
+ * Execute command and return output (always silent)
23
+ */
24
+ export function execOutput(command, cwd) {
25
+ return exec(command, { cwd, silent: true });
26
+ }
27
+ /**
28
+ * Check if a command exists
29
+ */
30
+ export function commandExists(command) {
31
+ try {
32
+ execSync(`which ${command}`, { stdio: 'pipe' });
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ /**
40
+ * Check if running as root
41
+ */
42
+ export function isRoot() {
43
+ return process.getuid?.() === 0;
44
+ }
45
+ /**
46
+ * Get current username
47
+ */
48
+ export function getCurrentUser() {
49
+ return process.env.USER || process.env.USERNAME || 'unknown';
50
+ }
51
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,OAAe,EAAE,UAA8C,EAAE;IACpF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE;YAC/B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SAC3C,CAAC,CAAC;QACH,OAAO,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YAChD,OAAQ,KAA4B,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC5D,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,GAAY;IACtD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,CAAC;QACH,QAAQ,CAAC,SAAS,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM;IACpB,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,SAAS,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { ProcessManager, ProcessManagerOptions } from './process-manager.js';
2
+ /**
3
+ * Systemd Process Manager implementation
4
+ *
5
+ * Uses systemctl to manage services. The processName is expected to be
6
+ * a systemd service name (e.g., "myapp.service" or just "myapp").
7
+ */
8
+ export declare class SystemdProcessManager implements ProcessManager {
9
+ readonly name = "systemd";
10
+ private serviceName;
11
+ restart(processName: string, options?: ProcessManagerOptions): void;
12
+ list(options?: ProcessManagerOptions): string;
13
+ save(options?: ProcessManagerOptions): void;
14
+ show(processName: string, options?: ProcessManagerOptions): string;
15
+ exists(processName: string, options?: ProcessManagerOptions): boolean;
16
+ asUser(user: string, command: string, options?: ProcessManagerOptions): void;
17
+ /**
18
+ * Enable service to start on boot
19
+ */
20
+ enable(processName: string): void;
21
+ /**
22
+ * Disable service from starting on boot
23
+ */
24
+ disable(processName: string): void;
25
+ /**
26
+ * Reload systemd daemon (after changing unit files)
27
+ */
28
+ daemonReload(): void;
29
+ /**
30
+ * Check if service is active
31
+ */
32
+ isActive(processName: string): boolean;
33
+ }
34
+ //# sourceMappingURL=systemd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemd.d.ts","sourceRoot":"","sources":["../../src/utils/systemd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGlF;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,QAAQ,CAAC,IAAI,aAAa;IAE1B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAKnE,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAK7C,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAM3C,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAKlE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO;IAUrE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;IAM5E;;OAEG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKjC;;OAEG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKlC;;OAEG;IACH,YAAY,IAAI,IAAI;IAIpB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;CASvC"}
@@ -0,0 +1,79 @@
1
+ import { exec, execOutput } from './shell.js';
2
+ /**
3
+ * Systemd Process Manager implementation
4
+ *
5
+ * Uses systemctl to manage services. The processName is expected to be
6
+ * a systemd service name (e.g., "myapp.service" or just "myapp").
7
+ */
8
+ export class SystemdProcessManager {
9
+ name = 'systemd';
10
+ serviceName(name) {
11
+ return name.endsWith('.service') ? name : `${name}.service`;
12
+ }
13
+ restart(processName, options) {
14
+ const service = this.serviceName(processName);
15
+ exec(`sudo systemctl restart ${service}`, { silent: options?.silent });
16
+ }
17
+ list(options) {
18
+ // List all running services
19
+ return execOutput('systemctl list-units --type=service --state=running --no-pager');
20
+ }
21
+ save(options) {
22
+ // systemd auto-saves, but we can enable the service for boot
23
+ // This is a no-op for systemd as it manages state automatically
24
+ console.log('Note: systemd manages service state automatically.');
25
+ }
26
+ show(processName, options) {
27
+ const service = this.serviceName(processName);
28
+ return execOutput(`systemctl status ${service} --no-pager`);
29
+ }
30
+ exists(processName, options) {
31
+ const service = this.serviceName(processName);
32
+ try {
33
+ execOutput(`systemctl cat ${service} 2>/dev/null`);
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ asUser(user, command, options) {
41
+ // For systemd, we use systemctl directly (no user switching needed)
42
+ // The 'command' here should be a systemctl action like 'restart myapp'
43
+ exec(`sudo systemctl ${command}`, { silent: options?.silent });
44
+ }
45
+ /**
46
+ * Enable service to start on boot
47
+ */
48
+ enable(processName) {
49
+ const service = this.serviceName(processName);
50
+ exec(`sudo systemctl enable ${service}`, { silent: true });
51
+ }
52
+ /**
53
+ * Disable service from starting on boot
54
+ */
55
+ disable(processName) {
56
+ const service = this.serviceName(processName);
57
+ exec(`sudo systemctl disable ${service}`, { silent: true });
58
+ }
59
+ /**
60
+ * Reload systemd daemon (after changing unit files)
61
+ */
62
+ daemonReload() {
63
+ exec('sudo systemctl daemon-reload', { silent: true });
64
+ }
65
+ /**
66
+ * Check if service is active
67
+ */
68
+ isActive(processName) {
69
+ const service = this.serviceName(processName);
70
+ try {
71
+ const result = execOutput(`systemctl is-active ${service}`);
72
+ return result.trim() === 'active';
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=systemd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemd.js","sourceRoot":"","sources":["../../src/utils/systemd.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,OAAO,qBAAqB;IACvB,IAAI,GAAG,SAAS,CAAC;IAElB,WAAW,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC;IAC9D,CAAC;IAED,OAAO,CAAC,WAAmB,EAAE,OAA+B;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC,0BAA0B,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,CAAC,OAA+B;QAClC,4BAA4B;QAC5B,OAAO,UAAU,CAAC,gEAAgE,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,CAAC,OAA+B;QAClC,6DAA6D;QAC7D,gEAAgE;QAChE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,CAAC,WAAmB,EAAE,OAA+B;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC9C,OAAO,UAAU,CAAC,oBAAoB,OAAO,aAAa,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,CAAC,WAAmB,EAAE,OAA+B;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC;YACH,UAAU,CAAC,iBAAiB,OAAO,cAAc,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,OAAe,EAAE,OAA+B;QACnE,oEAAoE;QACpE,uEAAuE;QACvE,IAAI,CAAC,kBAAkB,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAmB;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC,yBAAyB,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,WAAmB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC,0BAA0B,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,WAAmB;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,UAAU,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC;YAC5D,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "git-push-deploy-cli",
3
+ "version": "0.1.0",
4
+ "description": "Git Push Deploy - CLI for git-based deployments. Push to bare repos, auto npm install, PM2/systemd restart. Monorepo-ready.",
5
+ "keywords": [
6
+ "git",
7
+ "push",
8
+ "deploy",
9
+ "deployment",
10
+ "pm2",
11
+ "systemd",
12
+ "bare-repo",
13
+ "post-receive",
14
+ "hook",
15
+ "monorepo",
16
+ "cli",
17
+ "gpd"
18
+ ],
19
+ "author": "Andreas Schulz <aschulz@kairox.de>",
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/aschulz-kairox/git-push-deploy-cli.git"
24
+ },
25
+ "homepage": "https://github.com/aschulz-kairox/git-push-deploy-cli#readme",
26
+ "bugs": {
27
+ "url": "https://github.com/aschulz-kairox/git-push-deploy-cli/issues"
28
+ },
29
+ "type": "module",
30
+ "bin": {
31
+ "git-push-deploy": "./dist/index.js",
32
+ "gpd": "./dist/index.js"
33
+ },
34
+ "main": "./dist/index.js",
35
+ "types": "./dist/index.d.ts",
36
+ "files": [
37
+ "dist",
38
+ "templates"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "dev": "tsc --watch",
43
+ "start": "node dist/index.js",
44
+ "lint": "eslint src",
45
+ "test": "vitest run",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "dependencies": {
49
+ "commander": "^13.0.0",
50
+ "chalk": "^5.4.1"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^22.10.1",
54
+ "typescript": "^5.7.2",
55
+ "vitest": "^2.1.8"
56
+ },
57
+ "engines": {
58
+ "node": ">=18.0.0"
59
+ }
60
+ }
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+ # Post-receive hook template
3
+ # Copy this to your bare repo: hooks/post-receive
4
+ # Or use: git-deploy init <service>
5
+
6
+ set -e
7
+
8
+ # Configuration - adjust these values
9
+ SERVICE="my-service"
10
+ TARGET_DIR="/opt/myapp/my-service"
11
+ LOG_FILE="/var/log/deploy-my-service.log"
12
+ PM2_NAME="my-service"
13
+ PM2_HOME="/opt/myapp/.pm2"
14
+ PACKAGES=("my-service")
15
+ MAIN_PKG="my-service"
16
+ USER="myapp"
17
+
18
+ log() {
19
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | sudo tee -a "$LOG_FILE"
20
+ }
21
+
22
+ log "=== Deployment started ==="
23
+
24
+ while read oldrev newrev refname; do
25
+ BRANCH=$(echo "$refname" | sed 's|refs/heads/||')
26
+ log "Received push to branch: $BRANCH"
27
+
28
+ if [ "$BRANCH" != "main" ] && [ "$BRANCH" != "master" ]; then
29
+ log "Ignoring non-main branch"
30
+ continue
31
+ fi
32
+
33
+ # Extract packages using git archive
34
+ for pkg in "${PACKAGES[@]}"; do
35
+ log "Extracting $pkg..."
36
+ git archive "$BRANCH" "$pkg/" 2>/dev/null | sudo tar -x -C "$TARGET_DIR/" || true
37
+ done
38
+
39
+ # Set ownership
40
+ sudo chown -R $USER:$USER "$TARGET_DIR"
41
+
42
+ # Install dependencies
43
+ log "Installing dependencies..."
44
+ cd "$TARGET_DIR/$MAIN_PKG"
45
+ sudo -u $USER npm install --omit=dev 2>&1 | sudo tee -a "$LOG_FILE"
46
+
47
+ # Restart PM2
48
+ log "Restarting $PM2_NAME..."
49
+ sudo -u $USER PM2_HOME=$PM2_HOME pm2 restart "$PM2_NAME" --no-color 2>&1 | sudo tee -a "$LOG_FILE"
50
+
51
+ log "Current status:"
52
+ sudo -u $USER PM2_HOME=$PM2_HOME pm2 list --no-color 2>&1 | sudo tee -a "$LOG_FILE"
53
+ done
54
+
55
+ log "=== Deployment completed ==="