Skip to content

Commit a921a98

Browse files
authored
Merge pull request #476 from kbsali/behat-tests-in-github-actions
Behat tests with Github Actions
2 parents 969291d + de2eaa4 commit a921a98

6 files changed

Lines changed: 108 additions & 70 deletions

File tree

.github/workflows/tests.yml

Lines changed: 73 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -37,53 +37,79 @@ jobs:
3737
- name: Run tests
3838
run: composer run phpunit -- --no-coverage
3939

40-
# This does not work
41-
# behat:
42-
# name: Tests (Behat with PHP ${{ matrix.php }})
43-
# runs-on: ubuntu-latest
44-
45-
# services:
46-
# redmine-6-0:
47-
# image: redmine:6.0.7
48-
# ports:
49-
# - "5060:3000"
50-
# env:
51-
# # Workaround: Remove secret for Rails 7.2 so it will be generated automatically
52-
# # @see https://github.com/docker-library/redmine/issues/349#issuecomment-2516634932
53-
# # REDMINE_SECRET_KEY_BASE: supersecretkey
54-
# REDMINE_PLUGINS_MIGRATE: true
55-
# volumes:
56-
# - /home/runner/work/_temp/redmine-60007_data/files:/usr/src/redmine/files
57-
# - /home/runner/work/_temp/redmine-60007_data/sqlite:/usr/src/redmine/sqlite
58-
# options: --health-cmd="wget -O /dev/null http://localhost:3000" --health-start-period=30s --health-interval=30s --health-timeout=30s --health-retries=3
59-
60-
# strategy:
61-
# fail-fast: false
62-
# matrix:
63-
# operating-system: ["ubuntu-latest"]
64-
# php: ["8.3"]
65-
66-
# steps:
67-
# - name: Checkout
68-
# uses: actions/checkout@v4
69-
# with:
70-
# fetch-depth: 2
71-
72-
# - name: Setup PHP, with composer and extensions
73-
# uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php
74-
# with:
75-
# php-version: ${{ matrix.php }}
76-
# tools: phpunit
77-
# extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite
78-
# coverage: xdebug
79-
80-
# # Install composer dependencies and handle caching in one go.
81-
# # @link https://github.com/marketplace/actions/install-composer-dependencies
82-
# - name: "Install Composer dependencies"
83-
# uses: "ramsey/composer-install@v2"
84-
85-
# - name: Run behat
86-
# run: vendor/bin/behat --config tests/Behat/behat.yml --profile=github-actions --suite=redmine_6_0
40+
behat:
41+
name: Behat ${{ matrix.suite }} (PHP ${{ matrix.php }})
42+
runs-on: ubuntu-latest
43+
permissions:
44+
contents: read
45+
46+
strategy:
47+
fail-fast: false
48+
matrix:
49+
php: ["8.3"]
50+
suite: [redmine_6_1, redmine_6_0, redmine_5_1]
51+
include:
52+
- suite: redmine_6_1
53+
service: redmine-6-1
54+
port: 5061
55+
data-dir: redmine-60101_data
56+
- suite: redmine_6_0
57+
service: redmine-6-0
58+
port: 5060
59+
data-dir: redmine-60008_data
60+
- suite: redmine_5_1
61+
service: redmine-5-1
62+
port: 5051
63+
data-dir: redmine-50111_data
64+
65+
steps:
66+
- name: Checkout
67+
uses: actions/checkout@v4
68+
with:
69+
fetch-depth: 2
70+
71+
- name: Setup PHP, with composer and extensions
72+
uses: shivammathur/setup-php@v2
73+
with:
74+
php-version: ${{ matrix.php }}
75+
tools: phpunit
76+
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, curl
77+
coverage: xdebug
78+
79+
- name: Install Composer dependencies
80+
uses: ramsey/composer-install@v2
81+
82+
- name: Create data directory
83+
run: |
84+
mkdir -p .docker/${{ matrix.data-dir }}/{files,sqlite}
85+
chmod -R 777 .docker/${{ matrix.data-dir }}/
86+
87+
- name: Start Redmine container
88+
run: docker compose up -d ${{ matrix.service }}
89+
90+
- name: Wait for Redmine to be healthy
91+
run: |
92+
for i in $(seq 1 60); do
93+
if curl -sf http://localhost:${{ matrix.port }} > /dev/null 2>&1; then
94+
echo "Redmine ${{ matrix.service }} is ready"
95+
exit 0
96+
fi
97+
echo "Waiting... ($i/60)"
98+
sleep 5
99+
done
100+
echo "Redmine ${{ matrix.service }} did not become ready"
101+
docker compose logs ${{ matrix.service }}
102+
exit 1
103+
104+
- name: Fix permissions
105+
run: sudo chmod -R 777 .docker/${{ matrix.data-dir }}/
106+
107+
- name: Run behat
108+
run: vendor/bin/behat --config tests/Behat/behat.yml --profile=github-actions --format=progress --suite=${{ matrix.suite }}
109+
110+
- name: Cleanup
111+
if: always()
112+
run: docker compose down -v
87113

