Automatizar acciones manuales con acciones de GitHub

Acciones de GitHub es una herramienta para automatizar acciones de rutina desde su paquete en GitHub.



Por experiencia personal les contaré cómo, sin experiencia y conocimiento sobre la configuración de CI, aprendí a automatizar una rutina en mi proyecto de Código Abierto en tan solo un día y que de hecho no es tan aterrador y difícil como muchos piensan.



GitHub proporciona herramientas de trabajo realmente convenientes para esto.





Plan de ACCION

  • configurar CI en acciones de GitHub para un pequeño proyecto PHP





  • ( )





  • , / , PR-s ( ), Check Suite PR, .





  • , , packagist.





, , , Open-Source , , -, . , , .





CI

CI , , PHP Postgres CI . , .



:





.github/workflows/ci.yml
name: CI

on:
  push:
    branches:
      - master
  pull_request:
    types:
      - opened
      - reopened
      - edited
      - synchronize

env:
  COVERAGE: '1'
  php_extensions: 'pdo, pdo_pgsql, pcntl, pcov, ...'
  key: cache-v0.1
  DB_USER: 'postgres'
  DB_NAME: 'testing'
  DB_PASSWORD: 'postgres'
  DB_HOST: '127.0.0.1'

jobs:	
  lint:
    runs-on: '${{ matrix.operating_system }}'
    timeout-minutes: 20	
    strategy:	
      matrix:
        operating_system: ['ubuntu-latest']
        php_versions: ['7.4']
      fail-fast: false
    env:	
      PHP_CS_FIXER_FUTURE_MODE: '0'
    name: 'Lint PHP'
    steps:	
      - name: 'Checkout'
        uses: actions/checkout@v2
      - name: 'Setup cache environment'
        id: cache-env
        uses: shivammathur/cache-extensions@v1
        with:
          php-version: '${{ matrix.php_versions }}'
          extensions: '${{ env.php_extensions }}'
          key: '${{ env.key }}'
      - name: 'Cache extensions'
        uses: actions/cache@v1
        with:
          path: '${{ steps.cache-env.outputs.dir }}'
          key: '${{ steps.cache-env.outputs.key }}'
          restore-keys: '${{ steps.cache-env.outputs.key }}'
      - name: 'Setup PHP'
        uses: shivammathur/setup-php@v2	
        with:	
          php-version: ${{ matrix.php_versions }}
          extensions: '${{ env.php_extensions }}'
          ini-values: memory_limit=-1	
          tools: pecl, composer
          coverage: none
      - name: 'Setup problem matchers for PHP (aka PHP error logs)'
        run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"'
      - name: 'Setup problem matchers for PHPUnit'
        run: 'echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"'
      - name: 'Install PHP dependencies with Composer'
        run: composer install --prefer-dist --no-progress --no-suggest --optimize-autoloader
        working-directory: './'
      - name: 'Linting PHP source files'
        run: 'composer lint'
  test:
    strategy:
      fail-fast: false
      matrix:
        operating_system: ['ubuntu-latest']
        postgres: [11, 12]
        php_versions: ['7.3', '7.4', '8.0']
        experimental: false
        include:
          - operating_system: ubuntu-latest
            postgres: '13'
            php_versions: '8.0'
            experimental: true   
    runs-on: '${{ matrix.operating_system }}'
    services:
      postgres:
        image: 'postgres:${{ matrix.postgres }}'
        env:
          POSTGRES_USER: ${{ env.DB_USER }}
          POSTGRES_PASSWORD: ${{ env.DB_PASSWORD }}
          POSTGRES_DB: ${{ env.DB_NAME }}
        ports:
          - 5432:5432
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    name: 'Test / PHP ${{ matrix.php_versions }} / Postgres ${{ matrix.postgres }}'
    needs:
      - lint
    steps:
      - name: 'Checkout'
        uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - name: 'Install postgres client'
        run: |
          sudo apt-get update -y
          sudo apt-get install -y libpq-dev postgresql-client
      - name: 'Setup cache environment'
        id: cache-env
        uses: shivammathur/cache-extensions@v1
        with:
          php-version: ${{ matrix.php_versions }}
          extensions: ${{ env.php_extensions }}
          key: '${{ env.key }}'
      - name: 'Cache extensions'
        uses: actions/cache@v1
        with:
          path: '${{ steps.cache-env.outputs.dir }}'
          key: '${{ steps.cache-env.outputs.key }}'
          restore-keys: '${{ steps.cache-env.outputs.key }}'
      - name: 'Setup PHP'
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php_versions }}
          extensions: ${{ env.php_extensions }}
          ini-values: 'pcov.directory=src, date.timezone=UTC, upload_max_filesize=20M, post_max_size=20M, memory_limit=512M, short_open_tag=Off'
          coverage: pcov
          tools: 'phpunit'
      - name: 'Install PHP dependencies with Composer'
        run: composer install --prefer-dist --no-progress --no-suggest --optimize-autoloader
        working-directory: './'
      - name: 'Run Unit Tests with PHPUnit'
        continue-on-error: ${{ matrix.experimental }}
        run: |
          sed -e "s/\${USERNAME}/${{ env.DB_USER }}/" \
              -e "s/\${PASSWORD}/${{ env.DB_PASSWORD }}/" \
              -e "s/\${DATABASE}/${{ env.DB_NAME }}/" \
              -e "s/\${HOST}/${{ env.DB_HOST }}/" \
              phpunit.xml.dist > phpunit.xml
          ./vendor/bin/phpunit \
            --verbose \
            --stderr \
            --coverage-clover build/logs/clover.xml
        working-directory: './'
      - name: 'Upload coverage results to Coveralls'
        if: ${{ !matrix.experimental }}
        env:
          COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          COVERALLS_PARALLEL: true
          COVERALLS_FLAG_NAME: php-${{ matrix.php_versions }}-postgres-${{ matrix.postgres }}
        run: |
          ./vendor/bin/php-coveralls \
            --coverage_clover=build/logs/clover.xml \
            -v
  coverage:
    needs: test
    runs-on: ubuntu-latest
    name: "Code coverage"
    steps:
      - name: 'Coveralls Finished'
        uses: coverallsapp/github-action@v1.1.2
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          parallel-finished: true
      
      







