Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions homeboy.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"changelog_target": "docs/CHANGELOG.md",
"extensions": {
"wordpress": {
"release_latest_branch": "release-latest"
"release_latest_branch": "release-latest",
"settings": {
"test_backend": "host-smoke"
}
}
},
"id": "data-machine-code",
Expand All @@ -18,4 +21,4 @@
"pattern": "DATAMACHINE_CODE_VERSION',\\s*'([0-9.]+)'"
}
]
}
}
109 changes: 40 additions & 69 deletions inc/Abilities/GitHubAbilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,15 @@ private function registerAbilities(): void {
'type' => 'object',
'properties' => array(
'success' => array( 'type' => 'boolean' ),
'kind' => array( 'type' => 'string' ),
'repo' => array( 'type' => 'string' ),
'number' => array( 'type' => 'integer' ),
'pull_number' => array( 'type' => 'integer' ),
'url' => array( 'type' => 'string' ),
'html_url' => array( 'type' => 'string' ),
'reused' => array( 'type' => 'boolean' ),
'pull_request' => array( 'type' => 'object' ),
'labeling' => array( 'type' => 'object' ),
'error' => array( 'type' => 'string' ),
),
),
Expand Down Expand Up @@ -523,15 +531,15 @@ private function registerAbilities(): void {
'output_schema' => array(
'type' => 'object',
'properties' => array(
'success' => array( 'type' => 'boolean' ),
'repo' => array( 'type' => 'string' ),
'pull_number' => array( 'type' => 'integer' ),
'merged' => array( 'type' => 'boolean' ),
'sha' => array( 'type' => 'string' ),
'message' => array( 'type' => 'string' ),
'html_url' => array( 'type' => 'string' ),
'success' => array( 'type' => 'boolean' ),
'repo' => array( 'type' => 'string' ),
'pull_number' => array( 'type' => 'integer' ),
'merged' => array( 'type' => 'boolean' ),
'sha' => array( 'type' => 'string' ),
'message' => array( 'type' => 'string' ),
'html_url' => array( 'type' => 'string' ),
'local_worktree_cleanup' => array( 'type' => 'object' ),
'error' => array( 'type' => 'string' ),
'error' => array( 'type' => 'string' ),
),
),
'execute_callback' => array( self::class, 'mergePullRequest' ),
Expand Down Expand Up @@ -1491,7 +1499,7 @@ public static function createIssue( array $input ): array|\WP_Error {
if ( ! empty( $input['assignees'] ) && is_array( $input['assignees'] ) ) {
$body['assignees'] = array_map( 'sanitize_text_field', $input['assignees'] );
}
if ( isset( $input['milestone'] ) && null !== $input['milestone'] && '' !== $input['milestone'] ) {
if ( isset( $input['milestone'] ) && '' !== $input['milestone'] ) {
$milestone = (int) $input['milestone'];
if ( $milestone > 0 ) {
$body['milestone'] = $milestone;
Expand Down Expand Up @@ -1758,9 +1766,9 @@ private static function preparePullRequestRunArtifacts( array $input, string $re
foreach ( $file_writes as $file ) {
$file_result = self::createOrUpdateFile( array(
'repo' => $repo,
'file_path' => $file['file_path'] ?? '',
'content' => $file['content'] ?? '',
'commit_message' => $file['commit_message'] ?? 'chore: persist Data Machine run artifact',
'file_path' => $file['file_path'],
'content' => $file['content'],
'commit_message' => $file['commit_message'],
'branch' => $head,
) );

Expand All @@ -1769,7 +1777,7 @@ private static function preparePullRequestRunArtifacts( array $input, string $re
}

$committed_files[] = array(
'file_path' => (string) ( $file_result['content']['path'] ?? ( $file['file_path'] ?? '' ) ),
'file_path' => (string) ( $file_result['content']['path'] ?? $file['file_path'] ),
'commit_sha' => (string) ( $file_result['commit']['sha'] ?? '' ),
'file_url' => (string) ( $file_result['content']['html_url'] ?? '' ),
);
Expand Down Expand Up @@ -1821,17 +1829,6 @@ private static function runArtifactEgressPolicyFromInput( array $input, array $a
}
}

$job_id = (int) ( $input['job_id'] ?? 0 );
if ( $job_id > 0 && class_exists( '\\DataMachine\\Core\\Database\\Jobs\\Jobs' ) ) {
$jobs = new \DataMachine\Core\Database\Jobs\Jobs();
if ( method_exists( $jobs, 'retrieve_engine_data' ) ) {
$engine_data = $jobs->retrieve_engine_data( $job_id );
if ( is_array( $engine_data['run_artifact_egress_policy'] ?? null ) ) {
return $engine_data['run_artifact_egress_policy'];
}
}
}

return is_array( $artifacts['run_artifact_egress_policy'] ?? null ) ? $artifacts['run_artifact_egress_policy'] : array();
}

Expand Down Expand Up @@ -1911,12 +1908,10 @@ private static function mergeProvenanceLabels( array $labels ): array {
* Resolve the current Data Machine agent slug when running in agent context.
*/
private static function getCurrentAgentSlug(): string {
foreach ( array( 'get_runtime_context', 'runtime_context' ) as $method ) {
if ( method_exists( PermissionHelper::class, $method ) ) {
$agent_slug = self::agentSlugFromContext( call_user_func( array( PermissionHelper::class, $method ) ) );
if ( '' !== $agent_slug ) {
return $agent_slug;
}
if ( method_exists( PermissionHelper::class, 'get_runtime_context' ) ) {
$agent_slug = self::agentSlugFromContext( PermissionHelper::get_runtime_context() );
if ( '' !== $agent_slug ) {
return $agent_slug;
}
}

Expand All @@ -1937,24 +1932,7 @@ private static function getCurrentAgentSlug(): string {
}
}

if ( ! method_exists( PermissionHelper::class, 'get_acting_agent_id' ) ) {
return '';
}

$agent_id = PermissionHelper::get_acting_agent_id();
if ( empty( $agent_id ) || ! class_exists( '\DataMachine\Core\Database\Agents\Agents' ) ) {
return '';
}

$agents_repo = new \DataMachine\Core\Database\Agents\Agents();
if ( ! method_exists( $agents_repo, 'get_agent' ) ) {
return '';
}

$agent = $agents_repo->get_agent( (int) $agent_id );
$agent_slug = is_array( $agent ) ? (string) ( $agent['agent_slug'] ?? '' ) : '';

return '' !== trim( $agent_slug ) ? sanitize_text_field( $agent_slug ) : '';
return '';
}

/**
Expand Down Expand Up @@ -2469,7 +2447,7 @@ public static function cleanupPullRequest( array $input, ?callable $api_get = nu

$encoded_head_branch = implode( '/', array_map( 'rawurlencode', explode( '/', $head_branch ) ) );
$delete_url = sprintf( '%s/repos/%s/git/refs/heads/%s', self::API_BASE, $repo, $encoded_head_branch );
$deleted = $api_request( 'DELETE', $delete_url, null, $pat );
$deleted = $api_request( 'DELETE', $delete_url, null, $pat );
if ( is_wp_error( $deleted ) ) {
$status = is_array( $deleted->get_error_data() ) ? (int) ( $deleted->get_error_data()['status'] ?? 0 ) : 0;
if ( 404 !== $status ) {
Expand Down Expand Up @@ -2504,14 +2482,6 @@ private static function cleanupMergedPullRequestWorktree( string $repo, string $
}

$workspace = new Workspace();
if ( ! method_exists( $workspace, 'cleanup_merged_pr_worktree' ) ) {
return array(
'success' => true,
'skipped' => true,
'reason' => 'workspace_cleanup_unsupported',
);
}

return $workspace->cleanup_merged_pr_worktree( $repo, $head_branch, '' !== $pr_url ? $pr_url : null );
}

Expand Down Expand Up @@ -2702,9 +2672,9 @@ private static function buildPullRequestCommentInput( array $input ): array {
}

return array(
'repo' => $input['repo'] ?? '',
'issue_number' => (int) ( $input['pull_number'] ?? 0 ),
'body' => $body,
'repo' => $input['repo'] ?? '',
'issue_number' => (int) ( $input['pull_number'] ?? 0 ),
'body' => $body,
'skip_automation_comment_guard' => true,
);
}
Expand Down Expand Up @@ -2943,8 +2913,8 @@ public static function buildRepoReviewProfile( string $repo, array $options, cal
$max_docs = max( 0, (int) ( $options['max_architecture_docs'] ?? 8 ) );
$limits = array(
'max_profile_files' => $max_files,
'max_file_chars' => max( 1, (int) ( $options['max_file_chars'] ?? 12000 ) ),
'max_total_chars' => max( 1, (int) ( $options['max_total_chars'] ?? 60000 ) ),
'max_file_chars' => (int) max( 1, (int) ( $options['max_file_chars'] ?? 12000 ) ),
'max_total_chars' => (int) max( 1, (int) ( $options['max_total_chars'] ?? 60000 ) ),
'max_architecture_docs' => $max_docs,
);

Expand Down Expand Up @@ -2991,7 +2961,7 @@ public static function buildRepoReviewProfile( string $repo, array $options, cal
}

$paths = array_values( array_unique( $paths ) );
$remaining_chars = $limits['max_total_chars'];
$remaining_chars = (int) $limits['max_total_chars'];

foreach ( $paths as $path ) {
if ( $profile['truncation']['included_files'] >= $limits['max_profile_files'] || $remaining_chars <= 0 ) {
Expand All @@ -3015,7 +2985,7 @@ public static function buildRepoReviewProfile( string $repo, array $options, cal

++$profile['truncation']['included_files'];
$profile['truncation']['included_chars'] += $entry['included_chars'];
$remaining_chars = max( 0, $remaining_chars - $entry['included_chars'] );
$remaining_chars = (int) max( 0, $remaining_chars - $entry['included_chars'] );

if ( ! empty( $entry['truncated'] ) ) {
++$profile['truncation']['truncated_files'];
Expand Down Expand Up @@ -3564,7 +3534,7 @@ private static function suggestLikelyStaleDocs( array $impacts, array $changed_d
}

foreach ( $wanted as &$entry ) {
$entry['reasons'] = array_values( array_unique( $entry['reasons'] ?? array() ) );
$entry['reasons'] = array_values( array_unique( $entry['reasons'] ) );
}

return array_values( $wanted );
Expand Down Expand Up @@ -4843,7 +4813,8 @@ public static function apiRequest( string $method, string $url, ?array $body, st
);

if ( null !== $body ) {
$args['body'] = wp_json_encode( $body );
$encoded_body = wp_json_encode( $body );
$args['body'] = false === $encoded_body ? '' : $encoded_body;
}

$response = wp_remote_request( $url, $args );
Expand Down Expand Up @@ -5250,7 +5221,7 @@ public static function normalizePullReviewContext( string $repo, array $pull, ar
$repo,
$pull,
$changed_files,
isset( $context['checks'] ) && is_array( $context['checks'] ) ? $context['checks'] : array(),
$context['checks'] ?? array(),
isset( $options['escalation_policy'] ) && is_array( $options['escalation_policy'] ) ? $options['escalation_policy'] : array()
);
}
Expand Down Expand Up @@ -5339,7 +5310,7 @@ public static function getPat( ?array $selector = null ): string {

self::$last_auth_error = null;
$token = (string) $credential['token'];
self::$token_modes[ $token ] = (string) ( $credential['mode'] ?? 'pat' );
self::$token_modes[ $token ] = (string) $credential['mode'];
return $token;
}

Expand All @@ -5358,7 +5329,7 @@ public static function getCredential( ?array $selector = null ): array|\WP_Error

$token = (string) $credential['token'];
self::$last_auth_error = null;
self::$token_modes[ $token ] = (string) ( $credential['mode'] ?? 'pat' );
self::$token_modes[ $token ] = (string) $credential['mode'];
return $credential;
}

Expand Down
5 changes: 5 additions & 0 deletions tests/smoke-github-create-abilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ function wp_remote_retrieve_body( $response ): string {
$assert( 'create-github-pull-request exposes labels', array_key_exists( 'labels', $pr_ability['input_schema']['properties'] ?? array() ) );
$assert( 'create-github-pull-request labels schema declares string items', array( 'type' => 'string' ) === ( $pr_ability['input_schema']['properties']['labels']['items'] ?? null ) );
$assert( 'create-github-pull-request exposes maintainer_can_modify', array_key_exists( 'maintainer_can_modify', $pr_ability['input_schema']['properties'] ?? array() ) );
$pr_output_properties = $pr_ability['output_schema']['properties'] ?? array();
$assert( 'create-github-pull-request output exposes top-level url', array_key_exists( 'url', $pr_output_properties ) );
$assert( 'create-github-pull-request output exposes top-level html_url', array_key_exists( 'html_url', $pr_output_properties ) );
$assert( 'create-github-pull-request output exposes top-level pull_number', array_key_exists( 'pull_number', $pr_output_properties ) );
$assert( 'create-github-pull-request output exposes top-level reused', array_key_exists( 'reused', $pr_output_properties ) );
$assert( 'create-github-pull-request is hidden from REST', false === ( $pr_ability['meta']['show_in_rest'] ?? null ) );

$assert( 'create-or-update-github-file ability is registered', null !== $file_ability );
Expand Down
Loading