Skip to content

Commit 5cbea63

Browse files
authored
fix: retry bundle preload through remote workspace backend (#607)
* fix: retry bundle preload through remote workspace backend * fix: keep remote workspace backend after preload
1 parent 99965e8 commit 5cbea63

3 files changed

Lines changed: 84 additions & 0 deletions

File tree

inc/Bundle/WorkspacePreloadArtifact.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace DataMachineCode\Bundle;
99

1010
use DataMachineCode\Abilities\WorkspaceAbilities;
11+
use DataMachineCode\Workspace\RemoteWorkspaceBackend;
1112

1213
defined('ABSPATH') || exit;
1314

@@ -179,6 +180,16 @@ private function clone_repository( array $repository ): array|\WP_Error {
179180
$callback = $this->clone_callback ? $this->clone_callback : array( WorkspaceAbilities::class, 'cloneRepo' );
180181
$result = call_user_func($callback, $input);
181182

183+
if ( is_wp_error($result) && 'datamachine_workspace_git_unavailable' === $result->get_error_code() && class_exists(RemoteWorkspaceBackend::class) ) {
184+
$remote_result = ( new RemoteWorkspaceBackend() )->clone_repo(
185+
$input['url'],
186+
$input['name'] ?? null
187+
);
188+
if ( ! is_wp_error($remote_result) ) {
189+
return $remote_result;
190+
}
191+
}
192+
182193
if ( is_wp_error($result) && 'repo_exists' === $result->get_error_code() ) {
183194
$data = (array) $result->get_error_data();
184195
if ( 'existing checkout' === (string) ( $data['state'] ?? '' ) ) {

inc/Workspace/RemoteWorkspaceBackend.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ class RemoteWorkspaceBackend {
2222
* Whether the remote backend should handle workspace operations.
2323
*/
2424
public static function should_handle(): bool {
25+
if ( self::has_registered_state() ) {
26+
return true;
27+
}
28+
2529
$diagnostic = \DataMachineCode\Support\GitRunner::diagnose();
2630
$default = self::should_handle_for_local_capabilities(
2731
! empty($diagnostic['git_available']),
@@ -41,6 +45,18 @@ public static function should_handle_for_local_capabilities( bool $git_available
4145
return ! ( $git_available && $streaming_available );
4246
}
4347

48+
/**
49+
* Whether remote workspace state already exists for this runtime.
50+
*/
51+
public static function has_registered_state(): bool {
52+
$state = function_exists('get_option') ? get_option(self::OPTION, array()) : array();
53+
if ( ! is_array($state) ) {
54+
return false;
55+
}
56+
57+
return ! empty($state['repos']) || ! empty($state['worktrees']);
58+
}
59+
4460
/**
4561
* Clone/register a GitHub repository as a remote workspace primary.
4662
*

tests/smoke-workspace-preload-artifact.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99

1010
declare( strict_types=1 );
1111

12+
namespace DataMachineCode\Abilities {
13+
class GitHubAbilities
14+
{
15+
}
16+
}
17+
1218
namespace {
1319
if (! defined('ABSPATH') ) {
1420
define('ABSPATH', __DIR__ . '/');
@@ -50,6 +56,25 @@ function wp_parse_url( string $url, int $component = -1 ): mixed
5056
}
5157
}
5258

59+
$GLOBALS['dmc_remote_workspace_options'] = array();
60+
61+
if (! function_exists('get_option') ) {
62+
function get_option( string $key, mixed $default_value = false ): mixed
63+
{
64+
return $GLOBALS['dmc_remote_workspace_options'][ $key ] ?? $default_value;
65+
}
66+
}
67+
68+
if (! function_exists('update_option') ) {
69+
function update_option( string $key, mixed $value, bool $autoload = true ): bool
70+
{
71+
unset($autoload);
72+
$GLOBALS['dmc_remote_workspace_options'][ $key ] = $value;
73+
return true;
74+
}
75+
}
76+
77+
include __DIR__ . '/../inc/Workspace/RemoteWorkspaceBackend.php';
5378
include __DIR__ . '/../inc/Bundle/WorkspacePreloadArtifact.php';
5479

5580
use DataMachineCode\Bundle\WorkspacePreloadArtifact;
@@ -151,6 +176,38 @@ static function ( array $input ): WP_Error {
151176
);
152177
$assert('treats existing checkout as idempotent success', ! is_wp_error($exists) && true === ( $exists['repositories'][0]['already_exists'] ?? false ));
153178

179+
$remote_fallback_artifact = new WorkspacePreloadArtifact(
180+
static function (): WP_Error {
181+
return new WP_Error(
182+
'datamachine_workspace_git_unavailable',
183+
'Clone workspace repository cannot run with the current workspace backend.',
184+
array( 'status' => 500 )
185+
);
186+
}
187+
);
188+
$remote_fallback = $remote_fallback_artifact->apply_artifact(
189+
null,
190+
array(
191+
'artifact_type' => WorkspacePreloadArtifact::ARTIFACT_TYPE,
192+
'artifact_id' => 'remote-fallback',
193+
'payload' => array(
194+
'repositories' => array(
195+
array(
196+
'name' => 'static-site-importer',
197+
'url' => 'https://github.com/chubes4/static-site-importer.git',
198+
),
199+
),
200+
),
201+
)
202+
);
203+
$assert('falls back to remote backend when local git clone is unavailable', ! is_wp_error($remote_fallback) && 'github_api' === ( $remote_fallback['repositories'][0]['result']['backend'] ?? '' ));
204+
$assert(
205+
'remote preload state keeps remote backend active for later tools',
206+
\DataMachineCode\Workspace\RemoteWorkspaceBackend::has_registered_state()
207+
&& false === \DataMachineCode\Workspace\RemoteWorkspaceBackend::should_handle_for_local_capabilities(true, true)
208+
&& \DataMachineCode\Workspace\RemoteWorkspaceBackend::should_handle()
209+
);
210+
154211
if (array() !== $failures ) {
155212
echo "\nFailures:\n";
156213
foreach ( $failures as $failure ) {

0 commit comments

Comments
 (0)