Repository navigation
fix: count bot-merged prs and bot-closed issues in development pipes #5028
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ef3ddb9
fix: count bot-merged prs and bot-closed issues in development pipes
joanagmaia 1c194d9
docs: drop the pr duplicate rebuild steps from the lambda doc
joanagmaia 3629481
fix: give the insights app token read access to the count pipes
joanagmaia 0585ef5
fix: keep issue analysis hourly by adding the unmerged daily deltas
joanagmaia 29df5bf
fix: read the whole issue mv delta so the copy pipe passes the push c…
joanagmaia 9029806
fix: formatting
joanagmaia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| DESCRIPTION > | ||
| - `issues_count.pipe` serves the opened and closed counts of the "Development - Issues resolution" widget. | ||
| - Counts issues from `issues_analyzed`, which holds one row per issue, so each issue is counted once per state. | ||
| - Includes issues opened or closed by bots (e.g. stale bots), since `issues_analyzed` is built from the unfiltered activity source. | ||
| - `state` picks the lifecycle timestamp the count is based on: `openedAt` or `closedAt`. Issues without that timestamp are not counted. | ||
| - **When `granularity` is NOT provided, returns a single total count** across the entire time range. | ||
| - **When `granularity` is provided, returns time-series data** aggregated by period (daily, weekly, monthly, quarterly, yearly), using `generate_timeseries` so periods without issues return 0. | ||
| - The pipe scopes data either to a single project (via `segments_filtered`) or to every project in a | ||
| collection (via `segments_filtered_by_collection`). Exactly one of `project`/`collectionSlug` must be given. | ||
| - Parameters: | ||
| - `project`: Project slug (e.g., 'k8s', 'tensorflow') - inherited from `segments_filtered`. Required unless `collectionSlug` is given. | ||
| - `collectionSlug`: Collection slug (e.g., 'cncf') - inherited from `segments_filtered_by_collection`. Required unless `project` is given. | ||
| - `repos`: Optional array of repository URLs for filtering (e.g., ['https://github.com/kubernetes/kubernetes']) | ||
| - `state`: Optional string, one of 'opened' (default) or 'closed' | ||
| - `startDate`: Optional DateTime filter for the `state` timestamp after this value (e.g., '2024-01-01 00:00:00') | ||
| - `endDate`: Optional DateTime filter for the `state` timestamp before this value (e.g., '2024-12-31 23:59:59') | ||
| - `platform`: Optional string filter for source platform (e.g., 'github', 'gitlab') | ||
| - `granularity`: Optional string for time aggregation ('daily', 'weekly', 'monthly', 'quarterly', 'yearly') | ||
| - Response: | ||
| - Without granularity: `issueCount` (total count) | ||
| - With granularity: `startDate`, `endDate`, and `issueCount` for each time period | ||
|
|
||
| TOKEN "insights-app-token" READ | ||
|
|
||
| TAGS "Development metrics", "Widget", "Issues" | ||
|
|
||
| NODE issues_by_state | ||
| SQL > | ||
| % | ||
| SELECT | ||
| id, | ||
| {% if String( | ||
| state, 'opened', description="One of 'opened' or 'closed'", required=False | ||
| ) == 'closed' %} closedAt | ||
| {% else %} openedAt | ||
| {% end %} AS eventAt | ||
| FROM issues_analyzed | ||
| WHERE | ||
| {% if defined(collectionSlug) %} | ||
| segmentId IN (SELECT segmentId FROM segments_filtered_by_collection) | ||
| {% else %} segmentId = (SELECT segmentId FROM segments_filtered) | ||
| {% end %} AND channel IN (SELECT channel FROM repos_to_channels) AND isNotNull(eventAt) | ||
| {% if defined(platform) %} | ||
| AND platform | ||
| = {{ | ||
| String( | ||
| platform, | ||
| description="Filter by platform (e.g., 'github', 'gitlab')", | ||
| required=False, | ||
| ) | ||
| }} | ||
| {% end %} | ||
| {% if defined(startDate) %} | ||
| AND eventAt | ||
| > {{ DateTime(startDate, description="Filter state timestamp after", required=False) }} | ||
| {% end %} | ||
| {% if defined(endDate) %} | ||
| AND eventAt | ||
| < {{ DateTime(endDate, description="Filter state timestamp before", required=False) }} | ||
| {% end %} | ||
|
|
||
| NODE timeseries_generation_for_issues_count | ||
| SQL > | ||
| % | ||
| {% if defined(granularity) %} | ||
| SELECT ds."startDate", ds."endDate", countIf(iss.id != '') AS "issueCount" | ||
| FROM generate_timeseries ds | ||
|
joanagmaia marked this conversation as resolved.
|
||
| LEFT JOIN | ||
| issues_by_state iss | ||
| ON CASE | ||
| WHEN {{ granularity }} = 'daily' | ||
| THEN toDate(iss.eventAt) | ||
| WHEN {{ granularity }} = 'weekly' | ||
| THEN toStartOfWeek(iss.eventAt) | ||
| WHEN {{ granularity }} = 'monthly' | ||
| THEN toStartOfMonth(iss.eventAt) | ||
| WHEN {{ granularity }} = 'quarterly' | ||
| THEN toStartOfQuarter(iss.eventAt) | ||
| WHEN {{ granularity }} = 'yearly' | ||
| THEN toStartOfYear(iss.eventAt) | ||
| END | ||
| = ds."startDate" | ||
| GROUP BY ds."startDate", ds."endDate" | ||
| ORDER BY ds."startDate" | ||
| {% else %} SELECT 1 | ||
| {% end %} | ||
|
|
||
| NODE issues_count_merged | ||
| SQL > | ||
| % | ||
| {% if not defined(granularity) %} SELECT count() AS "issueCount" FROM issues_by_state | ||
| {% else %} SELECT * FROM timeseries_generation_for_issues_count | ||
| {% end %} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| DESCRIPTION > | ||
| - `pull_requests_count.pipe` serves the opened, merged and closed counts of the "Development - Pull requests" widget. | ||
| - Counts pull requests (GitHub PRs, GitLab MRs and Gerrit changesets) from `pull_requests_filtered`. `pull_requests_analyzed` holds one row per PR, so each PR is counted once per state. | ||
| - Includes PRs opened, merged or closed by bots. A PR merged by a bot account (e.g. Prow or a merge queue) counts as merged, since `pull_requests_analyzed` takes `mergedAt` from the merge event whoever performed it. | ||
| - `state` picks the lifecycle timestamp the count is based on: `openedAt`, `mergedAt` or `closedAt`. PRs without that timestamp are not counted. | ||
| - **When `granularity` is NOT provided, returns a single total count** across the entire time range. | ||
| - **When `granularity` is provided, returns time-series data** aggregated by period (daily, weekly, monthly, quarterly, yearly), using `generate_timeseries` so periods without PRs return 0. | ||
| - Parameters: | ||
| - `project`: Project slug (e.g., 'k8s', 'tensorflow') - inherited from `segments_filtered`. Required unless `collectionSlug` is given. | ||
| - `collectionSlug`: Collection slug (e.g., 'cncf') - inherited from `segments_filtered_by_collection`. Required unless `project` is given. | ||
| - `repos`: Optional array of repository URLs for filtering (e.g., ['https://github.com/kubernetes/kubernetes']) | ||
| - `state`: Optional string, one of 'opened' (default), 'merged' or 'closed' | ||
| - `startDate`: Optional DateTime filter for the `state` timestamp after this value (e.g., '2024-01-01 00:00:00') | ||
| - `endDate`: Optional DateTime filter for the `state` timestamp before this value (e.g., '2024-12-31 23:59:59') | ||
| - `platform`: Optional string filter for source platform (e.g., 'github', 'gitlab', 'gerrit') | ||
| - `granularity`: Optional string for time aggregation ('daily', 'weekly', 'monthly', 'quarterly', 'yearly') | ||
| - Response: | ||
| - Without granularity: `pullRequestCount` (total count) | ||
| - With granularity: `startDate`, `endDate`, and `pullRequestCount` for each time period | ||
|
|
||
| TOKEN "insights-app-token" READ | ||
|
|
||
| TAGS "Development metrics", "Widget", "Pull requests" | ||
|
|
||
| NODE pull_requests_by_state | ||
| SQL > | ||
| % | ||
| SELECT | ||
|
joanagmaia marked this conversation as resolved.
|
||
| prf.id, | ||
| {% if String( | ||
| state, | ||
| 'opened', | ||
| description="One of 'opened', 'merged' or 'closed'", | ||
| required=False, | ||
| ) == 'merged' %} prf.mergedAt | ||
| {% elif String( | ||
| state, | ||
| 'opened', | ||
| description="One of 'opened', 'merged' or 'closed'", | ||
| required=False, | ||
| ) == 'closed' %} prf.closedAt | ||
| {% else %} prf.openedAt | ||
| {% end %} AS eventAt | ||
| FROM pull_requests_filtered prf | ||
| WHERE | ||
| isNotNull(eventAt) | ||
| {% if defined(platform) %} | ||
| AND prf.platform | ||
| = {{ | ||
| String( | ||
| platform, | ||
| description="Filter by platform (e.g., 'gerrit', 'github', 'gitlab')", | ||
| required=False, | ||
| ) | ||
| }} | ||
| {% end %} | ||
| {% if defined(startDate) %} | ||
| AND eventAt | ||
| > {{ DateTime(startDate, description="Filter state timestamp after", required=False) }} | ||
| {% end %} | ||
| {% if defined(endDate) %} | ||
| AND eventAt | ||
| < {{ DateTime(endDate, description="Filter state timestamp before", required=False) }} | ||
| {% end %} | ||
|
|
||
| NODE timeseries_generation_for_pull_requests_count | ||
| SQL > | ||
| % | ||
| {% if defined(granularity) %} | ||
| SELECT ds."startDate", ds."endDate", countIf(prs.id != '') AS "pullRequestCount" | ||
| FROM generate_timeseries ds | ||
|
joanagmaia marked this conversation as resolved.
joanagmaia marked this conversation as resolved.
|
||
| LEFT JOIN | ||
| pull_requests_by_state prs | ||
| ON CASE | ||
| WHEN {{ granularity }} = 'daily' | ||
| THEN toDate(prs.eventAt) | ||
| WHEN {{ granularity }} = 'weekly' | ||
| THEN toStartOfWeek(prs.eventAt) | ||
| WHEN {{ granularity }} = 'monthly' | ||
| THEN toStartOfMonth(prs.eventAt) | ||
| WHEN {{ granularity }} = 'quarterly' | ||
| THEN toStartOfQuarter(prs.eventAt) | ||
| WHEN {{ granularity }} = 'yearly' | ||
| THEN toStartOfYear(prs.eventAt) | ||
| END | ||
| = ds."startDate" | ||
| GROUP BY ds."startDate", ds."endDate" | ||
| ORDER BY ds."startDate" | ||
| {% else %} SELECT 1 | ||
| {% end %} | ||
|
|
||
| NODE pull_requests_count_merged | ||
| SQL > | ||
| % | ||
| {% if not defined(granularity) %} SELECT count() AS "pullRequestCount" FROM pull_requests_by_state | ||
| {% else %} SELECT * FROM timeseries_generation_for_pull_requests_count | ||
| {% end %} | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.