cirruslabs/cirrus-ci-docs

Requesting not to update the `CIRRUS_LAST_GREEN_CHANGE` after builds with no tasks, nor after builds with all tasks skipped

DeeDeeG opened this issue · 1 comments

Description

It would be really nice, in my opinion, for builds with no tasks, or builds where all tasks are SKIPPED, for the CIRRUS_LAST_GREEN_CHANGE not to be updated or changed by these builds. (That the CIRRUS_LAST_GREEN_CHANGE would remain the same as before the build with only skipped tasks, or no tasks, had run.)

This aids in the ability to filter most build types/build triggers to safeguard credits, and follow-up with a cron rule to actually build the repo every so often.

Context

  • Builds with no tasks can happen due to the use of only_if: in .cirrus.yml.
  • Builds with all skipped tasks can happen due to use of skip: in .cirrus.yml.

For example, our real-world use-case: we are using only_if: to skip PR and branch push builds, and instead only build our default branch every few days with cron builds. And we are using skip: based on checking CIRRUS_LAST_GREEN_CHANGE to skip if the current commit has already been built before. (We could do both via only_if:, but the result seems to be the same, from some quick testing. I didn't test doing all the skipping logic in skip:, but I expect no difference?) But the cron builds see the skipped branch push builds to our default branch as successful, in terms of the fact that they update CIRRUS_LAST_GREEN_CHANGE. So these cron builds are now skipping as well! We have effectively no builds ever, with our current setup.

Basically I consider it (subjectively) a bug that CIRRUS_LAST_GREEN_CHANGE updates to the commit of these builds which have no tasks scheduled due to only_if:, or all tasks skipped due to skip:.

If there is any concern about breaking existing workflows, then perhaps the info should be presented in a new env var? Perhaps called: CIRRUS_LAST_GREEN_CHANGE_WITH_TASKS?

Anything Else

Similar to previous issue I found, #891.

But unlike that issue, I'm referring to situations where the overall build is reporting asCOMPLETED aka successful, but there were no tasks or all skipped tasks. Whereas I suppose #891 was just about if the entire build was SKIPPED.

By the way, we have found a (rather hacky feeling) workaround for this... A task designed to execute as quickly as possible and mark the overall build as technically "failed", if we would have skipped all its tasks.

We would rather have a way that feels officially supported in Cirrus rather than a hack or workaround, ideally though. Thank you for considering.

silently_mark_skipped_or_no_scheduled_task_builds_as_failed_task:
  skip_notifications: true
  only_if: $CIRRUS_CRON == "" && $CIRRUS_TAG == ""
  container:
    image: alpine:latest
    cpu: 1
  clone_script: |
    exit 0
  mark_task_as_failed_script: |
    exit 1
  timeout_in: 6s
The same task definition as above, annotated with a lot of comments (click to expand):
silently_mark_skipped_or_no_scheduled_task_builds_as_failed_task:
  skip_notifications: true
  # "skip_notifications: true" makes GitHub see the build as successful, for cleaner statuses on GitHub.
  only_if: $CIRRUS_CRON == "" && $CIRRUS_TAG == ""
  # Only mark the "skipped" or "no-tasks-cheduled" builds as failed. "Cron" builds and "tag push" builds should be allowed to succeed.
  # !!! Don't forget to update the "only_if:" for this task to match, if you update the "only_if:" logic in the other tasks. !!!
  container:
    image: alpine:latest
    # A light and minimal image, to save Cirrus some resources, why not?
    cpu: 1
    # Set CPU cores used by the VM to 1. Otherwise, we burn double the CPU-seconds per IRL second, due to 2 CPU cores being provisioned by default.
  clone_script: |
    exit 0
    # Fake "clone repo" script that overrides the default, actual clone script.
    # Actually cloning the repo isn't necessary for this task. But if cloning fails, it triggers an automatic re-run.
    # So, we have to provide this fake clone script to override the real one, if we want to save any IRL time versus an actual clone.
    # Saves ~2 CPU-seconds vs a real, clone_depth 1 clone. Saves ~2 minutes IRL time vs a clone script that deliberately fails or times out.
  mark_task_as_failed_script: |
    exit 1 # This script does nothing but mark the build as failed, protecting the CIRRUS_LAST_GREEN_CHANGE from being updated when it shouldn't be.
  timeout_in: 6s
  # Avoid wasting any more than 6 seconds, or up to 12 seconds if an automatic re-run is triggered. 2 seconds is typical for the whole task, though.