Jenkins: running PHPUnit from Codeception by a Pull Request in Github and Allure-reports
Tags: jenkins, git, unittesting, phpunit
Published: 2019-06-20 12:01:13

---
title: Jenkins: running PHPUnit from Codeception by a Pull Request in Github and Allure-reports
published: true
tags: Jenkins,Git,unittesting,PHPUnit
canonical_url: https://rtfm.co.ua/en/jenkins-running-phpunit-from-codeception-by-a-pull-reguest-in-github-and-allure-reports/
---

![](https://rtfm.co.ua/wp-content/uploads/2016/01/Jenkins.sh-600x600-e1453134979914.png)The task is to create a Jenkins Scripted Pipeline job to run [PHPUnit](https://phpunit.de/) with our PHP-based backend unit-tests.

To run PHPUnit [Codeception](https://codeception.com/) will be used.

This Jenkins job must be triggered from a Github repository after creating Pull Request so will use [Github Pull-Request Builder](https://rtfm.co.ua/jenkins-github-pull-request-builder-plagin/) plugin here.

To view generated reports – [Allure](https://rtfm.co.ua/jenkins-allure-reports-plugin-v-scripted-pipeline/) Jenkins plugin will be used.

Our Jenkins is running in a Docker container and all its tasks also will be running as Docker containers using [Docker plugin](https://plugins.jenkins.io/docker-plugin).

### Testing tests

To get a picture how tests will be running in Jenkins – first, let’s run them locally.

PHP:

```
$ docker run -ti php:7.2 php --version
PHP 7.2.19 (cli) (built: Jun  1 2019 00:50:51) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```

Make `init`:

```
$ docker run -ti -v $(pwd):/data/ php:7.2 /data/init --env=Development
Yii Application Initialization Tool v1.0
...
initialization completed.
```

Now – Composer to install dependencies:

```
$ docker run -ti -v $(pwd):/data/ --workdir /data composer install --optimize-autoloader --ignore-platform-reqs
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 118 installs, 0 updates, 0 removals
...
Generating optimized autoload files
```

And finally – unit-tests itself, from our _backend_ directory first:

```
$ docker docker run -ti -v $(pwd):/data/ codeception/codeception run -c /data/backend/ unit
Codeception PHP Testing Framework v3.0.1
Powered by PHPUnit 7.5.9 by Sebastian Bergmann and contributors.
Running with seed:
Backend\tests.unit Tests (0) ----
Time: 99 ms, Memory: 16.00 MB
No tests executed!
```

Okay – there are no tests yet, developers will add them later and our task for now just make it works. Let’s go to Jenkins.

### Jenkins

Create a Pipeline job, configure the _GitHub project_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_125109.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_125109.png)

Write a pipeline script:

```
node {
    
    stage('Clone repo') {
        git branch: "master", url: "git@github.com:orgname/reponame.git", credentialsId: "jenkins-github"
    }
    
    stage('Build app') {
        docker.image('php:7.2').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "php init --env=Development"
        }
    }
}
```

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_142617.png "Jenkins: running PHPUnit from Codeception by a Pull Reguest in Github and Allure-reports")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_142617.png)

Run:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_131748.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_131748.png)

Okay, all work here, now add Composer:

```
node {
    
    stage('Clone repo') {
        git branch: "master", url: "git@github.com:orgname/reponame.git", credentialsId: "jenkins-github"
    }
    
    stage('Build app') {
        docker.image('php:7.2').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "php init --env=Development"
        }
        docker.image('composer').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "composer install --optimize-autoloader --ignore-platform-reqs"
        }
    }
}
```

Run the job and:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_132504.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_132504.png)

> …  
> – Installing orgname/itunes-receipt-validator (dev-master c8c11ba): Cloning c8c11ba7ba  
> Failed to download orgname/itunes-receipt-validator from source: Failed to execute git clone –no-checkout ‘git@github.com:orgname/itunes-receipt-validator.git’ ‘/var/lib/jenkins/workspace/BackendUnitTests/ProjectName/vendor/orgname/itunes-receipt-validator’ && cd ‘/var/lib/jenkins/workspace/BackendUnitTests/ProjectName/vendor/orgname/itunes-receipt-validator’ && git remote add composer ‘git@github.com:orgname/itunes-receipt-validator.git’ && git fetch composer
> 
> Now trying to download from dist  
> – Installing orgname/itunes-receipt-validator (dev-master c8c11ba): Downloading (connecting…)… Downloading (failed)
> 
> [Composer\Downloader\TransportException]  
> The “https://api.github.com/repos/orgname/itunes-receipt-validator/zipball/c8c11ba7ba1741c7dec248e6f9c0787cb146730a” file could not be downloaded (HTTP/1.1 404 Not Found)  
> …

