From c9d2748f7222ec107e2aa92aceac34c3d352add6 Mon Sep 17 00:00:00 2001 From: David Smith Date: Sat, 30 Aug 2025 11:18:40 -0400 Subject: [PATCH] Add PHP 8.5 support, documentation publisher, and Docker setup --- .gitattributes | 1 - .github/workflows/docblock_update.yml | 156 ++++++++++++++++++++++++-- .github/workflows/test.yml | 4 +- README.md | 35 ++++++ bin/zero-to-prod-stream-socket | 32 ++++++ composer.json | 5 +- docker-compose.yml | 27 +++++ docker/8.5/.gitignore | 1 + docker/8.5/Dockerfile | 33 ++++++ docker/8.5/php.ini | 5 + test.sh | 2 +- 11 files changed, 285 insertions(+), 16 deletions(-) create mode 100755 bin/zero-to-prod-stream-socket create mode 100644 docker/8.5/.gitignore create mode 100644 docker/8.5/Dockerfile create mode 100644 docker/8.5/php.ini diff --git a/.gitattributes b/.gitattributes index 22321f3..7155010 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15,4 +15,3 @@ /dock export-ignore /test.sh export-ignore /art/ export-ignore -` \ No newline at end of file diff --git a/.github/workflows/docblock_update.yml b/.github/workflows/docblock_update.yml index ec73536..65a3569 100644 --- a/.github/workflows/docblock_update.yml +++ b/.github/workflows/docblock_update.yml @@ -14,30 +14,164 @@ jobs: - name: Checkout code uses: actions/checkout@v5 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }} ref: ${{ github.head_ref || github.ref }} fetch-depth: 0 - name: Update docblocks run: | - set -e - SOURCE_URL=$(jq -r '.support.source' composer.json) - if [ ! -d ./src ]; then - echo "Source directory ./src does not exist!" - exit 1 - fi - docker run --rm -v "$PWD/src:/app/run" davidsmith3/docblock-annotator-cli \ - docblock-annotator-cli:update-directory /app/run "@link $SOURCE_URL" + set -euo pipefail + + # Constants + readonly COMPOSER_JSON="composer.json" + readonly DOCBLOCK_DOCKER_IMAGE="davidsmith3/docblock-annotator-cli" + readonly DOCBLOCK_COMMAND="docblock-annotator-cli:update-file" + + # Execute docblock annotator via Docker for a specific file + execute_docblock_annotator() { + local file_path="$1" + shift + + docker run \ + --rm \ + --volume "$(pwd):/app/run" \ + "${DOCBLOCK_DOCKER_IMAGE}" \ + "${DOCBLOCK_COMMAND}" \ + "/app/run/${file_path}" \ + "$@" + } + + # Validate required dependencies are available + validate_dependencies() { + if ! command -v jq &> /dev/null; then + echo "Error: jq is required but not installed." >&2 + return 1 + fi + + if [[ ! -f "${COMPOSER_JSON}" ]]; then + echo "Error: ${COMPOSER_JSON} not found in current directory." >&2 + return 1 + fi + } + + # Extract the main PHP class file path from composer.json PSR-4 autoload configuration + get_main_class_file() { + local namespace directory class_name php_file + + namespace=$(jq -r '.autoload."psr-4" | keys[0] // empty' "${COMPOSER_JSON}") + directory=$(jq -r --arg ns "$namespace" '.autoload."psr-4"[$ns] // empty' "${COMPOSER_JSON}") + + if [[ -z "$namespace" || -z "$directory" ]]; then + echo "Error: Could not extract PSR-4 namespace or directory from ${COMPOSER_JSON}." >&2 + return 1 + fi + + # Remove trailing backslash from namespace + namespace="${namespace%\\}" + + # Extract class name from namespace (last segment) + class_name=$(echo "$namespace" | awk -F'\\\\' '{print $NF}') + + # Construct PHP file path + php_file="${directory}${class_name}.php" + + # Convert backslashes to forward slashes for file path + php_file=$(echo "$php_file" | sed 's/\\/\//g') + + if [[ ! -f "$php_file" ]]; then + echo "Error: Main class file '$php_file' not found." >&2 + return 1 + fi + + echo "$php_file" + } + + # Extract package description from composer.json + get_package_description() { + local description + description=$(jq -r '.description // empty' "${COMPOSER_JSON}") + + if [[ -z "$description" ]]; then + echo "Error: Could not extract package description from ${COMPOSER_JSON}." >&2 + return 1 + fi + + echo "$description" + } + + # Extract package homepage from composer.json + get_package_homepage() { + local homepage + homepage=$(jq -r '.homepage // empty' "${COMPOSER_JSON}") + + if [[ -z "$homepage" ]]; then + echo "Error: Could not extract package homepage from ${COMPOSER_JSON}." >&2 + return 1 + fi + + echo "$homepage" + } + + # Update docblock with package description + update_docblock_with_description() { + local php_file description + + php_file=$(get_main_class_file) || return 1 + description=$(get_package_description) || return 1 + + execute_docblock_annotator "$php_file" "$description" "--statements=class" + } + + # Update docblock with homepage link + update_docblock_with_link() { + local php_file homepage + + php_file=$(get_main_class_file) || return 1 + homepage=$(get_package_homepage) || return 1 + + execute_docblock_annotator "$php_file" "@link $homepage" + } + + # Main function to update all docblocks + update_package_docblocks() { + validate_dependencies || return 1 + + echo "Updating docblocks with package description..." + update_docblock_with_description || return 1 + + echo "Updating docblocks with homepage link..." + update_docblock_with_link || return 1 + + echo "Docblock updates completed successfully." + } + + # Execute the main function + update_package_docblocks - name: Commit and push changes (if any) run: | - set -e + set -euo pipefail + + # Configure git user for commits git config --local user.email "action@github.com" git config --local user.name "GitHub Action" + + # Stage all changes git add -A + + # Check if there are any changes to commit if ! git diff --cached --quiet; then - git commit -m "Update docblocks with @link annotations" --no-verify + echo "Changes detected, committing docblock updates..." + + # Commit without skip-ci to allow other workflows to run + git commit -m "Update docblocks with @link annotations" \ + --no-verify + + # Push changes - using PAT_TOKEN if available to trigger workflows properly git push + + echo "Docblock updates committed and pushed successfully." + echo "Other workflows will run on the new commit." else echo "No changes to commit." fi \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 98ddb4f..fa0af93 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,10 +12,10 @@ jobs: strategy: matrix: - php-version: ["8.4", "8.3", "8.2", "8.1"] + php-version: ["8.5", "8.4", "8.3", "8.2", "8.1"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Create .env run: touch .env diff --git a/README.md b/README.md index fb7f5ab..66ceab3 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ - [Requirements](#requirements) - [Installation](#installation) - [Usage](#usage) +- [Documentation Publishing](#documentation-publishing) + - [Automatic Documentation Publishing](#automatic-documentation-publishing) - [Local Development](./LOCAL_DEVELOPMENT.md) - [Contributing](#contributing) @@ -57,6 +59,39 @@ echo $SocketClient->remoteSocketName(); // 34.223.124.45:443 $SocketClient->close(); ``` +## Documentation Publishing + +You can publish this README to your local documentation directory. + +This can be useful for providing documentation for AI agents. + +This can be done using the included script: + +```bash +# Publish to default location (./docs/zero-to-prod/stream-socket) +vendor/bin/zero-to-prod-stream-socket + +# Publish to custom directory +vendor/bin/zero-to-prod-stream-socket /path/to/your/docs +``` + +### Automatic Documentation Publishing + +You can automatically publish documentation by adding the following to your `composer.json`: + +```json +{ + "scripts": { + "post-install-cmd": [ + "zero-to-prod-stream-socket" + ], + "post-update-cmd": [ + "zero-to-prod-stream-socket" + ] + } +} +``` + ## Contributing Contributions, issues, and feature requests are welcome! diff --git a/bin/zero-to-prod-stream-socket b/bin/zero-to-prod-stream-socket new file mode 100755 index 0000000..b249072 --- /dev/null +++ b/bin/zero-to-prod-stream-socket @@ -0,0 +1,32 @@ +#!/usr/bin/env php +getMessage()."\n"); + exit(1); +} \ No newline at end of file diff --git a/composer.json b/composer.json index cdb7e61..09bb924 100644 --- a/composer.json +++ b/composer.json @@ -51,5 +51,8 @@ }, "suggest": { "zero-to-prod/stream-context": "A wrapper for stream_context_create()." - } + }, + "bin": [ + "bin/zero-to-prod-stream-socket" + ] } diff --git a/docker-compose.yml b/docker-compose.yml index 7271fd4..3a8cf5c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,31 @@ services: + php8.5: + volumes: + - ./:/app:delegated + - ./.vendor/php8.5:/app/vendor + build: + context: ./docker/8.5 + target: base + + debug8.5: + extends: + service: php8.5 + volumes: + - ./:/app:delegated + - ./docker/8.5:/usr/local/etc/php + - ./.vendor/php8.5:/app/vendor + build: + target: debug + + composer8.5: + extends: + service: php8.5 + volumes: + - ./:/app:delegated + - ./.vendor/php8.5:/app/vendor + build: + target: composer + php8.1: volumes: - ./:/app:delegated diff --git a/docker/8.5/.gitignore b/docker/8.5/.gitignore new file mode 100644 index 0000000..143c426 --- /dev/null +++ b/docker/8.5/.gitignore @@ -0,0 +1 @@ +.phpunit.result.cache \ No newline at end of file diff --git a/docker/8.5/Dockerfile b/docker/8.5/Dockerfile new file mode 100644 index 0000000..66aefda --- /dev/null +++ b/docker/8.5/Dockerfile @@ -0,0 +1,33 @@ +FROM php:8.5-rc-alpine AS builder + +RUN apk add --no-cache \ + git \ + unzip \ + $PHPIZE_DEPS + +RUN git config --global --add safe.directory /app + +WORKDIR /app + +FROM builder AS composer + +RUN curl -sS https://getcomposer.org/installer | php -- \ + --install-dir=/usr/local/bin \ + --filename=composer + +FROM builder AS debug + +RUN apk add --no-cache --virtual .build-deps \ + $PHPIZE_DEPS \ + linux-headers \ + && pecl channel-update pecl.php.net \ + && pecl install xdebug \ + && docker-php-ext-enable xdebug \ + && apk del .build-deps \ + && rm -rf /tmp/* /var/cache/apk/* + +FROM php:8.5-rc-alpine AS base + +WORKDIR /app + +CMD ["bash"] \ No newline at end of file diff --git a/docker/8.5/php.ini b/docker/8.5/php.ini new file mode 100644 index 0000000..f38f5c9 --- /dev/null +++ b/docker/8.5/php.ini @@ -0,0 +1,5 @@ +zend_extension = xdebug.so +xdebug.mode = debug +xdebug.start_with_request = yes +xdebug.client_host = host.docker.internal +xdebug.client_port = 9003 \ No newline at end of file diff --git a/test.sh b/test.sh index 15ddd16..0960815 100755 --- a/test.sh +++ b/test.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e -PHP_VERSIONS=("8.4" "8.3" "8.2" "8.1") +PHP_VERSIONS=("8.5" "8.4" "8.3" "8.2" "8.1") for PHP_VERSION in "${PHP_VERSIONS[@]}"; do