ETL pipelines for engineering metrics. Extracts data from JIRA and GitHub, computing metrics such as cycle time, bug counts, and PR statistics, with summaries broken down by month, quarter, severity, contributor, and team.
npm install
cp .env.example .env
# Edit .env with your JIRA and GitHub credentialsAfter configuring your .env, verify that your credentials work:
npm run check-tokenThis will confirm your JIRA connection and display the authenticated user. Fix any errors before running pipelines — common issues:
- Authentication failed — double-check
JIRA_EMAILandJIRA_API_TOKEN - Access denied — your account may lack the required JIRA permissions
- Cannot reach JIRA — verify
JIRA_BASE_URLis correct (e.g.,https://fariaedu.atlassian.net)
| Variable | Required | Description |
|---|---|---|
JIRA_BASE_URL |
Yes | Your Atlassian instance URL (e.g., https://fariaedu.atlassian.net) |
JIRA_EMAIL |
Yes | Email associated with your Atlassian account |
JIRA_API_TOKEN |
Yes | JIRA Cloud API token (generate one here) |
GITHUB_TOKEN |
Yes (for github-prs) |
GitHub personal access token with repo scope (generate one here) |
NEWRELIC_API_KEY |
Yes (for newrelic-sla) |
New Relic User API key (generate one here) |
NEWRELIC_ACCOUNT_ID |
Yes (for newrelic-sla) |
New Relic account ID |
Each team key has pipeline-specific settings. Teams only need sections for the pipelines they use:
MB:
jira-cycle-time:
startStatus: Ready For Development
endStatus: Closed
filter: # optional JQL fragment
jira-bugs:
severityFieldName: "Severity"
customerBugsFilter: >-
issuetype = Bug
AND resolution IN (Done, Unresolved)
AND labels = jira_escalated
github-prs:
repos:
- eduvo/managebac # owner/repo format
newrelic-sla:
apps:
- ManageBac Canada # New Relic application nameWhen running without --team, each pipeline auto-discovers all teams that have its config section.
Extracts resolved JIRA issues and computes cycle time (time between configured start and end status transitions). Produces per-team and cross-team summaries broken down by month, quarter, and overall totals.
# All configured teams
npm run etl -- jira-cycle-time --since 2026-01-01
# Single team with date range
npm run etl -- jira-cycle-time --team MB --since 2026-01-01 --until 2026-03-31Options:
| Flag | Required | Default | Description |
|---|---|---|---|
-t, --team <key> |
No | all configured | Team key (JIRA project key) |
-s, --since <date> |
No | 2026-02-09 |
Start date for resolved issues (YYYY-MM-DD) |
-u, --until <date> |
No | — | End date for resolved issues (YYYY-MM-DD) |
Config options:
| Key | Required | Description |
|---|---|---|
startStatus |
Yes | Status marking cycle start (case-insensitive) |
endStatus |
Yes | Status marking cycle end (case-insensitive) |
filter |
No | Additional JQL fragment AND-ed into the query |
Summary output: ticket count, average and median cycle time — per team per month, per team per quarter, per team total, cross-team per month, cross-team per quarter, and cross-team total.
Counts customer-reported bugs matching a configurable JQL filter, broken down by severity. Produces per-team and cross-team summaries by month and overall.
# All configured teams
npm run etl -- jira-bugs --since 2026-01-01
# Single team
npm run etl -- jira-bugs --team MB --since 2026-01-01Options:
| Flag | Required | Default | Description |
|---|---|---|---|
-t, --team <key> |
No | all configured | Team key (JIRA project key) |
-s, --since <date> |
No | 2026-02-09 |
Start date for created issues (YYYY-MM-DD) |
-u, --until <date> |
No | — | End date for created issues (YYYY-MM-DD) |
Config options:
| Key | Required | Description |
|---|---|---|
customerBugsFilter |
Yes | JQL fragment AND-ed with project + date range |
severityFieldName |
Yes | JIRA field name for the Severity dropdown (resolved to field ID at runtime) |
Summary output: total bugs and median time-to-resolve per severity — per team per month, per team total, cross-team per month, and cross-team total. Severity values are the first two characters of the JIRA field value (e.g., S1, S2).
Extracts closed/merged pull requests from GitHub repositories and computes PR statistics. Produces per-team and cross-team summaries broken down by month, quarter, and overall totals.
# All configured teams
npm run etl -- github-prs --since 2026-01-01
# Single team with date range
npm run etl -- github-prs --team MB --since 2026-01-01 --until 2026-03-31Options:
| Flag | Required | Default | Description |
|---|---|---|---|
-t, --team <key> |
No | all configured | Team key (as in config.yaml) |
-s, --since <date> |
No | 2026-02-09 |
Start date for closed PRs (YYYY-MM-DD) |
-u, --until <date> |
No | — | End date for closed PRs (YYYY-MM-DD) |
Config options:
| Key | Required | Description |
|---|---|---|
repos |
Yes | List of GitHub repositories in owner/repo format |
Summary output: PR count, average and median time-to-close (days), PRs per contributor — per team per month, per team per quarter, per team total, cross-team per month, cross-team per quarter, and cross-team total.
Extracts APM SLA metrics (Apdex, satisfied %, error rate %, response time, throughput) from the New Relic REST API v2 and browser error rates from NerdGraph (NRQL). SLA data is fetched per calendar month within the date range; browser errors cover the last 7 days only.
# All configured teams
npm run etl -- newrelic-sla --since 2026-01-01
# Single team with date range
npm run etl -- newrelic-sla --team MB --since 2026-01-01 --until 2026-03-01Options:
| Flag | Required | Default | Description |
|---|---|---|---|
-t, --team <key> |
No | all configured | Team key (as in config.yaml) |
-s, --since <date> |
No | 2026-02-09 |
Start date (YYYY-MM-DD) |
-u, --until <date> |
No | — | End date (YYYY-MM-DD) |
Config options:
| Key | Required | Description |
|---|---|---|
apps |
Yes | List of New Relic application names to fetch metrics for |
Summary output: Per team per month: Apdex, satisfied %, error rate %, response time (ms), throughput (rpm) for each app. Per team average across the full time window. Cross-team average error rate %. Browser error rate per app (last 7 days only).
Results are written as JSON to data/<pipeline-name>-<timestamp>.json, containing both summary and records.
- Create a new directory under
src/pipelines/(e.g.,src/pipelines/github/) - Extend the
Pipelinebase class fromsrc/pipelines/base.ts - Implement
extract(),transform(),summarize(), andload()methods - Register a new command in
src/index.ts
See docs/architecture.md for detailed architecture documentation.