@ongtrieuhau861457/runner-tailscale-sync 1.260202.11948 → 1.260202.12010

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 CHANGED
@@ -26,61 +26,55 @@ npm install -g runner-tailscale-sync
26
26
  ### CLI
27
27
 
28
28
  ```bash
29
- # Full sync workflow
29
+ # Run full workflow (init → detect → pull → stop → push)
30
30
  TAILSCALE_ENABLE=1 runner-sync
31
31
 
32
- # Chỉ khởi tạo Tailscale
33
- runner-sync init
34
-
35
- # Chỉ push git
36
- runner-sync push
37
-
38
- # Xem status
39
- runner-sync status
40
-
41
32
  # Custom working directory
42
33
  runner-sync --cwd /path/to/project
43
34
 
44
35
  # Verbose mode
45
- runner-sync -v
36
+ runner-sync --verbose
37
+
38
+ # Quiet mode
39
+ runner-sync --quiet
46
40
  ```
47
41
 
42
+ **Workflow tự động**:
43
+
44
+ 1. **Init**: Cài đặt Tailscale và kết nối mạng
45
+ 2. **Detect**: Tìm runner trước đó (cùng tag)
46
+ 3. **Pull**: Đồng bộ `.runner-data` từ runner cũ (nếu có)
47
+ 4. **Stop**: Dừng services trên runner cũ (nếu có)
48
+ 5. **Push**: Đẩy `.runner-data` lên git (nếu có runner cũ)
49
+
48
50
  ### Library
49
51
 
50
52
  ```javascript
51
- const runnerSync = require('runner-tailscale-sync');
53
+ const runnerSync = require("runner-tailscale-sync");
52
54
 
53
- // Full sync
55
+ // Run full workflow
54
56
  await runnerSync.sync({
55
- cwd: '/path/to/project',
57
+ cwd: "/path/to/project",
56
58
  verbose: true,
57
59
  });
58
60
 
59
- // Chỉ init
60
- await runnerSync.init();
61
+ // Access individual modules (advanced)
62
+ const { Config, Logger, syncOrchestrator } = require("runner-tailscale-sync");
61
63
 
62
- // Chỉ push git
63
- await runnerSync.push();
64
+ const config = new Config({ cwd: process.cwd() });
65
+ const logger = new Logger({ packageName: "my-tool", version: "1.0.0" });
64
66
 
65
- // Xem status
66
- await runnerSync.status();
67
+ await syncOrchestrator.orchestrate(config, logger);
67
68
  ```
68
69
 
69
70
  ### Advanced Usage - Sử dụng modules riêng lẻ
70
71
 
71
72
  ```javascript
72
- const {
73
- Config,
74
- Logger,
75
- syncOrchestrator,
76
- runnerDetector,
77
- dataSync,
78
- tailscale
79
- } = require('runner-tailscale-sync');
73
+ const { Config, Logger, syncOrchestrator, runnerDetector, dataSync, tailscale } = require("runner-tailscale-sync");
80
74
 
81
75
  // Tạo config
82
76
  const config = new Config({ cwd: process.cwd() });
83
- const logger = new Logger({ packageName: 'my-tool', version: '1.0.0' });
77
+ const logger = new Logger({ packageName: "my-tool", version: "1.0.0" });
84
78
 
85
79
  // Detect previous runner
86
80
  const detection = await runnerDetector.detectPreviousRunner(config, logger);
@@ -177,7 +171,7 @@ Tất cả dữ liệu được lưu trong `.runner-data/`:
177
171
  TAILSCALE_CLIENT_ID: $(TAILSCALE_CLIENT_ID)
178
172
  TAILSCALE_CLIENT_SECRET: $(TAILSCALE_CLIENT_SECRET)
179
173
  TAILSCALE_ENABLE: 1
180
- displayName: 'Sync Runner Data'
174
+ displayName: "Sync Runner Data"
181
175
  ```
182
176
 
183
177
  ### Self-hosted Runner
@@ -231,6 +225,7 @@ node -e "require('./src/index.js').status().then(console.log)"
231
225
  Version theo giờ Việt Nam (UTC+7): `1.yyMMdd.1HHmm`
232
226
 
