Skip to content
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

Add GitHub Enterprise Server support #7570

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

doew
Copy link

@doew doew commented Mar 28, 2025

  • This change is worth documenting at https://docs.all-hands.dev/
  • Include this change in the Release Notes. If checked, you must provide an end-user friendly description for your change below

End-user friendly description of the problem this fixes or functionality that this introduces.
This update introduces support for GitHub Enterprise Server (GHES), allowing OpenHands to integrate seamlessly with self-hosted GitHub environments. Users can now configure OpenHands to connect with GHES instances through updated API endpoints and improved authentication mechanisms.


Give a summary of what the PR does, explaining any non-trivial design decisions.
This PR adds support for GitHub Enterprise Server by:

  • Implementing configuration options specific to GHES
  • Updating API endpoint logic to accommodate GHES-specific paths
  • Enhancing authentication flows to support GHES tokens and permissions
  • Adding test cases to validate GHES functionality

The design ensures that these changes are backward-compatible with existing GitHub.com integrations.


Link of any specific issues this addresses.
N/A

doew and others added 16 commits March 27, 2025 13:48
- Add TypeScript interface declarations for GitHub-related global window properties
- Fix TypeScript build errors related to missing window property types
- Ensure proper type checking for GitHub Enterprise integration
- Fix trailing whitespace in GitHub auth URL and URL parsing test files
- Add proper end-of-file newlines to test files
- Improve code formatting consistency in test files
- Add proper end-of-file newlines to Python files
- Fix import ordering in test files
- Standardize string quote style in GitHub configuration files
- Improve code formatting and line wrapping in GitHub service tests
- Fix import ordering and remove unused imports
- Improve function parameter formatting for better readability
- Standardize string quote style in GitHub and settings related files
- Fix whitespace and indentation issues
- Remove unnecessary blank lines
@malhotra5
Copy link
Contributor

malhotra5 commented Mar 31, 2025

Thanks a bunch for putting this together!

The main feedback I have is

  1. to make sure we're saving the enterprise url inside the secret _store field inside Settings. Specifically, adding an extra field HOST_URL inside ProviderToken

  2. Inside the accountsettings page for the FE, add an extra host url field which saves/stores the HOST_URL for the user in the BE

  3. Use the settings provider in the FE to access the HOST_URL and pass around the attribute as needed

We're trying to make this configurable on a per-user; let me know if you need any help with this!

@doew
Copy link
Author

doew commented Mar 31, 2025

@malhotra5
Happy to take this suggestion on!
Initially, I thought having a global setting would be sufficient for self-hosting OpenHands, but I assume this change is necessary to support the SaaS version as well — is that correct?
It might take me a bit of time to implement, but I’ll keep working on it.

@malhotra5
Copy link
Contributor

Yup its so that the changes can be ported over to SAAS as well

Its also a matter of consistency, as for self hosted openhands we still maintain values inside user settings rather than setting values globally

This commit adds support for GitHub Enterprise Server instances:

- Add base_url parameter to GitService interface
- Add host_url field to ProviderToken model
- Enhance GitHubService to handle custom API URLs for Enterprise Server
- Update settings models and routes to handle host_url information
- Add Enterprise Host URL input field to account settings UI
- Update tests to validate Enterprise Server functionality

These changes enable users to configure and connect to their own
self-hosted GitHub Enterprise Server instances through the UI,
allowing each user to specify their own custom GitHub host.
Backward compatibility with github.com is maintained.
@doew doew force-pushed the feature/github-enterprise-server-support branch 2 times, most recently from c7a108c to 98adb9f Compare April 2, 2025 11:36
@doew
Copy link
Author

doew commented Apr 2, 2025

@malhotra5

I've implemented the changes you suggested. Here's what I've done:

  1. Added a HOST_URL field to the ProviderToken class
  2. Added a GitHub Enterprise Server Host URL input field to the frontend account settings page
  3. Implemented the backend logic to save and retrieve the HOST_URL
  4. Modified the frontend settings provider to access and pass the HOST_URL attribute as needed

