-
Notifications
You must be signed in to change notification settings - Fork 3
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
feat: return runtime versions used by the application with a doctor hook #81
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #81 +/- ##
==========================================
+ Coverage 77.24% 78.53% +1.29%
==========================================
Files 16 17 +1
Lines 813 876 +63
Branches 111 129 +18
==========================================
+ Hits 628 688 +60
- Misses 182 187 +5
+ Partials 3 1 -2 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have much to say about the code 💯
Comparing the current version with the minimum is a task left to the CLI! However this might be better handled by a hook? I'm really not sure... 🤔
It would make sense to have the hook compare the current versions I feel like the version patterns might be slightly difference from runtime to runtime, this is also how the check update handles it
src/doctor.ts
Outdated
const message = Deno.version.deno !== version | ||
? `Applications deployed to Slack use Deno version ${version}` | ||
: undefined; | ||
return { minimum: version, message }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 I'm not sure if the deno-runtime used by run on slack infra is the "minimum" version I think it might just be the version being used since we did not implement a way for developers to set a specific version they can't change it
For example if a developer is using new features found in Deno 1.41.x and run on slack support 1.37.x that does not have those features then the developers code would fail so 1.37.x is not the minimum version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we discussed this point in the spec @zimeg wrote. The minimum
is just the payload shape, but you can see in the messaging to the user we don't actually mention minimum. This is intentional. We are very carefully choosing our words when raising this to the user so that we don't imply a 'minimum' version but rather communicate that ROSI uses one EXACT version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that "minimum" isn't a super ideal word for this case but it gives us flexibility across other SDKs to specify certain runtime requirements IMO.
With the current
and minimum
version comparison moving into the hooks I'm super interested in how this output might change. Or maybe it doesn't? But wanted to share an example for reference:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to circle back on this discussion with the latest updates- minimum
no longer exists. Neither does latest
. At least in the hook response. Only message
and errors.message
can provide additional detail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM also 👍
The hook can also use the protocol to share an error message correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested this with the CLI PR you have up as well as with an old (2.5.0) version of the CLI - works well in both cases!
Left a few suggestions but looking real good and close to shipping! Nicely done.
Comparing the current version with the minimum is a task left to the CLI! However this might be better handled by a hook? I'm really not sure... 🤔
Good point. I suppose in order to try to adhere to the design of 'the CLI is dumb' we should err on the side of pushing complexity to the SDKs. We should probably make a decision on this at this point, while we are baking this new hook, rather than delay on this down the road, as that would complicate rollout in the future (would need to first roll out hook changes, possibly consider backwards compatibility, and so on).
My vote is to push the comparison logic to the SDK, which as Will points out is what we do for check-update
too.
src/doctor.ts
Outdated
const metadataURL = "https://api.slack.com/slackcli/metadata.json"; | ||
const response = await fetch(metadataURL); | ||
if (!response.ok) { | ||
throw new Error("Failed to collect upstream CLI metadata"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add the error details here when we raise this, at least the HTTP response code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the same vein as my last comment, perhaps we pump the error details over the CLI/SDK protocol's diagnostic line to allow the CLI to more gracefully handle showing the error in the right place (high level error in the output, with a pointer to the debug log, where the full details can be shown)? WDYT?
src/doctor.ts
Outdated
const metadata = await response.json(); | ||
const version = metadata?.["deno-runtime"]?.releases[0]?.version; | ||
if (!version) { | ||
throw new Error("Failed to find the minimum Deno version"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add the metadata.cli
response payload as part of the error too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, thoughts on maybe pumping the specific error to the debug log and not messing up the delicate doctor template? We may have to use the protocol
's differing respond
vs. log
methods to enable the CLI to distinguish between the two.
src/doctor.ts
Outdated
const message = Deno.version.deno !== version | ||
? `Applications deployed to Slack use Deno version ${version}` | ||
: undefined; | ||
return { minimum: version, message }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we discussed this point in the spec @zimeg wrote. The minimum
is just the payload shape, but you can see in the messaging to the user we don't actually mention minimum. This is intentional. We are very carefully choosing our words when raising this to the user so that we don't imply a 'minimum' version but rather communicate that ROSI uses one EXACT version.
src/doctor.ts
Outdated
return { minimum: version, message }; | ||
} catch (err) { | ||
if (err instanceof Error) { | ||
return { error: { message: err.message } }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my earlier comments, can we check to make sure that the HTTP response code/body are at a minimum raised if the error caught is one of the HTTP or payload-parsing code fails? Perhaps add that as part of the test suite (if it's not already there).
@WilliamBergamin @filmaj appreciate all of this feedback and I'll start making changes on this! I'm agreeing with all of the points on comparing versions within the hook so will start with that too. And maybe adding a few responses to feedback in the process? We'll see. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗒️ A few notes on changes to HTTP error handling!
try { | ||
const metadataURL = "https://api.slack.com/slackcli/metadata.json"; | ||
const response = await fetch(metadataURL); | ||
if (!response.ok || response.status !== 200) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The response.status !== 200
protects against successful but unexpected responses, but maybe we want to strengthen this?
The actual fetch follows redirects which I think is good for future compatibility, but that means this can be redirected (302) to a successful page (200) which is not the right page. For instance, a login page. Then the result is this:
const getHostedDenoRuntimeVersion = async (): Promise<RuntimeDetails> => { | ||
try { | ||
const metadataURL = "https://api.slack.com/slackcli/metadata.json"; | ||
const response = await fetch(metadataURL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good but my general question is: how does leveraging the protocol's log
/warn
/error
methods to pump error/diagnostic info back to the CLI impact how we want to use this hook? Particularly for the failure modes, e.g. the response is not what we expect from a remote URL, do we want to include the unexpected response payload (could be JSON, or weird XML, or something else) as part of the hook's response? Or does sending it over the diagnostic line back to the CLI to let it handle that kind of information differently (by e.g. writing to the debug log) clean the output up? I just don't know if we should be showing HTTP status codes and that kind of thing in the doctor output.
In any case this is all up for debate - WDYT?
EDIT: and sorry for the back and forth here, it's not until I saw the error details show up in-line with the doctor output did I remember we have a whole-ass protocol designed for exchanging this kind of information available to us as well. I know it can be frustrating getting things over the finish line but the introduction of a new hook is a particularly good time to be extra-detail-oriented.
@filmaj I'm liking the idea of sending this back as diagnostic info much better! It lets us send waaay more detail without cluttering the I'll make updates to log HTTP errors with Right now both This is what the output with `protocol.warn` looks like now - no explicit error for a failed HTTP requestNote: The only other |
The latest protocol implementation has the CLI treat Ah yes, that's right, the CLI just streams the diagnostic info as a lesser-impact-colour text. So I suppose that puts the onus on the SDK hook implementation to use that in whatever way it sees fit - that is, the SDK hook should format what it passes to the protocol logging methods in a way that would make the output on the CLI side presentable. I trust you! What do you think feels right in this context? |
Since I imagine (hope) HTTP errors will be uncommon I think a `warn` with some leading detail would be most useful.If we want to hold off on making diagnostic info |
The latter looks good to me! |
@filmaj @WilliamBergamin and all other kind reviewers, here's a collection of outputs and error states for easy review: Common casesHTTP errorsThe "project runtime" section in the NotesI'll begin making the CLI output changes now to preserve spacing like these HTTP errors, but please let me know if you think anything should be changed! 🪝 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good 💯
@filmaj @WilliamBergamin really appreciate all of the feedback and reviews. Many exciting changes happened here. Y'all rock 🪨 🚀 |
Summary
This PR introduces a
doctor
hook that returns runtime versions for the application's execution environment in a structured way. The tests demonstrate the expected response shape!Information about the version of Deno used for hosted apps is collected from: https://api.slack.com/slackcli/metadata.json
Testing
In your own sample application and with a prepared version of the CLI, update your
slack.json
to include the following then runslack doctor
:Note: You can replace the SHA with the latest commit! But this should work pretty well.
Notes
Comparing the🤔current
version with theminimum
is a task left to the CLI! However this might be better handled by a hook? I'm really not sure...Update: It has been decided that this is the better way. So now it's been changed.
Requirements