Skip to content

github: move all GitHub logic to dedicated class (bug 1996507, bug 1995679)#604

Merged
shtrom merged 18 commits intozeid/bug-1989635-github-pr-pilotfrom
no-bug/github-api-url-parsing
Nov 3, 2025
Merged

github: move all GitHub logic to dedicated class (bug 1996507, bug 1995679)#604
shtrom merged 18 commits intozeid/bug-1989635-github-pr-pilotfrom
no-bug/github-api-url-parsing

Conversation

@shtrom
Copy link
Copy Markdown
Member

@shtrom shtrom commented Oct 14, 2025

  • add a GitHub object allowing to renew tokens, parse URLs, and generate authenticated URLs
  • also add a pre-authenticated session attribute to the GitHubAPI object
  • utils: move URL_USERINFO_RE to const (bug 1995679)
  • utils: add basic test for github classes

@shtrom shtrom requested a review from zzzeid October 14, 2025 02:02
@shtrom shtrom force-pushed the no-bug/github-api-url-parsing branch 3 times, most recently from d89e879 to 8ce72bd Compare October 14, 2025 02:14
@shtrom shtrom force-pushed the no-bug/github-api-url-parsing branch from e0cd493 to 97f0d2f Compare October 14, 2025 06:27
@shtrom shtrom marked this pull request as ready for review October 14, 2025 06:28
Comment thread src/lando/utils/github.py Outdated
Comment on lines +27 to +31
# NOTE: This RE takes care of removing the '.git' suffix, to provide normalised URLs.
GITHUB_URL_RE = re.compile(
f"https://{URL_USERINFO_RE.pattern}?github.com/(?P<owner>[-A-Za-z0-9]+)/(?P<repo>[^/]+)(.git)?"
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See #536 (comment). I think it would simplify things if we did much of this in the Repo class. We could simply pass the repo name and owner directly to this API class and avoid doing any parsing here.

If we need the repo URL we can generate it manually with this info.

Side note, the Repo class already has a method to normalize the URL (Repo.normalized_url and also Repo._github_repo_url).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I agree that passing the owner and repo name strings is better than passing a Repo, and achieves the initial decoupling objective.

However, I think it may be better to do all the bespoke URL parsing in the GitHub class, so we have all the GitHub logic there. If we just pass a URL with no additional parsing needed, we can hide all the inner workings of GitHub in one location.

This also opens up the way for... supporting another hosting platform, where we could have HostingPlatformAPI.supports_url(url) , much like how GitHubAPI.is_github_url (we could acctually rename that method to match) is used to simplify the bespoke logic in here https://github.com/mozilla-conduit/lando/pull/604/files#diff-2337f63ffc234b7c7cbd13e6ab6f4e1122832768b9ea5250508f5830a5bf71e5L111-R109 This is obviously not needed at the moment, but it would make it easier to handle if ever needed.

I guess the flip side to my argument is if we need the repo_owner and repo_name anywhere outside of the GitHubAPI interaction. I suspect it's not the case, but I may be missing something.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah, with the GitHub class, we can now get them out if needed:

github_repo = GitHub(<URL>)
github_repo.repo_owner
github_repo.repo_name

zzzeid
zzzeid previously requested changes Oct 21, 2025
Comment thread src/lando/utils/github.py Outdated
Comment thread src/lando/utils/github.py
Comment thread src/lando/utils/github.py
@zzzeid zzzeid force-pushed the zeid/bug-1989637-github-api-client branch 4 times, most recently from 73a4727 to af52580 Compare October 21, 2025 19:50
@shtrom shtrom force-pushed the no-bug/github-api-url-parsing branch 2 times, most recently from 640470f to 13666dc Compare October 22, 2025 04:20
@shtrom shtrom dismissed zzzeid’s stale review October 22, 2025 04:20

added utils.github.GitHub class for common URL and token logic

@shtrom
Copy link
Copy Markdown
Member Author

shtrom commented Oct 22, 2025

@zzzeid I had to rebase, as it applied orders of magnitude more cleanly than merging the base branch back in.

There is just a single commit added 064c7da to add the GitHub class, which the GitHubAPI now inherits from.

@shtrom shtrom force-pushed the no-bug/github-api-url-parsing branch 2 times, most recently from fbc2cc7 to 064c7da Compare October 22, 2025 04:31
@shtrom shtrom requested a review from zzzeid October 22, 2025 04:42
@shtrom shtrom changed the title GitSCM/GitHubAPI: move all github logic to dedicated class github: move all github logic to dedicated class Oct 22, 2025
@shtrom shtrom changed the title github: move all github logic to dedicated class github: move all GitHub logic to dedicated class Oct 22, 2025
Base automatically changed from zeid/bug-1989637-github-api-client to zeid/bug-1989635-github-pr-pilot October 22, 2025 13:04
@zzzeid
Copy link
Copy Markdown
Contributor

zzzeid commented Oct 24, 2025

@zzzeid I had to rebase, as it applied orders of magnitude more cleanly than merging the base branch back in.

There is just a single commit added 064c7da to add the GitHub class, which the GitHubAPI now inherits from.

I'm going to re-apply the two commits in this branch to the new base (i.e., c1cda56 and 064c7da).

@zzzeid zzzeid force-pushed the no-bug/github-api-url-parsing branch from 064c7da to 9b607e8 Compare October 24, 2025 18:56
zzzeid
zzzeid previously requested changes Oct 24, 2025
Comment thread src/lando/utils/github.py Outdated
Comment thread src/lando/utils/github.py
@shtrom shtrom changed the title github: move all GitHub logic to dedicated class github: move all GitHub logic to dedicated class (bug 1996507) Oct 27, 2025
@shtrom shtrom changed the title github: move all GitHub logic to dedicated class (bug 1996507) github: move all GitHub logic to dedicated class (bug 1996507, bug 1995679) Oct 27, 2025
@shtrom shtrom dismissed zzzeid’s stale review October 27, 2025 06:59

added utils.const for URL_USERINFO_RE, and updated PR description

@shtrom shtrom force-pushed the no-bug/github-api-url-parsing branch from 9d1fb16 to b57ce51 Compare October 28, 2025 23:35
@shtrom
Copy link
Copy Markdown
Member Author

shtrom commented Oct 28, 2025

Ok, @zzzeid this has been rebased onto the latest pilot PR, and should be good to go.

zzzeid
zzzeid previously requested changes Oct 29, 2025
Copy link
Copy Markdown
Contributor

@zzzeid zzzeid left a comment

Choose a reason for hiding this comment

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

This will break all the spots that use the GitHubAPIClient class, so they need to be updated with the new implementation:

  • src/lando/ui/pull_requests.py
  • src/lando/api/legacy/workers/landing_worker.py
  • src/lando/api/views.py

Also I think the PR description is outdated.

@shtrom shtrom dismissed zzzeid’s stale review October 30, 2025 05:13

fixed callsites, and added some basic tests for good measure (it's the third PR where I start a test_github.py from scratch 😅); they allowed me to identify some discrepancies in behaviour, which I've fixed, too

@shtrom shtrom requested a review from zzzeid October 30, 2025 05:13
@shtrom
Copy link
Copy Markdown
Member Author

shtrom commented Oct 30, 2025

I reviewed the PR description, and I think it's still accurate. Do you think something's missing, perhaps? [I just added a mention of the tests]

@shtrom shtrom force-pushed the no-bug/github-api-url-parsing branch from 583783e to 4493dee Compare October 30, 2025 05:33
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I had to cherry-pick the tests fix from main. This tagged along.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

May have been a little easier to update the pilot branch with main and then bubble up the changes to all the branches. It's gonna be a little tricky approving things in a state that's different than what they will end up in the squash and merge.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yep fair enough. I didn't want to update the pilot branch myself, so as not to step of each other's feet.

@zzzeid

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

@zzzeid zzzeid left a comment

Choose a reason for hiding this comment

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

r+ with some caveats/nits that should be addressed before merging.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

May have been a little easier to update the pilot branch with main and then bubble up the changes to all the branches. It's gonna be a little tricky approving things in a state that's different than what they will end up in the squash and merge.

Comment thread src/lando/utils/tests/test_cache.py
Comment thread src/lando/utils/github.py Outdated
Comment thread src/lando/utils/github.py Outdated
self.repo_url = repo_url
# GitHub doesn't allow '.git' to be at the end of a repository name, so we
# normalise it out to be sure. This include first removing any trailing /
self.repo_url = repo_url.removesuffix("/").removesuffix(".git")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here (i.e., duplicated from Repo).

Also, i think these lines are mixing the concepts of a repo name and a repo URL. It's OK to have .git suffix in the repo URL (as long as it is so consistently) but not in the name.

The rest of Lando expects a GitHub repo URL to contain a .git suffix. It's the "normalized" URL that does not have a suffix (in terms of existing conventions/terminology.) I.e., Repo.url has a .git suffix, Repo.normalized_url does not.

Copy link
Copy Markdown
Member Author

@shtrom shtrom Oct 31, 2025

Choose a reason for hiding this comment

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

Yep, I had trouble supporting all URLs that we might throw at the util and doing the right thing, which ended up like that.

I just tried a bit harder, and found a way to make the RE as greedy as needed, and now it seems to work in all cases, regardless of whether the URL is normalised or not, or if it has a full REST path vs. just being a base URL. It also simplifies the logic! (:

Comment thread src/lando/utils/github.py Outdated
Comment thread src/lando/utils/github.py
Comment thread src/lando/utils/github.py Outdated
Comment thread src/lando/utils/github.py
Comment on lines +72 to +74
# We didn't get a token
logger.warning(f"Couldn't obtain a token for GitHub repo at {self.repo_url}")
return self.repo_url
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this fail more loudly? If we're expecting credentials in the URL and we can't get them, maybe this should throw an exception instead.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think if it doesn't fail here, it will fail when trying to push, and then the warning should give us a clue.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think given that the purpose of this method is to return an authenticated URL, not returning one should lead to a failure, rather than a warning. Won't block this but this could potentially obfuscate issues down the road.

Comment thread src/lando/utils/tests.py Outdated
Comment thread pyproject.toml
Co-authored-by: Zeid <2043828+zzzeid@users.noreply.github.com>
@shtrom shtrom force-pushed the zeid/bug-1989635-github-pr-pilot branch from 3d9712a to f51d72f Compare October 31, 2025 05:39
@shtrom shtrom force-pushed the no-bug/github-api-url-parsing branch from 9ddc083 to 09000ad Compare October 31, 2025 06:36
@shtrom shtrom requested a review from zzzeid October 31, 2025 06:51
@shtrom
Copy link
Copy Markdown
Member Author

shtrom commented Oct 31, 2025

@zzzeid Ok, the merge was a bit bigger than I'd want to get through without review, but I think it looks good, and most of the noise is gone.

There's one question about early vs. late failure.

However, if you're happy with it, I'd say go ahead and merge it!

Copy link
Copy Markdown
Contributor

@zzzeid zzzeid left a comment

Choose a reason for hiding this comment

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

Looks good. I think the issue remaining can be addressed at a later time.

Comment thread src/lando/utils/github.py
Comment on lines +72 to +74
# We didn't get a token
logger.warning(f"Couldn't obtain a token for GitHub repo at {self.repo_url}")
return self.repo_url
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think given that the purpose of this method is to return an authenticated URL, not returning one should lead to a failure, rather than a warning. Won't block this but this could potentially obfuscate issues down the road.

@shtrom shtrom merged commit a82047d into zeid/bug-1989635-github-pr-pilot Nov 3, 2025
1 check passed
@shtrom shtrom deleted the no-bug/github-api-url-parsing branch November 3, 2025 03:56
zzzeid added a commit that referenced this pull request Nov 6, 2025
…95679) (#604)

* add a `GitHub` object allowing to renew tokens, parse URLs, and
generate authenticated URLs
* also add a pre-authenticated `session` attribute to the `GitHubAPI`
object
* utils: move `URL_USERINFO_RE` to const (bug 1995679)
* utils: add basic test for github classes

---------

Co-authored-by: Zeid <2043828+zzzeid@users.noreply.github.com>
Co-authored-by: Zeid <zeid@mozilla.com>
zzzeid added a commit that referenced this pull request Nov 6, 2025
…95679) (#604)

* add a `GitHub` object allowing to renew tokens, parse URLs, and
generate authenticated URLs
* also add a pre-authenticated `session` attribute to the `GitHubAPI`
object
* utils: move `URL_USERINFO_RE` to const (bug 1995679)
* utils: add basic test for github classes

---------

Co-authored-by: Zeid <2043828+zzzeid@users.noreply.github.com>
Co-authored-by: Zeid <zeid@mozilla.com>
zzzeid added a commit that referenced this pull request Nov 20, 2025
…95679) (#604)

* add a `GitHub` object allowing to renew tokens, parse URLs, and
generate authenticated URLs
* also add a pre-authenticated `session` attribute to the `GitHubAPI`
object
* utils: move `URL_USERINFO_RE` to const (bug 1995679)
* utils: add basic test for github classes

---------

Co-authored-by: Zeid <2043828+zzzeid@users.noreply.github.com>
Co-authored-by: Zeid <zeid@mozilla.com>
zzzeid added a commit that referenced this pull request Nov 24, 2025
…95679) (#604)

* add a `GitHub` object allowing to renew tokens, parse URLs, and
generate authenticated URLs
* also add a pre-authenticated `session` attribute to the `GitHubAPI`
object
* utils: move `URL_USERINFO_RE` to const (bug 1995679)
* utils: add basic test for github classes

---------

Co-authored-by: Zeid <2043828+zzzeid@users.noreply.github.com>
Co-authored-by: Zeid <zeid@mozilla.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.

2 participants