Skip to content

Add GitHub App service #12072

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 14 commits into from
Apr 15, 2025
Merged

Add GitHub App service #12072

merged 14 commits into from
Apr 15, 2025

Conversation

stsewd
Copy link
Member

@stsewd stsewd commented Mar 26, 2025

This is the big one :D

  • After this PR is merged, we will start keeping in sync installations and remote repositories, but they won't be exposed to users yet (we can manually set up our projects to use a remote repo to test things out, private repos are not supported with this PR).
  • All operations from the old integration are supported, except for cloning private repos (will open another PR for that).
  • PyGitHub is an okay solution, it abstracts dealing with the JWT and has types for everything. But it can also be inefficient in some cases (like to interact with a commit, you need to retrieve the commit from the API first), but I think that's fine for now, we can always fallback to do this manually, and hopefully shouldn't be that much work, or the other option is keep using PyGitHub and use a raw call (requester.getJsonResponse("url")).
  • Webhooks always recover nicely in case the installation wasn't tracked, so if one operation fails for whatever reason (a bug, github is down, our app is down), we can recover the state in the next operation. Users can also manually hit "sync".
  • The webhook is exposed from the /webhook/githubapp/ URL, we can change that if needed.
  • We need to add the secrets and IDs on the ops repos.
  • Could I have divided this into smaller PRs? Maybe, but that may require more time removing the tests that are not needed...

Extracted from #11942

@stsewd stsewd marked this pull request as ready for review March 26, 2025 18:58
@stsewd stsewd requested a review from a team as a code owner March 26, 2025 18:58
@stsewd stsewd requested a review from humitos March 26, 2025 18:58
@stsewd stsewd requested a review from a team as a code owner March 26, 2025 19:03
Copy link

@Copilot 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

This PR adds a GitHub App service to support synchronizing installations and remote repositories while maintaining backward compatibility with existing integrations. Key changes include:

  • Adding GitHub App–specific models, service methods, and deletion logic.
  • Introducing a new GitHub App webhook URL and client for integration.
  • Updating service registries and test cases to account for GitHub App behavior.

Reviewed Changes

Copilot reviewed 16 out of 23 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
readthedocs/oauth/models.py Added GitHubAppInstallation methods and constants support
readthedocs/oauth/urls.py Introduced a dedicated GitHub App webhook URL
readthedocs/oauth/clients.py Added a client for GitHub App integration
readthedocs/oauth/querysets.py Updated querysets to exclude GitHub App related objects
readthedocs/settings/docker_compose.py Added environment variables for GitHub App configuration
readthedocs/oauth/services/init.py Updated the service registry to include GitHubAppService
readthedocs/settings/base.py Added default settings for the GitHub App integration
readthedocs/settings/test.py Added test settings including a sample RSA private key for GitHub App
readthedocs/oauth/services/base.py Defined base methods for cloning token retrieval, updated with GitHub App behavior
readthedocs/projects/models.py Updated GitHub project checks to consider both GitHub services
readthedocs/urls.py Included OAuth URL patterns for handling GitHub App webhooks
readthedocs/rtd_tests/tests/test_oauth_tasks.py Extended tests to include GitHubAppService sync calls
Files not reviewed (7)
  • docs/dev/install.rst: Language not supported
  • docs/dev/settings.rst: Language not supported
  • requirements/deploy.txt: Language not supported
  • requirements/docker.txt: Language not supported
  • requirements/pip.in: Language not supported
  • requirements/pip.txt: Language not supported
  • requirements/testing.txt: Language not supported
Comments suppressed due to low confidence (1)

readthedocs/oauth/services/base.py:334

  • Duplicate definitions of 'get_clone_token' exist in this class; merge the implementations to prevent unintended overriding and ensure a single consistent behavior.
def get_clone_token(self, project):

Copy link
Member

@ericholscher ericholscher left a comment

Choose a reason for hiding this comment

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

Overall this looks great -- it's a big change tho, and a little scary. Had a bunch of smaller comments, but I think it could also be useful to describe the architecture a bit more in our dev docs somewhere. It seems like there's a bunch of webhooks, and we're syncing data based on those, but it was hard for me to wrap my head around the whole flow of data and responsibility of each piece.

