Skip to content

feat: introduce GitHubHelper module as first step toward SCM service layer#507

Open
being-iota wants to merge 5 commits intofossasia:mainfrom
being-iota:feat/github-helper-module
Open

feat: introduce GitHubHelper module as first step toward SCM service layer#507
being-iota wants to merge 5 commits intofossasia:mainfrom
being-iota:feat/github-helper-module

Conversation

@being-iota
Copy link
Copy Markdown

@being-iota being-iota commented Mar 31, 2026

This PR introduces a basic GitHubHelper module as a first step toward modularizing GitHub-specific logic.

Currently, GitHub-related functionality is tightly coupled within scrumHelper.js, which makes it difficult to extend support to other SCM platforms like GitLab or Bitbucket.

Changes:

  • Add src/scripts/githubHelper.js with GitHubHelper class
  • Move fetchUserRepositories into GitHubHelper.fetchUserRepositories()
  • Expose window.gitHubHelper instance and backward-compat shim for window.fetchUserRepositories so popup.js needs zero changes
  • Register githubHelper.js in popup.html and both manifests before scrumHelper.js

This change lays the foundation for extracting GitHub logic into a reusable service layer, enabling future multi-SCM support.

Fixes

Part of #495

Summary by Sourcery

Extract GitHub-specific repository fetching into a dedicated GitHubHelper service and wire it into the extension while preserving backwards compatibility.

Enhancements:

  • Introduce a GitHubHelper class encapsulating GitHub API logic for fetching user-contributed repositories.
  • Remove the inline fetchUserRepositories implementation from scrumHelper in favor of using the shared GitHubHelper instance and a backward-compatible window.fetchUserRepositories shim.
  • Register githubHelper.js in the popup and manifests so GitHubHelper is loaded before scrumHelper and popup scripts, preparing for a future SCM service layer.

…layer

This PR introduces a basic GitHubHelper module as a first step toward
modularizing GitHub-specific logic.

Currently, GitHub-related functionality is tightly coupled within
scrumHelper.js, which makes it difficult to extend support to other
SCM platforms like GitLab or Bitbucket.

Changes:
- Add src/scripts/githubHelper.js with GitHubHelper class
- Move fetchUserRepositories into GitHubHelper.fetchUserRepositories()
- Expose window.gitHubHelper instance and backward-compat shim for
  window.fetchUserRepositories so popup.js needs zero changes
- Register githubHelper.js in popup.html and both manifests before
  scrumHelper.js

This change lays the foundation for extracting GitHub logic into a
reusable service layer, enabling future multi-SCM support.
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Mar 31, 2026

Reviewer's Guide

Extracts GitHub-specific repo fetching logic from scrumHelper into a new reusable GitHubHelper service module, wires it into the extension bootstrap, and preserves backward-compatible globals for existing popup behavior.

Sequence diagram for GitHubHelper.fetchUserRepositories flow

sequenceDiagram
    actor User
    participant PopupUI as popupJs
    participant GitHubHelper as gitHubHelper
    participant BrowserStorage as browser_storage
    participant GitHubREST as github_search_api
    participant GitHubGraphQL as github_graphql_api

    User->>PopupUI: trigger repo filtering
    PopupUI->>GitHubHelper: fetchUserRepositories(username, token, org)

    GitHubHelper->>BrowserStorage: storage.local.get(startingDate, endingDate, yesterdayContribution)
    BrowserStorage-->>GitHubHelper: date range settings

    GitHubHelper->>GitHubREST: GET /search/issues (author query)
    GitHubHelper->>GitHubREST: GET /search/issues (commenter query)
    GitHubREST-->>GitHubHelper: issues and comments

    GitHubHelper->>GitHubGraphQL: POST /graphql (batched repo queries)
    GitHubGraphQL-->>GitHubHelper: repo metadata

    GitHubHelper-->>PopupUI: sorted list of repositories
    PopupUI-->>User: render repo list

    note over PopupUI,GitHubHelper: window.fetchUserRepositories(username, token, org) calls gitHubHelper.fetchUserRepositories
Loading

Class diagram for new GitHubHelper service module

classDiagram
    class GitHubHelper {
        +fetchUserRepositories(username, token, org) Promise
    }

    class WindowGlobal {
        +GitHubHelper
        +gitHubHelper
        +fetchUserRepositories(username, token, org) Promise
    }

    GitHubHelper <.. WindowGlobal : constructor reference
    GitHubHelper <.. WindowGlobal : gitHubHelper instance
    GitHubHelper <.. WindowGlobal : fetchUserRepositories delegation
Loading

File-Level Changes