Add a Github Auth Token by calling `composer config`:

```
...
        docker.image('composer').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "composer config -g github-oauth.github.com 64b***554"
            sh "composer install --optimize-autoloader --ignore-platform-reqs"
        }
...
```

Restart the job:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_132956.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_132956.png)

Nice.

Add tests execution:

```
node {
    
    stage('Clone repo') {
        git branch: "master", url: "git@github.com:orgname/reponame.git", credentialsId: "jenkins-github"
    }
    
    stage('Build app') {
        docker.image('php:7.2').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "php init --env=Development"
        }
        docker.image('composer').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "composer config -g github-oauth.github.com 64b***554"
            sh "composer install --optimize-autoloader --ignore-platform-reqs"
        }
    }
    
    stage('Backend tests') {
        docker.image('codeception/codeception').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "codeception run -c backend/ unit"
        }        
    }
}
```

#### Jenkins Docker Plugin – The container started but didn’t run the expected command. Please double check your ENTRYPOINT.

The next error was when `codeception` Docker container was added:

> …  
> [Pipeline] withDockerContainer  
> Jenkins seems to be running inside container 81f6a8cbdb28a86b5e156a929ef06c2a68dd5c716910f0ab66073656c32c6472  
> $ docker run -t -d -u 0:0 -v /var/run/docker.sock:/var/run/docker.sock -w /var/lib/jenkins/workspace/BackendUnitTests/ProjectName –volumes-from 81f6a8cbdb28a86b5e156a929ef06c2a68dd5c716910f0ab66073656c32c6472 -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* -e \*\*\*\*\*\*\*\* codeception/codeception cat  
> $ docker top 7e909bf25e232c951658478c1a82a93504061a4de4d90b2134680b3ca5f59f36 -eo pid,comm  
> ERROR: The container started but didn’t run the expected command. Please double check your ENTRYPOINT does execute the command passed as docker run argument, as required by official docker images (see https://github.com/docker-library/official-images#consistency for entrypoint consistency requirements).  
> Alternatively you can force image entrypoint to be disabled by adding option `–entrypoint=”`.  
> …  
> process apparently never started in /var/lib/jenkins/workspace/BackendUnitTests/ProjectName@tmp/durable-49ccb7e5  
> …  
> [Pipeline] End of Pipeline  
> ERROR: script returned exit code -2  
> Finished: FAILURE

It’s not the first time I see this error and usually, I’m solving it just by building own Docker image with all necessary tools.

But this time I was a bit lazy to write Dockerfile and build it, so found another “solution”.

In this [Jenkins issue](https://issues.jenkins-ci.org/browse/JENKINS-39748?focusedCommentId=285351&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-285351) opened in 2016 and still with fresh comments, people say that `--entrypoint=""` may help.

But in this case the `sh "codeception run [...]"` call will not work.

Thus, need to find an executable Codeception in the Codeception Docker image.

This could be made by googling its `Dockerfile` with `entrypoint` specified, or by running a container and checking it with `docker inspect` but I did it in another way.

Run a container locally with redefined `entrypoint` to `bash`:

```
$ docker run -ti --entrypoint bash codeception/codeception
root@596960d14192:/project#
```

Then I tried to find `codeception` executable file:

```
root@596960d14192:/project# find / -name codeception
/root/.composer/cache/files/codeception
/repo/vendor/codeception
```

[/simterm]

But those all are directories…

Then how it is started?

So I started to type _code_ and hit by the TAB button and it set me the executable name – `codecept` instead of `codeception`.

Then just call `which codecept` which returned me `/repo/codecept`.

Now update pipeline script – add `--entrypoint=""` and change `sh` call:

```
...
    stage('Backend tests') {
        docker.image('codeception/codeception').inside('-v /var/run/docker.sock:/var/run/docker.sock --entrypoint=""') {
            sh "/repo/codecept run -c backend/ unit"
        }        
    }
...
```

Run it:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_141215.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_141215.png)

Nice.

During writing this post till this lines – developers added a “test test” so let’s run it with reports generation, see docs [here>>>](https://codeception.com/docs/11-Codecoverage).

```
...
    stage('Backend tests') {
        docker.image('codeception/codeception').inside('-v /var/run/docker.sock:/var/run/docker.sock --entrypoint=""') {
            sh "/repo/codecept run -c backend/ unit --coverage-xml --coverage-html"
        }        
    }
...
```

Run:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_142511.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_142511.png)

### Allure reports

The next thing I want to do is an Allure report after the job will be finished.

We already have [Allure Reports Plugin](https://rtfm.co.ua/jenkins-allure-reports-plugin-v-scripted-pipeline/) for another builds so let’s try to use it with Codeception/PHPUnit.

Another solution could be using [Clover PHP Plugin](https://wiki.jenkins.io/display/JENKINS/Clover+PHP+Plugin).

Allure docs for Codeception is available [here>>>](https://github.com/allure-framework/allure-codeception).

Edit a project’s `composer.json`, add the Allure dependency:

```
...
{
    "require": {
            ...
      "allure-framework/allure-codeception": ">=1.1.0"
    }
}
...
```

Update `backend/codeception.yml` config and add `extensions`:

```
namespace: backend\tests
actor: Tester
paths:
    tests: tests
    log: tests/_output
    data: tests/_data
    helpers: tests/_support
settings:
    bootstrap: _bootstrap.php
    colors: true
    memory_limit: 1024M
modules:
    config:
        Yii2:
            configFile: 'config/test-local.php'
extensions: 
    enabled:
        - Yandex\Allure\Codeception\AllureCodeception
    config:
        Yandex\Allure\Codeception\AllureCodeception:
            deletePreviousResults: false
            outputDirectory: allure-results 
            ignoredAnnotations:
                - env        
                - dataprovider
```

In the job add `composer.lock` update (later better to update it in the project’s repository to avoid calling `update` each time in the job):

```
...
    stage('Build app') {
            ...
            sh "composer update --lock --ignore-platform-reqs"
            sh "composer install --optimize-autoloader --ignore-platform-reqs"
        }
    }
...
```

Add Allure plugin settings to the build script:

```
...
    stage('Backend tests') {
        docker.image('codeception/codeception').inside('-v /var/run/docker.sock:/var/run/docker.sock --entrypoint=""') {
            sh "/repo/codecept run -c backend/ unit"
        }        
    }
    
    stage('Reports') {
        allure([
            includeProperties: false,
            jdk: '',
            properties: [],
            reportBuildPolicy: 'ALWAYS',
            results: [[path: 'backend/tests/_output/allure-results']]
        ])
    }
...
```

Run the build:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_171735.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_171735.png)

And the report is ready:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_171801-1.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_171801-1.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_171820.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190605_171820.png)

### Github webhook

The last thing to do is to configure a Github repository to execute a webhook after a Pull Request will be created to trigger unit tests job on the Jenkins.

See [Jenkins: Github Pull-Request Builder плагин](https://rtfm.co.ua/jenkins-github-pull-request-builder-plagin/) (_Rus_).

In the job’s settings add _GitHub project_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_105353.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_105353.png)

Create a Github token and configure the plugin.

In the job’s settings in its _Build Triggers_ enable _GitHub Pull Request Builder_, set _Use github hooks for build triggering._

In the _List of organizations. Their members will be whitelisted_ add a Github’s organization (or a dedicated user in the _Admin list_, if no organization in your Github), and set _Allow members of whitelisted organizations as admins_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_105807.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_105807.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112239.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112239.png)

If a webhook wasn’t created by the plugin – add it yourself:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_111850-1.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_111850-1.png)

