|
17 | 17 | use DataMachineCode\Support\PermissionHelper; |
18 | 18 | use DataMachineCode\Workspace\CleanupRunService; |
19 | 19 | use DataMachineCode\Workspace\RemoteWorkspaceBackend; |
| 20 | +use DataMachineCode\Workspace\RunnerWorkspacePublisher; |
20 | 21 | use DataMachineCode\Workspace\Workspace; |
21 | 22 | use DataMachineCode\Workspace\WorkspaceReader; |
22 | 23 | use DataMachineCode\Workspace\WorkspaceWriter; |
|
31 | 32 | if ( ! class_exists(RuntimeCapabilities::class) ) { |
32 | 33 | require_once dirname(__DIR__) . '/Support/RuntimeCapabilities.php'; |
33 | 34 | } |
| 35 | +if ( ! class_exists(GitHubAbilities::class) ) { |
| 36 | + require_once __DIR__ . '/GitHubAbilities.php'; |
| 37 | +} |
| 38 | +if ( ! class_exists(RunnerWorkspacePublisher::class) ) { |
| 39 | + require_once dirname(__DIR__) . '/Workspace/RunnerWorkspacePublisher.php'; |
| 40 | +} |
34 | 41 |
|
35 | 42 | class WorkspaceAbilities { |
36 | 43 |
|
@@ -1043,6 +1050,20 @@ private function registerAbilities(): void { |
1043 | 1050 | ) |
1044 | 1051 | ); |
1045 | 1052 |
|
| 1053 | + AbilityRegistry::register( |
| 1054 | + 'datamachine-code/publish-runner-workspace', |
| 1055 | + array( |
| 1056 | + 'label' => 'Publish Runner Workspace', |
| 1057 | + 'description' => 'Canonical Data Machine Code publication API for runner-owned workspace changes: stage/commit/push the workspace branch and open or reuse the pull request.', |
| 1058 | + 'category' => 'datamachine-code-workspace', |
| 1059 | + 'input_schema' => self::runnerWorkspacePublishInputSchema(), |
| 1060 | + 'output_schema' => self::runnerWorkspacePublishOutputSchema(), |
| 1061 | + 'execute_callback' => array( self::class, 'publishRunnerWorkspace' ), |
| 1062 | + 'permission_callback' => fn() => PermissionHelper::can_manage(), |
| 1063 | + 'meta' => array( 'show_in_rest' => false ), |
| 1064 | + ) |
| 1065 | + ); |
| 1066 | + |
1046 | 1067 | AbilityRegistry::register( |
1047 | 1068 | 'datamachine-code/workspace-git-rebase', |
1048 | 1069 | array( |
@@ -3018,6 +3039,140 @@ public static function gitPush( array $input ): array|\WP_Error { |
3018 | 3039 | ); |
3019 | 3040 | } |
3020 | 3041 |
|
| 3042 | + /** |
| 3043 | + * Publish runner-owned workspace changes through one canonical DMC API. |
| 3044 | + * |
| 3045 | + * @param array<string,mixed> $input Publication input. |
| 3046 | + * @return array<string,mixed>|\WP_Error |
| 3047 | + */ |
| 3048 | + public static function publishRunnerWorkspace( array $input ): array|\WP_Error { |
| 3049 | + return ( new RunnerWorkspacePublisher() )->publish($input); |
| 3050 | + } |
| 3051 | + |
| 3052 | + /** |
| 3053 | + * @return array<string,mixed> |
| 3054 | + */ |
| 3055 | + private static function runnerWorkspacePublishInputSchema(): array { |
| 3056 | + return array( |
| 3057 | + 'type' => 'object', |
| 3058 | + 'required' => array( 'workspace_handle', 'target_repo', 'commit_message', 'pr_title' ), |
| 3059 | + 'properties' => array( |
| 3060 | + 'workspace_handle' => array( |
| 3061 | + 'type' => 'string', |
| 3062 | + 'description' => 'Workspace handle: <repo> or <repo>@<branch-slug>.', |
| 3063 | + ), |
| 3064 | + 'target_repo' => array( |
| 3065 | + 'type' => 'string', |
| 3066 | + 'description' => 'GitHub repository in owner/repo format for the pull request.', |
| 3067 | + ), |
| 3068 | + 'base' => array( |
| 3069 | + 'type' => 'string', |
| 3070 | + 'description' => 'Base branch/ref for the pull request.', |
| 3071 | + ), |
| 3072 | + 'base_branch' => array( |
| 3073 | + 'type' => 'string', |
| 3074 | + 'description' => 'Alias for base.', |
| 3075 | + ), |
| 3076 | + 'head' => array( |
| 3077 | + 'type' => 'string', |
| 3078 | + 'description' => 'Pull request head branch or owner:branch.', |
| 3079 | + ), |
| 3080 | + 'head_branch' => array( |
| 3081 | + 'type' => 'string', |
| 3082 | + 'description' => 'Head branch to push and publish.', |
| 3083 | + ), |
| 3084 | + 'branch' => array( |
| 3085 | + 'type' => 'string', |
| 3086 | + 'description' => 'Alias for head_branch.', |
| 3087 | + ), |
| 3088 | + 'commit_message' => array( |
| 3089 | + 'type' => 'string', |
| 3090 | + 'description' => 'Commit message for workspace changes.', |
| 3091 | + ), |
| 3092 | + 'pr_title' => array( |
| 3093 | + 'type' => 'string', |
| 3094 | + 'description' => 'Pull request title.', |
| 3095 | + ), |
| 3096 | + 'pr_body' => array( |
| 3097 | + 'type' => 'string', |
| 3098 | + 'description' => 'Pull request body.', |
| 3099 | + ), |
| 3100 | + 'labels' => array( |
| 3101 | + 'type' => 'array', |
| 3102 | + 'items' => array( 'type' => 'string' ), |
| 3103 | + 'description' => 'Optional pull request labels.', |
| 3104 | + ), |
| 3105 | + 'draft' => array( |
| 3106 | + 'type' => 'boolean', |
| 3107 | + 'description' => 'Open the pull request as a draft.', |
| 3108 | + ), |
| 3109 | + 'maintainer_can_modify' => array( |
| 3110 | + 'type' => 'boolean', |
| 3111 | + 'description' => 'Allow maintainers to modify the pull request branch.', |
| 3112 | + ), |
| 3113 | + 'evidence_context' => array( |
| 3114 | + 'type' => 'object', |
| 3115 | + 'description' => 'Runner evidence metadata appended to the PR body and returned in the result.', |
| 3116 | + ), |
| 3117 | + 'artifact_context' => array( |
| 3118 | + 'type' => 'object', |
| 3119 | + 'description' => 'Alias for evidence_context.', |
| 3120 | + ), |
| 3121 | + 'run_artifacts' => array( |
| 3122 | + 'type' => 'array', |
| 3123 | + 'items' => array( 'type' => 'object' ), |
| 3124 | + 'description' => 'Run artifacts forwarded to PR artifact egress handling.', |
| 3125 | + ), |
| 3126 | + 'run_artifact_policy' => array( |
| 3127 | + 'type' => 'object', |
| 3128 | + 'description' => 'Run artifact egress policy forwarded to PR creation.', |
| 3129 | + ), |
| 3130 | + 'paths' => array( |
| 3131 | + 'type' => 'array', |
| 3132 | + 'items' => array( 'type' => 'string' ), |
| 3133 | + 'description' => 'Workspace paths to stage before commit. Defaults to all changes.', |
| 3134 | + ), |
| 3135 | + 'remote' => array( |
| 3136 | + 'type' => 'string', |
| 3137 | + 'description' => 'Git remote name for local workspaces. Default origin.', |
| 3138 | + ), |
| 3139 | + 'allow_primary_mutation' => array( |
| 3140 | + 'type' => 'boolean', |
| 3141 | + 'description' => 'Permit publication from a primary checkout. Default false.', |
| 3142 | + ), |
| 3143 | + 'force_with_lease' => array( |
| 3144 | + 'type' => 'boolean', |
| 3145 | + 'description' => 'Use --force-with-lease for local workspace push.', |
| 3146 | + ), |
| 3147 | + 'expected_sha' => array( |
| 3148 | + 'type' => 'string', |
| 3149 | + 'description' => 'Expected remote branch SHA for --force-with-lease.', |
| 3150 | + ), |
| 3151 | + ), |
| 3152 | + ); |
| 3153 | + } |
| 3154 | + |
| 3155 | + /** |
| 3156 | + * @return array<string,mixed> |
| 3157 | + */ |
| 3158 | + private static function runnerWorkspacePublishOutputSchema(): array { |
| 3159 | + return array( |
| 3160 | + 'type' => 'object', |
| 3161 | + 'properties' => array( |
| 3162 | + 'success' => array( 'type' => 'boolean' ), |
| 3163 | + 'kind' => array( 'type' => 'string' ), |
| 3164 | + 'workspace' => array( 'type' => 'object' ), |
| 3165 | + 'branch' => array( 'type' => 'object' ), |
| 3166 | + 'commit' => array( 'type' => 'object' ), |
| 3167 | + 'pull_request' => array( 'type' => 'object' ), |
| 3168 | + 'evidence' => array( 'type' => 'object' ), |
| 3169 | + 'message' => array( 'type' => 'string' ), |
| 3170 | + 'failure_type' => array( 'type' => 'string' ), |
| 3171 | + 'error' => array( 'type' => 'string' ), |
| 3172 | + ), |
| 3173 | + ); |
| 3174 | + } |
| 3175 | + |
3021 | 3176 | /** |
3022 | 3177 | * Rebase a workspace repository. |
3023 | 3178 | * |
|
0 commit comments