233
227
  Ví dụ:
228
+
234
229
  - Build lúc 15:30 ngày 02/02/2025 → `1.250202.11530`
235
230
  - Build lúc 09:45 ngày 15/03/2025 → `1.250315.10945`
236
231
 
@@ -246,11 +241,13 @@ Ví dụ:
246
241
  ### Windows
247
242
 
248
243
  Trên Windows, cần cài thêm:
244
+
249
245
  - [Tailscale for Windows](https://tailscale.com/download/windows)
250
246
  - Git for Windows (có sẵn ssh/scp)
251
247
  - Hoặc cài rsync qua: `choco install rsync` hoặc WSL
252
248
 
253
249
  Cấu hình đường dẫn trong `.env`:
250
+
254
251
  ```env
255
252
  SSH_PATH=C:\Program Files\Git\usr\bin\ssh.exe
256
253
  RSYNC_PATH=C:\Program Files\rsync\rsync.exe
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * bin/runner-sync.js
4
- * CLI entry point
4
+ * CLI entry point - Always run full workflow
5
5
  */
6
6
 
7
- const path = require("path");
8
7
  const Config = require("../src/utils/config");
9
8
  const Logger = require("../src/utils/logger");
10
9
  const { parseArgs, printHelp } = require("../src/cli/parser");
10
+ const syncOrchestrator = require("../src/core/sync-orchestrator");
11
11
  const pkg = require("../package.json");
12
12
 
13
13
  // Parse arguments
14
- const { command, options } = parseArgs(process.argv);
14
+ const { options } = parseArgs(process.argv);
15
15
 
16
16
  // Handle help
17
17
  if (options.help) {
@@ -20,19 +20,17 @@ if (options.help) {
20
20
  }
21
21
 
22
22
  // Handle version
23
- if (command === "version") {
23
+ if (options.version) {
24
24
  console.log(`${pkg.name} v${pkg.version}`);
25
25
  process.exit(0);
26
26
  }
27
27
 
28
- // Create config
28
+ // Create config & logger
29
29
  const config = new Config(options);
30
-
31
- // Create logger
32
30
  const logger = new Logger({
33
31
  packageName: pkg.name,
34
32
  version: pkg.version,
35
- command,
33
+ command: "sync",
36
34
  verbose: options.verbose,
37
35
  quiet: options.quiet,
38
36
  });
@@ -40,46 +38,16 @@ const logger = new Logger({
40
38
  // Print banner
41
39
  logger.printBanner();
42
40
 
43
- // Run command
41
+ // Run full workflow
44
42
  (async () => {
45
43
  try {
46
- let commandModule;
47
-
48
- switch (command) {
49
- case "init":
50
- commandModule = require("../src/cli/commands/init");
51
- break;
52
- case "sync":
53
- commandModule = require("../src/cli/commands/sync");
54
- break;
55
- case "push":
56
- commandModule = require("../src/cli/commands/push");
57
- break;
58
- case "status":
59
- commandModule = require("../src/cli/commands/status");
60
- break;
61
- default:
62
- logger.error(`Unknown command: ${command}`);
63
- printHelp();
64
- process.exit(1);
65
- }
66
-
67
- const result = await commandModule.run(config, logger);
68
-
69
- if (result.success) {
70
- process.exit(0);
71
- } else {
72
- process.exit(1);
73
- }
44
+ const result = await syncOrchestrator.orchestrate(config, logger);
45
+ process.exit(result.success ? 0 : 1);
74
46
  } catch (err) {
75
47
  logger.error(err.message);
76
-
77
48
  if (options.verbose && err.stack) {
78
49
  logger.debug(err.stack);
79
50
  }
80
-
81
- // Exit with appropriate code
82
- const exitCode = err.exitCode || 1;
83
- process.exit(exitCode);
51
+ process.exit(err.exitCode || 1);
84
52
  }
85
53
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ongtrieuhau861457/runner-tailscale-sync",
3
- "version": "1.260202.11948",
3
+ "version": "1.260202.12010",
4
4
  "description": "Đồng bộ runner-data giữa các runner trên GitHub Actions, Azure Pipeline qua Tailscale network",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/cli/parser.js CHANGED
@@ -3,32 +3,20 @@
3
3
  * Parse command-line arguments
4
4
  */
5
5
 
6
- /**
7
- * Parse command line arguments
8
- * Returns: { command, options }
9
- */
10
6
  function parseArgs(argv) {
11
- const args = argv.slice(2); // Remove node and script path
7
+ const args = argv.slice(2);
12
8
 
13
9
  const options = {
14
10
  cwd: null,
15
11
  verbose: false,
16
12
  quiet: false,
17
13
  help: false,
14
+ version: false,
18
15
  };
19
16
 
20
- let command = "sync"; // Default command
21
-
22
17
  for (let i = 0; i < args.length; i++) {
23
18
  const arg = args[i];
24
19
 
25
- // Commands
26
- if (arg === "init" || arg === "sync" || arg === "push" || arg === "status") {
27
- command = arg;
28
- continue;
29
- }
30
-
31
- // Options
32
20
  if (arg === "--cwd" && i + 1 < args.length) {
33
21
  options.cwd = args[++i];
34
22
  continue;
@@ -50,60 +38,56 @@ function parseArgs(argv) {
50
38
  }
51
39
 
52
40
  if (arg === "--version") {
53
- command = "version";
41
+ options.version = true;
54
42
  continue;
55
43
  }
56
44
  }
57
45
 
58
- return { command, options };
46
+ return { options };
59
47
  }
60
48
 
61
- /**
62
- * Print help
63
- */
64
49
  function printHelp() {
65
50
  console.log(`
66
51
  runner-tailscale-sync - Đồng bộ runner data qua Tailscale network
67
52
 
68
53
  USAGE:
69
- runner-sync [command] [options]
54
+ runner-sync [options]
70
55
 
71
- COMMANDS:
72
- init Khởi tạo Tailscale detect previous runner
73
- sync Full sync workflow (init + pull + stop services + push git)
74
- push Push .runner-data to git only
75
- status Show Tailscale status
76
- --version Show version
56
+ DESCRIPTION:
57
+ Tự động chạy workflow: init → detect pull → stop → push
58
+ - Init: Cài đặt kết nối Tailscale
59
+ - Detect: Tìm runner trước đó trên mạng
60
+ - Pull: Đồng bộ .runner-data (nếu có runner cũ)
61
+ - Stop: Dừng services trên runner cũ (nếu có)
62
+ - Push: Đẩy code lên git
77
63
 
78
64
  OPTIONS:
79
65
  --cwd <path> Set working directory (default: current dir)
80
- --verbose, -v Enable verbose logging
81
- --quiet, -q Suppress non-error output
66
+ --verbose Enable verbose logging
67
+ --quiet Suppress non-error output
82
68
  --help, -h Show this help
69
+ --version Show version
83
70
 
84
71
  ENVIRONMENT VARIABLES:
85
72
  TAILSCALE_CLIENT_ID OAuth client ID (required if TAILSCALE_ENABLE=1)
86
73
  TAILSCALE_CLIENT_SECRET OAuth client secret (required if TAILSCALE_ENABLE=1)
87
74
  TAILSCALE_TAGS Tailscale tags (default: tag:ci)
88
75
  TAILSCALE_ENABLE Enable Tailscale (0 or 1, default: 0)
89
- SERVICES_TO_STOP Comma-separated services to stop (default: cloudflared,pocketbase,http-server)
76
+ SERVICES_TO_STOP Services to stop on old runner (default: cloudflared,pocketbase)
90
77
  GIT_PUSH_ENABLED Enable git push (0 or 1, default: 1)
91
78
  GIT_BRANCH Git branch (default: main)
92
79
  TOOL_CWD Working directory (can be overridden by --cwd)
93
80
 
94
81
  EXAMPLES:
95
- # Full sync with Tailscale
82
+ # Run full workflow
96
83
  TAILSCALE_ENABLE=1 runner-sync
97
84
 
98
- # Just push to git
99
- runner-sync push
85
+ # Verbose mode
86
+ runner-sync --verbose
100
87
 
101
88
  # Custom working directory
102
89
  runner-sync --cwd /path/to/project
103
90
 
104
- # Verbose mode
105
- runner-sync -v
106
-
107
91
  For more info: https://github.com/yourname/runner-tailscale-sync
108
92
  `);
109
93
  }
@@ -50,9 +50,6 @@ function plan(input) {
50
50
  };
51
51
  }
52
52
 
53
- /**
54
- * Execute - chạy từng bước
55
- */
56
53
  async function execute(planResult, input) {
57
54
  const { config, logger } = input;
58
55
  const results = {};
@@ -77,25 +74,45 @@ async function execute(planResult, input) {
77
74
 
78
75
  case "detect_previous_runner":
79
76
  results.detection = await runnerDetector.detectPreviousRunner(config, logger);
77
+
78
+ // Set flag for later steps
79
+ const hasPreviousRunner = results.detection?.previousRunner != null;
80
+
81
+ if (!hasPreviousRunner) {
82
+ logger.info("No previous runner detected - skipping pull/stop/push");
83
+ }
80
84
  break;
81
85
 
82
86
  case "pull_data":
83
- results.pullData = await dataSync.pullData(
84
- config,
85
- results.detection?.previousRunner,
86
- logger
87
- );
87
+ // Check if we have previous runner
88
+ if (!results.detection?.previousRunner) {
89
+ logger.info("Skipping pull - no previous runner");
90
+ results.pullData = { success: true, skipped: true };
91
+ break;
92
+ }
93
+
94
+ results.pullData = await dataSync.pullData(config, results.detection.previousRunner, logger);
88
95
  break;
89
96
 
90
97
  case "stop_remote_services":
91
- results.stopServices = await serviceController.stopRemoteServices(
92
- config,
93
- results.detection?.previousRunner,
94
- logger
95
- );
98
+ // Check if we have previous runner
99
+ if (!results.detection?.previousRunner) {
100
+ logger.info("Skipping service stop - no previous runner");
101
+ results.stopServices = { success: true, skipped: true };
102
+ break;
103
+ }
104
+
105
+ results.stopServices = await serviceController.stopRemoteServices(config, results.detection.previousRunner, logger);
96
106
  break;
97
107
 
98
108
  case "push_to_git":
109
+ // Check if we have previous runner
110
+ if (!results.detection?.previousRunner) {
111
+ logger.info("Skipping git push - no previous runner");
112
+ results.pushGit = { success: true, skipped: true };
113
+ break;
114
+ }
115
+
99
116
  results.pushGit = await pushToGit(config, logger);
100
117
  break;
101
118
 
@@ -150,7 +167,7 @@ function report(results, input) {
150
167
  */
151
168
  async function setupDirectories(config, logger) {
152
169
  logger.info("Setting up directories...");
153
-
170
+
154
171
  const dirs = config.getDirectoriesToEnsure();
155
172
  fs_adapter.ensureDirs(dirs);
156
173
 
@@ -175,13 +192,7 @@ async function connectTailscale(config, logger) {
175
192
  }
176
193
 
177
194
  // Login
178
- await tailscale.login(
179
- config.tailscaleClientId,
180
- config.tailscaleClientSecret,
181
- config.tailscaleTags,
182
- logger,
183
- config
184
- );
195
+ await tailscale.login(config.tailscaleClientId, config.tailscaleClientSecret, config.tailscaleTags, logger, config);
185
196
 
186
197
  // Get connection info
187
198
  const ip = tailscale.getIP(logger);
@@ -241,7 +252,7 @@ async function orchestrate(config, logger) {
241
252
 
242
253
  // Step 3: Plan
243
254
  const planResult = plan(input);
244
- logger.debug(`Planned ${planResult.steps.filter(s => s.enabled).length} steps`);
255
+ logger.debug(`Planned ${planResult.steps.filter((s) => s.enabled).length} steps`);
245
256
 
246
257
  // Step 4: Execute
247
258
  const execResult = await execute(planResult, input);
package/src/index.js CHANGED
@@ -110,9 +110,6 @@ async function status(options = {}) {
110
110
  module.exports = {
111
111
  // Main API
112
112
  sync,
113
- init,
114
- push,
115
- status,
116
113
 
117
114
  // Core modules
118
115
  syncOrchestrator,