devs-webhook 1.0.0__tar.gz → 1.0.2__tar.gz

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 (50) hide show
  1. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/PKG-INFO +1 -1
  2. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/cli/worker.py +23 -6
  3. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/config.py +14 -1
  4. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/container_pool.py +12 -2
  5. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/test_dispatcher.py +2 -2
  6. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook.egg-info/PKG-INFO +1 -1
  7. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/pyproject.toml +1 -1
  8. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/LICENSE +0 -0
  9. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/README.md +0 -0
  10. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/__init__.py +0 -0
  11. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/app.py +0 -0
  12. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/cli/__init__.py +0 -0
  13. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/__init__.py +0 -0
  14. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/base_dispatcher.py +0 -0
  15. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/claude_dispatcher.py +0 -0
  16. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/deduplication.py +0 -0
  17. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/repository_manager.py +0 -0
  18. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/task_processor.py +0 -0
  19. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/webhook_config.py +0 -0
  20. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/core/webhook_handler.py +0 -0
  21. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/github/__init__.py +0 -0
  22. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/github/app_auth.py +0 -0
  23. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/github/client.py +0 -0
  24. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/github/models.py +0 -0
  25. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/github/parser.py +0 -0
  26. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/main_cli.py +0 -0
  27. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/sources/__init__.py +0 -0
  28. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/sources/base.py +0 -0
  29. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/sources/sqs_source.py +0 -0
  30. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/sources/webhook_source.py +0 -0
  31. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/utils/__init__.py +0 -0
  32. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/utils/async_utils.py +0 -0
  33. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/utils/container_logs.py +0 -0
  34. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/utils/github.py +0 -0
  35. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/utils/logging.py +0 -0
  36. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/utils/s3_artifacts.py +0 -0
  37. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook/utils/serialization.py +0 -0
  38. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook.egg-info/SOURCES.txt +0 -0
  39. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook.egg-info/dependency_links.txt +0 -0
  40. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook.egg-info/entry_points.txt +0 -0
  41. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook.egg-info/requires.txt +0 -0
  42. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/devs_webhook.egg-info/top_level.txt +0 -0
  43. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/setup.cfg +0 -0
  44. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/tests/test_allowlist.py +0 -0
  45. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/tests/test_authentication.py +0 -0
  46. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/tests/test_authorized_users.py +0 -0
  47. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/tests/test_container_logs.py +0 -0
  48. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/tests/test_single_queue.py +0 -0
  49. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/tests/test_sqs_burst.py +0 -0
  50. {devs_webhook-1.0.0 → devs_webhook-1.0.2}/tests/test_webhook_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devs-webhook
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: GitHub webhook handler for automated devcontainer operations with Claude Code
5
5
  Author: Dan Lester
6
6
  License-Expression: MIT
@@ -29,7 +29,8 @@ logger = structlog.get_logger()
29
29
  @click.option('--repo-path', required=True, help='Path to repository on host')
30
30
  @click.option('--task-type', default='claude', help='Task type: claude or tests (default: claude)')
31
31
  @click.option('--timeout', default=3600, help='Task timeout in seconds (default: 3600)')
32
- def worker(task_id: str, dev_name: str, repo_name: str, repo_path: str, task_type: str, timeout: int):
32
+ @click.option('--worker-logs-dir', default=None, help='Directory for worker log files (enables file logging)')
33
+ def worker(task_id: str, dev_name: str, repo_name: str, repo_path: str, task_type: str, timeout: int, worker_logs_dir: Optional[str]):
33
34
  """Process a single webhook task in an isolated subprocess.
34
35
 
35
36
  This command runs the complete task processing logic in a separate process to provide
@@ -47,15 +48,30 @@ def worker(task_id: str, dev_name: str, repo_name: str, repo_path: str, task_typ
47
48
  """
48
49
  # Set environment variable to redirect console output to stderr
49
50
  os.environ['DEVS_WEBHOOK_MODE'] = '1'
50
-
51
- # Configure structured logging for subprocess to output to stderr
51
+
52
+ # Configure structured logging for subprocess
52
53
  import logging
