Skip to content

Track SDLC metrics.#31409

Merged
eashaw merged 30 commits into
mainfrom
victor/30483-sdlc-metrics
Aug 19, 2025
Merged

Track SDLC metrics.#31409
eashaw merged 30 commits into
mainfrom
victor/30483-sdlc-metrics

Conversation

@getvictor
Copy link
Copy Markdown
Member

@getvictor getvictor commented Jul 30, 2025

Fixes #30483

Summary by CodeRabbit

  • New Features

    • Added a new webhook endpoint to track GitHub Projects v2 item status changes and record engineering metrics.
    • Integrated with Google BigQuery for storing and analyzing issue status transition data.
  • Chores

    • Introduced a new POST API route for receiving GitHub Projects v2 item events.
    • Added configuration options for GitHub webhook secrets and Google Cloud service account keys (commented out for future use).
    • Added a new dependency for Google BigQuery integration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 30, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

A new webhook endpoint was added to receive GitHub Projects v2 item events, focusing on tracking status changes for specific projects. The handler verifies signatures, processes status transitions, fetches issue details, calculates time metrics, and writes results to Google BigQuery. Supporting configuration and dependencies were updated.

Changes

Cohort / File(s) Change Summary
Webhook Handler Implementation
website/api/controllers/webhooks/receive-github-projects-v2-item.js
Adds a webhook controller to process GitHub Projects v2 item events, verify signatures, track status changes, calculate metrics, and save to BigQuery.
Configuration Additions
website/config/custom.js
Adds commented-out configuration keys for the GitHub webhook secret and GCP service account key for engineering metrics.
Route Registration
website/config/routes.js
Registers a new POST route for the GitHub Projects v2 item webhook endpoint, disabling CSRF protection.
Dependency Update
website/package.json
Adds the @google-cloud/bigquery dependency to support BigQuery operations.

Sequence Diagram(s)