Change Details Files
Introduce GitHubHelper service module and move fetchUserRepositories logic into it with improved logging and error handling.
  • Create GitHubHelper class encapsulating GitHub API calls, currently implementing fetchUserRepositories
  • Port existing fetchUserRepositories implementation from scrumHelper into GitHubHelper, refactoring for clearer date-range handling and log messages
  • Use GitHub Search API plus GraphQL to resolve contributed repositories and sort them by last update
  • Standardize error handling to log and return an empty array on failure instead of swallowing errors silently
  • Support both CommonJS export (for tests/Node) and browser global usage via window.GitHubHelper and a shared window.gitHubHelper instance
src/scripts/githubHelper.js
Remove the inlined fetchUserRepositories implementation from scrumHelper while keeping compatibility via a global shim.
  • Delete the fetchUserRepositories function implementation from scrumHelper.js, leaving only a comment pointing to GitHubHelper
  • Remove assignment of window.fetchUserRepositories at the end of scrumHelper.js, since the shim is now provided by GitHubHelper
src/scripts/scrumHelper.js
Wire the new GitHubHelper script into the extension HTML and manifest loading order so it is available before scrumHelper/popup code executes.
  • Register githubHelper.js in popup.html before scrumHelper.js and popup.js to ensure globals are initialized before usage
  • Add githubHelper.js to the browser extension manifests so it is loaded as part of the extension scripts (Chrome and Firefox JSON manifests)
src/popup.html
src/manifests/chrome.json
src/manifests/firefox.json

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions Bot added javascript Pull requests that update javascript code core frontend extension labels Mar 31, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • GitHubHelper currently depends directly on browser.storage.local and window, which makes it harder to reuse or unit-test; consider passing storage and environment objects into the constructor so the helper is less tightly coupled to the extension runtime.
  • The fetchUserRepositories method hard-codes a limit of 50 repos from repoNames.slice(0, 50); it would be clearer to extract this into a named constant or parameter and document the trade-off so future changes don’t inadvertently change behavior.
  • The global exports block mixes CommonJS (module.exports) with assignment to window.*; to avoid surprising behavior in different environments, consider centralizing this in a small wrapper or using a single export strategy with a thin browser-specific bootstrap script.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- GitHubHelper currently depends directly on `browser.storage.local` and `window`, which makes it harder to reuse or unit-test; consider passing storage and environment objects into the constructor so the helper is less tightly coupled to the extension runtime.
- The `fetchUserRepositories` method hard-codes a limit of 50 repos from `repoNames.slice(0, 50)`; it would be clearer to extract this into a named constant or parameter and document the trade-off so future changes don’t inadvertently change behavior.
- The global exports block mixes CommonJS (`module.exports`) with assignment to `window.*`; to avoid surprising behavior in different environments, consider centralizing this in a small wrapper or using a single export strategy with a thin browser-specific bootstrap script.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

- Inject storage via constructor (storage = browser.storage.local) to remove tight coupling and enable testing without a real browser
- Replace hardcoded .slice(0, 50) with MAX_REPOS constant
- Add clarifying comment on dual export (browser + Node compatibility)
@mariobehling mariobehling requested a review from Copilot April 11, 2026 11:13
@mariobehling
Copy link
Copy Markdown
Member

Thanks for the contribution!

A process note.

We have automatic Copilot PR reviews enabled on this repository. These reviews are only triggered if the contributor has GitHub Copilot enabled and an active license on their own account.

Please enable Copilot in your GitHub settings if you have access. In many regions, free licenses are available through educational institutions or developer programs. Enabling Copilot helps us speed up the auto review process and reduces manual review overhead for the core team.

Copy link
Copy Markdown
Member

@mariobehling mariobehling left a comment

Choose a reason for hiding this comment

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

Please resolve conflicts and address AI reviews.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces a new GitHubHelper module to begin separating GitHub-specific logic from scrumHelper.js, while keeping existing popup behavior working via a backward-compat window.fetchUserRepositories shim.

Changes:

  • Added src/scripts/githubHelper.js with a GitHubHelper class and fetchUserRepositories() implementation plus a global shim/instance.
  • Removed the inline fetchUserRepositories implementation from src/scripts/scrumHelper.js.
  • Registered githubHelper.js to load before scrumHelper.js in popup.html and both browser manifests.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/scripts/scrumHelper.js Removes the embedded GitHub repo-fetching function and relies on the helper-provided shim.
src/scripts/githubHelper.js Adds a GitHub-specific helper class and global instance/shim for repository discovery.
src/popup.html Loads githubHelper.js before scrumHelper.js so the shim is available.
src/manifests/firefox.json Ensures githubHelper.js is loaded before scrumHelper.js in content scripts.
src/manifests/chrome.json Ensures githubHelper.js is loaded before scrumHelper.js in content scripts.
.vscode/settings.json Adds a (currently empty) VS Code workspace settings file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/scripts/githubHelper.js Outdated
Comment on lines +5 to +7
* This is the first step toward a generic SCM service layer — mirroring the
* existing GitLabHelper pattern so scrumHelper.js can eventually call either
* platform through a unified interface.
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

