Skip to content

Commit

Permalink
Merge pull request #1044 from CircleCI-Public/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
JulesFaucherre authored Feb 14, 2024
2 parents 9c87a3e + 430c09a commit 16acd35
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 6 deletions.
2 changes: 1 addition & 1 deletion cmd/.circleci/update_check.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
last_update_check: 2024-01-11T10:44:52.12818Z
last_update_check: 2023-12-11T13:24:04.24843+01:00
42 changes: 37 additions & 5 deletions cmd/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"strings"

"github.com/CircleCI-Public/circleci-cli/api"
"github.com/CircleCI-Public/circleci-cli/api/graphql"
Expand Down Expand Up @@ -83,9 +84,9 @@ Please note that at this time all namespaces created in the registry are world-r

return err
},
Args: cobra.ExactArgs(1),
Args: cobra.RangeArgs(1, 3),
Annotations: make(map[string]string),
Example: ` circleci namespace create NamespaceName --org-id 00000000-0000-0000-0000-000000000000`,
Example: `circleci namespace create NamespaceName --org-id 00000000-0000-0000-0000-000000000000`,
}

createCmd.Annotations["<name>"] = "The name to give your new namespace"
Expand Down Expand Up @@ -137,11 +138,42 @@ To change the namespace, you will have to contact CircleCI customer support.
return nil
}

func createNamespaceWithVcsTypeAndOrgName(opts namespaceOptions, namespaceName, vcsType, orgName string) error {
if !opts.noPrompt {
fmt.Printf(`You are creating a namespace called "%s".
This is the only namespace permitted for your %s organization, %s.
To change the namespace, you will have to contact CircleCI customer support.
`, namespaceName, strings.ToLower(opts.args[1]), opts.args[2])
}

confirm := fmt.Sprintf("Are you sure you wish to create the namespace: `%s`", namespaceName)
if opts.noPrompt || opts.tty.askUserToConfirm(confirm) {
_, err := api.CreateNamespace(opts.cl, namespaceName, opts.args[2], strings.ToUpper(opts.args[1]))
if err != nil {
return err
}

fmt.Printf("Namespace `%s` created.\n", namespaceName)
fmt.Println("Please note that any orbs you publish in this namespace are open orbs and are world-readable.")
}
return nil
}

func createNamespace(cmd *cobra.Command, opts namespaceOptions) error {
namespaceName := opts.args[0]
_, err := uuid.Parse(*opts.orgID)
if err == nil {
return createNamespaceWithOrgId(opts, namespaceName, *opts.orgID)
//skip if no orgid provided
if opts.orgID != nil && strings.TrimSpace(*opts.orgID) != "" {
_, err := uuid.Parse(*opts.orgID)
if err == nil {
return createNamespaceWithOrgId(opts, namespaceName, *opts.orgID)
}

//skip if no vcs type and org name provided
} else if len(opts.args) == 3 {
return createNamespaceWithVcsTypeAndOrgName(opts, namespaceName, opts.args[1], opts.args[2])
}
return cmd.Help()
}
Expand Down
209 changes: 209 additions & 0 deletions cmd/namespace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/CircleCI-Public/circleci-cli/telemetry"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
)

