Just to add another voice here ...
I originally had a multi-job deployment stage. Having multiple jobs gave two things ... 1. Quicker visibility in to where failures occurred. 2. parallelisation of deployment steps where beneficial.
When it came time to plan rollback handling on a failed deployment, I wasn't willing to maintain multiple rollback tasks configured on multiple jobs. Conceptually, we needed one rollback sequence to be triggered at any point the deployment failed.
What we ended up with is a more concerted investment in Ansible, and a reduction in the use of the multi tiered Pipeline definition. Our typical deployment pipeline now has a single stage with a single job with the following tasks
- Fetch Artifact
- Command: ansible-playbook deploy.yml
- Command (RunIf Failed): ansible-playbook rollback.yml
And note I'm doing deployment at a pipeline level. Whilst that "may" be the right thing to do anyway, we actually had no choice as each deployment along the road to production has exactly the same set of instruction (with a different environment). Because templates can only be applied to Pipelines, we couldn't model a deployment template and apply it to a Stage.
Just in case I'm misinterpreted as complaining - I'm not. Go CD is a pretty good tool, and I'm still very happy with our decision to use it. However, we just can't use some of the more complex aspects of Pipeline/Stage configuration due to the above mentioned shortcomings.
Mark