Skip to content

Commit

Permalink
Add app spec validate-offline (Resolves #1449) (#1450)
Browse files Browse the repository at this point in the history
* integration/apps_spec_test: Add tests for apps spec validate-offline

* commands/apps: Add apps spec validate-offline command (Fixes #1449)

Implement a new command to validate an app spec without requiring
auth & connection to the API. This is useful for validating app specs
in CI pipelines and untrusted environments.  As there is no currently
published [YAML schema][1] for use with [`redhat.vscode-yaml`][2], this
seems to be the best approach for now.

[1]: https://www.schemastore.org/json/
[2]: https://github.com/redhat-developer/yaml-language-server

* commands/apps: Refactor spec validation into a common function

* commands/apps: refactor validate-offline -> --schema-only (Fixes #1449) (#1)

Thanks to @andrewsomething for the suggestion!

Reference:

- #1450 (review)

* Add integration test without auth.

---------

Co-authored-by: Andrew Starr-Bochicchio <[email protected]>
  • Loading branch information
trinitronx and andrewsomething authored Oct 24, 2023
1 parent f6d249b commit 1df456e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
10 changes: 8 additions & 2 deletions commands/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,9 @@ Optionally, pass a deployment ID to get the spec of that specific deployment.`,
AddStringFlag(getCmd, doctl.ArgAppDeployment, "", "", "optional: a deployment ID")
AddStringFlag(getCmd, doctl.ArgFormat, "", "yaml", `the format to output the spec in; either "yaml" or "json"`)

validateCmd := CmdBuilder(cmd, RunAppsSpecValidate, "validate <spec file>", "Validate an application spec", `Use this command to check whether a given app spec (YAML or JSON) is valid.
validateCmd := cmdBuilderWithInit(cmd, RunAppsSpecValidate, "validate <spec file>", "Validate an application spec", `Use this command to check whether a given app spec (YAML or JSON) is valid.
You may pass - as the filename to read from stdin.`, Writer)
You may pass - as the filename to read from stdin.`, Writer, false)
AddBoolFlag(validateCmd, doctl.ArgSchemaOnly, "", false, "Only validate the spec schema and not the correctness of the spec.")

return cmd
Expand Down Expand Up @@ -762,6 +762,7 @@ func RunAppsSpecGet(c *CmdConfig) error {
}

// RunAppsSpecValidate validates an app spec file
// doesn't require auth & connection to the API with doctl.ArgSchemaOnly flag
func RunAppsSpecValidate(c *CmdConfig) error {
if len(c.Args) < 1 {
return doctl.NewMissingArgsErr(c.NS)
Expand All @@ -778,6 +779,7 @@ func RunAppsSpecValidate(c *CmdConfig) error {
return err
}

// validate schema only (offline)
if schemaOnly {
ymlSpec, err := yaml.Marshal(appSpec)
if err != nil {
Expand All @@ -787,6 +789,10 @@ func RunAppsSpecValidate(c *CmdConfig) error {
return err
}

// validate the spec against the API
if err := c.initServices(c); err != nil {
return err
}
res, err := c.Apps().Propose(&godo.AppProposeRequest{
Spec: appSpec,
})
Expand Down
18 changes: 18 additions & 0 deletions integration/apps_spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,24 @@ var _ = suite("apps/spec/validate", func(t *testing.T, when spec.G, it spec.S) {
expect.Equal(expectedOutput, strings.TrimSpace(string(output)))
})

it("schema-only works without auth", func() {
cmd := exec.Command(builtBinaryPath,
"-u", server.URL,
"apps", "spec", "validate",
"--schema-only", "-",
)
byt, err := json.Marshal(testAppSpec)
expect.NoError(err)

cmd.Stdin = bytes.NewReader(byt)

output, err := cmd.CombinedOutput()
expect.NoError(err)

expectedOutput := "name: test\nservices:\n- github:\n branch: main\n repo: digitalocean/doctl\n name: service"
expect.Equal(expectedOutput, strings.TrimSpace(string(output)))
})

it("calls proposeapp", func() {
cmd := exec.Command(builtBinaryPath,
"-t", "some-magic-token",
Expand Down

0 comments on commit 1df456e

Please sign in to comment.