Flow Metrics

Lean Flow Metrics

Extract flow metrics from Jira and Azure DevOps. A fast, self-contained Rust CLI.

Lean Flow Metrics is the Rust rewrite of Actionable Metrics. It connects to your Jira or Azure DevOps instance and produces ActionableAgile-compatible exports — cycle time, throughput, work item age, an interactive HTML dashboard, and more — from a single dataset configuration file. It ships as one small container image with zero cloud dependencies.


Why Lean Flow Metrics?


Quick Start

Prerequisites

Before continuing, ensure you have completed the following from the main installation guide:

  1. Git installed and configured
  2. Docker or Podman installed and running
  3. Repository cloned via git clone

If you haven’t completed these steps, return to the main page and follow the Requirements and Getting Started sections first.

cd lean-flow-metrics

2. Configure Environment

cp .env.example .env

Edit .env and configure the required settings:

# Container image link (required)
IMAGE_NAME=registry.gitlab.com/tomasz-feliksik/flow-metrics-base/lean-flow-metrics

# Container image version (pinned; `git pull` brings a new one)
RELEASE=9.0.0

# Authentication token (required for accessing the registry)
ACCESS_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx

RELEASE is pinned to a specific version, not latest, so you get the release this checkout was tested against and upgrading is a deliberate git pull — never a silent change under a moving tag. Set RELEASE=latest if you would rather track the newest release, but be aware a major version can change the config schema underneath you (9.0.0 did — see Upgrading).

Optional settings:

How the container sees your files: the runner mounts the current directory into the container at /data, which is the CLI’s working directory. Every path you pass (config files, output) is relative to this directory.

3. Generate Example Configurations

Linux/macOS:

./run_lean_flow_metrics.sh --generate-config-examples

Windows:

.\run_lean_flow_metrics.cmd --generate-config-examples

Why .cmd and not .ps1 on Windows? Stock Windows refuses to run .ps1 files (running scripts is disabled on this system) and opens them in Notepad when double-clicked. run_lean_flow_metrics.cmd is a one-line launcher that hands the same PowerShell script to PowerShell with -ExecutionPolicy Bypass for that launch only — it changes no setting on your machine, and it forwards every argument you give it. So you never have to touch execution policy, and the command line is identical to the Linux and macOS one. Prefer the .ps1 directly? It works unchanged in a PowerShell window where scripts are allowed; if yours blocks them, run powershell -ExecutionPolicy Bypass -File .\run_lean_flow_metrics.ps1 [args], or ask your IT administrator to relax the policy.

This writes annotated examples to configurations/examples/:

Running the script with no arguments prints the CLI’s help.

4. Set Up Your Source Credentials

Create a source YAML (referenced by source_config_file in your dataset config). It declares the source type under the source: envelope — exactly one of jira: or azure_devops:. Copy the annotated template and fill in your values:

# Jira:
cp credentials.jira.yaml.example credentials.yaml          # match your configs' source_config_file
# or Azure DevOps:
cp credentials.azure-devops.yaml.example credentials.yaml

For Jira, the minimum is:

source:
  jira:
    url: https://your-company.atlassian.net # Cloud; or https://jira.your-company.com (Server/DC)
    user: your.email@company.com # email (Cloud) / username (basic); empty for a Server PAT
    auth_method: api_token # api_token (Cloud, default) | basic | pat (Server/DC)
    token: your-jira-api-token # the secret: API token, password, or PAT

Generate your Jira API token at your Atlassian account. The field names are validated strictly (unknown keys are rejected), so use token — not pass. Any value may reference an environment variable as ${NAME} (e.g. token: ${JIRA_TOKEN}), so the secret can live in .env instead of the YAML. See credentials.jira.yaml.example (or credentials.azure-devops.yaml.example) for the full annotated schema: connection tuning, the fields: list, and the optional cache: block.

Two field vocabularies, and they are not interchangeable. A source YAML’s fields: list takes your tracker’s own ids (issuetype, System.Title) because that list is what goes on the wire. A dataset YAML’s fields: list takes canonical names (issue_type, story_points, links). Getting them the wrong way round is caught before any fetch, with an error naming what the source can actually produce.

Comments and links are opt-in on Jira. They are the expensive part of an issue, so neither is fetched unless you set include_comments: true / include_links: true in the source YAML. A dataset that needs one and does not get it is a hard error naming the knob — the blocked-history report needs comments, and the Shipcast export needs links. Azure DevOps always supplies both, so nothing is needed there.

Upgrading an existing configuration? See Upgrading.

5. Configure Your Dataset

Copy an example to configurations/your_dataset.yaml and edit it. The key fields:

name: My Team
source_config_file: source_jira.yaml # the credentials file from step 4
query: <JQL (Jira) or WIQL (Azure DevOps)>

arrival_column: In Progress
departure_column: Done

workflow:
  columns: # ordered map — YAML key order = column order
    Backlog: [Inbox, Prioritized]
    In Progress: [In Progress, In Review]
    Done: [Done]

calculation_rolling_window: 28 # days, used by every rolling-stat chart
throughput_report_window: 0 # 0 disables the throughput CSV export

generate_flow_dashboard: true # write the HTML dashboard

Run --generate-config-examples (step 3) for the fully-commented schema, including caching, blocked-signal configuration, theming, and the Shipcast export block.

6. Generate the Exports

Linux/macOS:

./run_lean_flow_metrics.sh -c configurations/your_dataset.yaml

Windows:

.\run_lean_flow_metrics.cmd -c configurations/your_dataset.yaml

Output files are written to ./output/ by default.


CLI Reference

Arguments are forwarded directly to the lean-flow-metrics binary inside the container. Every example below is written with the Linux/macOS runner; on Windows use .\run_lean_flow_metrics.cmd with exactly the same arguments.

Flag Description
-c, --configuration <FILE> Dataset configuration YAML (required for a run)
-o, --output-path <DIR> Output directory or full filename (default: output)
--datetime-suffix Append __YYYY-MM-DD_HH-MM to every output filename
--generate-config-examples Write example dataset configs to configurations/examples/ and exit
--no-cache Bypass the dataset’s cache for this run
--invalidate-cache Drop the dataset’s cache before fetching
-l, --log-level <LEVEL> debug, info, warn, error (default: info)
--help / --version Print the CLI’s help / version

Run ./run_lean_flow_metrics.sh --help (Windows: .\run_lean_flow_metrics.cmd --help) for the full, authoritative list.


Upgrading

The image version is pinned in .env (RELEASE=), so git pull is what brings a new release — it updates the pinned default and the templates that go with it. Bump RELEASE to match, then run as usual.

To 9.0.0

9.0.0 retires four source-YAML keys. A config still carrying one is rejected when it loads, with the replacement spelled out — nothing is silently ignored, and nothing runs against a half-understood config.

Old key (rejected) Replacement
epic_link_field: customfield_10014 domain_fields: {epic_link: customfield_10014}
story_points_field: customfield_100 domain_fields: {story_points: customfield_100}
parent_field: System.Parent (ADO) domain_fields: {parent: System.Parent} — or delete
field_mappings: (Jira) delete it; select the field by its native id

domain_fields: is one map naming which native field backs a domain concept on your instance. Jira accepts epic_link and story_points; Azure DevOps accepts parent, which already defaults to System.Parent — so most ADO users can simply delete the old key rather than translate it.

Two more changes to know about, neither of which needs an edit:

Also new in 9.0.0, and worth a look: links is a selectable dataset column, creator joins the canonical vocabulary, and connection failures now say what actually went wrong (and which timeout to reach for) instead of one fixed message.

From v4.0.1 or older

The source YAML schema changed shape: the old top-level jira: block with server:/auth_secret: (ADO: organization_url:/access_token:) became the source: envelope shown above with url:/token:. Every release after v4.0.1 rejects the old shape.


Troubleshooting

Issue Solution
running scripts is disabled (Windows) Run .\run_lean_flow_metrics.cmd instead of the .ps1 — it bypasses the policy for that launch only, and takes the same arguments
Double-clicking the runner opens Notepad (Windows) You opened the .ps1; use run_lean_flow_metrics.cmd. It needs arguments, so run it from a terminal rather than double-clicking
Docker permission errors on Linux Add your user to the docker group
Cannot pull container image Verify IMAGE_NAME and ACCESS_TOKEN in .env
IMAGE_NAME is not set error Set IMAGE_NAME in your .env file
missing --configuration error Pass -c configurations/your_dataset.yaml
moved to 'domain_fields' error A retired source-YAML key after upgrading to 9.0.0 — see Upgrading; the error names the fix
A field exports an empty column 9.0.0 rejects unproducible fields up front instead; if you still see one, check the source’s fields: list
Output files owned by root (Linux) The runner already maps your host user via --user; ensure you ran the .sh script (not a raw docker run)
Connection failures Check internet connectivity and firewall settings
Container won’t start Ensure Docker or Podman is running

Resources