Graceful Enterprise degradation #919
Description
In order to support GitHub Enterprise (#270), we need to have some mechanism by which we can tailor the GitHub integration experience to whatever version of the GraphQL API is available on the Enterprise instance, in case the user tries to run a newer version of the package against a GitHub Enterprise instance that's using an older version of the API. I can think of a few techniques and associated thoughts.
-
Mark components as having a minimum Enterprise version (e.g. with a decorator or something) and fall back to the component/method with the highest marked version that works with the current version
This technique comes with a couple problems:
- It makes it really easy for a human to mess up, specifically by accidentally using a field that doesn't exist in an API version in a component or method that's marked for that version
- We have to be very intentional about how we add new features. If we have a component marked for Enterprise 2.10.0 and then we add new functionality in a component marked for 2.11.0 or whatever, we'll have to think hard about whether or not the functionality can be backported to the other components. (Marking certain methods instead of entire components might make this a bit easier, but we'll still need to be quite cautious)
- We need to have some way of figuring out the Enterprise version and doing version comparisons (this might already exist, not sure)
-
Do automatic detection of which GraphQL fields are available and automatically fall back
This removes the first issue above, since the system will automatically pick the component that works with the current version of the API, but it's still possible to get into a situation where we mistakenly have no version of a component that works with the current API (e.g. imagine accidentally using a newer field in all versions of a component — customers on older Enterprise releases won't be able to use the integration at all)
-
We need some mechanism by which to do the analysis. My thought is to run the introspection query against the GraphQL API and then statically analyze the GraphQL query/queries we plan on sending to the server to see if all the fields we need exist
- It's unclear how hard this would be to do with Relay, if it's possible at all
-
We'll still need multiple versions of components, and it won't be as clear by just looking at the code which components support which APIs
We can maybe make this less error-prone by having copies of the GraphQL schema for all the Enterprise releases and doing static analysis on them all to ensure at least one path works for the oldest supported Enterprise version
-
In any case, it's possible that relatively large portions of the UI might simply not get rendered for certain API versions, or perhaps we could implement certain functionality via the REST API — though I'm not a huge fan of maintaining a lot of REST-based components (which is the whole point of using GraphQL in the first place).
In additional all the above, we also need to have good support for (1) detecting remotes hosted on an Enterprise instance and (2) allowing users to authenticate against those instances and store off their tokens. It's unclear how different this process will need to look for Enterprise customers (especially since they won't have e.g. an OAuth server to authenticate against).
/cc @gjtorikian and @shiftkey for info and potentially initial thoughts
Ref #270