GitHub Actions est un outil permettant d'automatiser les actions de routine de votre package sur GitHub.
Par expérience personnelle, je vais vous dire comment, sans expérience et sans connaissance de la mise en place de CI, j'ai appris à automatiser une routine dans mon projet Open Source en une journée et qu'en fait ce n'est vraiment pas aussi effrayant et difficile que beaucoup le pensent.
GitHub fournit des outils vraiment pratiques et fonctionnels pour cela.
Plan d'action
configurer CI dans GitHub Actions pour un petit projet 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 , :
Je serai heureux si mon tutoriel est utile à quelqu'un, car Avant d'écrire cet article, j'ai rencontré pour la première fois GitHub Actions, je ne suis pas DevOps et je ne m'occupe pas de la configuration CI, j'ai moi-même dû rechercher sur Google plusieurs sites pour configurer le flux de travail dont j'avais besoin.