go-task / task

A task runner / simpler Make alternative written in Go
https://taskfile.dev
MIT License
11.03k stars 586 forks source link

Gentle force experiment #1200

Open pd93 opened 1 year ago

pd93 commented 1 year ago

[!WARNING] All experimental features are subject to breaking changes and/or removal at any time. We strongly recommend that you do not use these features in a production environment. They are intended for testing and feedback only.

[!NOTE] You can view the Gentle Force experiment documentation on our website, including instructions on how to enable/disable it.

Context

As discussed in #189, the current behavior of the --force flag is to run all tasks (i.e. ignoring all fingerprinting checks on the called task and its dependant tasks). This can be useful, but I think that most users would expect the force flag to only force the direct task that the user is calling. Implicitly running all dependant tasks could be dangerous and unexpected.

Here's a real world scenario:

If I have a task called setup that configures a local k8s cluster and takes a few minutes to complete, I might want to add a status check that queries the cluster to see if it is already running. I can then make any tasks that perform operations on the cluster depend on the setup task. This way, if the cluster is not running, it will create it before running the called task, but if the cluster is already running, it will skip the setup task and run the called task immediately.

If I then create a parent task (let's call it deploy), and this Task also has fingerprinting on it, I would expect that if I run task deploy --force, it would only force the deploy task and not force the setup task which takes a long time to complete.

version: 3

tasks:
  setup:
    status: # check if k8s cluster is running
    cmds:
      - # steps to run cluster

  deploy:
    deps: [setup]
    status: # check if app is already deployed
    cmds:
      - # steps to deploy app to cluster

This example is pretty basic and not particularly dangerous (mostly inconvenient), but I can imagine scenarios where this could accidentally run destructive tasks unintentionally.

Proposal

Theoretically, we could add a --force-task flag which will only force the called task and not its dependant tasks. However, I feel that this is counterintuitive and that it should be "harder" or "more explicit" to force all tasks than it is to force only the called task.

Instead, I propose that we change the behavior of the --force flag to only force run the called task and that we add a new flag called --force-all which will force run the called task and all of its dependant tasks.

Since this is a breaking change, we would need to add this change as an experiment. The variable to enable this experiment would be TASK_X_GENTLE_FORCE=1.

It is important to note that this experimental flag will not actually force a task when used. Instead, it will change the behavior of the existing --force flag and add the ability to call a new flag --force-all which will force all tasks. In other words, to get the new experimental behavior, you would run a command like this:

You can set the TASK_X_GENTLE_FORCE environment variable in your dotfiles if you want to permanently enable this new behavior.

andreynering commented 1 year ago

Hi @pd93,

I like this proposal. The biggest reason on why we were avoiding changes like this is because it's a breaking change, but with the new proposal pattern we're now able to proceed with scenarios like this, so 👍.

task-bot commented 1 year ago

This issue has been marked as an experiment proposal! :test_tube: It will now enter a period of consultation during which we encourage the community to provide feedback on the proposed design. Please see the experiment workflow documentation for more information on how we release experiments.

task-bot commented 1 year ago

This experiment has been marked as a draft! :sparkles: This means that an initial implementation has been added to the latest release of Task! You can find information about this experiment and how to enable it in our experiments documentation. Please see the experiment workflow documentation for more information on how we release experiments.

task-bot commented 1 year ago

This experiment has been marked as a candidate! :fire: This means that the implementation is nearing completion and we are entering a period for final comments and feedback! You can find information about this experiment and how to enable it in our experiments documentation. Please see the experiment workflow documentation for more information on how we release experiments.

task-bot commented 1 year ago

This experiment has been marked as stable! :metal: This means that the implementation is now final and ready to be released. No more changes will be made and the experiment is safe to use in production! You can find information about this experiment and how to enable it in our experiments documentation. Please see the experiment workflow documentation for more information on how we release experiments.