These changes allow users to configure their GitHub Enterprise Server host URL on a per-user basis, maintaining consistency with other OpenHands settings that are managed at the user level.

For self-hosted environments, I've maintained the ability to configure global settings through environment variables (GITHUB_ENTERPRISE_URL) and configuration files. The implementation prioritizes the user-specific host_url when available, falling back to the globally configured URL when not set.

Please let me know if you'd like to see any additional changes or have any questions!

@doew
Copy link
Author

doew commented Apr 4, 2025

@malhotra5

Thank you for reviewing this PR. Since the last review, I have added new commits, but in the meantime, GitLab-related changes were introduced, requiring me to resolve conflicts twice.

Given that the time available for this PR is limited, I would like to discuss the best way to proceed smoothly. For example, one possible approach could be merging the PR in its current state and handling any necessary fixes in a separate PR.

Could you share your thoughts on this? I appreciate your help.

@doew
Copy link
Author

doew commented Apr 4, 2025

Thanks for running the CI! It looks like it failed, so I’ll go ahead and push a fix to get it passing.

@enyst
Copy link
Collaborator

enyst commented Apr 4, 2025

@doew I think, if you run a make build in the project, it will install the pre-commit hooks that make it simple.

export const initGitHubEnterpriseConfig = () => {
// Set GitHub Enterprise URL if available
if (import.meta.env.VITE_GITHUB_ENTERPRISE_URL) {
window.GITHUB_ENTERPRISE_URL = import.meta.env.VITE_GITHUB_ENTERPRISE_URL;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we avoid using window to pass around GitHub related settings. We'd rather just use the UserSettings because its persists for local installations as well


// Extend Window interface to include GitHub Enterprise URL
declare global {
interface Window {
Copy link
Contributor

Choose a reason for hiding this comment

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

similarly remove use of window here

@@ -18,7 +32,7 @@ export type Settings = {
ENABLE_DEFAULT_CONDENSER: boolean;
ENABLE_SOUND_NOTIFICATIONS: boolean;
USER_CONSENTS_TO_ANALYTICS: boolean | null;
PROVIDER_TOKENS: Record<Provider, string>;
PROVIDER_TOKENS: Record<Provider, ProviderTokenDataGet | string>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we enforce this to always be ProviderTokenData instead of `string

Also the backend route can end empty token for GET requests, instead of making ProviderTokenDataPost and ProviderTokenDataGet

@@ -7,6 +7,19 @@
*/
export const generateGitHubAuthUrl = (clientId: string, requestUrl: URL) => {
const redirectUri = `${requestUrl.origin}/oauth/keycloak/callback`;

// Check if GitHub Enterprise Server URL is configured
const githubEnterpriseUrl = window.GITHUB_ENTERPRISE_URL || "";
Copy link
Contributor

Choose a reason for hiding this comment

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

can we have a param from the user settings passed to this function instead of pulling the URL value out from window

)
else:
# Default to github.com API
self.BASE_URL = get_github_api_url() or self.DEFAULT_BASE_URL
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: lets define the helper functions within this class (e.g get_github_api_url)

Let's remove the config class and just use user settings for storing the BASE_URL values

@@ -93,9 +96,14 @@ async def get_github_installation_ids(
):
if provider_tokens and ProviderType.GITHUB in provider_tokens:
token = provider_tokens[ProviderType.GITHUB]
# Use the host_url from the token if available, otherwise use the default API URL
github_api_url = token.host_url or get_github_api_url()
Copy link
Contributor

Choose a reason for hiding this comment

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

We should have host_url information available in the token, so get_github_api_url should be unnecessary

We strictly want to store such information on a per user basis

@malhotra5
Copy link
Contributor

FYI #7766 is adding similar support but for Gitlab, so some of the scaffolding changes may be quite similar

@doew
Copy link
Author

doew commented Apr 11, 2025

Thank you very much for the helpful review!
I’ll go through each point and address them one by one.

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.

4 participants