, 3 (lint, tests coverage)





lint - , , , , .



code style , CI . , umbrellio/code-style-php, ( , ):





"scripts": {
   "lint": "ecs check --config=ecs.yml .",
   "lint-fix": "ecs check --config=ecs.yml . --fix"
}
      
      



test - (os, postgres php), include - ( ).





, :





  • experimental ( ) , CI, , PHP, . ( ).





  • sed -e "s/\${USERNAME}/${{ env.DB_USER }}/"...



    , phpunit.xml.dist phpunit.xml, , ENV, :





phpunit.xml.dist
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
>
    <php>
        <env name="APP_ENV" value="testing"/>
        <ini name="error_reporting" value="-1" />
        <var name="db_type" value="pdo_pgsql"/>
        <var name="db_host" value="${HOST}" />
        <var name="db_username" value="${USERNAME}" />
        <var name="db_password" value="${PASSWORD}" />
        <var name="db_database" value="${DATABASE}" />
        <var name="db_port" value="5432"/>
    </php>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./src</directory>
            <exclude>
                <file>./src/.meta.php</file>
            </exclude>
        </whitelist>
    </filter>
    <testsuites>
        <testsuite name="Test suite">
            <directory suffix="Test.php">./tests</directory>
        </testsuite>
    </testsuites>
</phpunit>
      
      







coverage - .. , .. Postgres, , 100% . , composer, Bandler- Ruby, .





.. badge:100% coverage, , , . , coveralls.io .





CI, .





- (labels)

( ):





.github/labeler.config.yml
type:build:
  - ".github/**/*"
  - ".coveralls.yml"
  - ".gitignore"
  - "ecs.yml"
  - "phpcs.xml"

dependencies:
  - "composer.json"
  - "composer.lock"

type:common
  - "src/**/*"

type:tests:
  - 'tests/**/*'
  - 'phpunit.xml.dist'
  - 'tests.sh'

theme:docs:
  - "README.md"
  - "LICENSE"
  - "CONTRIBUTING.md"
  - "CODE_OF_CONDUCT.md"
      
      







, , PR, PR.





, Summary PR ( patch, minor major). , -, , (pull-) .





.github/workflows/labeler.yml
name: "Auto labeling for a pull request"
on:
  - pull_request_target

jobs:
  triage:
    name: "Checking for labels"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/labeler@main
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"
          sync-labels: true
          configuration-path: ".github/labeler.config.yml"
      
      







-

( ):





.github/assignee.config.yml
addReviewers: true
numberOfReviewers: 1
reviewers:
 - pvsaitpe

