On a tangential note, I'm doing another pass on the whole checks API as part of fixing them. I'm only slightly changing the actual api:
@@ -261,7 +261,7 @@ type EnvironmentCheck {
setStringFlag(name: String!, value: String!): EnvironmentCheck!
"TODO"
- result: [EnvironmentCheckResult!]
+ result: EnvironmentCheckResult!
}
"A flag accepted by a environment check."
@@ -275,8 +275,16 @@ type EnvironmentCheckFlag {
"TODO"
type EnvironmentCheckResult {
+ name: String!
+ withName(name: String!): EnvironmentCheckResult!
+
success: Boolean!
+ withSuccess(success: Boolean!): EnvironmentCheckResult!
+
output: String!
- name: String!
+ withOutput(output: String!): EnvironmentCheckResult!
+
+ subresults: [EnvironmentCheckResult!]
+ withSubresult(id: EnvironmentCheckID!): EnvironmentCheckResult!
}
And then on the SDK side the new rule is that:
- The resolver must return an
EnvironmentCheckResult
- If the resolver returns an error (or in python an exception is thrown), that's not interpreted as a check failure but a runtime error (so check is in a unknown state)
Sketch of what that'll look like for various use cases in Go SDK:
func main() {
DaggerClient().Environment().
WithCheck_(UnitTest).
WithCheck_(IntegTest).
WithCheck_(TODOTest).
Serve()
}
func UnitTest(ctx dagger.Context) (*dagger.EnvironmentCheckResult, error) {
return DaggerClient().EnvironmentCheck().
WithSubcheck(DaggerClient().Democlient().UnitTest()).
WithSubcheck(DaggerClient().Demoserver().UnitTest()).
Result(), nil
}
func IntegTest(ctx dagger.Context) (*dagger.EnvironmentCheckResult, error) {
clientApp := DaggerClient().Apko().Wolfi([]string{"curl"})
stdout, err := clientApp.
WithServiceBinding("server", DaggerClient().Demoserver().Container()).
WithExec([]string{"curl", "http://server:8081/hello"}).
Stdout(ctx)
if err != nil {
return DaggerClient().EnvironmentCheckResult().
WithSuccess(false).
WithOutput(err.Error()), nil
}
return DaggerClient().EnvironmentCheckResult().
WithSuccess(true).
WithOutput(stdout), nil
}
func TODOTest(ctx dagger.Context) (*dagger.EnvironmentCheckResult, error) {
return DaggerClient().Go().TestsFrom(DaggerClient().Host().Directory(".")).Result(), nil
}
The IntegTest example is particularly ugly relative to before, but it can be addressed by adding sdk-specific helpers as needed. That code is basically what a helper would internally be doing.
There are just way too many problems and ambiguities with the existing check implementation, especially around what is test output, what does an error mean, etc. I think this approach will result in more consistent comprehensible behavior. Though I am still in the middle of implementing so still subject to change π