diff --git a/README.md b/README.md index 18beace6c..bece11c0d 100644 --- a/README.md +++ b/README.md @@ -178,3 +178,8 @@ Development instructions for the CircleCI CLI can be found in [HACKING.md](HACKI Please see the [documentation](https://circleci-public.github.io/circleci-cli) or `circleci help` for more. +## Server compatibility + +There are some difference of behavior depending on the version you use: + - config validation will use the GraphQL API until **Server v4.0.5, v4.1.3, v4.2.0**. The above versions will use the new route `compile-config-with-defaults` + - `circleci orb validate` will only allow you to validate orbs using other private orbs with the option `--org-slug` from version **Server v4.2.0** diff --git a/api/api.go b/api/api.go index 3d283930c..0c51b486d 100644 --- a/api/api.go +++ b/api/api.go @@ -564,7 +564,7 @@ func makeOrbRequest(cl *graphql.Client, configContent string, ownerId string) (* } if ownerId != "" { - return nil, errors.Errorf("Your version of server does not support validating orbs that refer private orbs") + return nil, errors.Errorf("Your version of Server does not support validating orbs that refer to other private orbs. Please see the README for more information on server compatibility: https://github.com/CircleCI-Public/circleci-cli#server-compatibility") } query := ` query ValidateOrb ($config: String!) { diff --git a/cmd/orb_test.go b/cmd/orb_test.go index 3d2f586d5..7b4e917ba 100644 --- a/cmd/orb_test.go +++ b/cmd/orb_test.go @@ -210,6 +210,77 @@ See a full explanation and documentation on orbs here: https://circleci.com/docs }) }) + Describe("with old server version", func() { + BeforeEach(func() { + token = "testtoken" + command = exec.Command(pathCLI, + "orb", "validate", + "--skip-update-check", + "--token", token, + "--host", tempSettings.TestServer.URL(), + "-", + ) + stdin, err := command.StdinPipe() + Expect(err).ToNot(HaveOccurred()) + go func() { + defer stdin.Close() + _, err := io.WriteString(stdin, "{}") + if err != nil { + panic(err) + } + }() + }) + + It("should use the old GraphQL resolver", func() { + By("setting up a mock server") + + mockOrbIntrospection(false, "", tempSettings) + + gqlResponse := `{ + "orbConfig": { + "sourceYaml": "{}", + "valid": true, + "errors": [] + } + }` + + response := struct { + Query string `json:"query"` + Variables struct { + Config string `json:"config"` + } `json:"variables"` + }{ + Query: ` + query ValidateOrb ($config: String!) { + orbConfig(orbYaml: $config) { + valid, + errors { message }, + sourceYaml, + outputYaml + } + }`, + Variables: struct { + Config string `json:"config"` + }{ + Config: "{}", + }, + } + expected, err := json.Marshal(response) + Expect(err).ShouldNot(HaveOccurred()) + + tempSettings.AppendPostHandler(token, clitest.MockRequestResponse{ + Status: http.StatusOK, + Request: string(expected), + Response: gqlResponse}) + + session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) + + Expect(err).ShouldNot(HaveOccurred()) + Eventually(session.Out).Should(gbytes.Say("Orb input is valid.")) + Eventually(session).Should(gexec.Exit(0)) + }) + }) + Context("with 'some orb'", func() { BeforeEach(func() { orb.Write([]byte(`some orb`))