From fb8db38ceb075799dfaa38dfd535540c9ae20e2d Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Wed, 20 May 2026 13:34:40 -0400 Subject: [PATCH] feat: add GitSync pull system task --- data-machine-code.php | 1 + docs/gitsync.md | 14 +++++ inc/Tasks/GitSyncPullTask.php | 99 +++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 inc/Tasks/GitSyncPullTask.php diff --git a/data-machine-code.php b/data-machine-code.php index 90e1a99..5e601df 100644 --- a/data-machine-code.php +++ b/data-machine-code.php @@ -303,6 +303,7 @@ function datamachine_code_load_chat_tools() { $tasks['workspace_disk_emergency_cleanup'] = \DataMachineCode\Tasks\WorkspaceDiskEmergencyCleanupTask::class; $tasks['workspace_retention_cleanup'] = \DataMachineCode\Tasks\WorkspaceRetentionCleanupTask::class; $tasks['workspace_hygiene_report'] = \DataMachineCode\Tasks\WorkspaceHygieneReportTask::class; + $tasks['gitsync_pull'] = \DataMachineCode\Tasks\GitSyncPullTask::class; return $tasks; } ); diff --git a/docs/gitsync.md b/docs/gitsync.md index afbf1cf..041196b 100644 --- a/docs/gitsync.md +++ b/docs/gitsync.md @@ -92,6 +92,20 @@ wp datamachine-code gitsync unbind intelligence-wiki wp datamachine-code gitsync unbind intelligence-wiki --purge --yes ``` +## System task + +GitSync pull is also available as a Data Machine system task for flows that need +to refresh a binding after a schedule or webhook trigger without shelling out to +WP-CLI: + +```bash +wp datamachine system run gitsync_pull --param=slug:intelligence-wiki +wp datamachine system run gitsync_pull --param=slug:intelligence-wiki --param=allow_dirty:1 +``` + +The task delegates to the same API-first `GitSync::pull()` path as the CLI and +therefore does not require a local git binary, `.git` directory, or shell access. + ## Abilities Every CLI subcommand is a thin shell over the matching ability. Consumers should call abilities directly, not the service class. diff --git a/inc/Tasks/GitSyncPullTask.php b/inc/Tasks/GitSyncPullTask.php new file mode 100644 index 0000000..f5a1c70 --- /dev/null +++ b/inc/Tasks/GitSyncPullTask.php @@ -0,0 +1,99 @@ + + */ + public static function getTaskMeta(): array { + return array( + 'label' => 'GitSync Pull', + 'description' => 'Pull a registered GitSync binding from GitHub into its site-owned local directory. Designed for webhook-triggered flows and managed hosts.', + 'setting_key' => null, + 'default_enabled' => true, + 'trigger' => 'Manual, scheduled, or webhook-triggered Data Machine system task', + 'trigger_type' => 'manual_or_background', + 'supports_run' => true, + ); + } + + /** + * Pull one GitSync binding. + * + * Params: + * - slug: required GitSync binding slug. + * - allow_dirty: optional bool to override conflict policy for this pull. + * + * @param int $jobId Data Machine job ID. + * @param array $params Task params. + */ + public function executeTask( int $jobId, array $params ): void { + $slug = sanitize_key( (string) ( $params['slug'] ?? '' ) ); + if ( '' === $slug ) { + $this->failJob( $jobId, 'gitsync_pull requires a slug parameter.' ); + return; + } + + $args = array(); + if ( array_key_exists( 'allow_dirty', $params ) ) { + $args['allow_dirty'] = self::truthy( $params['allow_dirty'] ); + } + + $result = ( new GitSync() )->pull( $slug, $args ); + if ( $result instanceof \WP_Error ) { + do_action( + 'datamachine_log', + 'error', + 'GitSync pull failed', + array( + 'task' => $this->getTaskType(), + 'jobId' => $jobId, + 'slug' => $slug, + 'error' => $result->get_error_message(), + 'code' => $result->get_error_code(), + ) + ); + $this->failJob( $jobId, $result->get_error_message() ); + return; + } + + do_action( + 'datamachine_log', + 'info', + 'GitSync pull completed', + array( + 'task' => $this->getTaskType(), + 'jobId' => $jobId, + 'slug' => $slug, + 'result' => $result, + ) + ); + + $this->completeJob( $jobId, $result ); + } + + private static function truthy( mixed $value ): bool { + if ( is_bool( $value ) ) { + return $value; + } + return in_array( strtolower( (string) $value ), array( '1', 'true', 'yes', 'on' ), true ); + } +}