In the _Payload URL_ set _https://<jenkins-URL>/ghprbhook/_, chose _Let me select individual events_ and select events which will trigger this webhook – _Issue comments_ and _Pull requests_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_134502-1.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_134502-1.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112035.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112035.png)

Create a PR:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112426.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112426.png)

Check the webhook status – must be a new call to the Jenkins:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112500.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112500.png)

And Jenkin’s job new build:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112539.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112539.png)

PR status:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112607.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_112607.png)

In general – that’s all.

To finalize all we did above – move the Pipeline script to a repository and hardcoded Github repositories/branches – as the job’s parameters.

So the build-script now looks like this:

```
node {
    stage('Clone repo') {
        git branch: "${APPLICATION_BRANCH}", url: "${APPLICATION_URL}", credentialsId: "jenkins-github"
    }
    stage('Build app') {
        docker.image('php:7.2').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "php init --env=Development"
        }
        docker.image('composer').inside('-v /var/run/docker.sock:/var/run/docker.sock') {
            sh "composer config -g github-oauth.github.com ${GITHUB_TOKEN}"
            sh "composer update --lock --ignore-platform-reqs"
            sh "composer install --optimize-autoloader --ignore-platform-reqs"
        }
    }
    try {
        stage('Backend tests') {
            docker.image('codeception/codeception').inside('-v /var/run/docker.sock:/var/run/docker.sock --entrypoint=""') {
                sh "/repo/codecept run -c backend/ unit"
            }
        }
        stage('Frontend tests') {
            docker.image('codeception/codeception').inside('-v /var/run/docker.sock:/var/run/docker.sock --entrypoint=""') {
                sh "/repo/codecept run -c frontend/ unit"
            }
        }
    } finally {
        stage('Reports') {
            allure([
                includeProperties: false,
                jdk: '',
                properties: [],
                reportBuildPolicy: 'ALWAYS',
                results: [[path: 'backend/tests/_output/allure-results'],[path: 'frontend/tests/_output/allure-results']]
            ])
        }
    }
}
```

