diff --git a/tests/playground-ci/scripts/run-docs-agent.sh b/tests/playground-ci/scripts/run-docs-agent.sh index 39333b9..53de4f7 100755 --- a/tests/playground-ci/scripts/run-docs-agent.sh +++ b/tests/playground-ci/scripts/run-docs-agent.sh @@ -4,6 +4,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" COMPONENT_PATH="$REPO_ROOT/tests/playground-ci/component" +DOCS_LINK_VALIDATOR="$SCRIPT_DIR/validate-docs-links.php" EXTENSION_PATH="${HOMEBOY_EXTENSION_PATH:-/Users/chubes/Developer/homeboy-extensions/wordpress}" AGENTS_API_PATH="${AGENTS_API_PATH:-$REPO_ROOT}" @@ -276,6 +277,16 @@ if [ -n "${GITHUB_OUTPUT:-}" ]; then } >> "$GITHUB_OUTPUT" fi +if [ "$job_status" = "completed" ] && [ "$success_status" = "pr_opened" ] && [[ "$DOCS_AGENT_FLOW_SLUG" == *-bootstrap-flow ]]; then + if [ ! -f "$DOCS_LINK_VALIDATOR" ]; then + echo "ERROR: Docs link validator missing at $DOCS_LINK_VALIDATOR" >&2 + exit 1 + fi + + git -C "$AGENTS_API_PATH" fetch origin "$DOCS_AGENT_BRANCH" + php "$DOCS_LINK_VALIDATOR" "$AGENTS_API_PATH" FETCH_HEAD +fi + if [ "$job_status" = "completed" ] && { [ "$success_status" = "pr_opened" ] || [ "$success_status" = "no_changes" ]; }; then echo "Docs Agent maintenance PASSED - $success_status" exit 0 diff --git a/tests/playground-ci/scripts/validate-docs-links.php b/tests/playground-ci/scripts/validate-docs-links.php new file mode 100644 index 0000000..9feee25 --- /dev/null +++ b/tests/playground-ci/scripts/validate-docs-links.php @@ -0,0 +1,105 @@ + + */ + +declare( strict_types=1 ); + +$repo = $argv[1] ?? ''; +$ref = $argv[2] ?? ''; + +if ( '' === $repo || '' === $ref ) { + fwrite( STDERR, "Usage: php validate-docs-links.php \n" ); + exit( 2 ); +} + +$run_git = static function ( array $args ) use ( $repo ): string { + $command = 'git -C ' . escapeshellarg( $repo ); + foreach ( $args as $arg ) { + $command .= ' ' . escapeshellarg( (string) $arg ); + } + + $output = array(); + $status = 0; + exec( $command, $output, $status ); + if ( 0 !== $status ) { + throw new RuntimeException( "Git command failed: {$command}" ); + } + + return implode( "\n", $output ); +}; + +$normalize_path = static function ( string $path ): string { + $parts = array(); + foreach ( explode( '/', str_replace( '\\', '/', $path ) ) as $part ) { + if ( '' === $part || '.' === $part ) { + continue; + } + if ( '..' === $part ) { + array_pop( $parts ); + continue; + } + $parts[] = $part; + } + return implode( '/', $parts ); +}; + +$tree_output = $run_git( array( 'ls-tree', '-r', '--name-only', $ref ) ); +$all_files = array_filter( explode( "\n", $tree_output ) ); +$file_set = array_fill_keys( $all_files, true ); +$markdown_files = array_values( + array_filter( + $all_files, + static fn( string $file ): bool => ( 'README.md' === $file || str_starts_with( $file, 'docs/' ) ) && str_ends_with( strtolower( $file ), '.md' ) + ) +); + +$missing = array(); +foreach ( $markdown_files as $file ) { + $content = $run_git( array( 'show', $ref . ':' . $file ) ); + if ( ! preg_match_all( '/(? {$target}"; + } + } +} + +if ( ! empty( $missing ) ) { + fwrite( STDERR, "Broken relative Markdown links found:\n" ); + foreach ( $missing as $link ) { + fwrite( STDERR, "- {$link}\n" ); + } + exit( 1 ); +} + +fwrite( STDOUT, "Docs Markdown link validation passed.\n" );