54
+
55
+ # Build list of handlers - always include stderr
56
+ handlers = [logging.StreamHandler(sys.stderr)]
57
+
58
+ # Add file handler if worker_logs_dir is provided
59
+ log_file_path = None
60
+ if worker_logs_dir:
61
+ log_dir = Path(worker_logs_dir)
62
+ log_dir.mkdir(parents=True, exist_ok=True)
63
+ log_file_path = log_dir / f"{task_id}.log"
64
+ file_handler = logging.FileHandler(log_file_path, encoding='utf-8')
65
+ file_handler.setLevel(logging.INFO)
66
+ file_handler.setFormatter(logging.Formatter('%(message)s'))
67
+ handlers.append(file_handler)
68
+
53
69
  logging.basicConfig(
54
- stream=sys.stderr,
70
+ handlers=handlers,
55
71
  level=logging.INFO,
56
72
  format='%(message)s'
57
73
  )
58
-
74
+
59
75
  structlog.configure(
60
76
  processors=[
61
77
  structlog.stdlib.filter_by_level,
@@ -79,7 +95,8 @@ def worker(task_id: str, dev_name: str, repo_name: str, repo_path: str, task_typ
79
95
  repo_name=repo_name,
80
96
  repo_path=repo_path,
81
97
  timeout=timeout,
82
- pid=os.getpid())
98
+ pid=os.getpid(),
99
+ log_file=str(log_file_path) if log_file_path else None)
83
100
 
84
101
  try:
85
102
  # Read payload from stdin
@@ -109,6 +109,16 @@ class WebhookConfig(BaseSettings, BaseConfig):
109
109
  description="Enable writing container output to log files"
110
110
  )
111
111
 
112
+ # Worker process logging (captures full worker subprocess logs)
113
+ worker_logs_dir: Path = Field(
114
+ default_factory=lambda: Path("/var/log/devs-webhook/workers"),
115
+ description="Directory for worker subprocess logs"
116
+ )
117
+ worker_logs_enabled: bool = Field(
118
+ default=True,
119
+ description="Enable writing worker subprocess logs to files (recommended)"
120
+ )
121
+
112
122
  # Task source configuration
113
123
  task_source: str = Field(
114
124
  default="webhook",
@@ -212,7 +222,10 @@ class WebhookConfig(BaseSettings, BaseConfig):
212
222
  # Container logs directory (if enabled)
213
223
  if self.container_logs_enabled:
214
224
  self.container_logs_dir.mkdir(parents=True, exist_ok=True)
215
-
225
+ # Worker logs directory (if enabled)
226
+ if self.worker_logs_enabled:
227
+ self.worker_logs_dir.mkdir(parents=True, exist_ok=True)
228
+
216
229
  def validate_required_settings(self) -> None:
217
230
  """Validate that required settings are present."""
218
231
  missing = []
@@ -575,12 +575,22 @@ class ContainerPool:
575
575
  "--task-type", queued_task.task_type,
576
576
  "--timeout", str(3600) # 60 minute timeout
577
577
  ]
578
-
578
+
579
+ # Add worker logs directory if enabled
580
+ if self.config.worker_logs_enabled:
581
+ cmd.extend(["--worker-logs-dir", str(self.config.worker_logs_dir)])
582
+
583
+ # Determine log file path for logging
584
+ worker_log_file = None
585
+ if self.config.worker_logs_enabled:
586
+ worker_log_file = str(self.config.worker_logs_dir / f"{queued_task.task_id}.log")
587
+
579
588
  logger.info("Launching worker subprocess",
580
589
  task_id=queued_task.task_id,
581
590
  container=dev_name,
582
591
  command_length=len(' '.join(cmd)),
583
- stdin_payload_size=len(stdin_json))
592
+ stdin_payload_size=len(stdin_json),
593
+ worker_log_file=worker_log_file)
584
594
 
585
595
  # Launch subprocess with timeout
586
596
  # Set environment to suppress console output
@@ -479,8 +479,8 @@ class TestDispatcher(BaseDispatcher):
479
479
 
480
480
  try:
481
481
  # Execute command in the container
482
- # Use same pattern as devs shell: bash execs into interactive zsh
483
- shell_cmd = f"cd {container_workspace_dir} && exec /bin/zsh -ic '{command}'"
482
+ # Use login shell (-l) for proper PATH/env, but not interactive (-i) to avoid ZLE errors
483
+ shell_cmd = f"cd {container_workspace_dir} && exec /bin/zsh -lc '{command}'"
484
484
  cmd = [
485
485
  'docker', 'exec', '-i', # -i for stdin, no TTY
486
486
  container_name,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devs-webhook
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: GitHub webhook handler for automated devcontainer operations with Claude Code
5
5
  Author: Dan Lester
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devs-webhook"
7
- version = "1.0.0"
7
+ version = "1.0.2"
8
8
  description = "GitHub webhook handler for automated devcontainer operations with Claude Code"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
File without changes
File without changes
File without changes