There is a _frontend_ tests stage added and tests execution set in the `try/catch`, to always collect reports by Allure (in the `finally`) otherwise, if any test will fail – build just will stop without executing the `stage('Reports')`.

The script execution in the job now:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_130009.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_130009.png)

And reports – _backend_ one passed, _frontend_ one failed:

[![](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_130210.png "Jenkins: запуск PHPUnit из Codeception по Pull Reguest в Github и Allure-репорты")](https://rtfm.co.ua/wp-content/uploads/2019/06/Screenshot_20190606_130210.png)

Done.

- [![](https://rtfm.co.ua/wp-content/plugins/share-me//assets/images/cercle/facebook.png)](http://www.facebook.com/sharer.php?u=https://rtfm.co.ua/en/jenkins-running-phpunit-from-codeception-by-a-pull-reguest-in-github-and-allure-reports/&t=Jenkins%3A+running+PHPUnit+from+Codeception+by+a+Pull+Request+in+Github+and+Allure-reports "Share on Facebook")
- [![](https://rtfm.co.ua/wp-content/plugins/share-me//assets/images/cercle/twitter.png)](http://twitter.com/share?text=Jenkins%3A+running+PHPUnit+from+Codeception+by+a+Pull+Request+in+Github+and+Allure-reports-&url=https://rtfm.co.ua/en/jenkins-running-phpunit-from-codeception-by-a-pull-reguest-in-github-and-allure-reports/&via=RTFM:%20Linux,%20DevOps%20and%20system%20administration "Tweet This Post")
- [![](https://rtfm.co.ua/wp-content/plugins/share-me//assets/images/cercle/googleplus.png)](https://plusone.google.com/_/+1/confirm?hl=fr-FR&url=https://rtfm.co.ua/en/jenkins-running-phpunit-from-codeception-by-a-pull-reguest-in-github-and-allure-reports/ "Share on Google+")
- [![](https://rtfm.co.ua/wp-content/plugins/share-me//assets/images/cercle/tumblr.png)](http://www.tumblr.com/share/photo?source=https%3A%2F%2Frtfm.co.ua%2Fwp-content%2Fuploads%2F2016%2F01%2FJenkins.sh-600x600-e1453134979914-1.png&caption=Jenkins%3A+running+PHPUnit+from+Codeception+by+a+Pull+Request+in+Github+and+Allure-reports&clickthru=https%3A%2F%2Frtfm.co.ua%2Fen%2Fjenkins-running-phpunit-from-codeception-by-a-pull-reguest-in-github-and-allure-reports%2F "Share on Tumblr")
- [![](https://rtfm.co.ua/wp-content/plugins/share-me//assets/images/cercle/linkedin.png)](http://www.linkedin.com/shareArticle?mini=true&url=https://rtfm.co.ua/en/jenkins-running-phpunit-from-codeception-by-a-pull-reguest-in-github-and-allure-reports/&title=Jenkins%3A+running+PHPUnit+from+Codeception+by+a+Pull+Request+in+Github+and+Allure-reports&source=RTFM:%20Linux,%20DevOps%20and%20system%20administration)

  

### Similar posts
  
- <small>06/18/2019</small> [SonarQube: running tests from Jenkins Pipeline from Docker](https://rtfm.co.ua/en/sonarqube-running-tests-from-jenkins-pipeline-from-docker/)<small> (0)</small>  
- <small>06/18/2019</small> [SonarQube: запуск в Docker и вызов из Jenkins Pipeline](https://rtfm.co.ua/sonarqube-zapusk-v-docker-i-vyzov-iz-jenkins-pipeline/)<small> (0)</small>  
- <small>02/24/2017</small> [Jenkins: pipeline плагин и триггер билда через Github webhook](https://rtfm.co.ua/jenkins-pipeline-plagin-i-trigger-bilda-cherez-github-webhook/)<small> (1)</small>  
- <small>04/16/2019</small> [Jenkins: a job to check a Github organization’s public repositories list](https://dev.to/setevoy/jenkins-a-job-to-check-a-github-organization-s-public-repositories-list-129p)<small> (0)</small>