addAssignees: true
assignees:
 - pvsaintpe
numberOfAssignees: 1

skipKeywords:
  - wip
  - draft
      
      







, - , GitHub.





.github/workflows/assignee.yml
name: 'Auto assign assignees or reviewers'
on: pull_request

jobs:
  add-reviews:
    name: "Auto assignment of a assignee"
    runs-on: ubuntu-latest
    steps:
      - uses: kentaro-m/auto-assign-action@v1.1.2
        with:
          configuration-path: ".github/assignee.config.yml"
      
      







- PR

:





.github/workflows/auto_merge.yml
name: 'Auto merge of approved pull requests with passed checks'

on:
  pull_request:
    types:
      - labeled
      - unlabeled
      - synchronize
      - opened
      - edited
      - ready_for_review
      - reopened
      - unlocked
  pull_request_review:
    types:
      - submitted
  check_suite:
    types:
      - completed
  status: {}

jobs:
  automerge:
    runs-on: ubuntu-latest
    steps:
      - name: 'Automerge PR'
        uses: "pascalgn/automerge-action@v0.12.0"
        env:
          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
          MERGE_METHOD: 'squash'
          MERGE_LABELS: "approved,!work in progress"
          MERGE_REMOVE_LABELS: "approved"
          MERGE_COMMIT_MESSAGE: "pull-request-description"
          MERGE_RETRIES: "6"
          MERGE_RETRY_SLEEP: "10000"
          UPDATE_LABELS: ""
          UPDATE_METHOD: "rebase"
          MERGE_DELETE_BRANCH: false
      
      







, PR, approved, CheckSuite .





Squash, .





- PR

PR, approved, :





.github/workflows/auto_approve.yml
on: pull_request_review
name: 'Label approved pull requests'
jobs:
  labelWhenApproved:
    name: 'Label when approved'
    runs-on: ubuntu-latest
    steps:
      - name: 'Label when approved'
        uses: pullreminders/label-when-approved-action@master
        env:
          APPROVALS: "1"
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ADD_LABEL: "approved"
          REMOVE_LABEL: "awaiting review"
      
      







-

( ) :





.github/release-drafter.yml
template: |
  ## Changes
  $CHANGES
change-template: '- **$TITLE** (#$NUMBER)'

version-template: "$MAJOR.$MINOR.$PATCH"
name-template: '$RESOLVED_VERSION'
tag-template: '$RESOLVED_VERSION'

categories:
  - title: 'Features'
    labels:
      - 'feature'
      - 'type:common'
  - title: 'Bug Fixes'
    labels:
      - 'fix'
      - 'bugfix'
      - 'bug'
      - 'hotfix'
      - 'dependencies'
  - title: 'Maintenance'
    labels:
      - 'type:build'
      - 'refactoring'
      - 'theme:docs'
      - 'type:tests'

change-title-escapes: '\<*_&'

version-resolver:
  major:
    labels:
      - major
      - refactoring
  minor:
    labels:
      - feature
      - minor
      - type:common
  patch:
    labels:
      - patch
      - type:build
      - bug
      - bugfix
      - hotfix
      - fix
      - theme:docs
      - type:tests
  default: patch
      
      







, MAJOR, MINOR, PATCH





.github/workflows/release_drafter.yml
name: Release Drafter

on:
  push:
    branches:
      - master

jobs:
  update_release_draft:
    runs-on: ubuntu-latest
    steps:
      - uses: release-drafter/release-drafter@v5
        with:
          publish: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      
      







GitHub Settings





Check Suite GitHub

GitHub , , , , , 100%, , Check Suite.





,





. , , :





approvals





, - , PR, , , Code Owners .





, approvalls





Check Suite





( CI , , , , Coveralls / Scrutinizer, ), .





, PR .





, Check Suite









, , Settings => Options Squash, "Automatically delete head branches"









- packagist.org





, packagist , .





, webhook packagist

packagist (Show Api Token).





, - OpenSource , Contributor- ( ), CI , , , workflow .





coveralls / scrutinizer , Check Suite % 100%, Readme , :





Estaré encantado si mi tutorial es útil para alguien, porque Antes de escribir esta publicación, encontré por primera vez Acciones de GitHub, no soy DevOps y no estoy involucrado en la configuración de CI, yo mismo tuve que buscar en Google más de un sitio para configurar el flujo de trabajo que necesitaba.








All Articles