Parses pipeline targets from commit messages and the CI_TARGET environment variable.
Targets allow developers to manually select which groups and steps to run, bypassing file-based scope detection. This is useful for re-running specific checks or skipping irrelevant CI work.
Commit Message Syntax
Prefix the commit message with [ci:<targets>]:
[ci:api] Fix login bug # run :api group
[ci:api/test] Fix flaky test # run only :test step in :api
[ci:api,web] Update shared types # run :api and :web groupsGroup and step names must match [a-z_]+.
CI_TARGET Environment Variable
Same format as the tag content (without brackets):
CI_TARGET=api # run :api group
CI_TARGET=api/test # run only :test step in :api
CI_TARGET=api,web # run :api and :web groupsCommit message targets take precedence over CI_TARGET.
Return Format
Parsed targets are returned as a map with two keys:
:groups—MapSetof group name atoms to activate:steps—MapSetof{group, step}tuples for step-level filtering
Examples
Pipette.Target.parse_commit_message("[ci:api] Fix login bug")
#=> {:ok, %{groups: MapSet.new([:api]), steps: MapSet.new()}}
Pipette.Target.parse_ci_target("api/test")
#=> {:ok, %{groups: MapSet.new([:api]), steps: MapSet.new([{:api, :test}])}}
Pipette.Target.resolve(ctx)
#=> {:ok, %{groups: ..., steps: ...}} or :none
Summary
Functions
Parse targets from the CI_TARGET environment variable value.
Parse targets from a commit message.
Resolve targets from the build context.
Types
Functions
@spec parse_ci_target(String.t() | nil) :: {:ok, target_set()} | :none
Parse targets from the CI_TARGET environment variable value.
Examples
iex> Pipette.Target.parse_ci_target("api")
{:ok, %{groups: MapSet.new([:api]), steps: MapSet.new()}}
iex> Pipette.Target.parse_ci_target("api,web")
{:ok, %{groups: MapSet.new([:api, :web]), steps: MapSet.new()}}
iex> Pipette.Target.parse_ci_target(nil)
:none
@spec parse_commit_message(String.t()) :: {:ok, target_set()} | :none
Parse targets from a commit message.
Looks for a [ci:...] prefix at the start of the message.
Examples
iex> Pipette.Target.parse_commit_message("[ci:api] Fix bug")
{:ok, %{groups: MapSet.new([:api]), steps: MapSet.new()}}
iex> Pipette.Target.parse_commit_message("[ci:api/test] Fix flaky")
{:ok, %{groups: MapSet.new([:api]), steps: MapSet.new([{:api, :test}])}}
iex> Pipette.Target.parse_commit_message("No targets here")
:none
@spec resolve(Pipette.Context.t()) :: {:ok, target_set()} | :none
Resolve targets from the build context.
Checks the commit message first, then falls back to CI_TARGET.
Returns :none if no targets are found.
Examples
ctx = %Pipette.Context{message: "[ci:api] Fix bug", ci_target: nil}
Pipette.Target.resolve(ctx)
#=> {:ok, %{groups: MapSet.new([:api]), steps: MapSet.new()}}