Expand Down Expand Up @@ -118,5 +119,213 @@ Namespace %s created.
Please note that any orbs you publish in this namespace are open orbs and are world-readable.`, "foo-ns", "bb604b45-b6b0-4b81-ad80-796f15eddf87", "`foo-ns`", "`foo-ns`")))
})
})

Describe("registering a namespace with OrgName and OrgVcs", func() {
BeforeEach(func() {
command = exec.Command(pathCLI,
"namespace", "create",
"--skip-update-check",
"--token", token,
"--host", tempSettings.TestServer.URL(),
"--integration-testing",
"foo-ns",
"BITBUCKET",
"test-org",
)
})

It("works with organizationName and organizationVcs", func() {
By("setting up a mock server")

gqlOrganizationResponse := `{
"organization": {
"name": "test-org",
"id": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}`

expectedOrganizationRequest := `{
"query": "query($organizationName: String!, $organizationVcs: VCSType!) {\n\t\t\t\torganization(\n\t\t\t\t\tname: $organizationName\n\t\t\t\t\tvcsType: $organizationVcs\n\t\t\t\t) {\n\t\t\t\t\tid\n\t\t\t\t}\n\t\t\t}","variables":{"organizationName":"test-org","organizationVcs":"BITBUCKET"}}`

gqlNsResponse := `{
"createNamespace": {
"errors": [],
"namespace": {
"id": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}
}`

expectedNsRequest := `{
"query": "\n\t\t\tmutation($name: String!, $organizationId: UUID!) {\n\t\t\t\tcreateNamespace(\n\t\t\t\t\tname: $name,\n\t\t\t\t\torganizationId: $organizationId\n\t\t\t\t) {\n\t\t\t\t\tnamespace {\n\t\t\t\t\t\tid\n\t\t\t\t\t}\n\t\t\t\t\terrors {\n\t\t\t\t\t\tmessage\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}",
"variables": {
"name": "foo-ns",
"organizationId": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}`

tempSettings.AppendPostHandler(token, clitest.MockRequestResponse{
Status: http.StatusOK,
Request: expectedOrganizationRequest,
Response: gqlOrganizationResponse})
tempSettings.AppendPostHandler(token, clitest.MockRequestResponse{
Status: http.StatusOK,
Request: expectedNsRequest,
Response: gqlNsResponse})

By("running the command")
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ShouldNot(HaveOccurred())
Eventually(session).Should(gexec.Exit(0))

stdout := session.Wait().Out.Contents()

Expect(string(stdout)).To(ContainSubstring(fmt.Sprintf(`You are creating a namespace called "%s".
This is the only namespace permitted for your bitbucket organization, test-org.
To change the namespace, you will have to contact CircleCI customer support.
Are you sure you wish to create the namespace: %s
Namespace %s created.
Please note that any orbs you publish in this namespace are open orbs and are world-readable.`, "foo-ns", "`foo-ns`", "`foo-ns`")))
})
})

Describe("when creating / reserving a namespace", func() {
BeforeEach(func() {
command = exec.Command(pathCLI,
"namespace", "create",
"--skip-update-check",
"--token", token,
"--host", tempSettings.TestServer.URL(),
"--integration-testing",
"foo-ns",
"BITBUCKET",
"test-org",
)
})

It("works with organizationName and organizationVcs", func() {
By("setting up a mock server")

gqlOrganizationResponse := `{
"organization": {
"name": "test-org",
"id": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}`

expectedOrganizationRequest := `{
"query": "query($organizationName: String!, $organizationVcs: VCSType!) {\n\t\t\t\torganization(\n\t\t\t\t\tname: $organizationName\n\t\t\t\t\tvcsType: $organizationVcs\n\t\t\t\t) {\n\t\t\t\t\tid\n\t\t\t\t}\n\t\t\t}",
"variables": {
"organizationName": "test-org",
"organizationVcs": "BITBUCKET"
}
}`

gqlNsResponse := `{
"createNamespace": {
"errors": [],
"namespace": {
"id": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}
}`

expectedNsRequest := `{
"query": "\n\t\t\tmutation($name: String!, $organizationId: UUID!) {\n\t\t\t\tcreateNamespace(\n\t\t\t\t\tname: $name,\n\t\t\t\t\torganizationId: $organizationId\n\t\t\t\t) {\n\t\t\t\t\tnamespace {\n\t\t\t\t\t\tid\n\t\t\t\t\t}\n\t\t\t\t\terrors {\n\t\t\t\t\t\tmessage\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}",
"variables": {
"name": "foo-ns",
"organizationId": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}`

tempSettings.AppendPostHandler(token, clitest.MockRequestResponse{
Status: http.StatusOK,
Request: expectedOrganizationRequest,
Response: gqlOrganizationResponse})
tempSettings.AppendPostHandler(token, clitest.MockRequestResponse{
Status: http.StatusOK,
Request: expectedNsRequest,
Response: gqlNsResponse})

By("running the command")
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ShouldNot(HaveOccurred())
Eventually(session).Should(gexec.Exit(0))

stdout := session.Wait().Out.Contents()

Expect(string(stdout)).To(ContainSubstring(fmt.Sprintf(`You are creating a namespace called "%s".
This is the only namespace permitted for your bitbucket organization, test-org.
To change the namespace, you will have to contact CircleCI customer support.
Are you sure you wish to create the namespace: %s
Namespace %s created.
Please note that any orbs you publish in this namespace are open orbs and are world-readable.`, "foo-ns", "`foo-ns`", "`foo-ns`")))
})

It("prints all in-band errors returned by the GraphQL API", func() {
By("setting up a mock server")

gqlOrganizationResponse := `{
"organization": {
"name": "test-org",
"id": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}`

expectedOrganizationRequest := `{
"query": "query($organizationName: String!, $organizationVcs: VCSType!) {\n\t\t\t\torganization(\n\t\t\t\t\tname: $organizationName\n\t\t\t\t\tvcsType: $organizationVcs\n\t\t\t\t) {\n\t\t\t\t\tid\n\t\t\t\t}\n\t\t\t}",
"variables": {
"organizationName": "test-org",
"organizationVcs": "BITBUCKET"
}
}`

gqlResponse := `{
"createNamespace": {
"errors": [
{"message": "error1"},
{"message": "error2"}
],
"namespace": null
}
}`

gqlNativeErrors := `[ { "message": "ignored error" } ]`

expectedRequestJSON := `{
"query": "\n\t\t\tmutation($name: String!, $organizationId: UUID!) {\n\t\t\t\tcreateNamespace(\n\t\t\t\t\tname: $name,\n\t\t\t\t\torganizationId: $organizationId\n\t\t\t\t) {\n\t\t\t\t\tnamespace {\n\t\t\t\t\t\tid\n\t\t\t\t\t}\n\t\t\t\t\terrors {\n\t\t\t\t\t\tmessage\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}",
"variables": {
"name": "foo-ns",
"organizationId": "bb604b45-b6b0-4b81-ad80-796f15eddf87"
}
}`

tempSettings.AppendPostHandler(token, clitest.MockRequestResponse{
Status: http.StatusOK,
Request: expectedOrganizationRequest,
Response: gqlOrganizationResponse,
})
tempSettings.AppendPostHandler(token, clitest.MockRequestResponse{
Status: http.StatusOK,
Request: expectedRequestJSON,
Response: gqlResponse,
ErrorResponse: gqlNativeErrors,
})

By("running the command")
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)

Expect(err).ShouldNot(HaveOccurred())
Eventually(session.Err).Should(gbytes.Say(`Error: error1
error2`))
Eventually(session).ShouldNot(gexec.Exit(0))
})
})
})
})

0 comments on commit 16acd35

Please sign in to comment.