88114
code-quality:
89115
name: Check ${{ matrix.tool }} (PHP ${{ matrix.php }})

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
/composer.lock
66
/phpunit.xml
77
/vendor
8+
.env
9+
.env.local

tests/Behat/Bootstrap/FeatureContext.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ public static function clean(AfterSuiteScope $scope): void
8484
*/
8585
private array $lastReturnAsArray;
8686

87-
public function __construct(string $redmineVersion, string $rootPath)
87+
public function __construct(string $redmineVersion, string $rootPath, string $redmineUrl)
8888
{
8989
$version = RedmineVersion::tryFrom($redmineVersion);
9090

9191
if (!$version instanceof RedmineVersion) {
9292
throw new InvalidArgumentException('Redmine ' . $redmineVersion . ' is not supported.');
9393
}
9494

95-
$this->redmine = self::$tracer::getRedmineInstance($version, $rootPath);
95+
$this->redmine = self::$tracer::getRedmineInstance($version, $rootPath, $redmineUrl);
9696
}
9797

9898
/**

tests/Behat/behat.yml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,44 @@ default:
66
contexts:
77
- Redmine\Tests\Behat\Bootstrap\FeatureContext:
88
redmineVersion: '6.1.1'
9-
rootPath: '%paths.base%/../../.docker'
9+
rootPath: '%paths.base%/../../.docker/redmine-dev_data'
10+
redmineUrl: 'http://redmine-dev:3000'
1011
redmine_6_1:
1112
contexts:
1213
- Redmine\Tests\Behat\Bootstrap\FeatureContext:
1314
redmineVersion: '6.1.1'
14-
rootPath: '%paths.base%/../../.docker'
15+
rootPath: '%paths.base%/../../.docker/redmine-60101_data'
16+
redmineUrl: 'http://redmine-6-1:3000'
1517
redmine_6_0:
1618
contexts:
1719
- Redmine\Tests\Behat\Bootstrap\FeatureContext:
1820
redmineVersion: '6.0.8'
19-
rootPath: '%paths.base%/../../.docker'
21+
rootPath: '%paths.base%/../../.docker/redmine-60008_data'
22+
redmineUrl: 'http://redmine-6-0:3000'
2023
redmine_5_1:
2124
contexts:
2225
- Redmine\Tests\Behat\Bootstrap\FeatureContext:
2326
redmineVersion: '5.1.11'
24-
rootPath: '%paths.base%/../../.docker'
27+
rootPath: '%paths.base%/../../.docker/redmine-50111_data'
28+
redmineUrl: 'http://redmine-5-1:3000'
2529

2630
github-actions:
2731
suites:
2832
redmine_6_1:
2933
contexts:
3034
- Redmine\Tests\Behat\Bootstrap\FeatureContext:
3135
redmineVersion: '6.1.1'
32-
rootPath: '/home/runner/work/_temp'
36+
rootPath: '%paths.base%/../../.docker/redmine-60101_data'
37+
redmineUrl: 'http://localhost:5061'
3338
redmine_6_0:
3439
contexts:
3540
- Redmine\Tests\Behat\Bootstrap\FeatureContext:
3641
redmineVersion: '6.0.8'
37-
rootPath: '/home/runner/work/_temp'
42+
rootPath: '%paths.base%/../../.docker/redmine-60008_data'
43+
redmineUrl: 'http://localhost:5060'
3844
redmine_5_1:
3945
contexts:
4046
- Redmine\Tests\Behat\Bootstrap\FeatureContext:
4147
redmineVersion: '5.1.11'
42-
rootPath: '/home/runner/work/_temp'
48+
rootPath: '%paths.base%/../../.docker/redmine-50111_data'
49+
redmineUrl: 'http://localhost:5051'

tests/RedmineExtension/BehatHookTracer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ final class BehatHookTracer implements InstanceRegistration
1919
*/
2020
private static array $instances = [];
2121

22-
public static function getRedmineInstance(RedmineVersion $redmineVersion, string $rootPath): RedmineInstance
22+
public static function getRedmineInstance(RedmineVersion $redmineVersion, string $rootPath, string $redmineUrl): RedmineInstance
2323
{
2424
if (!self::$tracer instanceof \Redmine\Tests\RedmineExtension\BehatHookTracer) {
2525
throw new RuntimeException('You can only get a Redmine instance while a Behat Suite is running.');
2626
}
2727

2828
if (! array_key_exists($redmineVersion->asId(), self::$instances)) {
29-
RedmineInstance::create(self::$tracer, $redmineVersion, $rootPath);
29+
RedmineInstance::create(self::$tracer, $redmineVersion, $rootPath, $redmineUrl);
3030
}
3131

3232
return self::$instances[$redmineVersion->asId()];

tests/RedmineExtension/RedmineInstance.php

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ final class RedmineInstance
1313
{
1414
/**
1515
* @param InstanceRegistration $tracer Required to ensure that RedmineInstance is created while Test Runner is running
16+
* @param string $rootPath The full path to the Redmine instance data directory (e.g. '/path/to/.docker/redmine-dev_data')
17+
* @param string $redmineUrl The full URL to the Redmine instance (e.g. 'http://localhost:5061')
1618
*/
17-
public static function create(InstanceRegistration $tracer, RedmineVersion $version, string $rootPath): void
19+
public static function create(InstanceRegistration $tracer, RedmineVersion $version, string $rootPath, string $redmineUrl): void
1820
{
19-
$tracer->registerInstance(new self($tracer, $version, $rootPath));
21+
$tracer->registerInstance(new self($tracer, $version, $rootPath, $redmineUrl));
2022
}
2123

2224
private InstanceRegistration $tracer;
@@ -41,19 +43,22 @@ public static function create(InstanceRegistration $tracer, RedmineVersion $vers
4143

4244
private string $apiKey;
4345

44-
private function __construct(InstanceRegistration $tracer, RedmineVersion $version, string $rootPath)
46+
private function __construct(InstanceRegistration $tracer, RedmineVersion $version, string $rootPath, string $redmineUrl)
4547
{
48+
if (trim($rootPath) === '') {
49+
throw new InvalidArgumentException('Redmine data path cannot be empty.');
50+
}
51+
52+
if (trim($redmineUrl) === '') {
53+
throw new InvalidArgumentException('Redmine url cannot be empty.');
54+
}
55+
4656
$this->tracer = $tracer;
4757
$this->version = $version;
4858

4959
$versionId = strval($version->asId());
5060

51-
// Default to .docker folder
52-
if ($rootPath === '') {
53-
$rootPath = dirname(__FILE__, 3) . '/.docker';
54-
}
55-
56-
$this->dataPath = $rootPath . '/redmine-' . $versionId . '_data/';
61+
$this->dataPath = rtrim($rootPath, '/') . '/';
5762

5863
$this->workingDB = 'sqlite/redmine.db';
5964
$this->migratedDB = 'sqlite/redmine-migrated.db';
@@ -63,9 +68,7 @@ private function __construct(InstanceRegistration $tracer, RedmineVersion $versi
6368
$this->migratedFiles = 'files-migrated/';
6469
$this->backupFiles = 'files-bak/';
6570

66-
$parts = explode('.', $version->asString());
67-
68-
$this->redmineUrl = 'http://redmine-' . intval($parts[0]) . '-' . intval($parts[1]) . ':3000';
71+
$this->redmineUrl = $redmineUrl;
6972
$this->apiKey = sha1($versionId . time());
7073

7174
$this->runHealthChecks($version);

0 commit comments

Comments
 (0)