Using concurrency_group for multiple steps

Hi there! We’d like to “guard” two or more build steps with one concurrency_group. The documentation doesn’t describe this scenario. Is there a proper way to do it?

e.g.

steps:

  • deploy
  • e2e test

the deploy step should never start on a 2nd pipeline run until the e2e test finished on the 1st

Hey @pkonyves!

Welcome to the community :slight_smile: that’s a great question! You’ll want to make use of concurrency gates, this will all you to prevent other steps from running in the same concurrency group until the previous step has been completed, you can refer to the example in the docs I linked for a similar scenario to the one you are describing. Let me know if that makes sense or if you have further questions!

Best,

Jeremy

hi @jeremy
Yes based on this I added ‘wait’ steps between ‘deploy’ and ‘e2e test’, but I don’t understand why it works. The documentation is very brief and doesn’t give a clear explanation of what a ‘concurrency gate’ is, or that ‘wait’ steps make the subsequent tasks “atomic”.

e.g. I tried using ‘depends_on’ instead of ‘wait’, which should have the same effect, but when using depends_on parallel running pipelines had interleaving run of the two steps.

Moreover the wait has the effect that it waits for everything before this step, whereas I only need to wait for the 1st task in the ‘concurrency gate’.

it would be a cleaner solution if ‘group step’ had a concurrency_group attribute

Hi @pkonyves

I am jumping in for Jeremy! Thanks for all the details!

Here is a blog Concurrency Gates - Buildkite Blog with flow-diagram and video that describes the exact scenario you wanted to implement.

Please have a read and let us know if you have any questions.

Best,
Nithya

Hi @nithya , thanks. This blog post doesn’t make things much more clear for me why and how it works :slight_smile:

Regarding the above blog post. Can you tell me exactly what defines the end of a concurrency gate? does buildkite search for pairs of concurrency_group: gate to find the beginning and end of a gate?

Why is the wait needed after the start of the concurrency gate if depends_on is also defined, does it affect the concurrency gate?

thanks in advance

Hey @pkonyves,

I reached out to the team for some clarification and to hopefully get a better answer to your questions (and help to improve our documentation!)

First, I’d like to add some context to concurrency groups. A concurrency group is essentially just a queue; it returns jobs in the queued order (oldest → newest). At run-time there are a number of active job states that the concurrency group cares about (limiting/limited/scheduled/waiting/assigned/accepted/running/cancelling/timing out) and the group becomes “locked” when the concurrency limit for jobs in these states is hit. Once a job moves from an active state to a terminal state (finished or cancelled) the job is removed from the queue, opening up a spot for another job to enter.

This guarantees jobs are run in the scheduled order they were created with the concurrency limits defined by the group, and only applying to jobs that are based on that step (limited by the agent pool)

Now, to try and answer your questions around the gates:

Can you tell me exactly what defines the end of a concurrency gate? does Buildkite search for pairs of concurrency_group: gate to find the beginning and end of a gate?

The way that the gate is marked as “closed” is by having another job enter the queue, which makes any subsequent tasks run independently of the concurrency group.

Why is the wait needed after the start of the concurrency gate if depends_on is also defined, does it affect the concurrency gate?

The wait step is there to ensure that each command is run subsequently (you don’t need depends_on ) so you can use either or both.

Hopefully this helps to clear up any confusion, but if there is still more that doesn’t make sense, please let me know!

Best,

Jeremy