[ci-jobs] Add the optional property for jobs (#47261)
This commit is contained in:
parent
18e83a2467
commit
5591b25367
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: dev
|
||||||
|
|
||||||
|
Add the optional property for ci jobs
|
|
@ -239,6 +239,7 @@
|
||||||
"name": "Core API tests",
|
"name": "Core API tests",
|
||||||
"testType": "api",
|
"testType": "api",
|
||||||
"command": "test:api-pw",
|
"command": "test:api-pw",
|
||||||
|
"optional": false,
|
||||||
"changes": [
|
"changes": [
|
||||||
"client/admin/config/*.json",
|
"client/admin/config/*.json",
|
||||||
"composer.lock",
|
"composer.lock",
|
||||||
|
@ -259,6 +260,7 @@
|
||||||
"name": "Core API tests - HPOS disabled",
|
"name": "Core API tests - HPOS disabled",
|
||||||
"testType": "api",
|
"testType": "api",
|
||||||
"command": "test:api-pw",
|
"command": "test:api-pw",
|
||||||
|
"optional": false,
|
||||||
"changes": [
|
"changes": [
|
||||||
"client/admin/config/*.json",
|
"client/admin/config/*.json",
|
||||||
"composer.lock",
|
"composer.lock",
|
||||||
|
@ -280,6 +282,7 @@
|
||||||
"name": "Core Performance tests (K6)",
|
"name": "Core Performance tests (K6)",
|
||||||
"testType": "performance",
|
"testType": "performance",
|
||||||
"command": "test:perf",
|
"command": "test:perf",
|
||||||
|
"optional": true,
|
||||||
"changes": [
|
"changes": [
|
||||||
"client/admin/config/*.json",
|
"client/admin/config/*.json",
|
||||||
"composer.lock",
|
"composer.lock",
|
||||||
|
@ -299,6 +302,7 @@
|
||||||
"name": "Metrics",
|
"name": "Metrics",
|
||||||
"testType": "performance",
|
"testType": "performance",
|
||||||
"command": "test:metrics:ci",
|
"command": "test:metrics:ci",
|
||||||
|
"optional": true,
|
||||||
"changes": [
|
"changes": [
|
||||||
"client/admin/config/*.json",
|
"client/admin/config/*.json",
|
||||||
"composer.lock",
|
"composer.lock",
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -77,7 +77,10 @@ const program = new Command( 'ci-jobs' )
|
||||||
if ( jobs.lint.length > 0 ) {
|
if ( jobs.lint.length > 0 ) {
|
||||||
Logger.notice( 'Lint Jobs' );
|
Logger.notice( 'Lint Jobs' );
|
||||||
for ( const job of jobs.lint ) {
|
for ( const job of jobs.lint ) {
|
||||||
Logger.notice( `- ${ job.projectName } - ${ job.command }` );
|
const optional = job.optional ? '(optional)' : '';
|
||||||
|
Logger.notice(
|
||||||
|
`- ${ job.projectName } - ${ job.command }${ optional }`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger.notice( 'No lint jobs to run.' );
|
Logger.notice( 'No lint jobs to run.' );
|
||||||
|
@ -87,7 +90,10 @@ const program = new Command( 'ci-jobs' )
|
||||||
if ( jobs[ `${ type }Test` ].length > 0 ) {
|
if ( jobs[ `${ type }Test` ].length > 0 ) {
|
||||||
Logger.notice( `${ type } test Jobs` );
|
Logger.notice( `${ type } test Jobs` );
|
||||||
for ( const job of jobs[ `${ type }Test` ] ) {
|
for ( const job of jobs[ `${ type }Test` ] ) {
|
||||||
Logger.notice( `- ${ job.projectName } - ${ job.name }` );
|
const optional = job.optional ? ' (optional)' : '';
|
||||||
|
Logger.notice(
|
||||||
|
`- ${ job.projectName } - ${ job.name }${ optional }`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger.notice( `No ${ type } test jobs to run.` );
|
Logger.notice( `No ${ type } test jobs to run.` );
|
||||||
|
|
|
@ -348,5 +348,90 @@ describe( 'Config', () => {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it( 'should return default optional value for jobs', () => {
|
||||||
|
const parsed = parseCIConfig( {
|
||||||
|
name: 'foo',
|
||||||
|
config: {
|
||||||
|
ci: {
|
||||||
|
lint: {
|
||||||
|
changes: [],
|
||||||
|
command: 'foo',
|
||||||
|
},
|
||||||
|
tests: [
|
||||||
|
{
|
||||||
|
name: 'default',
|
||||||
|
changes: [],
|
||||||
|
command: 'foo',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( parsed ).toMatchObject( {
|
||||||
|
jobs: [
|
||||||
|
{
|
||||||
|
type: JobType.Lint,
|
||||||
|
optional: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: JobType.Test,
|
||||||
|
optional: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it.each( [
|
||||||
|
[ true, true ],
|
||||||
|
[ false, false ],
|
||||||
|
] )(
|
||||||
|
'should parse config with values for the optional property',
|
||||||
|
( input, result ) => {
|
||||||
|
const parsed = parseCIConfig( {
|
||||||
|
name: 'foo',
|
||||||
|
config: {
|
||||||
|
ci: {
|
||||||
|
lint: {
|
||||||
|
changes: '/src/**/*.{js,jsx,ts,tsx}',
|
||||||
|
command: 'foo',
|
||||||
|
optional: input,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( parsed ).toMatchObject( {
|
||||||
|
jobs: [
|
||||||
|
{
|
||||||
|
type: JobType.Lint,
|
||||||
|
optional: result,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each( [ [ 'bad', 1, undefined ] ] )(
|
||||||
|
'should error for config with invalid values for the optional property',
|
||||||
|
( input ) => {
|
||||||
|
const expectation = () => {
|
||||||
|
parseCIConfig( {
|
||||||
|
name: 'foo',
|
||||||
|
config: {
|
||||||
|
ci: {
|
||||||
|
lint: {
|
||||||
|
changes: [],
|
||||||
|
command: 'some command',
|
||||||
|
optional: input,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
expect( expectation ).toThrow();
|
||||||
|
}
|
||||||
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -1085,6 +1085,94 @@ describe( 'Job Processing', () => {
|
||||||
expect( jobs.lint ).toHaveLength( 0 );
|
expect( jobs.lint ).toHaveLength( 0 );
|
||||||
expect( jobs.test ).toHaveLength( 0 );
|
expect( jobs.test ).toHaveLength( 0 );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
it( 'should create non-optional lint job', async () => {
|
||||||
|
const jobs = await createJobsForChanges(
|
||||||
|
{
|
||||||
|
name: 'test',
|
||||||
|
path: 'test',
|
||||||
|
ciConfig: {
|
||||||
|
jobs: [
|
||||||
|
{
|
||||||
|
type: JobType.Lint,
|
||||||
|
changes: [ /test.js$/ ],
|
||||||
|
command: 'test-lint <baseRef>',
|
||||||
|
events: [],
|
||||||
|
optional: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: [ 'test.js' ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandVars: {
|
||||||
|
baseRef: 'test-base-ref',
|
||||||
|
event: 'foo',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( jobs.lint ).toHaveLength( 1 );
|
||||||
|
expect( jobs.lint ).toContainEqual( {
|
||||||
|
projectName: 'test',
|
||||||
|
projectPath: 'test',
|
||||||
|
command: 'test-lint test-base-ref',
|
||||||
|
optional: false,
|
||||||
|
} );
|
||||||
|
expect( jobs.test ).toHaveLength( 0 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should create optional test job', async () => {
|
||||||
|
const testType = 'default';
|
||||||
|
const jobs = await createJobsForChanges(
|
||||||
|
{
|
||||||
|
name: 'test',
|
||||||
|
path: 'test',
|
||||||
|
ciConfig: {
|
||||||
|
jobs: [
|
||||||
|
{
|
||||||
|
type: JobType.Test,
|
||||||
|
testType,
|
||||||
|
name: 'Default',
|
||||||
|
shardingArguments: [],
|
||||||
|
changes: [ /test.js$/ ],
|
||||||
|
command: 'test-cmd <baseRef>',
|
||||||
|
optional: true,
|
||||||
|
events: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: [ 'test.js' ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandVars: {
|
||||||
|
baseRef: 'test-base-ref',
|
||||||
|
event: 'foo',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( jobs.lint ).toHaveLength( 0 );
|
||||||
|
expect( jobs[ `${ testType }Test` ] ).toHaveLength( 1 );
|
||||||
|
expect( jobs[ `${ testType }Test` ] ).toContainEqual( {
|
||||||
|
projectName: 'test',
|
||||||
|
projectPath: 'test',
|
||||||
|
name: 'Default',
|
||||||
|
command: 'test-cmd test-base-ref',
|
||||||
|
shardNumber: 0,
|
||||||
|
testEnv: {
|
||||||
|
shouldCreate: false,
|
||||||
|
envVars: {},
|
||||||
|
},
|
||||||
|
optional: true,
|
||||||
|
} );
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
describe( 'getShardedJobs', () => {
|
describe( 'getShardedJobs', () => {
|
||||||
|
@ -1100,6 +1188,7 @@ describe( 'Job Processing', () => {
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
envVars: {},
|
envVars: {},
|
||||||
},
|
},
|
||||||
|
optional: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: JobType.Test,
|
type: JobType.Test,
|
||||||
|
@ -1121,6 +1210,7 @@ describe( 'Job Processing', () => {
|
||||||
name: 'Default 1/2',
|
name: 'Default 1/2',
|
||||||
command: 'test-cmd --shard-arg-1',
|
command: 'test-cmd --shard-arg-1',
|
||||||
shardNumber: 1,
|
shardNumber: 1,
|
||||||
|
optional: false,
|
||||||
testEnv: {
|
testEnv: {
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
envVars: {},
|
envVars: {},
|
||||||
|
@ -1132,6 +1222,7 @@ describe( 'Job Processing', () => {
|
||||||
name: 'Default 2/2',
|
name: 'Default 2/2',
|
||||||
command: 'test-cmd --shard-arg-2',
|
command: 'test-cmd --shard-arg-2',
|
||||||
shardNumber: 2,
|
shardNumber: 2,
|
||||||
|
optional: false,
|
||||||
testEnv: {
|
testEnv: {
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
envVars: {},
|
envVars: {},
|
||||||
|
@ -1155,6 +1246,7 @@ describe( 'Job Processing', () => {
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
envVars: {},
|
envVars: {},
|
||||||
},
|
},
|
||||||
|
optional: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: JobType.Test,
|
type: JobType.Test,
|
||||||
|
@ -1174,6 +1266,7 @@ describe( 'Job Processing', () => {
|
||||||
name: 'Default',
|
name: 'Default',
|
||||||
command: 'test-cmd',
|
command: 'test-cmd',
|
||||||
shardNumber: 0,
|
shardNumber: 0,
|
||||||
|
optional: false,
|
||||||
testEnv: {
|
testEnv: {
|
||||||
shouldCreate: false,
|
shouldCreate: false,
|
||||||
envVars: {},
|
envVars: {},
|
||||||
|
|
|
@ -60,6 +60,11 @@ interface BaseJobConfig {
|
||||||
*/
|
*/
|
||||||
events: string[];
|
events: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether a job should be required to pass in CI for merging to be allowed.
|
||||||
|
*/
|
||||||
|
optional?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether or not a job has been created for this config.
|
* Indicates whether or not a job has been created for this config.
|
||||||
*/
|
*/
|
||||||
|
@ -166,30 +171,52 @@ function validateCommandVars( command: string ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the lint job configuration.
|
* Parses the base job configuration.
|
||||||
*
|
*
|
||||||
* @param {Object} raw The raw config to parse.
|
* @param {Object} raw The raw config to parse.
|
||||||
*/
|
*/
|
||||||
function parseLintJobConfig( raw: any ): LintJobConfig {
|
function parseBaseJobConfig( raw: any ): BaseJobConfig {
|
||||||
if ( ! raw.changes ) {
|
if ( ! raw.changes ) {
|
||||||
throw new ConfigError(
|
throw new ConfigError( 'A "changes" option is required for the job.' );
|
||||||
'A "changes" option is required for the lint job.'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! raw.command || typeof raw.command !== 'string' ) {
|
if ( ! raw.command || typeof raw.command !== 'string' ) {
|
||||||
throw new ConfigError(
|
throw new ConfigError(
|
||||||
'A string "command" option is required for the lint job.'
|
'A string "command" option is required for the job.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateCommandVars( raw.command );
|
validateCommandVars( raw.command );
|
||||||
|
|
||||||
|
let optional = false;
|
||||||
|
if ( raw.optional ) {
|
||||||
|
if ( typeof raw.optional !== 'boolean' ) {
|
||||||
|
throw new ConfigError(
|
||||||
|
'The "optional" property must be a boolean.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
optional = raw.optional;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: JobType.Lint,
|
type: null,
|
||||||
changes: parseChangesConfig( raw.changes, [ 'package.json' ] ),
|
changes: parseChangesConfig( raw.changes, [ 'package.json' ] ),
|
||||||
command: raw.command,
|
command: raw.command,
|
||||||
events: raw.events || [],
|
events: raw.events || [],
|
||||||
|
optional,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the lint job configuration.
|
||||||
|
*
|
||||||
|
* @param {Object} raw The raw config to parse.
|
||||||
|
*/
|
||||||
|
function parseLintJobConfig( raw: any ): LintJobConfig {
|
||||||
|
const baseJob = parseBaseJobConfig( raw );
|
||||||
|
return {
|
||||||
|
...baseJob,
|
||||||
|
type: JobType.Lint,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,24 +352,14 @@ function parseTestCascade( raw: unknown ): string[] {
|
||||||
* @param {Object} raw The raw config to parse.
|
* @param {Object} raw The raw config to parse.
|
||||||
*/
|
*/
|
||||||
function parseTestJobConfig( raw: any ): TestJobConfig {
|
function parseTestJobConfig( raw: any ): TestJobConfig {
|
||||||
|
const baseJob = parseBaseJobConfig( raw );
|
||||||
|
|
||||||
if ( ! raw.name || typeof raw.name !== 'string' ) {
|
if ( ! raw.name || typeof raw.name !== 'string' ) {
|
||||||
throw new ConfigError(
|
throw new ConfigError(
|
||||||
'A string "name" option is required for test jobs.'
|
'A string "name" option is required for test jobs.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! raw.changes ) {
|
|
||||||
throw new ConfigError(
|
|
||||||
'A "changes" option is required for the test jobs.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! raw.command || typeof raw.command !== 'string' ) {
|
|
||||||
throw new ConfigError(
|
|
||||||
'A string "command" option is required for the test jobs.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let testType: ( typeof testTypes )[ number ] = 'default';
|
let testType: ( typeof testTypes )[ number ] = 'default';
|
||||||
if (
|
if (
|
||||||
raw.testType &&
|
raw.testType &&
|
||||||
|
@ -351,16 +368,12 @@ function parseTestJobConfig( raw: any ): TestJobConfig {
|
||||||
testType = raw.testType.toLowerCase();
|
testType = raw.testType.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
validateCommandVars( raw.command );
|
|
||||||
|
|
||||||
const config: TestJobConfig = {
|
const config: TestJobConfig = {
|
||||||
|
...baseJob,
|
||||||
type: JobType.Test,
|
type: JobType.Test,
|
||||||
testType,
|
testType,
|
||||||
shardingArguments: raw.shardingArguments || [],
|
shardingArguments: raw.shardingArguments || [],
|
||||||
events: raw.events || [],
|
|
||||||
name: raw.name,
|
name: raw.name,
|
||||||
changes: parseChangesConfig( raw.changes, [ 'package.json' ] ),
|
|
||||||
command: raw.command,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( raw.testEnv ) {
|
if ( raw.testEnv ) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ interface LintJob {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
projectPath: string;
|
projectPath: string;
|
||||||
command: string;
|
command: string;
|
||||||
|
optional: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +41,7 @@ interface TestJob {
|
||||||
command: string;
|
command: string;
|
||||||
testEnv: TestJobEnv;
|
testEnv: TestJobEnv;
|
||||||
shardNumber: number;
|
shardNumber: number;
|
||||||
|
optional: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,6 +155,7 @@ function createLintJob(
|
||||||
projectName,
|
projectName,
|
||||||
projectPath,
|
projectPath,
|
||||||
command: replaceCommandVars( config.command, options ),
|
command: replaceCommandVars( config.command, options ),
|
||||||
|
optional: config.optional,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +231,7 @@ async function createTestJob(
|
||||||
envVars: {},
|
envVars: {},
|
||||||
},
|
},
|
||||||
shardNumber,
|
shardNumber,
|
||||||
|
optional: config.optional,
|
||||||
};
|
};
|
||||||
|
|
||||||
// We want to make sure that we're including the configuration for
|
// We want to make sure that we're including the configuration for
|
||||||
|
|
Loading…
Reference in New Issue