Starter.Workflow behaviour (starter v0.1.2)

Copy Markdown View Source

Defines a setup workflow: an ordered list of steps applied to a project.

use Starter.Workflow turns a module into a full Igniter.Mix.Task. Name it under Mix.Tasks (for example Mix.Tasks.MyApp.Workflow) and it becomes runnable as mix my_app.workflow — or via mix starter.run, which finds it — with a --flag option for every optional step.

Step forms

  • {:add, :oban} — run the built-in add step oban
  • {:remove, :topbar} — run the built-in remove step topbar
  • {:gen, :gitignore} — run the built-in gen step gitignore
  • {:add, :oban, if: :oban} — only when the --oban flag is passed
  • {:install, :ash} — fetch a package via mix igniter.install and run the package's own installer when it ships one. Queued to run right after the workflow's other changes apply.
  • {:queue, "starter.add", ["oban_pro"]} — queue any Mix task to run after the workflow's changes apply; queued tasks run in order, so this is how to sequence work after {:install, ...} steps

Queued tasks (including {:install, ...}) run non-interactively with --yes appended — their subprocesses have no stdin, so a prompt there could never be answered. Confirming the workflow's diff is the approval for everything it queues; queued tasks must tolerate the --yes flag (every Igniter task does).

Ordering

In-run steps apply first, in list order. Queued steps then run in list order against the applied project. To guarantee a step runs last — after the installers have added their deps — express it as a queued task and place it at the end of the list, e.g. {:queue, "starter.gen.sort_deps"}.

  • {:task, "some.igniter.task"} — compose any Igniter-aware Mix task, with optional argv and an if: option as a fourth element; non-Igniter tasks are skipped with a warning
  • {:workflow, OtherWorkflow} — include another workflow's steps
  • MyApp.Steps.Custom — any module implementing Igniter.Mix.Task, optionally as {MyApp.Steps.Custom, if: :flag}

Example

defmodule Mix.Tasks.MyApp.Workflow do
  use Starter.Workflow

  @impl Starter.Workflow
  def steps do
    [
      {:remove, :daisy_ui},
      {:gen, :gitignore},
      {:add, :credo},
      {:add, :oban, if: :oban}
    ]
  end
end

Running mix my_app.workflow applies every unconditional step; mix my_app.workflow --oban also applies the Oban step.

Summary

Types

A single entry in a workflow's steps/0 list.

Callbacks

Returns the workflow's steps, in the order they should run.

Functions

Returns every flag referenced by if: options in the given steps, including flags of nested workflows.

Returns every flag used by the given workflow module.

Types

step()

@type step() ::
  {:add | :remove | :gen, atom()}
  | {:add | :remove | :gen, atom(), keyword()}
  | {:install, atom()}
  | {:install, atom(), keyword()}
  | {:queue, String.t()}
  | {:queue, String.t(), [String.t()]}
  | {:queue, String.t(), [String.t()], keyword()}
  | {:task, String.t()}
  | {:task, String.t(), [String.t()]}
  | {:task, String.t(), [String.t()], keyword()}
  | {:workflow, module()}
  | {:workflow, module(), keyword()}
  | module()
  | {module(), keyword()}

A single entry in a workflow's steps/0 list.

Callbacks

steps()

@callback steps() :: [step()]

Returns the workflow's steps, in the order they should run.

Functions

flags(steps)

@spec flags([step()]) :: [atom()]

Returns every flag referenced by if: options in the given steps, including flags of nested workflows.

flags_of(workflow)

@spec flags_of(module()) :: [atom()]

Returns every flag used by the given workflow module.