@stsewd
Copy link
Member Author

stsewd commented Apr 1, 2025

I think it could also be useful to describe the architecture a bit more in our dev docs somewhere.

Hope this helps
https://github.com/readthedocs/readthedocs.org/pull/12072/files#diff-0bbc5fbaa17dc973c571176f0ac6bdc3849be5fe9b81aeb4847318df613740c6

Copy link
Member

@ericholscher ericholscher left a comment

Choose a reason for hiding this comment

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

I think it could also be useful to describe the architecture a bit more in our dev docs somewhere.

Hope this helps https://github.com/readthedocs/readthedocs.org/pull/12072/files#diff-0bbc5fbaa17dc973c571176f0ac6bdc3849be5fe9b81aeb4847318df613740c6

Yea, that's great.

This looks great to me. To confirm, when we merge this we mostly are still installing backend infrastructure, and there is still not a user-facing change with this? If so, I think I'm 👍 on merging it, but would also love for another set of eyes on it before we ship it.

@stsewd
Copy link
Member Author

stsewd commented Apr 3, 2025

To confirm, when we merge this we mostly are still installing backend infrastructure, and there is still not a user-facing change with this?

yep, we can actually start testing it in our own repos by manually linking projects to a remote repository.

Metadata (read only, so we read the repo collaborators),
Pull requests (read and write, so we can post a comment on PRs in the future).
- Organization permissions: Members (read only so we can read the organization members).
- Account permissions: Email addresses (read only, so allauth can fetch all verified emails).
Copy link

Choose a reason for hiding this comment

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

It would be preferred if these permissions are on an opt-in basis. Many projects may want to start small, and i've seen plenty of them that are skeptical about every little permission. So instead it could be like

The minimum permissions necessary for this app are
- Repository permissions:
  Contents (read only, so we can clone the repo contents)

Additionally you may grand additional permissions depending on the features you wish to have
- Repository permissions:
  Commit statuses (read and write, so we can create commit statuses)

It does require the app to read the granted permissions.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hi, don't think GH allows for this, the permissions are defined by the app, installations can't choose a subset of permissions. What can happen is that the app requires more permissions and the user can accept or reject those new permissions, but all new installations will always require granting all permissions designated by the app.

And even if GH allows for this, not sure that we will support that case, as it requires considering more cases to support, and also support time, as some users don't know why a feature isn't working.

Copy link
Member

@humitos humitos left a comment

Choose a reason for hiding this comment

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

I'm pushing the review I was able to do today so @stsewd has some feedback from my side; but it's not finished yet. I will continue tomorrow with it.

Comment on lines +343 to +344
# NOTE: do we need the email of the organization?
remote_org.email = gh_org.email
Copy link
Member

Choose a reason for hiding this comment

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

Probably not.

Copy link
Member

@humitos humitos 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 to me 👍🏼 Nice work!

Summary of comments:

  • there is a pattern that I don't like too much: variable = self.install.property raises an exception
  • there are some tests where we only check if a method was called, but we don't check changes in the db -- it seems we are missing easy checks we can perform there

},
}
r = self.post_webhook("pull_request", payload)
assert r.status_code == 200
Copy link
Member

Choose a reason for hiding this comment

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

What's the goal of this webhook? Just communicate to GitHub that we handled it but we do nothing? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

We handle the pull_request event, but with we don't do anything with the "edited" action.

@stsewd
Copy link
Member Author

stsewd commented Apr 15, 2025

dev docs are failing because intersphinx is using the data from the current latest version instead of this PR.

@stsewd stsewd merged commit a012077 into main Apr 15, 2025
4 of 6 checks passed
@stsewd stsewd deleted the add-gh-app-service branch April 15, 2025 17:37
@github-project-automation github-project-automation bot moved this from Needs review to Done in 📍Roadmap Apr 15, 2025
@stsewd stsewd mentioned this pull request Apr 17, 2025
stsewd added a commit that referenced this pull request Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants