diff --git a/README.md b/README.md
index cdcaf7ac..ab13ff88 100644
--- a/README.md
+++ b/README.md
@@ -111,8 +111,8 @@ The "job" element will have the following elements, but is not restricted to the
],
"dependencies": "(optional) dependencies to test against; one of lowest, locked, latest. default: locked",
"command": "(required) command to run to perform the check",
- "ignore_platform_reqs_8": "(optional; deprecated) boolean; whether to add `--ignore-platform-req=php` to composer for PHP 8.0. default: true",
- "ignore_php_platform_requirement": "(optional) boolean; whether to add `--ignore-platform-req=php` to composer for this job.",
+ "ignore_platform_reqs_8": "(optional; deprecated) boolean; whether to add `--ignore-platform-req=php` to Composer for PHP 8.0. default: true",
+ "ignore_php_platform_requirement": "(optional) boolean; whether to add `--ignore-platform-req=php` to Composer for this job.",
"additional_composer_arguments": [
"(optional) list of arguments to be passed to `composer install` and `composer update`"
]
@@ -200,18 +200,45 @@ The tool discovers checks first, then appends any `additional_checks` are concat
### Excluding specific jobs
-The easiest way to exclude a single job is via the `name` parameter:
+You can exclude specific jobs by using their names:
```json
{
"exclude": [
{
- "name": "PHPUnit on PHP 8.0 with latest dependencies"
+ "name": "PHPUnit"
}
]
}
```
+If you want to limit the exclusion to specific PHP versions, you can additionally add a PHP version:
+
+```json
+{
+ "exclude": [
+ {
+ "name": "PHPUnit",
+ "php": "8.0"
+ }
+ ]
+}
+```
+
+In case you only want to exclude jobs for specific Composer dependency sets, add `dependencies` to the `exclude` configuration:
+
+```json
+{
+ "exclude": [
+ {
+ "name": "PHPUnit",
+ "php": "8.0",
+ "dependencies": "latest"
+ }
+ ]
+}
+```
+
## Testing matrix generation locally using Docker
To test matrix generation in a local checkout on your own machine, you can do the following:
diff --git a/laminas-ci.schema.json b/laminas-ci.schema.json
index a11ba295..72aeff83 100644
--- a/laminas-ci.schema.json
+++ b/laminas-ci.schema.json
@@ -25,6 +25,11 @@
"exclude": [
{
"name": "Codeception [8.2, latest]"
+ },
+ {
+ "name": "Codeception",
+ "php": "8.2",
+ "dependencies": "latest"
}
],
"ignore_php_platform_requirements": {
@@ -243,6 +248,33 @@
}
],
"definitions": {
+ "installablePhpVersion": {
+ "type": "string",
+ "title": "Installable PHP versions from available from within the container.",
+ "enum": [
+ "8.0",
+ "8.1",
+ "8.2",
+ "8.3",
+ "@default"
+ ]
+ },
+ "php": {
+ "title": "The PHP version",
+ "type": "string",
+ "anyOf": [
+ {
+ "$ref": "#/definitions/installablePhpVersion"
+ },
+ {
+ "enum": [
+ "*",
+ "@latest",
+ "@lowest"
+ ]
+ }
+ ]
+ },
"extensions": {
"type": "array",
"title": "A list of PHP extensions",
@@ -285,6 +317,11 @@
[
{
"name": "Codeception [8.2, latest]"
+ },
+ {
+ "name": "Codeception",
+ "php": "8.2",
+ "dependencies": "latest"
}
]
],
@@ -294,6 +331,11 @@
"examples": [
{
"name": "Codeception [8.2, latest]"
+ },
+ {
+ "name": "Codeception",
+ "php": "8.2",
+ "dependencies": "latest"
}
],
"required": [
@@ -306,8 +348,21 @@
"description": "The name of the job to be excluded. Must be an exact match.",
"minLength": 1,
"examples": [
- "Codeception [8.2, latest]"
+ "Codeception [8.2, latest]",
+ "Codeception"
]
+ },
+ "php": {
+ "ref": "#/definitions/php",
+ "description": "The PHP version to to be excluded.",
+ "default": "*"
+ },
+ "dependencies": {
+ "type": "string",
+ "enum": ["latest", "lowest", "locked", "*"],
+ "title": "The composer dependencies to be excluded",
+ "description": "The composer dependencies to be excluded. If the wildcard `*` is passed, all dependencies are being excluded",
+ "default": "*"
}
},
"additionalProperties": false
@@ -331,13 +386,10 @@
}
},
"stablePHP": {
- "type": "string",
- "minLength": 1,
+ "$ref": "#/definitions/installablePhpVersion",
"title": "The PHP version to be used for stable checks",
"description": "This PHP version is used for all QA check jobs. The default depends on the `composer.json` of the project and usually reflects the minimum supported PHP version of that project.",
- "examples": [
- "8.0"
- ]
+ "default": "8.0"
},
"backwardCompatibilityCheck": {
"type": "boolean",
@@ -361,18 +413,9 @@
],
"properties": {
"php": {
- "type": "string",
- "title": "The php version",
+ "$ref": "#/definitions/php",
"description": "The PHP version to be used. If the wildcard `*` is passed, a list of checks is created containing *every* supported PHP version by the project and the matrix action.",
- "enum": [
- "8.0",
- "8.1",
- "8.2",
- "8.3",
- "*",
- "@latest",
- "@lowest"
- ]
+ "default": "*"
},
"dependencies": {
"type": "string",
diff --git a/src/config/app.ts b/src/config/app.ts
index 8cc7cdf0..12005b8d 100644
--- a/src/config/app.ts
+++ b/src/config/app.ts
@@ -3,9 +3,28 @@ import semver from 'semver';
import parseJsonFile from '../json';
import {isToolRunningContainerDefaultPhpVersion, Tool, ToolExecutionType} from '../tools';
import {Logger} from '../logging';
-import {CURRENT_STABLE, INSTALLABLE_VERSIONS, InstallablePhpVersionType, isInstallableVersion} from './php';
+import {
+ CONTAINER_DEFAULT_PHP_VERSION,
+ CURRENT_STABLE,
+ INSTALLABLE_VERSIONS,
+ InstallablePhpVersionType,
+ isInstallableVersion
+} from './php';
import {ComposerJson} from './composer';
-import {ConfigurationFromFile, isAdditionalChecksConfiguration, isAnyComposerDependencySet, isAnyPhpVersionType, isConfigurationContainingJobExclusions, isExplicitChecksConfiguration, isLatestPhpVersionType, isLowestPhpVersionType, JobDefinitionFromFile, JobFromFile, JobToExcludeFromFile} from './input';
+import {
+ ConfigurationFromFile,
+ isAdditionalChecksConfiguration,
+ isAnyComposerDependencySet,
+ isAnyPhpVersionType,
+ isConfigurationContainingJobExclusions,
+ isExplicitChecksConfiguration,
+ isLatestPhpVersionType,
+ isLowestPhpVersionType,
+ JobDefinitionFromFile,
+ JobFromFile,
+ JobToExcludeFromFile,
+ WILDCARD_ALIAS
+} from './input';
export const OPERATING_SYSTEM = 'ubuntu-latest';
export const ACTION = 'laminas/laminas-continuous-integration-action@v1';
@@ -242,12 +261,74 @@ function isJobExcludedByDeprecatedCommandName(job: Job, exclusions: JobToExclude
);
}
+function isJobExcludedByName(job: Job, exclude: JobToExcludeFromFile): boolean {
+ if (job.name === exclude.name) {
+ return true;
+ }
+
+ if (isJobFromTool(job)) {
+ return job.tool.name === exclude.name;
+ }
+
+ return false;
+}
+
+function isJobExcludedByConfiguration(
+ job: Job,
+ exclude: JobToExcludeFromFile,
+ config: Config,
+ logger: Logger
+): boolean {
+ if (!isJobExcludedByName(job, exclude)) {
+ return false;
+ }
+
+ const jobName = isJobFromTool(job) ? job.tool.name : job.name;
+
+ const phpVersionToExclude = exclude.php ?? WILDCARD_ALIAS;
+ const dependenciesToExclude = exclude.dependencies ?? WILDCARD_ALIAS;
+
+ if (!isAnyPhpVersionType(phpVersionToExclude)) {
+ const nonExcludedPhpVersionDebugMessage = `Job with name ${ jobName } is not matching exclusion rule`
+ + ` with name ${ exclude.name } due to non-excluded php version.`;
+
+ if (isLowestPhpVersionType(phpVersionToExclude) && job.job.php !== config.minimumPhpVersion) {
+ logger.debug(nonExcludedPhpVersionDebugMessage);
+
+ return false;
+ }
+
+ if (isLatestPhpVersionType(phpVersionToExclude) && job.job.php !== config.latestPhpVersion) {
+ logger.debug(nonExcludedPhpVersionDebugMessage);
+
+ return false;
+ }
+
+ if (phpVersionToExclude !== job.job.php) {
+ logger.debug(nonExcludedPhpVersionDebugMessage);
+
+ return false;
+ }
+ }
+
+ if (!isAnyComposerDependencySet(dependenciesToExclude) && dependenciesToExclude !== job.job.composerDependencySet) {
+ logger.debug(
+ `Job with name ${ jobName } is not matching exclusion rule`
+ + ` with name ${ exclude.name } due to non-excluded Composer dependencies.`
+ );
+
+ return false;
+ }
+
+ return true;
+}
+
function isJobExcluded(job: Job, exclusions: JobToExcludeFromFile[], config: Config, logger: Logger): boolean {
if (exclusions.length === 0) {
return false;
}
- if (exclusions.some((exclude) => job.name === exclude.name)) {
+ if (exclusions.some((exclude) => isJobExcludedByConfiguration(job, exclude, config, logger))) {
logger.info(`Job with name ${ job.name } is excluded due to application config.`);
return true;
@@ -385,7 +466,7 @@ function createNoOpCheck(config: Config): Job {
operatingSystem : OPERATING_SYSTEM,
action : ACTION,
job : {
- php : config.stablePhpVersion,
+ php : CONTAINER_DEFAULT_PHP_VERSION,
phpExtensions : [],
command : '',
composerDependencySet : ComposerDependencySet.LOCKED,
diff --git a/src/config/input.ts b/src/config/input.ts
index b4f5e9b0..02958cc7 100644
--- a/src/config/input.ts
+++ b/src/config/input.ts
@@ -3,13 +3,15 @@ import {ComposerDependencySet, IgnorePhpPlatformRequirements} from './app';
export interface JobToExcludeFromFile {
name: string;
+ php?: InstallablePhpVersionType,
+ dependencies?: ComposerDependencySet,
}
export interface ConfigurationFromFile {
extensions?: string[];
ini?: string[];
ignore_php_platform_requirements?: IgnorePhpPlatformRequirements;
- stablePHP?: string;
+ stablePHP?: InstallablePhpVersionType;
additional_composer_arguments?: string[];
backwardCompatibilityCheck?: boolean;
}
diff --git a/tests/configuration-exclude-php-dependency-combination/.laminas-ci.json b/tests/configuration-exclude-php-dependency-combination/.laminas-ci.json
new file mode 100644
index 00000000..808b7d40
--- /dev/null
+++ b/tests/configuration-exclude-php-dependency-combination/.laminas-ci.json
@@ -0,0 +1,9 @@
+{
+ "exclude": [
+ {
+ "name": "PHPUnit",
+ "php": "8.1",
+ "dependencies": "latest"
+ }
+ ]
+}
diff --git a/tests/configuration-exclude-php-dependency-combination/composer.json b/tests/configuration-exclude-php-dependency-combination/composer.json
new file mode 100644
index 00000000..31a4819d
--- /dev/null
+++ b/tests/configuration-exclude-php-dependency-combination/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "php": "~8.0.0 || ~8.1.0 || ~8.2.0"
+ }
+}
diff --git a/tests/configuration-exclude-php-dependency-combination/matrix.json b/tests/configuration-exclude-php-dependency-combination/matrix.json
new file mode 100644
index 00000000..03c77801
--- /dev/null
+++ b/tests/configuration-exclude-php-dependency-combination/matrix.json
@@ -0,0 +1,34 @@
+{
+ "include": [
+ {
+ "name": "PHPUnit [8.0, lowest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.0\",\"extensions\":[],\"ini\":[],\"dependencies\":\"lowest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ },
+ {
+ "name": "PHPUnit [8.0, latest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.0\",\"extensions\":[],\"ini\":[],\"dependencies\":\"latest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ },
+ {
+ "name": "PHPUnit [8.1, lowest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.1\",\"extensions\":[],\"ini\":[],\"dependencies\":\"lowest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ },
+ {
+ "name": "PHPUnit [8.2, lowest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.2\",\"extensions\":[],\"ini\":[],\"dependencies\":\"lowest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ },
+ {
+ "name": "PHPUnit [8.2, latest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.2\",\"extensions\":[],\"ini\":[],\"dependencies\":\"latest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ }
+ ]
+}
diff --git a/tests/configuration-exclude-php-dependency-combination/phpunit.xml.dist b/tests/configuration-exclude-php-dependency-combination/phpunit.xml.dist
new file mode 100644
index 00000000..0e632ce3
--- /dev/null
+++ b/tests/configuration-exclude-php-dependency-combination/phpunit.xml.dist
@@ -0,0 +1,2 @@
+
+
diff --git a/tests/configuration-exclude-php-dependency-combination/test.env b/tests/configuration-exclude-php-dependency-combination/test.env
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/configuration-exclude-php-specific-version/.laminas-ci.json b/tests/configuration-exclude-php-specific-version/.laminas-ci.json
new file mode 100644
index 00000000..9c05507c
--- /dev/null
+++ b/tests/configuration-exclude-php-specific-version/.laminas-ci.json
@@ -0,0 +1,8 @@
+{
+ "exclude": [
+ {
+ "name": "PHPUnit",
+ "php": "8.1"
+ }
+ ]
+}
diff --git a/tests/configuration-exclude-php-specific-version/composer.json b/tests/configuration-exclude-php-specific-version/composer.json
new file mode 100644
index 00000000..31a4819d
--- /dev/null
+++ b/tests/configuration-exclude-php-specific-version/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "php": "~8.0.0 || ~8.1.0 || ~8.2.0"
+ }
+}
diff --git a/tests/configuration-exclude-php-specific-version/matrix.json b/tests/configuration-exclude-php-specific-version/matrix.json
new file mode 100644
index 00000000..2cc70bf9
--- /dev/null
+++ b/tests/configuration-exclude-php-specific-version/matrix.json
@@ -0,0 +1,28 @@
+{
+ "include": [
+ {
+ "name": "PHPUnit [8.0, lowest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.0\",\"extensions\":[],\"ini\":[],\"dependencies\":\"lowest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ },
+ {
+ "name": "PHPUnit [8.0, latest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.0\",\"extensions\":[],\"ini\":[],\"dependencies\":\"latest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ },
+ {
+ "name": "PHPUnit [8.2, lowest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.2\",\"extensions\":[],\"ini\":[],\"dependencies\":\"lowest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ },
+ {
+ "name": "PHPUnit [8.2, latest]",
+ "job": "{\"command\":\"./vendor/bin/phpunit\",\"php\":\"8.2\",\"extensions\":[],\"ini\":[],\"dependencies\":\"latest\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[\"xmllint --schema vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist\"]}",
+ "operatingSystem": "ubuntu-latest",
+ "action": "laminas/laminas-continuous-integration-action@v1"
+ }
+ ]
+}
diff --git a/tests/configuration-exclude-php-specific-version/phpunit.xml.dist b/tests/configuration-exclude-php-specific-version/phpunit.xml.dist
new file mode 100644
index 00000000..0e632ce3
--- /dev/null
+++ b/tests/configuration-exclude-php-specific-version/phpunit.xml.dist
@@ -0,0 +1,2 @@
+
+
diff --git a/tests/configuration-exclude-php-specific-version/test.env b/tests/configuration-exclude-php-specific-version/test.env
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/no-checks-due-to-diff/matrix.json b/tests/no-checks-due-to-diff/matrix.json
index 89f94cc1..b056b800 100644
--- a/tests/no-checks-due-to-diff/matrix.json
+++ b/tests/no-checks-due-to-diff/matrix.json
@@ -2,7 +2,7 @@
"include": [
{
"name": "No checks",
- "job": "{\"command\":\"\",\"php\":\"8.2\",\"extensions\":[],\"ini\":[],\"dependencies\":\"locked\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[]}",
+ "job": "{\"command\":\"\",\"php\":\"@default\",\"extensions\":[],\"ini\":[],\"dependencies\":\"locked\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[]}",
"operatingSystem": "ubuntu-latest",
"action": "laminas/laminas-continuous-integration-action@v1"
}
diff --git a/tests/no-checks/matrix.json b/tests/no-checks/matrix.json
index 89f94cc1..b056b800 100644
--- a/tests/no-checks/matrix.json
+++ b/tests/no-checks/matrix.json
@@ -2,7 +2,7 @@
"include": [
{
"name": "No checks",
- "job": "{\"command\":\"\",\"php\":\"8.2\",\"extensions\":[],\"ini\":[],\"dependencies\":\"locked\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[]}",
+ "job": "{\"command\":\"\",\"php\":\"@default\",\"extensions\":[],\"ini\":[],\"dependencies\":\"locked\",\"ignore_platform_reqs_8\":false,\"ignore_php_platform_requirement\":false,\"additional_composer_arguments\":[],\"before_script\":[]}",
"operatingSystem": "ubuntu-latest",
"action": "laminas/laminas-continuous-integration-action@v1"
}