Using Garden Workflows
# 🌱|help-and-getting-started
Hi, i have two questions about Garden Workflows: 1. Are Garden workflows idempotent? 2. Can 1 Garden workflow depend on another workflow (so I can sequence the workflows one after another, if I were running certain tests) 3. If my development or testing workflow required me to manipulate my environment up to a certain point, is there a way for me to pin the environment in that exact moment in time and export that state either in a updated stack graph or workflow for local reproduction?
Also, why do I even need workflows? I should be able to do everything in the module definition via tests and tasks. Maybe I'm not understanding Garden 100% correctly.
Hey @wide-nest-40830 thanks a lot for asking! I probably will answer your questions in a different order but please feel free to ask for more details if you feel like I got short in the explanation. *1. Why do I even need workflows? *-> You can think of workflows as some sort of
for CI environments, so imagine you have a pipeline that do 3 steps:
Copy code
- garden deploy --env=ci
- garden run task migrations-up
- garden run test unit
So instead of having to do those 3 steps in your CI steps you can setup a simple workflow called
for example:
Copy code
kind: Workflow
name: run-ci
  - command: [deploy --env=ci]
  - command: [run, task, migrations-up]
  - command: [run, test, unit]
And now because you have that workflow defined, in your CI you can just simply run the workflow, saving a couple of lines and making your CI configuration even more clear.
Copy code
garden run workflow run-ci
You can basically see them as wrappers for running multiple commands with Garden easily? 2.* Can 1 Garden workflow depend on another workflow (so I can sequence the workflows one after another, if I were running certain tests)* No, unfortunately Workflows are outside of the "Stack Graph" so they cannot currently depend on a different workflow. 3. Are Garden workflows idempotent? It depends in the tasks you are running, Garden will always execute all the tasks in the workflow but it depends on the inside tasks to be idempotent, for example if you have a migration that can only be ran once, your workflow is not going to be idempotent because the second time you run the workflow it's going to fail. 4. If my development or testing workflow required me to manipulate my... Would you mind extending this point a little bit to get more context and give an appropriate answer? ❤️
@bright-policeman-43626 thoroughly illustrated how Workflows can absorb CI steps. I want to highlight the strongest argument for Workflows is their nature as fundamentally portable pipelines. Devs can run these workflows on their own machines, as many times as they want to to test CI before committing. It's all part of our shift-left approach to development. If you've ever run into the anti-pattern of pushing a series of tiny commits to fix a bad pipeline, that's almost totally solved by Workflows.
Here's my GitLab CI file. Notice how it has been turned into a glorified Workflows-runner:
Copy code
image: gardendev/garden:0.12.51

  stage: build
    - git config --global --add $CI_PROJECT_DIR
    - garden run workflow my-workflow --env=ci
Here's my Workflows file that's kicked off by GitLab CI:
Copy code
kind: Workflow
name: my-workflow
  - description: Source Terraform Cloud credentials and install Nixpacks
    script: |-
      cat >~/.terraformrc <<EOL
      credentials "" {
        token = "${local.env.TF_CLOUD_TOKEN}"
      if [[ "$OSTYPE" == "darwin"* ]]; then
        command -v nixpacks || brew install railwayapp/tap/nixpacks
        command -v nixpacks || curl -sSL | bash
  - description: Deploy app to Kubernetes cluster
    command: [deploy]
  - description: Run tests on app
    command: [test]
  - description: Delete namespace to clean up only in CI
    name: cleanup
    command: [delete, environment]
    skip: "${ != 'ci'}"
I have a pre-init script that sets up enough of an environment for
to run. It tests my app, then using a conditional, cleans up that environment namespace created just for CI, and runs that cleanup step only when the environment is my CI pipeline i. e. running inside GitLab. Pretty cool, right?