The header comment says this helper is “mirroring the existing GitLabHelper pattern”, but GitLabHelper currently only exposes the class (no shared instance/shim) and is instantiated inside scrumHelper.js. Please update this comment to reflect the actual pattern being used here (or align the implementations) to avoid misleading future refactors toward the SCM service layer.

Suggested change
* This is the first step toward a generic SCM service layer mirroring the
* existing GitLabHelper pattern so scrumHelper.js can eventually call either
* platform through a unified interface.
* This extracts GitHub-specific behavior into a helper class and, in the
* browser context, exposes a shared instance plus a backward-compatibility
* shim for existing callers in popup.js and scrumHelper.js.

Copilot uses AI. Check for mistakes.
Comment thread src/scripts/githubHelper.js Outdated
* @param {object} storage - Storage backend (defaults to browser.storage.local).
* Injected to avoid tight coupling and enable testing without a real browser env.
*/
constructor(storage = browser.storage.local) {
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

constructor(storage = browser.storage.local) will throw a ReferenceError in Node/test environments where browser is undefined, which undermines the “Node.js (test) compatibility” note later in the file. Consider defaulting via globalThis.browser?.storage?.local (or requiring an injected storage in non-extension contexts) so new GitHubHelper() is safe outside WebExtension runtimes.

Suggested change
constructor(storage = browser.storage.local) {
constructor(storage = globalThis.browser?.storage?.local) {

Copilot uses AI. Check for mistakes.
Comment thread .vscode/settings.json Outdated
Comment on lines +1 to +2
{
} No newline at end of file
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

This workspace settings file is currently an empty object and has no effect. If there are no intended VS Code settings to commit, consider removing it to avoid adding noise / implying editor-specific configuration.

Suggested change
{
}

Copilot uses AI. Check for mistakes.
…ection, extract MAX_REPOS

- Change constructor default to globalThis.browser?.storage?.local for safer optional chaining
- Replace browser.storage.local.get with this.storage.get throughout
- Update header comment to describe actual module purpose
- Remove .vscode/settings.json from tracking
Kept our version: window.fetchUserRepositories is now provided by
githubHelper.js as a backward-compat shim, so the old global
assignment in scrumHelper.js is intentionally removed.
@being-iota
Copy link
Copy Markdown
Author

Hi, @mariobehling!
I have addressed the Copilot AI feedback and resolved the requested changes:

  1. Constructor Optimization: Updated to globalThis.browser?.storage?.local to ensure compatibility across Node.js/Test and Browser environments.
  2. Header Documentation: Refined the documentation to accurately reflect the backward-compatibility shim pattern.
  3. Cleanup: Removed the redundant .vscode/settings.json and resolved all merge conflicts with the main branch.

Ready for your review!

@Ahmar004
Copy link
Copy Markdown

Ahmar004 commented Apr 19, 2026

"This change lays the foundation for extracting GitHub logic into a reusable service layer, enabling future multi-SCM support."

Hi @being-iota, my proposed solution as part of GSOC in the issue #495 is much similar to your approach in this PR.
To be honest, I just found out about this PR #507 about an hour ago, otherwise I would have loved to contribute and provide some help here from the beginning.

Implementing a service layer/shared interface which is independent of the SCM platform would be the best option, as it would allow easier addition of new SCM platforms in the future, like GitLab, Gitea, bitBucket and more...

Congrats on this PR though!

I am assuming that you have already verified (Locally) that the extension works well after the proposed changes in #507, but still, I would love to provide a secondary verification to help get this PR merged soon!

I am currently testing it locally by cloning from https://github.com/being-iota/scrum_helper/tree/feat/github-helper-module

In a while, I would share screenshots of the running extension here in the comments to help provide an additional verification about extension working fine locally, and hopefully this would be merged by @mariobehling soon.

@Ahmar004
Copy link
Copy Markdown

Ahmar004 commented Apr 20, 2026

Hi @mariobehling and @being-iota,

I have locally tested the extension after the changes that was done by @being-iota.
I cloned the branch from: https://github.com/being-iota/scrum_helper/tree/feat/github-helper-module

Here are the Results:
Everything is working Fine, except for the "Insert to Email" Button.

Needs fix: "Insert to Email Button" only, everything else is working.

Please refer to the screenshots attached to see the results:

  1. Extension is loading properlyExtension_loading

  2. Generate Report is workingReport_Working

  3. Dark mode is working:Dark_theme_running

  4. The copy Button is working: Copy_Button_working

  5. Pop-up style workingPopup_working

  6. The "Insert to Email" Button is not working:Insert_to_email_Button_NOT_WORKING

@mariobehling and @being-iota, Tomorrow I will try to figure out why the "Insert to Email" button is not working, and help resolve it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core extension frontend javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants