Commit c7438600 authored by Scott Hampton's avatar Scott Hampton

Merge branch 'vis-for-parallel-jobs' into 'master'

Adjust Pipeline Editor Vis to Handle Parallel Jobs

See merge request gitlab-org/gitlab!50897
parents f99d6755 0f5bee97
#import "~/pipelines/graphql/queries/pipeline_stages_connection.fragment.graphql"
#import "~/pipelines/graphql/fragments/pipeline_stages_connection.fragment.graphql"
query getCiConfigData($projectPath: ID!, $content: String!) {
ciConfig(projectPath: $projectPath, content: $content) {
......
......@@ -105,9 +105,7 @@ export default {
highlightedJobs() {
// If you are hovering on a job, then the jobs we want to highlight are:
// The job you are currently hovering + all of its needs.
return this.hasHighlightedJob
? [this.highlightedJob, ...this.needsObject[this.highlightedJob]]
: [];
return [this.highlightedJob, ...this.needsObject[this.highlightedJob]];
},
highlightedLinks() {
// If you are hovering on a job, then the links we want to highlight are:
......
import { pickBy } from 'lodash';
import { SUPPORTED_FILTER_PARAMETERS } from './constants';
import { createNodeDict } from './components/parsing_utils';
export const validateParams = (params) => {
return pickBy(params, (val, key) => SUPPORTED_FILTER_PARAMETERS.includes(key) && val);
......@@ -15,19 +16,8 @@ export const createUniqueLinkId = (stageName, jobName) => `${stageName}-${jobNam
* @returns {Object} - Hash of jobs
*/
export const createJobsHash = (stages = []) => {
const jobsHash = {};
stages.forEach((stage) => {
if (stage.groups.length > 0) {
stage.groups.forEach((group) => {
group.jobs.forEach((job) => {
jobsHash[job.name] = job;
});
});
}
});
return jobsHash;
const nodes = stages.flatMap(({ groups }) => groups);
return createNodeDict(nodes);
};
/**
......@@ -56,6 +46,14 @@ export const generateJobNeedsDict = (jobs = {}) => {
// to save some performance.
const newNeeds = acc[job] ?? recursiveNeeds(job);
// In case it's a parallel job (size > 1), the name of the group
// and the job will be different. This mean we also need to add the group name
// to the list of `needs` to ensure we can properly reference it.
const group = jobs[job];
if (group.size > 1) {
return [job, group.name, ...newNeeds];
}
return [job, ...newNeeds];
})
.flat(Infinity);
......
......@@ -49,6 +49,7 @@ export const mockCiConfigQueryResponse = {
nodes: [
{
name: 'job_test_1',
size: 1,
jobs: {
nodes: [
{
......@@ -63,10 +64,12 @@ export const mockCiConfigQueryResponse = {
},
{
name: 'job_test_2',
size: 1,
jobs: {
nodes: [
{
name: 'job_test_2',
needs: { nodes: [], __typename: 'CiConfigNeedConnection' },
__typename: 'CiConfigJob',
},
......@@ -86,6 +89,7 @@ export const mockCiConfigQueryResponse = {
nodes: [
{
name: 'job_build',
size: 1,
jobs: {
nodes: [
{
......
......@@ -68,10 +68,10 @@ describe('utils functions', () => {
it('returns a hash with the jobname as key and all its data as value', () => {
const jobs = {
[jobName1]: job1,
[jobName2]: job2,
[jobName3]: job3,
[jobName4]: job4,
[jobName1]: { jobs: [job1], name: jobName1, needs: [] },
[jobName2]: { jobs: [job2], name: jobName2, needs: [] },
[jobName3]: { jobs: [job3], name: jobName3, needs: job3.needs },
[jobName4]: { jobs: [job4], name: jobName4, needs: job4.needs },
};
expect(createJobsHash(pipelineGraphData.stages)).toEqual(jobs);
......@@ -110,5 +110,41 @@ describe('utils functions', () => {
[jobName4]: [jobName3, jobName1, jobName2],
});
});
it('handles parallel jobs by adding the group name as a need', () => {
const size = 3;
const jobOptimize1 = 'optimize_1';
const jobPrepareA = 'prepare_a';
const jobPrepareA1 = `${jobPrepareA} 1/${size}`;
const jobPrepareA2 = `${jobPrepareA} 2/${size}`;
const jobPrepareA3 = `${jobPrepareA} 3/${size}`;
const jobsParallel = {
[jobOptimize1]: {
jobs: [job1],
name: [jobOptimize1],
needs: [jobPrepareA1, jobPrepareA2, jobPrepareA3],
},
[jobPrepareA]: { jobs: [], name: jobPrepareA, needs: [], size },
[jobPrepareA1]: { jobs: [], name: jobPrepareA, needs: [], size },
[jobPrepareA2]: { jobs: [], name: jobPrepareA, needs: [], size },
[jobPrepareA3]: { jobs: [], name: jobPrepareA, needs: [], size },
};
expect(generateJobNeedsDict(jobsParallel)).toEqual({
[jobOptimize1]: [
jobPrepareA1,
// This is the important part, the `jobPrepareA` group name has been
// added to our list of needs.
jobPrepareA,
jobPrepareA2,
jobPrepareA3,
],
[jobPrepareA]: [],
[jobPrepareA1]: [],
[jobPrepareA2]: [],
[jobPrepareA3]: [],
});
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment