screwdriver-api 7.0.180 → 7.0.181

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-api",
3
- "version": "7.0.180",
3
+ "version": "7.0.181",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -86,8 +86,7 @@ class AndTrigger extends JoinBase {
86
86
  // If the build to join is in the child event, its event id is greater than current event.
87
87
  nextBuild = relatedBuilds.find(b => b.jobId === nextJobId && b.eventId > this.currentEvent.id);
88
88
  }
89
-
90
- const newParentBuilds = mergeParentBuilds(parentBuilds, relatedBuilds, this.currentEvent);
89
+ const newParentBuilds = mergeParentBuilds(parentBuilds, relatedBuilds, this.currentEvent, undefined);
91
90
  let nextEvent = this.currentEvent;
92
91
 
93
92
  if (nextBuild) {
@@ -668,6 +668,61 @@ async function getParallelBuilds({ eventFactory, parentEventId, pipelineId }) {
668
668
  return parallelBuilds;
669
669
  }
670
670
 
671
+ /**
672
+ * Get subsequent job names which the root is the start from node
673
+ * @param {Array} [workflowGraph] Array of graph vertices
674
+ * @param {Array} [workflowGraph.nodes] Array of graph vertices
675
+ * @param {Array} [workflowGraph.edges] Array of graph edges
676
+ * @param {String} [startNode] Starting/trigger node
677
+ * @returns {Array<String>} subsequent job names
678
+ */
679
+ function getSubsequentJobs(workflowGraph, startNode) {
680
+ const { nodes, edges } = workflowGraph;
681
+
682
+ // startNode can be a PR job in PR events, so trim PR prefix from node name
683
+ if (!startNode || !nodes.length) {
684
+ return [];
685
+ }
686
+ const nodeToEdgeDestsMap = Object.fromEntries(nodes.map(node => [node.name, []]));
687
+
688
+ let start = trimJobName(startNode);
689
+ // In rare cases, WorkflowGraph and startNode may have different start tildes
690
+
691
+ if (!(start in nodeToEdgeDestsMap)) {
692
+ if (start.startsWith('~')) {
693
+ start = start.slice(1);
694
+ } else {
695
+ start = `~${start}`;
696
+ }
697
+ }
698
+
699
+ if (!(start in nodeToEdgeDestsMap)) {
700
+ return [];
701
+ }
702
+
703
+ const visiting = [start];
704
+
705
+ const visited = new Set(visiting);
706
+
707
+ edges.forEach(edge => nodeToEdgeDestsMap[edge.src].push(edge.dest));
708
+ if (edges.length) {
709
+ while (visiting.length) {
710
+ const currentNode = visiting.pop();
711
+ const dests = nodeToEdgeDestsMap[currentNode];
712
+
713
+ dests.forEach(dest => {
714
+ if (!visited.has(dest)) {
715
+ visiting.push(dest);
716
+ visited.add(dest);
717
+ }
718
+ });
719
+ }
720
+ }
721
+ visited.delete(start);
722
+
723
+ return [...visited];
724
+ }
725
+
671
726
  /**
672
727
  * Merge parentBuilds object with missing job information from latest builds object
673
728
  * @param {ParentBuilds} parentBuilds parent builds
@@ -692,6 +747,11 @@ async function getParallelBuilds({ eventFactory, parentEventId, pipelineId }) {
692
747
  function mergeParentBuilds(parentBuilds, relatedBuilds, currentEvent, nextEvent) {
693
748
  const newParentBuilds = {};
694
749
 
750
+ const ignoreJobs =
751
+ nextEvent && currentEvent.startFrom.startsWith('~')
752
+ ? getSubsequentJobs(nextEvent.workflowGraph, nextEvent.startFrom)
753
+ : getSubsequentJobs(currentEvent.workflowGraph, currentEvent.startFrom);
754
+
695
755
  Object.entries(parentBuilds).forEach(([pipelineId, { jobs, eventId }]) => {
696
756
  const newBuilds = {
697
757
  jobs,
@@ -708,7 +768,7 @@ function mergeParentBuilds(parentBuilds, relatedBuilds, currentEvent, nextEvent)
708
768
  let { workflowGraph } = currentEvent;
709
769
  let nodeName = trimJobName(jobName);
710
770
 
711
- if (strToInt(pipelineId) !== currentEvent.pipelineId) {
771
+ if (strToInt(pipelineId) !== strToInt(currentEvent.pipelineId)) {
712
772
  if (nextEvent) {
713
773
  if (strToInt(pipelineId) !== nextEvent.pipelineId) {
714
774
  nodeName = `sd@${pipelineId}:${nodeName}`;
@@ -718,7 +778,6 @@ function mergeParentBuilds(parentBuilds, relatedBuilds, currentEvent, nextEvent)
718
778
  nodeName = `sd@${pipelineId}:${nodeName}`;
719
779
  }
720
780
  }
721
-
722
781
  const targetJob = workflowGraph.nodes.find(node => node.name === nodeName);
723
782
 
724
783
  if (!targetJob) {
@@ -735,8 +794,10 @@ function mergeParentBuilds(parentBuilds, relatedBuilds, currentEvent, nextEvent)
735
794
  return;
736
795
  }
737
796
 
738
- newBuilds.jobs[jobName] = targetBuild.id;
739
- newBuilds.eventId = targetBuild.eventId;
797
+ if (!ignoreJobs.includes(nodeName) || targetBuild.eventId === currentEvent.id) {
798
+ newBuilds.jobs[jobName] = targetBuild.id;
799
+ newBuilds.eventId = targetBuild.eventId;
800
+ }
740
801
  });
741
802
 
742
803
  newParentBuilds[pipelineId] = newBuilds;