diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..ec16eed --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,69 @@ +name: Tests + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + tests: + name: PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + timeout-minutes: 15 + continue-on-error: ${{ matrix.experimental }} + strategy: + fail-fast: false + matrix: + include: + - php-version: '8.2' + experimental: false + - php-version: '8.3' + experimental: false + - php-version: '8.4' + experimental: false + - php-version: '8.5' + experimental: false + - php-version: 'nightly' + experimental: true + + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Setup PHP + uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # 2.32.0 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, xml, soap, zip + coverage: none + + - name: Validate Composer files + run: composer validate + + - name: Get Composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Cache Composer packages + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php-version }}-composer-${{ hashFiles('composer.lock') }} + restore-keys: | + ${{ runner.os }}-php-${{ matrix.php-version }}-composer- + + - name: Install dependencies + run: composer install --no-progress --prefer-dist + + - name: Run tests + run: composer test diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 0000000..b7e2202 --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,19 @@ +ARG PHP_VERSION=8.2 + +FROM php:${PHP_VERSION}-cli + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + git \ + libonig-dev \ + libxml2-dev \ + libzip-dev \ + unzip \ + && docker-php-ext-install mbstring soap zip \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=composer:2 /usr/bin/composer /usr/bin/composer + +WORKDIR /app + +CMD ["composer", "test"] diff --git a/README.md b/README.md index 436d1d9..a7b4178 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,22 @@ To run tests for all packages that have them, run the following command from the composer test ``` +GitHub Actions runs the full test suite on every pull request and push to `main` across the supported PHP versions: 8.2, 8.3, 8.4, and 8.5. It also runs a non-blocking `nightly` job so upcoming PHP compatibility issues show up early. + +PHPUnit is configured to fail on notices, warnings, deprecations, PHPUnit warnings, and PHPUnit deprecations from the package source. Indirect dependency deprecations are ignored, so third-party internals do not hide Pulp compatibility issues. + +To reproduce the supported PHP matrix locally with Docker, run: + +```bash +bin/test-php-matrix +``` + +To run only selected versions, set `PHP_VERSIONS`: + +```bash +PHP_VERSIONS="8.4 8.5" bin/test-php-matrix +``` + Or run the PHP script directly: ```bash php test.php diff --git a/bin/test-php-matrix b/bin/test-php-matrix new file mode 100755 index 0000000..5da4335 --- /dev/null +++ b/bin/test-php-matrix @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +versions="${PHP_VERSIONS:-8.2 8.3 8.4 8.5}" +composer_cache="${COMPOSER_CACHE_DIR:-$repo_root/build/composer-cache}" +tty_args=() + +if [ -t 1 ]; then + tty_args=(-t) +fi + +mkdir -p "$composer_cache" + +for version in $versions; do + image="mapsight-pulp-test-php:$version" + + echo "==> Building PHP $version test image" + docker build \ + --build-arg "PHP_VERSION=$version" \ + -t "$image" \ + -f "$repo_root/Dockerfile.test" \ + "$repo_root" + + echo "==> Running tests on PHP $version" + docker run --rm "${tty_args[@]}" \ + -e COMPOSER_CACHE_DIR=/tmp/composer-cache \ + -v "$repo_root:/app" \ + -v "$composer_cache:/tmp/composer-cache" \ + -w /app \ + "$image" \ + sh -lc 'composer install --no-progress --prefer-dist && composer test' +done diff --git a/packages/pulp-concert/src/PulpConcert.php b/packages/pulp-concert/src/PulpConcert.php index d4a1e9f..20cdd7f 100644 --- a/packages/pulp-concert/src/PulpConcert.php +++ b/packages/pulp-concert/src/PulpConcert.php @@ -75,8 +75,8 @@ public static function trafficMessagesToGeoJSON(): TrafficMessagsToGeoJSONHandle } public static function parseTrafficCounters( - Pulp $counterDataPulp = null, - Pulp $counterDerivedDataPulp = null + ?Pulp $counterDataPulp = null, + ?Pulp $counterDerivedDataPulp = null ): ParseCountersHandler { return new ParseCountersHandler($counterDataPulp, $counterDerivedDataPulp); } diff --git a/packages/pulp-concert/src/pulpconcert/Model/DataObject.php b/packages/pulp-concert/src/pulpconcert/Model/DataObject.php index e37b069..6bb57d0 100644 --- a/packages/pulp-concert/src/pulpconcert/Model/DataObject.php +++ b/packages/pulp-concert/src/pulpconcert/Model/DataObject.php @@ -106,7 +106,7 @@ public function getAllPropertiesAsArray(): array ]; } - public function jsonSerialize() + public function jsonSerialize(): mixed { return $this->getAllPropertiesAsArray(); } diff --git a/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTable.php b/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTable.php index 3107636..22fd40f 100644 --- a/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTable.php +++ b/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTable.php @@ -72,7 +72,7 @@ public function getAllPropertiesAsArray(): array ]; } - public function jsonSerialize() + public function jsonSerialize(): mixed { return $this->getAllPropertiesAsArray(); } diff --git a/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTableAlgorithm.php b/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTableAlgorithm.php index c44efa4..c7844dd 100644 --- a/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTableAlgorithm.php +++ b/packages/pulp-concert/src/pulpconcert/TrafficData/Model/LosTableAlgorithm.php @@ -132,7 +132,7 @@ public function getAllPropertiesAsArray(): array ]; } - public function jsonSerialize() + public function jsonSerialize(): mixed { return $this->getAllPropertiesAsArray(); } diff --git a/packages/pulp-geocsv/src/FromCsvHandler.php b/packages/pulp-geocsv/src/FromCsvHandler.php index 61e986c..934b358 100644 --- a/packages/pulp-geocsv/src/FromCsvHandler.php +++ b/packages/pulp-geocsv/src/FromCsvHandler.php @@ -23,7 +23,7 @@ public function onFile(File $file): void $rows = explode($ls, $csv); $rows = array_map(static function ($row) use ($fs, $qc): array { - $items = str_getcsv($row, $fs, $qc); + $items = str_getcsv($row, $fs, $qc, ''); return array_map(stripslashes(...), $items); }, $rows); diff --git a/packages/pulp-geocsv/src/ToCsvHandler.php b/packages/pulp-geocsv/src/ToCsvHandler.php index 9ae4548..35401f4 100644 --- a/packages/pulp-geocsv/src/ToCsvHandler.php +++ b/packages/pulp-geocsv/src/ToCsvHandler.php @@ -36,7 +36,7 @@ public function onFile(File $file): void protected static function makeCsvString(array $fields, string $delimiter, string $enclosure): string { $f = fopen('php://memory', 'rwb'); - if (fputcsv($f, $fields, $delimiter, $enclosure) === false) { + if (fputcsv($f, $fields, $delimiter, $enclosure, '') === false) { return false; } rewind($f); diff --git a/packages/pulp-geojson/PulpGeoJSON.php b/packages/pulp-geojson/PulpGeoJSON.php index 77d5048..5f2b299 100644 --- a/packages/pulp-geojson/PulpGeoJSON.php +++ b/packages/pulp-geojson/PulpGeoJSON.php @@ -222,7 +222,7 @@ public static function setIds(): SetIdsHandler } public static function fromArcGisJson( - string $idAttribute = null + ?string $idAttribute = null ): FromArcGisJsonHandler { return new FromArcGisJsonHandler($idAttribute); } diff --git a/packages/pulp-gtfs/src/GtfsDirectoryReader.php b/packages/pulp-gtfs/src/GtfsDirectoryReader.php index e7ec009..ab49b54 100644 --- a/packages/pulp-gtfs/src/GtfsDirectoryReader.php +++ b/packages/pulp-gtfs/src/GtfsDirectoryReader.php @@ -22,7 +22,7 @@ public function csvRows(string $fileName): Generator } try { - $headers = fgetcsv($stream); + $headers = fgetcsv($stream, null, ',', '"', ''); if ($headers === false) { return; } @@ -30,7 +30,7 @@ public function csvRows(string $fileName): Generator $headers[0] = preg_replace('/^\xEF\xBB\xBF/', '', (string)$headers[0]); $headerCount = count($headers); - while (($row = fgetcsv($stream)) !== false) { + while (($row = fgetcsv($stream, null, ',', '"', '')) !== false) { if ($row === [null] || $row === []) { continue; } diff --git a/packages/pulp-gtfs/src/GtfsFileSetReader.php b/packages/pulp-gtfs/src/GtfsFileSetReader.php index bdf69e2..3215aac 100644 --- a/packages/pulp-gtfs/src/GtfsFileSetReader.php +++ b/packages/pulp-gtfs/src/GtfsFileSetReader.php @@ -27,7 +27,7 @@ public function csvRows(string $fileName): Generator $stream = $file->stream(); try { - $headers = fgetcsv($stream); + $headers = fgetcsv($stream, null, ',', '"', ''); if ($headers === false) { return; } @@ -35,7 +35,7 @@ public function csvRows(string $fileName): Generator $headers[0] = preg_replace('/^\xEF\xBB\xBF/', '', (string)$headers[0]); $headerCount = count($headers); - while (($row = fgetcsv($stream)) !== false) { + while (($row = fgetcsv($stream, null, ',', '"', '')) !== false) { if ($row === [null] || $row === []) { continue; } diff --git a/packages/pulp-gtfs/test/GtfsGeoJsonBuilderTest.php b/packages/pulp-gtfs/test/GtfsGeoJsonBuilderTest.php index e5549f4..c7d1429 100644 --- a/packages/pulp-gtfs/test/GtfsGeoJsonBuilderTest.php +++ b/packages/pulp-gtfs/test/GtfsGeoJsonBuilderTest.php @@ -223,7 +223,7 @@ private function writeCsv(string $directory, string $fileName, array $rows): voi $this->assertIsResource($stream); foreach ($rows as $row) { - fputcsv($stream, $row); + fputcsv($stream, $row, ',', '"', ''); } fclose($stream); diff --git a/packages/pulp-tic/test/files/tmp/.gitkeep b/packages/pulp-tic/test/files/tmp/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/packages/pulp-tic/test/files/tmp/.gitkeep @@ -0,0 +1 @@ + diff --git a/phpunit.xml b/phpunit.xml index a57969c..5371064 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,5 +1,31 @@ - + + + + + + + + packages + + packages/geojson-reproject/test