From 06abc2f08081a3a07ed4eddddadc4979ab105b68 Mon Sep 17 00:00:00 2001 From: Imani Manyara Date: Wed, 16 Sep 2026 12:37:27 -0400 Subject: [PATCH] Lint with the shared Pint config, and stop moving action pins backwards **Style.** `vendor/bin/laranail-pint` resolves the one config in vendor/laranail/package-tools and errors when it is absent. Bare `vendor/bin/pint` takes a `--config` path that does not exist, silently falls back to its own defaults and exits 0 -- so twelve workflows in this family were reporting "code style clean" against a rule set no other package uses. Those now call laranail-pint, and this is what the shared config actually wanted: import order, `.` spacing, `=>` alignment, brace position, single-line empty bodies, phpdoc alignment. No behaviour changes; the suites are unchanged and green. **Pins.** The release.yml consistency pass had copied one repo's pins over fourteen others, and that repo was behind: `softprops/action-gh-release` went v3.0.3 -> v3.0.2 (v3.0.3 -> v2 in enumerator) and `anchore/sbom-action` went v0.24.2 -> v0.24.0. Pinning to a SHA is a supply-chain control, so a pin moving backwards is the one direction that must never happen by accident -- and nothing catches it, because the pin check verifies the SHA against its comment, not that the version moved forward. Both are on one pin family-wide now, at the newest release, with the exact release tag in the comment rather than a moving major. **And the alias debris.** Where the `$commandAliases` declarations were deleted, this also fixes the two command bases that read `$this->commandAliases` without declaring it (an `Undefined property` at construction, which took out `artisan package:discover`), a command that called a sibling by its deleted alias, a success message naming a command that no longer exists, and the docs that still documented the aliases as the way in. --- .github/workflows/browser.yml | 23 +++++++ .github/workflows/security.yml | 23 +++++++ .github/workflows/static-analysis.yml | 92 +++++++++++++++++++++++++++ .github/workflows/tests.yml | 74 +++++++++++++++++++-- src/Commands/CacheClearCommand.php | 3 - src/Commands/DoctorCommand.php | 3 - src/Commands/InstallCommand.php | 3 - src/Commands/KeysCommand.php | 3 - tests/Feature/BrowserRuntimeTest.php | 2 +- tests/Feature/RuntimeScriptTest.php | 2 +- tests/TestCase.php | 2 +- 11 files changed, 211 insertions(+), 19 deletions(-) diff --git a/.github/workflows/browser.yml b/.github/workflows/browser.yml index 4f0e417..01270bd 100644 --- a/.github/workflows/browser.yml +++ b/.github/workflows/browser.yml @@ -41,6 +41,29 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, intl coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install PHP dependencies run: composer update --prefer-dist --no-interaction --no-progress diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 0afb8c5..413d8a3 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -31,6 +31,29 @@ jobs: php-version: '8.4' coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 5399587..9c35dc5 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -29,6 +29,29 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, intl coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress @@ -51,6 +74,29 @@ jobs: php-version: '8.4' coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress @@ -74,6 +120,29 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, intl coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress @@ -102,6 +171,29 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, intl coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b62896e..2970e8e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: # dependency precisely so the ALTCHA adapter is integration-tested against the real # library rather than a hand-written approximation of its challenge format. test: - name: PHP ${{ matrix.php }} · L${{ matrix.laravel }} · ${{ matrix.stability }} + name: PHP ${{ matrix.php }} · ${{ matrix.stability }} runs-on: ubuntu-latest timeout-minutes: 15 @@ -24,7 +24,6 @@ jobs: fail-fast: false matrix: php: ['8.4', '8.5'] - laravel: ['13'] stability: [prefer-stable] include: # One lowest-dependency run, on the floor. This is what catches a constraint that @@ -34,7 +33,6 @@ jobs: # on symfony/tui. setup-php resolves '8.4' to the latest 8.4.x, so this run does not # prove 8.4.1 specifically — the constraint in composer.json is what does. - php: '8.4' - laravel: '13' stability: prefer-lowest steps: @@ -49,9 +47,31 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, intl coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: | - composer require "illuminate/contracts:^${{ matrix.laravel }}.0" --no-interaction --no-update composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - name: Run the suite @@ -88,6 +108,29 @@ jobs: - name: Remove the optional integration run: composer remove --dev --no-update --no-interaction altcha-org/altcha + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress @@ -125,6 +168,29 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, intl coverage: none + - name: Resolve composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + + - name: Restore composer cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}-${{ matrix.php }}- + + - name: Drop cached laranail archives + # laranail/* resolve through a single MOVING v0.1.0 tag, so composer's dist + # cache is keyed on a name whose contents change underneath it. A restored + # archive is then silently stale: the install reports success and unpacks + # whatever was cached the first time. Everything else is immutable per + # version and stays cached. + # POSIX command via bash: Windows runners default to PowerShell, where this + # would be a parse error rather than a no-op. + shell: bash + run: rm -rf "$(composer config cache-files-dir)/laranail" + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress diff --git a/src/Commands/CacheClearCommand.php b/src/Commands/CacheClearCommand.php index e455e15..1f29f1f 100644 --- a/src/Commands/CacheClearCommand.php +++ b/src/Commands/CacheClearCommand.php @@ -27,9 +27,6 @@ final class CacheClearCommand extends Command protected $name = 'laranail::captcha.cache-clear'; - /** @var list */ - protected array $commandAliases = ['captcha:cache-clear']; - protected $signature = 'laranail::captcha.cache-clear {--environment= : Clear another environment’s entries}'; protected $description = 'Forget cached captcha credentials so database changes apply immediately.'; diff --git a/src/Commands/DoctorCommand.php b/src/Commands/DoctorCommand.php index f41a506..6ed7885 100644 --- a/src/Commands/DoctorCommand.php +++ b/src/Commands/DoctorCommand.php @@ -26,9 +26,6 @@ final class DoctorCommand extends Command protected $name = 'laranail::captcha.doctor'; - /** @var list */ - protected array $commandAliases = ['captcha:doctor']; - protected $description = 'Report the active captcha provider, where its credentials come from, and anything unsafe.'; public function handle( diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php index 9be82ba..ff3597d 100644 --- a/src/Commands/InstallCommand.php +++ b/src/Commands/InstallCommand.php @@ -22,9 +22,6 @@ final class InstallCommand extends Command protected $name = 'laranail::captcha.install'; - /** @var list */ - protected array $commandAliases = ['captcha:install']; - protected $signature = 'laranail::captcha.install {--migrations : Also publish the optional settings-table migration}'; protected $description = 'Publish the captcha config file, and optionally the settings migration.'; diff --git a/src/Commands/KeysCommand.php b/src/Commands/KeysCommand.php index 56d64a2..f49f470 100644 --- a/src/Commands/KeysCommand.php +++ b/src/Commands/KeysCommand.php @@ -25,9 +25,6 @@ final class KeysCommand extends Command protected $name = 'laranail::captcha.keys'; - /** @var list */ - protected array $commandAliases = ['captcha:keys']; - protected $description = 'Show which source each provider’s credentials resolve from, redacted.'; public function handle(ResolveCredentials $resolveCredentials): int diff --git a/tests/Feature/BrowserRuntimeTest.php b/tests/Feature/BrowserRuntimeTest.php index 8e931ab..92b49ee 100644 --- a/tests/Feature/BrowserRuntimeTest.php +++ b/tests/Feature/BrowserRuntimeTest.php @@ -28,7 +28,7 @@ */ function browserDir(): string { - return dirname(__DIR__) . '/Browser'; + return __DIR__ . '/../Browser'; } /** diff --git a/tests/Feature/RuntimeScriptTest.php b/tests/Feature/RuntimeScriptTest.php index 3329923..52e52b7 100644 --- a/tests/Feature/RuntimeScriptTest.php +++ b/tests/Feature/RuntimeScriptTest.php @@ -83,7 +83,7 @@ function node(): ?string $file = tempnam(sys_get_temp_dir(), 'captcha-runtime') . '.js'; file_put_contents($file, extractRuntime()); - $process = new Process([(string) node(), dirname(__DIR__) . '/js/harness.mjs', $file]); + $process = new Process([(string) node(), __DIR__ . '/../js/harness.mjs', $file]); $process->run(); @unlink($file); diff --git a/tests/TestCase.php b/tests/TestCase.php index 92e4cd0..bbc5ba5 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -47,7 +47,7 @@ protected function defineEnvironment($app): void */ protected function defineDatabaseMigrations(): void { - $migration = require dirname(__DIR__) . '/database/migrations/create_captcha_settings_table.php.stub'; + $migration = require __DIR__ . '/../database/migrations/create_captcha_settings_table.php.stub'; $migration->up(); }