Skip to content

Commit fde2c44

Browse files
Merge pull request #14 from weierophinney/feature/allow-object-jobs-in-checks
Allow object jobs in the "checks" configuration array
2 parents 604ed10 + 83db619 commit fde2c44

File tree

4 files changed

+145
-9
lines changed

4 files changed

+145
-9
lines changed

README.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,42 @@ The package can include a configuration file in its root, `.laminas-ci.json`, wh
119119
}
120120
```
121121

122-
The "checks" array should be in the same format as listed above for the outputs.
123-
Please remember that the **job** element **MUST** be a JSON **string**
122+
### Providing specific checks to run
123+
124+
If you do not want to autodiscover checks to run, you can provide the "checks" configuration.
125+
Each element in that array should be in the same format as listed above for the outputs:
126+
127+
```json
128+
{
129+
"name": "(string) Name of the check being run",
130+
"operatingSystem": "(string) Name of the OS the job should be run on (generally ubuntu-latest)",
131+
"action": "(string) GHA to run the step on; currently ignored, as GHA does not support dynamic action selection",
132+
"job": "(string) JSON object detailing the job (more on this later)",
133+
}
134+
```
135+
136+
The "job" element can either be a JSON string representing a job, or an object.
137+
In each case, it MUST have the structure as noted above:
138+
139+
```json
140+
{
141+
"php": "(string; REQUIRED) PHP minor version to run against",
142+
"extensions": [
143+
"OPTIONAL array of strings",
144+
"Each element represents an extension to install",
145+
"Names are from the Sury PHP repository, minus the php{VERSION}- prefix",
146+
],
147+
"ini": [
148+
"OPTIONAL array of strings",
149+
"Each element respresents one php.ini directive",
150+
"e.g. 'memory_limit=-1'",
151+
],
152+
"dependencies": "dependencies to test against; one of lowest, locked, latest",
153+
"command": "command to run to perform the check",
154+
}
155+
```
156+
157+
The action validates each check and its job to ensure it is structured correctly, and will provide warnings if not, omitting any check that is malformed from the output.
124158

125159
### Providing additional checks
126160

src/additional-checks.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,25 @@ import {Job} from "./job.js";
1010
const validateCheck = function (checkConfig) {
1111
if (typeof checkConfig !== 'object' || checkConfig === null) {
1212
// NOT AN OBJECT!
13-
core.warning("Skipping additional check; not an object, or is null", checkConfig);
13+
core.warning("Skipping additional check; not an object, or is null: " + JSON.stringify(checkConfig));
1414
return false;
1515
}
1616

1717
if (! ("name" in checkConfig) || ! ("job" in checkConfig)) {
1818
// Missing one or more required elements
19-
core.warning("Skipping additional check due to missing name or job keys", checkConfig);
19+
core.warning("Skipping additional check due to missing name or job keys: " + JSON.stringify(checkConfig));
2020
return false;
2121
}
2222

2323
if (typeof checkConfig.job !== 'object' || checkConfig.job === null) {
2424
// Job is malformed
25-
core.warning("Invalid job provided for check; not an object, or is null", checkConfig.job);
25+
core.warning("Invalid job provided for check; not an object, or is null: " + JSON.stringify(checkConfig.job));
2626
return false;
2727
}
2828

2929
if (! ("command" in checkConfig.job)) {
3030
// Job is missing a command
31-
core.warning("Invalid job provided for check; missing command property", checkConfig.job);
31+
core.warning("Invalid job provided for check; missing command property: " + JSON.stringify(checkConfig.job));
3232
return false;
3333
}
3434

@@ -53,7 +53,7 @@ const discoverPhpVersionsForCheck = function (job, config) {
5353
return config.versions;
5454
}
5555

56-
core.warning("Invalid PHP version specified for check job; must be a string version or '*'", job);
56+
core.warning("Invalid PHP version specified for check job; must be a string version or '*': " + JSON.stringify(job));
5757
return false;
5858
};
5959

@@ -101,7 +101,7 @@ const discoverDependencySetsForCheck = function (job, config) {
101101
return config.dependencies;
102102
}
103103

104-
core.warning("Invalid dependencies specified for check job; must be a string version or '*'", job);
104+
core.warning("Invalid dependencies specified for check job; must be a string version or '*': " + JSON.stringify(job));
105105
return false;
106106
};
107107

src/create-jobs.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Command } from './command.js';
55
import { Config } from './config.js';
66
import { Job } from './job.js';
77
import create_additional_jobs from './additional-checks.js';
8+
import validateAndNormalizeChecks from './validate-and-normalize-checks-from-config.js';
89

910
/**
1011
* @param {String} filename
@@ -198,7 +199,7 @@ const excludeJob = function (job, exclusion) {
198199
export default function (config) {
199200
if (config.checks.length) {
200201
core.info('Using checks found in configuration');
201-
return config.checks;
202+
return validateAndNormalizeChecks(config.checks);
202203
}
203204

204205
/** @var {Array} jobs */
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import core from '@actions/core';
2+
3+
const KNOWN_PHP_VERSIONS = [
4+
'5.6',
5+
'7.0',
6+
'7.1',
7+
'7.2',
8+
'7.3',
9+
'7.4',
10+
'8.0',
11+
];
12+
13+
/**
14+
* @param {(Object|String)} job
15+
* @return {(String|Boolean)} Returns false if job is invalid; otherwise, returns JSON representation of job
16+
*/
17+
const normalizeJob = function (job) {
18+
if (typeof job === 'string') {
19+
let parsedJob;
20+
try {
21+
parsedJob = JSON.parse(job);
22+
} catch(error) {
23+
core.warning("Unparseable JSON job provided: " + job);
24+
return false;
25+
}
26+
job = parsedJob;
27+
}
28+
29+
if (typeof job !== 'object' || job === null) {
30+
core.warning("Invalid job provided; must be a JSON string or an object: " + JSON.stringify(job));
31+
return false;
32+
}
33+
34+
if (! "php" in job || ! KNOWN_PHP_VERSIONS.includes(job.php)) {
35+
core.warning("Invalid job provided; no PHP version or unknown PHP version specified: " + JSON.stringify(job));
36+
return false;
37+
}
38+
39+
if (! "command" in job) {
40+
core.warning("Invalid job provided; no command specified: " + JSON.stringify(job));
41+
return false;
42+
}
43+
44+
if ("extensions" in job && ! Array.isArray(job.extensions)) {
45+
core.warning("Invalid job provided; extensions is not an Array: " + JSON.stringify(job));
46+
return false;
47+
}
48+
49+
if ("ini" in job && ! Array.isArray(job.ini)) {
50+
core.warning("Invalid job provided; ini is not an Array: " + JSON.stringify(job));
51+
return false;
52+
}
53+
54+
if ("dependencies" in job && ! ["locked", "latest", "lowest"].includes(job.dependencies)) {
55+
core.warning("Invalid job provided; invalid dependency set: " + JSON.stringify(job));
56+
return false;
57+
}
58+
59+
return JSON.stringify(job);
60+
};
61+
62+
/**
63+
* @param {Object} check
64+
* @return {(null|Object)} null if invalid, object representing check otherwise
65+
*/
66+
const validateAndNormalizeCheck = function (check) {
67+
if (! "name" in check) {
68+
core.warning("Invalid check detected; missing name: " + JSON.stringify(check));
69+
return null;
70+
}
71+
72+
if (! "job" in check) {
73+
core.warning("Invalid check detected; missing job: " + JSON.stringify(check));
74+
return null;
75+
}
76+
77+
let job = normalizeJob(check.job);
78+
if (! job) {
79+
return null;
80+
}
81+
82+
check.job = job;
83+
84+
if (! "operatingSystem" in check) {
85+
check.operatingSystem = 'ubuntu-latest';
86+
}
87+
88+
return check;
89+
};
90+
91+
/**
92+
* @param {Array} checks
93+
* @return {Array}
94+
*/
95+
export default function (checks) {
96+
return checks
97+
.map(validateAndNormalizeCheck)
98+
.filter(function (check) {
99+
return typeof check === 'object' && check !== null;
100+
});
101+
};

0 commit comments

Comments
 (0)