[ci-jobs] Add support for github event and include HPOS disabled e2e tests in ci (#46922)

* Update env setup script to disable hpos

* Use DISABLE_HPOS instead of ENABLE_HPOS

* Log HPOS state

* Configure project for core e2e with HPOS disabled

* Add event argument for ci-jobs util

* Add event option for test jobs

* Add support for github events

* Add changelog

* Configure HPOS tests to run on pull_request

* Fix utils tests for undefined commandVars

* Added some tests for the event configuration

* Revert event for HPOS e2e to push

* Use matrix name in artifact name to avoid duplication

* Test with pull_request event

* Use job-index for unique artifacts names

* Revert event for HPOS e2e to push

* Add api tests for HPOS disabled

* Use unique artifact name for api tests

* Revert event for HPOS disabled api tests to push

* Rebuild monorepo utils to fix a merge conflict

* Updated wording
This commit is contained in:
Adrian Moldovan 2024-05-01 20:36:24 +03:00 committed by GitHub
parent 96a8cd472b
commit de91a0881d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 316 additions and 15 deletions

View File

@ -41,8 +41,11 @@ jobs:
if ( baseRef ) {
baseRef = `--base-ref origin/${ baseRef }`;
}
let githubEvent = ${{ toJson( github.event_name ) }};
const child_process = require( 'node:child_process' );
child_process.execSync( `pnpm utils ci-jobs ${ baseRef }` );
child_process.execSync( `pnpm utils ci-jobs ${ baseRef } --event ${ githubEvent }` );
project-lint-jobs:
name: 'Lint - ${{ matrix.projectName }}'
@ -125,7 +128,7 @@ jobs:
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: all-blob-e2e-reports-${{ matrix.shardNumber }}
name: all-blob-e2e-reports-${{ strategy.job-index }}
path: ${{ matrix.projectPath }}/tests/e2e-pw/test-results
retention-days: 1
compression-level: 9
@ -162,7 +165,7 @@ jobs:
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: all-blob-api-reports-${{ matrix.shardNumber }}
name: all-blob-api-reports-${{ strategy.job-index }}
path: ${{ matrix.projectPath }}/tests/api-core-tests/test-results/allure-results
retention-days: 1
compression-level: 9

View File

@ -1,4 +1,4 @@
name: Run tests against PR in an environment with HPOS disabled
name: Run tests with HPOS disabled
on:
push:
branches:

View File

@ -32,7 +32,7 @@ jobs:
working-directory: plugins/woocommerce
env:
ENABLE_HPOS: 0
run: pnpm --filter=@woocommerce/plugin-woocommerce env:test:cot
run: pnpm --filter=@woocommerce/plugin-woocommerce env:test:no-hpos
- name: Download and install Chromium browser.
working-directory: plugins/woocommerce
@ -91,7 +91,7 @@ jobs:
working-directory: plugins/woocommerce
env:
ENABLE_HPOS: 0
run: pnpm --filter=@woocommerce/plugin-woocommerce env:test:cot
run: pnpm --filter=@woocommerce/plugin-woocommerce env:test:no-hpos
- name: Run Playwright API tests.
id: run_playwright_api_tests

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Monorepo utils: add support for github events in ci-jobs tool

View File

@ -29,7 +29,7 @@
"env:start": "pnpm wp-env start",
"env:stop": "pnpm wp-env stop",
"env:test": "pnpm env:dev && pnpm playwright install chromium",
"env:test:cot": "ENABLE_HPOS=1 pnpm env:test",
"env:test:no-hpos": "DISABLE_HPOS=1 pnpm env:test",
"env:perf:install-k6": "curl https://github.com/grafana/k6/releases/download/v0.33.0/k6-v0.33.0-linux-amd64.tar.gz -L | tar xvz --strip-components 1",
"env:perf": "pnpm env:dev && pnpm env:performance-init && pnpm env:perf:install-k6",
"preinstall": "npx only-allow pnpm",
@ -207,6 +207,34 @@
"start": "env:test"
}
},
{
"name": "Core e2e tests - HPOS disabled",
"testType": "e2e",
"command": "test:e2e-pw",
"shardingArguments": [
"--shard=1/5",
"--shard=2/5",
"--shard=3/5",
"--shard=4/5",
"--shard=5/5"
],
"events": [
"push"
],
"changes": [
"client/admin/config/*.json",
"composer.lock",
"includes/**/*.php",
"patterns/**/*.php",
"src/**/*.php",
"templates/**/*.php",
"tests/php/**/*.php",
"tests/e2e-pw/**"
],
"testEnv": {
"start": "env:test:no-hpos"
}
},
{
"name": "Core API tests",
"testType": "api",
@ -227,6 +255,27 @@
"start": "env:test"
}
},
{
"name": "Core API tests - HPOS disabled",
"testType": "api",
"command": "test:api-pw",
"changes": [
"client/admin/config/*.json",
"composer.lock",
"includes/**/*.php",
"patterns/**/*.php",
"src/**/*.php",
"templates/**/*.php",
"tests/php/**/*.php",
"tests/api-core-tests/**"
],
"events": [
"push"
],
"testEnv": {
"start": "env:test:no-hpos"
}
},
{
"name": "Core Performance tests (K6)",
"testType": "performance",

View File

@ -1,5 +1,13 @@
#!/usr/bin/env bash
DISABLE_HPOS="${DISABLE_HPOS:-0}"
echo -e "DISABLE_HPOS: $DISABLE_HPOS"
if [ $DISABLE_HPOS == 1 ]; then
echo -e 'Disabling HPOS\n'
wp-env run tests-cli wp option update woocommerce_custom_orders_table_enabled 'no'
fi
ENABLE_TRACKING="${ENABLE_TRACKING:-0}"
echo -e 'Activate default theme \n'

View File

@ -189,8 +189,8 @@ module.exports = async ( config ) => {
// (if a value for ENABLE_HPOS was set)
// This was always being set to 'yes' after login in wp-env so this step ensures the
// correct value is set before we begin our tests
if ( ENABLE_HPOS ) {
const hposSettingRetries = 5;
console.log( `ENABLE_HPOS: ${ ENABLE_HPOS }` );
const api = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
@ -198,6 +198,9 @@ module.exports = async ( config ) => {
version: 'wc/v3',
} );
if ( ENABLE_HPOS ) {
const hposSettingRetries = 5;
const value = ENABLE_HPOS === '0' ? 'no' : 'yes';
for ( let i = 0; i < hposSettingRetries; i++ ) {
@ -236,6 +239,12 @@ module.exports = async ( config ) => {
}
}
const response = await api.get(
'settings/advanced/woocommerce_custom_orders_table_enabled'
);
console.log( `HPOS configuration ${ response.data.value }` );
await site.useCartCheckoutShortcodes( baseURL, userAgent, admin );
await adminContext.close();

File diff suppressed because one or more lines are too long

View File

@ -23,11 +23,24 @@ const program = new Command( 'ci-jobs' )
'Base ref to compare the current ref against for change detection. If not specified, all projects will be considered changed.',
''
)
.option(
'-e --event <event>',
'Github event for which to run the jobs. If not specified, all events will be considered.',
''
)
.action( async ( options ) => {
Logger.startTask( 'Parsing Project Graph', true );
const projectGraph = buildProjectGraph();
Logger.endTask( true );
if ( options.event === '' ) {
Logger.warn( 'No event was specified, considering all projects.' );
} else {
Logger.warn(
`Only projects configured for '${ options.event }' event will be considered.`
);
}
let fileChanges;
if ( options.baseRef === '' ) {
Logger.warn(
@ -44,6 +57,7 @@ const program = new Command( 'ci-jobs' )
const jobs = await createJobsForChanges( projectGraph, fileChanges, {
commandVars: {
baseRef: options.baseRef,
event: options.event,
},
} );
Logger.endTask( true );

View File

@ -35,6 +35,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test.js$/ ],
command: 'test-lint',
events: [],
},
],
},
@ -66,6 +67,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test.js$/ ],
command: 'test-lint <baseRef>',
events: [],
},
],
},
@ -77,6 +79,7 @@ describe( 'Job Processing', () => {
{
commandVars: {
baseRef: 'test-base-ref',
event: '',
},
}
);
@ -101,6 +104,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test.js$/ ],
command: 'test-lint <invalid>',
events: [],
},
],
},
@ -126,6 +130,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test.js$/ ],
command: 'test-lint',
events: [],
jobCreated: true,
},
],
@ -153,6 +158,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test.js$/ ],
command: 'test-lint',
events: [],
},
],
},
@ -177,6 +183,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test.js$/ ],
command: 'test-lint',
events: [],
},
],
},
@ -190,6 +197,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test-a.js$/ ],
command: 'test-lint-a',
events: [],
},
],
},
@ -204,6 +212,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test-b.js$/ ],
command: 'test-lint-b',
events: [],
},
],
},
@ -248,6 +257,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test-a.js$/ ],
command: 'test-lint-a',
events: [],
},
],
},
@ -262,6 +272,7 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test-b.js$/ ],
command: 'test-lint-b',
events: [],
},
],
},
@ -304,6 +315,7 @@ describe( 'Job Processing', () => {
type: JobType.Test,
testType,
shardingArguments: [],
events: [],
name: 'Default',
changes: [ /test.js$/ ],
command: 'test-cmd',
@ -346,6 +358,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd <baseRef>',
},
@ -359,6 +372,7 @@ describe( 'Job Processing', () => {
{
commandVars: {
baseRef: 'test-base-ref',
event: '',
},
}
);
@ -391,6 +405,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
jobCreated: true,
@ -422,6 +437,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
@ -450,6 +466,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
@ -466,6 +483,7 @@ describe( 'Job Processing', () => {
testType: 'default',
name: 'Default A',
shardingArguments: [],
events: [],
changes: [ /test-b.js$/ ],
command: 'test-cmd-a',
},
@ -483,6 +501,7 @@ describe( 'Job Processing', () => {
testType: 'default',
name: 'Default B',
shardingArguments: [],
events: [],
changes: [ /test-b.js$/ ],
command: 'test-cmd-b',
},
@ -540,6 +559,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
@ -582,6 +602,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
cascadeKeys: [ 'test' ],
@ -599,6 +620,7 @@ describe( 'Job Processing', () => {
testType: 'default',
name: 'Default A',
shardingArguments: [],
events: [],
changes: [ /test-a.js$/ ],
command: 'test-cmd-a',
cascadeKeys: [ 'test-a', 'test' ],
@ -654,6 +676,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
cascadeKeys: [ 'test' ],
@ -671,6 +694,7 @@ describe( 'Job Processing', () => {
testType: 'default',
name: 'Default A',
shardingArguments: [],
events: [],
changes: [ /test-a.js$/ ],
command: 'test-cmd-a',
cascadeKeys: [ 'test-a', 'test' ],
@ -689,6 +713,7 @@ describe( 'Job Processing', () => {
testType: 'default',
name: 'Default B',
shardingArguments: [],
events: [],
changes: [ /test-b.js$/ ],
command: 'test-cmd-b',
cascadeKeys: [ 'test-b', 'test' ],
@ -748,6 +773,7 @@ describe( 'Job Processing', () => {
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
testEnv: {
@ -767,6 +793,7 @@ describe( 'Job Processing', () => {
{
commandVars: {
baseRef: 'test-base-ref',
event: '',
},
}
);
@ -801,12 +828,14 @@ describe( 'Job Processing', () => {
type: JobType.Lint,
changes: [ /test.js$/ ],
command: 'test-lint',
events: [],
},
{
type: JobType.Test,
testType,
name: 'Default',
shardingArguments: [],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
@ -854,6 +883,7 @@ describe( 'Job Processing', () => {
'--shard=1/2',
'--shard=2/2',
],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
@ -896,6 +926,165 @@ describe( 'Job Processing', () => {
] )
);
} );
it( 'should trigger job with event configured but no event cli argument', async () => {
const testType = 'default';
const jobs = await createJobsForChanges(
{
name: 'test',
path: 'test',
ciConfig: {
jobs: [
{
type: JobType.Test,
testType,
name: 'Default',
shardingArguments: [
'--shard=1/2',
'--shard=2/2',
],
events: [ 'push' ],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
],
},
dependencies: [],
},
{
test: [ 'test.js' ],
},
{}
);
expect( jobs.lint ).toHaveLength( 0 );
expect( jobs[ `${ testType }Test` ] ).toHaveLength( 2 );
expect( jobs[ `${ testType }Test` ] ).toEqual(
expect.arrayContaining( [
{
projectName: 'test',
projectPath: 'test',
name: 'Default 1/2',
command: 'test-cmd --shard=1/2',
shardNumber: 1,
testEnv: {
shouldCreate: false,
envVars: {},
},
},
{
projectName: 'test',
projectPath: 'test',
name: 'Default 2/2',
command: 'test-cmd --shard=2/2',
shardNumber: 2,
testEnv: {
shouldCreate: false,
envVars: {},
},
},
] )
);
} );
it( 'should trigger job with event configured and matching event cli argument', async () => {
const testType = 'default';
const jobs = await createJobsForChanges(
{
name: 'test',
path: 'test',
ciConfig: {
jobs: [
{
type: JobType.Test,
testType,
name: 'Default',
shardingArguments: [
'--shard=1/2',
'--shard=2/2',
],
events: [ 'push' ],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
],
},
dependencies: [],
},
{
test: [ 'test.js' ],
},
{ commandVars: { baseRef: 'test-base-ref', event: 'push' } }
);
expect( jobs.lint ).toHaveLength( 0 );
expect( jobs[ `${ testType }Test` ] ).toHaveLength( 2 );
expect( jobs[ `${ testType }Test` ] ).toEqual(
expect.arrayContaining( [
{
projectName: 'test',
projectPath: 'test',
name: 'Default 1/2',
command: 'test-cmd --shard=1/2',
shardNumber: 1,
testEnv: {
shouldCreate: false,
envVars: {},
},
},
{
projectName: 'test',
projectPath: 'test',
name: 'Default 2/2',
command: 'test-cmd --shard=2/2',
shardNumber: 2,
testEnv: {
shouldCreate: false,
envVars: {},
},
},
] )
);
} );
it( 'should not trigger job with event configured but not matching event cli argument', async () => {
const testType = 'default';
const jobs = await createJobsForChanges(
{
name: 'test',
path: 'test',
ciConfig: {
jobs: [
{
type: JobType.Test,
testType,
name: 'Default',
shardingArguments: [
'--shard=1/2',
'--shard=2/2',
],
events: [ 'push' ],
changes: [ /test.js$/ ],
command: 'test-cmd',
},
],
},
dependencies: [],
},
{
test: [ 'test.js' ],
},
{
commandVars: {
baseRef: 'test-base-ref',
event: 'pull_request',
},
}
);
expect( jobs.lint ).toHaveLength( 0 );
expect( jobs.test ).toHaveLength( 0 );
} );
} );
describe( 'getShardedJobs', () => {
@ -917,6 +1106,7 @@ describe( 'Job Processing', () => {
testType: 'e2e',
name: 'Default',
shardingArguments: [ '--shard-arg-1', '--shard-arg-2' ],
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
}
@ -971,6 +1161,7 @@ describe( 'Job Processing', () => {
testType: 'e2e',
name: 'Default',
shardingArguments,
events: [],
changes: [ /test.js$/ ],
command: 'test-cmd',
}

View File

@ -32,6 +32,7 @@ export const testTypes = [ 'default', 'e2e', 'api', 'performance' ] as const;
*/
export enum CommandVarOptions {
BaseRef = 'baseRef',
Event = 'event',
}
/**
@ -53,6 +54,12 @@ interface BaseJobConfig {
*/
command: string;
/**
* The type of GitHub events this job is supposed to run on.
* Example: push, pull_request
*/
events: string[];
/**
* Indicates whether or not a job has been created for this config.
*/
@ -182,6 +189,7 @@ function parseLintJobConfig( raw: any ): LintJobConfig {
type: JobType.Lint,
changes: parseChangesConfig( raw.changes, [ 'package.json' ] ),
command: raw.command,
events: raw.events || [],
};
}
@ -349,6 +357,7 @@ function parseTestJobConfig( raw: any ): TestJobConfig {
type: JobType.Test,
testType,
shardingArguments: raw.shardingArguments || [],
events: raw.events || [],
name: raw.name,
changes: parseChangesConfig( raw.changes, [ 'package.json' ] ),
command: raw.command,

View File

@ -275,7 +275,7 @@ async function createJobsForProject(
for ( const dependency of node.dependencies ) {
// Each dependency needs to have its own cascade keys so that they don't cross-contaminate.
// Keey in mind that arrays are passed by reference in JavaScript. This means that any changes
// Keep in mind that arrays are passed by reference in JavaScript. This means that any changes
// we make to the cascade keys array will be reflected in the parent scope. We need to copy
// the array before recursing our dependencies so that we don't accidentally add keys from
// one dependency to a sibling and accidentally trigger jobs that shouldn't be run.
@ -323,6 +323,20 @@ async function createJobsForProject(
continue;
}
// Do not create a job if:
// - there is an event argument in ci-job cli,
// - a non-empty list of events is defined in the job config,
// - the event argument is not in the defined list of events.
if (
options.commandVars?.event &&
jobConfig.events.length > 0 &&
! jobConfig.events
.map( ( e ) => e.toLowerCase() )
.includes( options.commandVars.event.toLowerCase() )
) {
continue;
}
// Jobs will check to see whether or not they should trigger based on the files
// that have been changed in the project. When "true" is given, however, it
// means that we should consider ALL files to have been changed and