Skip to content

Commit

Permalink
Merge pull request #2385 from flowforge/backport-2384
Browse files Browse the repository at this point in the history
Ensure pipeline stages are listed in the correct order (backport #2384)
  • Loading branch information
knolleary committed Jul 3, 2023
2 parents 63b8eda + 7078619 commit 5899847
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 1 deletion.
26 changes: 25 additions & 1 deletion forge/ee/db/views/PipelineStage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ module.exports = {
}

if (stage.Instances?.length > 0) {
// TODO: this should be an instanceSummaryList - back that doesn't
// exist in 1.8, so minimising the changes for this backport.
filtered.instances = await app.db.views.Project.instancesList(stage.Instances)
}

Expand All @@ -21,6 +23,28 @@ module.exports = {
return filtered
},
async stageList (app, stages) {
return await Promise.all(stages.map(app.db.views.PipelineStage.stage))
// Must ensure the stages are listed in the correct order
const stagesById = {}
const backReferences = {}
let pointer = null
// Scan the list of stages
// - build an id->stage reference table
// - find the last stage (!NextStageId) and set pointer
// - build a reference table of which stage points at which
stages.forEach(stage => {
stagesById[stage.id] = stage
if (!stage.NextStageId) {
pointer = stage
} else {
backReferences[stage.NextStageId] = stage.id
}
})
const orderedStages = []
// Starting at the last stage, work back through the references
while (pointer) {
orderedStages.unshift(pointer)
pointer = stagesById[backReferences[pointer.id]]
}
return await Promise.all(orderedStages.map(app.db.views.PipelineStage.stage))
}
}
68 changes: 68 additions & 0 deletions test/unit/forge/ee/db/views/PipelineStage_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const should = require('should') // eslint-disable-line
const setup = require('../../setup')

describe('PipelineStage view', function () {
let app
before(async function () {
app = await setup()
})

after(async function () {
await app.close()
})

describe('stageList', function () {
it('returns stages in the correct order', async function () {
const pipeline = await app.factory.createPipeline({
name: 'pipeline-1'
},
app.application)

const stage1 = await app.factory.createPipelineStage({
name: 's1',
instanceId: app.instance.id
}, pipeline)
const stage2 = await app.factory.createPipelineStage({
name: 's2',
instanceId: app.instance.id
}, pipeline)
const stage3 = await app.factory.createPipelineStage({
name: 's3',
instanceId: app.instance.id
}, pipeline)

stage1.NextStageId = stage2.id
stage2.NextStageId = stage3.id
await stage1.save()
await stage2.save()

function validateList (list) {
list.should.have.length(3)
list[0].should.have.property('id', stage1.hashid)
list[1].should.have.property('id', stage2.hashid)
list[2].should.have.property('id', stage3.hashid)
}

validateList(await app.db.views.PipelineStage.stageList([
stage1,
stage2,
stage3
]))
validateList(await app.db.views.PipelineStage.stageList([
stage3,
stage2,
stage1
]))
validateList(await app.db.views.PipelineStage.stageList([
stage2,
stage1,
stage3
]))
validateList(await app.db.views.PipelineStage.stageList([
stage1,
stage3,
stage2
]))
})
})
})

0 comments on commit 5899847

Please sign in to comment.