sequenceDiagram
    participant GitHub
    participant WebhookController as Webhook handler
    participant GitHubAPI as GitHub GraphQL API
    participant BigQuery

    GitHub->>WebhookController: POST /api/v1/webhooks/github/projects_v2_item
    WebhookController->>WebhookController: Verify signature
    alt Valid and projects_v2_item event
        WebhookController->>GitHubAPI: Fetch issue details
        WebhookController->>BigQuery: Check for existing records
        alt Status changed to "in progress"
            WebhookController->>BigQuery: Save status change record
        else Status changed to "awaiting qa"
            WebhookController->>BigQuery: Calculate time from "in progress"
            WebhookController->>BigQuery: Save QA ready metrics
        else Status changed to "release"
            WebhookController->>BigQuery: Calculate time from "in progress"
            WebhookController->>BigQuery: Save release ready metrics
        end
    end
    WebhookController-->>GitHub: Respond with status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Track GitHub Project V2 status changes via webhook, update BigQuery, calculate time to QA ready and release ready (#30483)
Use BigQuery as analytical datastore for engineering metrics (#30483)
Subscribe to "projects_v2_item" event and process status transitions for tracked projects (#30483)
Calculate and store time metrics for status transitions (QA ready, release ready) (#30483)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes were found.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch victor/30483-sdlc-metrics

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@getvictor
Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 3, 2025

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
website/api/controllers/webhooks/receive-github-projects-v2-item.js (2)

12-14: Consider moving the weekend exclusion flag to configuration.

The EXCLUDE_WEEKENDS feature flag is currently hardcoded. Moving it to sails.config.custom would make it easier to adjust without code changes.

-// Feature flag for excluding weekends in time calculations
-// Set to true to exclude weekends, false to include them
-const EXCLUDE_WEEKENDS = false;
+// Get weekend exclusion setting from config (default to false)
+const EXCLUDE_WEEKENDS = sails.config.custom.excludeWeekendsInMetrics || false;

613-813: Consider refactoring to reduce code duplication.

The three check functions (checkIfIssueExists, checkIfQaReadyExists, checkIfReleaseReadyExists) share almost identical logic. A generic helper function could reduce duplication.

// Add a generic helper function
async function checkIfRecordExists(repo, issueNumber, gcpServiceAccountKey, tableId, additionalCondition = '') {
  try {
    const bigquery = getBigQueryClient(gcpServiceAccountKey);
    const datasetId = 'github_metrics';
    
    const query = `
      SELECT 1
      FROM \`${gcpServiceAccountKey.project_id}.${datasetId}.${tableId}\`
      WHERE repo = @repo
        AND issue_number = @issueNumber
        ${additionalCondition}
      LIMIT 1
    `;
    
    const options = {
      query: query,
      params: { repo, issueNumber }
    };
    
    const [rows] = await bigquery.query(options);
    return rows.length > 0;
  } catch (err) {
    if (err.code === 404) {
      return false;
    }
    sails.log.error(`Error checking if record exists in ${tableId}:`, err);
    return false;
  }
}

// Then simplify the existing functions:
async function checkIfIssueExists(repo, issueNumber, gcpServiceAccountKey) {
  return checkIfRecordExists(repo, issueNumber, gcpServiceAccountKey, 'issue_status_change', "AND status = 'in_progress'");
}

async function checkIfQaReadyExists(repo, issueNumber, gcpServiceAccountKey) {
  return checkIfRecordExists(repo, issueNumber, gcpServiceAccountKey, 'issue_qa_ready');
}

async function checkIfReleaseReadyExists(repo, issueNumber, gcpServiceAccountKey) {
  return checkIfRecordExists(repo, issueNumber, gcpServiceAccountKey, 'issue_release_ready');
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 774dfb8 and d645409.

📒 Files selected for processing (4)
  • website/api/controllers/webhooks/receive-github-projects-v2-item.js (1 hunks)
  • website/config/custom.js (1 hunks)
  • website/config/routes.js (1 hunks)
  • website/package.json (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build-binaries
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: build (20.x)
🔇 Additional comments (8)
website/package.json (1)

8-8: BigQuery dependency version verified

I checked the npm registry and GitHub security advisories. Version 8.1.1 is the latest release and there are no known vulnerabilities. 🎉

You can safely keep "@google-cloud/bigquery": "^8.1.1" in your website/package.json.

website/config/routes.js (1)

996-996: Route configuration looks good!

The webhook route follows the established pattern and correctly disables CSRF protection, which is standard for webhook endpoints that use signature verification.

website/config/custom.js (1)

409-414: Configuration keys are well-organized.

The new configuration keys for the GitHub Projects v2 webhook secret and GCP service account are properly placed in their respective sections and follow the existing naming conventions.

website/api/controllers/webhooks/receive-github-projects-v2-item.js (5)

129-160: Webhook signature verification is properly implemented.

The verification uses timing-safe comparison and appropriate error handling, following security best practices.


205-281: Status change processing logic is well-structured.

The function properly validates inputs, filters for relevant projects and status changes, and delegates to appropriate handlers.


284-356: GraphQL query for issue details is efficient.

The function makes good use of GraphQL to fetch only the necessary fields and properly determines issue types from labels.


567-595: Error handling for BigQuery is comprehensive.

The function properly handles various error scenarios and includes a smart recovery mechanism by resetting the client on connection errors.


367-565: Status transition handlers implement the business logic correctly.

The handlers properly track status transitions, calculate time metrics, and prevent duplicate entries as required by the PR objectives.

Comment thread website/api/controllers/webhooks/receive-github-projects-v2-item.js Outdated
Comment thread website/api/controllers/webhooks/receive-github-projects-v2-item.js Outdated
Comment thread website/api/controllers/webhooks/receive-github-projects-v2-item.js Outdated
@getvictor getvictor marked this pull request as ready for review August 5, 2025 08:50
Comment thread website/package.json Outdated
Comment thread website/config/custom.js
// mergeFreezeAccessToken: '…',

// Metrics:
// engMetricsGcpServiceAccountKey: '…',
Copy link
Copy Markdown
Member

@mikermcneil mikermcneil Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

env vars:

sails_custom__githubProjectsV2ItemWebhookSecret
sails_custom__engMetricsGcpServiceAccountKey

Comment thread website/api/controllers/webhooks/receive-github-projects-v2-item.js Outdated
Comment thread website/api/controllers/webhooks/receive-github-projects-v2-item.js Outdated
Comment thread website/api/controllers/webhooks/receive-github-projects-v2-item.js Outdated
@Sampfluger88 Sampfluger88 removed their request for review August 18, 2025 17:53
fleet-release
fleet-release previously approved these changes Aug 19, 2025
@eashaw eashaw dismissed their stale review August 19, 2025 18:00

Requested changes have been made

Copy link
Copy Markdown
Contributor

@eashaw eashaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@getvictor, I made some changes to this PR to make it match the other code in that file and website conventions to get it merged. I tested and QA'd all updated behavior with a GH webhook pointed at my local instance of the website and a throwaway BigQuery dataset.

Here's a list of changes I made:

  • Added an error that is thrown if sails.config.custom.engMetricsGcpServiceAccountKey is not set.
  • Removed the parse-gcp-service-account-key, fetch-issue-details, get-big-query-client, get-latest-in-progress-status, and calculate-time-including-weekends helpers and moved them inline in the webhook. We deduplicate code with helpers if it is repeated in 3+ places. (These helpers were only being used in 1-2 places)
  • Removed the try-catch block so we would be alerted to any unexpected errors in the added code.
  • Changed messages logged with sails.log.error() to use sails.log.warn(). We don't have alerts configured for messages logged by sails.log.error(), but I am alerted in the help-p2 channel when a warning is logged.
  • Updated the warnings and error messages to include more context about what caused the error/warning.

@eashaw
Copy link
Copy Markdown
Contributor

eashaw commented Aug 19, 2025

FYI: @getvictor, I'm merging this PR.

If we need to create a new webhook for this, it should use the same URL as the webhook in the Fleet repo, and it needs to send payloads in JSON.

@eashaw eashaw merged commit a07f8f5 into main Aug 19, 2025
8 checks passed
@eashaw eashaw deleted the victor/30483-sdlc-metrics branch August 19, 2025 18:24
BCTBB pushed a commit that referenced this pull request Aug 19, 2025
Fixes #30483 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added a new webhook endpoint to track GitHub Projects v2 item status
changes and record engineering metrics.
* Integrated with Google BigQuery for storing and analyzing issue status
transition data.

* **Chores**
* Introduced a new POST API route for receiving GitHub Projects v2 item
events.
* Added configuration options for GitHub webhook secrets and Google
Cloud service account keys (commented out for future use).
  * Added a new dependency for Google BigQuery integration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Eric <eashaw@sailsjs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Track SDLC metrics: time to QA ready, time to release ready

4 participants