Support for conditional jobs in workflows
complete
T
Tom Wilson
Circle 2.0 has been a huge improvement over Circle 1.0 - thank you for all the new features! One thing that would really unlock a ton of power, though, would be adding support for conditional jobs.
Currently, in a workflow, you can specify "job B requires job A to succeed". But you can't author flows like "only run Job B if Job A succeeds, otherwise don't run it." There's a critical difference between these two semantics. In the first flow, job A is expected to usually succeed, and the build should be marked as failing if it doesn't. In the second case, Job A not succeeding is
expected
and shouldn't cause the build to fail.Perhaps an easy way to wire this would be to have jobs that aren't treated as "success" or "failure", but rather always succeed and just report the status to an environment variable. This would allow authoring a job that could kick off if a variable is set (or some similar mechanism)
CCI-I-216
Nathan Fish
complete
Job filters now support expression based evaluation on pipeline values. As noted in the example previously provided. We are still working on some aspects of improving when statements, to account for some edge cases. I'm going to close this issue as complete because it was specific to jobs.
Keep a look out for updated documentation in the next few days on CircleCI's docs for the job filters updates.
Keep a look out on the Changelog for when we add expression based evaluation to when statements for workflows and steps.
T
Tyler BoddySpargo
Nathan Fish - Can you please link to the documentation related to this new feature?
Nathan Fish
Tyler BoddySpargo right now the example is your best bet, we are working on the documentation but I don't expect that to be completed till next week.
workflows:
deploy:
jobs:
- init-service
- build-service-image:
requires:
- init-service
- dry-run-service:
requires:
- init-service
filters: pipeline.git.branch != "main" and pipeline.git.branch != "canary"
- publish-service:
requires:
- build-service-image
- test-service
filters: pipeline.git.branch == "main" or pipeline.git.tag starts-with "release"
- deploy-service:
context:
- org-global
requires:
- publish-service
filters: pipeline.git.branch == "main" and pipeline.git.commit.subject starts-with "DEPLOY:"
J
J. Casalino
Nathan Fish Thank you! Are you also able to request backport into the standalone server version?
Nathan Fish
J. Casalino should show up in server 4.8 release. Unfortunately 4.7 is already in code freeze.
P
Peter Darton
In an ideal world, I'd like to have "when" and/or "unless" support on jobs that support the "normal" condition syntax.
Full regex support would be nice but if we have to survive without them initially then that wouldn't kill me ... but please don't implement wildly different YML syntax for this - please use "the normal syntax" and have the code throw an easy to understand error if someone calls upon not-yet-implemented functionality.
Personally, I would also like to be able to specify that a filtered-out job still be visible on the UI in an obviously-not-run state.
e.g. when I'm using the filter orb (or similar) to decide what tests I need to run, I would like to still see the tests that I didn't run rather than just
not
seeing the ones I excluded.I don't want to have my developers thinking "the build is green so everything is good" when the reason it passed was that it didn't run the tests that would've failed; making it obvious what jobs were run and, just as importantly, what jobs were filtered out is part of that.
... although I'm sure other users will want a terse UX that hides the filtered-out jobs, so make this something that's configurable in the YML.
Nathan Fish
in progress
Nathan Fish
So here's some thought's on a first set of enhancements. Building off the "expression based restrictions" from contexts we would add similar "expression" based when statements for workflows and jobs. These are based on pipeline values, so if there isn't a pipeline value for the specific thing you are trying to do, let me know. Please note regular expression support is also not supported in this first version. Thoughts?
Job Filters Example
- The dry-run-service job is run for all branches except main or canary
- publish-service is run if the branch is main, or the tag starts with release
- deploy-service runs if the branch is main and the commit subject starts with DEPLOY:
workflows:
deploy:
jobs:
- init-service
- build-service-image:
requires:
- init-service
- dry-run-service:
requires:
- init-service
filters: pipeline.git.branch != "main" and pipeline.git.branch != "canary"
- publish-service:
requires:
- build-service-image
- test-service
filters: pipeline.git.branch == "main" or pipeline.git.tag starts-with "release"
- deploy-service:
context:
- org-global
requires:
- publish-service
filters: pipeline.git.branch == "main" and pipeline.git.commit.subject starts-with "DEPLOY:"
Workflow Example
parameters:
deploy-type:
type: string
default: ""
workflows:
experiments:
when: |
pipeline.parameters.deploy-type starts-with "experiments/"
or pipeline.git.commit.committer_email == "sre@example.com"
jobs:
- init-service
- build-service-image:
requires:
- init-service
Nathan Fish
J. Casalino, Bruce Tan let me know your thoughts on this one. Example config provided with a rather made up set of scenarios.
Nathan Fish
Link to pipeline values for reference https://circleci.com/docs/pipeline-variables/#pipeline-values
Bruce Tan
Nathan Fish
Nathan Fish Does filter support pipeline parameters?
The main use case of conditional job is to create conditional jobs based on pipeline parameters. For example, we have a workflow that have 15 different jobs in it. We also want to have one of the job conditional on pipeline parameter.
Under the current circleci config.we would have to create two different workflow duplicating the other 14 jobs, just for one conditional job
For example, this is what it looks like right now in our config
workflows:
deploy:
when:
equal: [<<pipeline.parameters.deploy-type>> , "dry-run" ]
jobs:
- joba
- foo
- bar
- jobb
- jobc
- joba
- foo
- bar
- jobb
- jobc
- dry-run-service
deploy-auto:
- joba
- foo
- bar
- jobb
- jobc
- joba
- foo
- bar
- jobb
- jobc
Ideally we want something like this
workflows:
deploy:
jobs:
- joba
- foo
- bar
- jobb
- jobc
- joba
- foo
- bar
- jobb
- jobc
- dry-run-service
filter: pipeline.parameters.deploy-type == "dry-run"
J
J. Casalino
Nathan Fish Looks like a good first swing at it. I don't think regex support is a dealbreaker right now; as long as I can set a parameter somewhere and the workflow or job will automatically run or skip based on the param value, I'm good.
G
Gordon Syme
Bruce Tan Yes, you'd be able to match against pipeline parameters in job filters, exactly like that.
Bruce Tan
Gordon Syme Awesome, looking forward to it
Nathan Fish
Would more flexible requires functionality solve for this issue?
It would give you more flexibility to run jobs when they fail or regardless of the outcome, like when they are completed.
J
J. Casalino
Nathan Fish Flexibility as proposed could be helpful to some as a first step, but it's still not a replacement for a fully-fledged "when" conditional with logical AND/OR/NOT support. I think building a job flow only with "requires:" would actually create more confusion and duplicate code because in many cases you'd still have to account for each permutation depending on the outcome of two or more jobs.
Bruce Tan
Nathan Fish No this doesn't address this issue, we need
when
conditions in jobs. Would be much appreciated if you could consider prioritising it as it has been a pain point for us when working on circle ci configsNathan Fish
Bruce Tan:
Nathan Fish
J. Casalino: Got it. So my thought would be to introduce a new tag for "when" statements called "expression" and you could use expressions (like expression based context restrictions) to create conditionals from pipeline values.
Expression based context restrictions https://circleci.com/docs/contexts/#expression-restrictions
Pipeline values https://circleci.com/docs/pipeline-variables/
- when:
expression:
- pipeline.git.branch == "main" and not job.ssh.enabled and not (pipeline.config_source starts-with "api"")
Thoughts?
Nathan Fish
I would also want to expand this to cover steps, jobs and workflows.
J
J. Casalino
Nathan Fish Yes, exactly. So extend
when
expression support to steps, jobs, and workflows, then allow an expression based on pipeline values or results of prior steps/jobs/workflows which have already run (or have been skipped). I could also see an argument to add a couple more operators like "ends-with" and "contains".I think you'll have to be careful not to break existing logic statements people have already written in dynamic config [1], but the
expression
approach will be much more flexible for everyone. I would suggest supporting, but deprecating, the old method to avoid further confusion. You could even give WARN-level hints on how to update such a statement in the new syntax.[1]
Bruce Tan
Nathan Fish Does expression support working with pipeline parameters?
Nathan Fish
Bruce Tan the proposal here would be pipeline values and not pipeline parameters. I'll discuss with the team if pipeline parameters could be included as an option.
T
Tyler BoddySpargo
I just wanted to share that I specifically would appreciate job-level support for very similar
when: <logic statement>
syntax to what is available for workflows today. If that can be implemented generically to also support the OP's use-case that would be great, but I personally see a better solution for the OP's case being accomplished by an expanded requires
syntax. For example:`requires: [ { name: <job_name>, when: always }, { name: <job_name>, when: on-fail } ]
Laurynas Pliuskys
Tyler BoddySpargo: yes I have the exact same request!! We have quite a complex workflow with different jobs depending on each other, but we also have a dynamic config implemented, so it would be nice if the complexity of the workflow was preserved (so only have 1 workflow) but only jobs that have `when: << pipeline.parameters.build-serviceX-job >> were run. That way the logic moves to the job level, rather than the workflow level
Tricia Spoonts
Hi all,
Looking at this post, it appears that you have interest in our config. We are making some updates to requires and would like to understand your processes and what formatting makes those most efficient.
Would any of you be interested in doing a formal user-interview with us? This is a 30 minute recorded video call in which we'll talk about requires in configuration and show you some approaches. If you're open to it, please book some time here: https://calendly.com/tricia-circleci/ux-session?month=2020-12 Thank you in advance, hope to learn from some of you.
Tricia Spoonts, Product Design Manager, CircleCI
Owen Hankinson
Tricia Spoonts: Looking for a way to access this feature, has this been added?
Tricia Spoonts
Owen Hankinson: I'm unsure of your use case, but dynamic configuration might be what you're looking for https://circleci.com/docs/using-dynamic-configuration/
Dennis Schridde
I would like for Terraform changes to normally be applied, but for changes to certain Resources to require approval.
I can inspect the Terraform Plan using
jq
and grep
, but what seems to be missing in CircleCI is a way to "hold" the pipeline if my jq | grep
script finds something.L
Liya Ai
under review
M
Maksim Iakunin
+++
Load More
→