加速github动作,通过缓存作曲家,校长和品脱
#重构 #php #laravel #测试

GitHub每月免费使用GitHub动作的2000分钟,通常足以处理轻型工作流程。但是,随着更多的技术自动运行,我们被迫升级到付费计划或优化我们的工作流程。

目前,我正在每个PR上运行校长,品脱和Phpunit测试。如果校长或品脱发现可以在其配置的PR上改进的东西,以进行另一个提交。这触发了另一个管道的运行。

在一个适中的代码库中,其中三个加在一起,每个执行平均总计15分钟,这很痛苦。通过使用GitHub动作缓存机制,我们设法将其降至4.5分钟。完整的代码和一些有用的链接在底部,以下是步骤。

缓存作曲家供应商

这是我们缓存供应商文件夹的工作定义的一部分:

jobs:
  code-quality:
    runs-on: ubuntu-latest
    steps:
      - uses: shivammathur/setup-php@v2
        with:
          php-version: 8.1
      - uses: actions/checkout@v3
      - name: Cache Vendor
        uses: actions/cache@v3
        with:
          path: vendor
          key: ${{ runner.os }}-vendor-${{ hashFiles('**/composer.lock') }}
      - name: "Install Dependencies"
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

这并不是什么改进,因为作曲家的安装通常很快,但是您每次运行中大约6-8秒就搁置了。缓存其他东西更具影响力。

缓存校长

校长默认情况下并联运行,通常在本地非常快。但是,GitHub托管的跑步者只有2个核心,因此校长有点慢。平均而言,校长花了大约5分钟的时间才能进行。

我们要做的第一件事是在我们的rector.php配置中启用基于文件的缓存。

<?php

declare(strict_types=1);

use Rector\Caching\ValueObject\Storage\FileCacheStorage;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig->paths([
        __DIR__.'/app',
        __DIR__.'/tests',
    ]);

    $rectorConfig->importNames();

    $rectorConfig->sets([...]);

    // Ensure file system caching is used instead of in-memory.
    $rectorConfig->cacheClass(FileCacheStorage::class);

    // Specify a path that works locally as well as on CI job runners.
    $rectorConfig->cacheDirectory('./storage/rector/cache');
};

这也将加快您后续的本地校长运行,因为它将仅检查修改后的文件而不是整个代码库。

接下来,在github操作中,我们执行与以前相同的缓存,但是我们没有缓存vendor目录,而是缓存storage/rector/cache目录,或者在存储校长缓存的任何地方。

jobs:
  code-quality:
    runs-on: ubuntu-latest
    steps:
      - ...
      - name: Cache Rector
        uses: actions/cache@v3
        with:
          path: ./storage/rector/cache
          key: ${{ runner.os }}-rector-${{ hashFiles('**/composer.lock') }}
          restore-keys: ${{ runner.os }}-rector-
      - name: Run Rector
        run: vendor/bin/rector --ansi

第一次触发管道时,将花费全部时间运行。但是,它将存储Recor Cache并将其用于随后的运行。根据PRS中影响的文件数量,校长步骤现在只需要几秒钟。

caching品脱

我对此有些挣扎,因为Pint是在PHP CS Fixer顶部构建的,并且如何配置缓存没有明确的方法。我发现PHP CS Fixer默认使用缓存,您可以在运行Fixer命令时提供选项来指定缓存文件位置。但是,品脱未将--cache-file选项传递给PHP CS Fixer。

相反,您可以在pint.json中配置Pint Cache位置:

{
    "preset": "laravel",
    "exclude":[...],
    "cache-file": "storage/pint.cache",
    "rules": {...}
}

您可以选择最适合自己的位置。现在我们有一个固定的缓存位置,我们为GitHub操作执行相同的代码:

jobs:
  code-quality:
    runs-on: ubuntu-latest
    steps:
      - ...
      - name: Cache Pint
        uses: actions/cache@v3
        with:
          path: ./storage/pint.cache
          key: ${{ runner.os }}-pint-${{ hashFiles('**/composer.lock') }}
          restore-keys: ${{ runner.os }}-pint-
      - name: Run Pint
        run: ./vendor/bin/pint

根据您的PRS的大小,这也将品品的执行降至几秒钟。

完整的管道

这是运行校长和品脱的Laravel项目管道的完整代码,如果需要,可以通过重构或造型更改对您的PR进行承诺。当校长和品脱作业结束时,Phpunit测试开始运行。

name: Rector, Pint & Tests

on:
  pull_request:
    branches: [ master ]

jobs:
  code-quality:
    runs-on: ubuntu-latest
    steps:
      - uses: shivammathur/setup-php@v2
        with:
          php-version: 8.1
      - uses: actions/checkout@v3
        with:
          # Must be used to trigger workflow after push
          token: ${{ secrets.ACCESS_TOKEN }}
      - name: Cache Vendor
        uses: actions/cache@v3
        with:
          path: vendor
          key: ${{ runner.os }}-vendor-${{ hashFiles('**/composer.lock') }}
      - name: "Install Dependencies"
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
      - name: Cache Rector
        uses: actions/cache@v3
        with:
          path: ./storage/rector/cache
          key: ${{ runner.os }}-rector-${{ hashFiles('**/composer.lock') }}
          restore-keys: ${{ runner.os }}-rector-
      - name: "Run Rector"
        run: vendor/bin/rector --ansi
      - name: Cache Pint
        uses: actions/cache@v3
        with:
          path: ./storage/pint.cache
          key: ${{ runner.os }}-pint-${{ hashFiles('**/composer.lock') }}
          restore-keys: ${{ runner.os }}-pint-
      - name: "Run Pint"
        run: ./vendor/bin/pint
      - uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: '[ci-review] Rector & Pint'
          commit_author: 'GitHub Action <actions@github.com>'
          commit_user_email: 'action@github.com'

  tests:
    runs-on: ubuntu-latest
    needs: code-quality
    services:
      mysql:
        image: mysql:8.0.25
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: false
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: my_app_test
        ports:
          - 3306/tcp
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
    steps:
      - uses: shivammathur/setup-php@2.23.0
        with:
          php-version: '8.1'
          extensions: mbstring, dom, fileinfo, mysql
      - uses: actions/checkout@v3
        with:
          # Must be used to trigger workflow after push
          token: ${{ secrets.ACCESS_TOKEN }}
      - name: Copy .env
        run: php -r "file_exists('.env') || copy('.env.example', '.env');"
      - name: Cache Vendor
        uses: actions/cache@v3
        with:
          path: vendor
          key: ${{ runner.os }}-vendor-${{ hashFiles('**/composer.lock') }}
      - name: Install Dependencies
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
      - name: Generate key
        run: php artisan key:generate
      - name: Clear Config
        run: php artisan config:clear
      - name: Run Migration
        run: php artisan migrate -v
        env:
          DB_TEST_PORT: ${{ job.services.mysql.ports['3306'] }}
      - name: Directory Permissions
        run: chmod -R 777 storage bootstrap/cache
      - name: PHPUnit
        run: php artisan test --parallel
        env:
          DB_TEST_PORT: ${{ job.services.mysql.ports['3306'] }}

查看这些资源以获取更多信息: