Skip to content

Commit

Permalink
Merge pull request #979 from CircleCI-Public/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
JulesFaucherre authored Aug 2, 2023
2 parents 0fd0133 + f8ce426 commit 50995b1
Show file tree
Hide file tree
Showing 53 changed files with 2,287 additions and 125 deletions.
32 changes: 14 additions & 18 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ executors:
go:
docker:
- image: cimg/go:1.20
resource_class: large
environment:
CGO_ENABLED: 0
mac:
Expand All @@ -25,7 +26,7 @@ commands:
# https://app.circleci.com/jobs/github/CircleCI-Public/circleci-cli/6480
# curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
# The issue seems to be on the server-side, so force HTTP 1.1
name: 'cURL: Force HTTP 1.1'
name: "cURL: Force HTTP 1.1"
command: echo '--http1.1' >> ~/.curlrc
build-docker-image:
steps:
Expand All @@ -41,36 +42,31 @@ commands:
command: |
docker build -t circleci/circleci-cli:0.1.$CIRCLE_BUILD_NUM-alpine --file Dockerfile.alpine .
docker run --rm circleci/circleci-cli:0.1.$CIRCLE_BUILD_NUM-alpine update check
deploy-save-cache-workspace-and-artifacts:
deploy-save-workspace-and-artifacts:
steps:
- save_cache:
key: v4-goreleaser-{{ checksum "~/goreleaser_amd64.deb" }}
paths: [~/goreleaser_amd64.deb]
- persist_to_workspace:
root: .
paths:
- 'dist'
- "dist"
- store_artifacts:
path: ./dist
destination: dist
install-goreleaser:
parameters:
GORELEASER_URL:
version:
type: string
default: https://github.com/goreleaser/goreleaser/releases/download/v0.184.0/goreleaser_amd64.deb
default: "1.19.1"
steps:
- restore_cache:
keys: [v5-goreleaser-]
- run:
name: Install GoReleaser
command: |
[ -f ~/goreleaser_amd64.deb ] || curl --silent --location --fail --retry 3 << parameters.GORELEASER_URL >> > ~/goreleaser_amd64.deb
sudo apt-get update -y
sudo apt install ~/goreleaser_amd64.deb
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt -q update -y
sudo apt -q install -y --no-install-recommends goreleaser=<< parameters.version >>
gomod:
steps:
- restore_cache:
keys: ['v3-gomod-{{ arch }}-']
keys: ["v3-gomod-{{ arch }}-"]
- run:
name: Download go module dependencies
command: go mod download
Expand Down Expand Up @@ -121,7 +117,7 @@ jobs:
- persist_to_workspace:
root: .
paths:
- 'build'
- "build"
cucumber:
docker:
- image: cimg/ruby:2.7
Expand All @@ -130,7 +126,7 @@ jobs:
- attach_workspace:
at: .
- run:
name: 'Install CLI tool from workspace'
name: "Install CLI tool from workspace"
command: sudo cp ~/project/build/linux/amd64/circleci /usr/local/bin/
- run:
command: bundle install
Expand Down Expand Up @@ -209,7 +205,7 @@ jobs:
docker_layer_caching: true
- build-docker-image
- build-alpine-image
- deploy-save-cache-workspace-and-artifacts
- deploy-save-workspace-and-artifacts

deploy:
executor: go
Expand Down Expand Up @@ -246,7 +242,7 @@ jobs:
docker push circleci/circleci-cli:0.1.$CIRCLE_BUILD_NUM-alpine
docker tag circleci/circleci-cli:0.1.$CIRCLE_BUILD_NUM-alpine circleci/circleci-cli:alpine
docker push circleci/circleci-cli:alpine
- deploy-save-cache-workspace-and-artifacts
- deploy-save-workspace-and-artifacts

snap:
docker:
Expand Down
4 changes: 2 additions & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
* @CircleCI-Public/developer-experience
*orb*.go @CircleCI-Public/orb-publishers @CircleCI-Public/developer-experience

/api/runner @CircleCI-Public/runner
/cmd/runner @CircleCI-Public/runner
/api/runner @CircleCI-Public/on-prem
/cmd/runner @CircleCI-Public/on-prem
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ LABEL maintainer="Developer Experience Team <[email protected]>"

ENV CIRCLECI_CLI_SKIP_UPDATE_CHECK true

COPY ./dist/circleci-cli_linux_amd64/circleci /usr/local/bin
COPY ./dist/circleci-cli_linux_amd64_v1/circleci /usr/local/bin
2 changes: 1 addition & 1 deletion Dockerfile.alpine
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM alpine:3.8

ENV CIRCLECI_CLI_SKIP_UPDATE_CHECK true

COPY ./dist/circleci-cli_linux_amd64/circleci /usr/local/bin
COPY ./dist/circleci-cli_linux_amd64_v1/circleci /usr/local/bin

RUN apk add --no-cache --upgrade git openssh ca-certificates

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ GOOS=$(shell go env GOOS)
GOARCH=$(shell go env GOARCH)

build: always
go build -o build/$(GOOS)/$(GOARCH)/circleci
go build -o build/$(GOOS)/$(GOARCH)/circleci -ldflags='-X github.com/CircleCI-Public/circleci-cli/telemetry.SegmentEndpoint=https://api.segment.io'

build-all: build/linux/amd64/circleci build/darwin/amd64/circleci

Expand Down
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,20 @@ Please see the [documentation](https://circleci-public.github.io/circleci-cli) o

## 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**
| Functionality | Impacted commands | Change description | Compatibility with Server |
| --- | --- | --- | --- |
| Config compilation and validation | <ul><li>`circleci config validate`</li><li>`circleci config process`</li><li>`circleci local execute`</li> | The config validation has been moved from the GraphQL API to a specific API endpoint | <ul><li>**Server v4.0.5, v4.1.3, v4.2.0 and above**: Commands use the new specific endpoint</li><li>**Previous version**: Commands use the GraphQL API</li></ul> |
| Orb compilation and validation of orb using private orbs | <ul><li>`circleci orb process`</li><li>`circleci orb validate`</li></ul> | To support the validation of orbs requesting private orbs (see [issue](https://github.com/CircleCI-Public/circleci-cli/issues/751)). A field `ownerId` has been added to the GraphQL orb validation endpoint. Thus allowing the `Impacted commands` to use the `--org-id` parameter to enable the orb compilation / validation | <ul><li>**Server v4.2.0 and above**: The field is accessible so you can use the parameter</li><li>**Previous versions**: The field does not exist making the functionality unavailable</li></ul> |

## Telemetry

The CircleCI CLI includes a telemetry feature that collects basic errors and feature usage data in order to help us improve the experience for everyone.

Telemetry works on an opt-in basis: when running a command for the first time, you will be asked for consent to enable telemetry. For non-TTY STDIN, telemetry is disabled by default, ensuring that scripts that use the CLI run smoothly.

You can disable or enable telemetry anytime in one of the following ways:

* Run the commands `circleci telemetry enable` or `circleci telemetry disable`

* Set the `CIRCLECI_CLI_TELEMETRY_OPTOUT` environment variable to `1` or `true` to disable it

10 changes: 6 additions & 4 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,16 @@ tasks:
build:
desc: Build main
cmds:
- go build -v -o build/darwin/amd64/circleci .

# LDFlags sets the segment endpoint to an empty string thus letting the analytics library set the default endpoint on its own
# Not setting the `SegmentEndpoint` variable would let the value in the code ie "http://localhost"
- go build -v -o build/$(go env GOOS)/$(go env GOARCH)/circleci -ldflags='-X github.com/CircleCI-Public/circleci-cli/telemetry.SegmentEndpoint=https://api.segment.io' .

build-linux:
desc: Build main
cmds:
- go build -v -o build/linux/amd64/circleci .

cover:
desc: tests and generates a cover profile
cmds:
- TESTING=true go test -race -coverprofile=coverage.txt ./...
- TESTING=true go test -race -coverprofile=coverage.txt ./...
19 changes: 19 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (
"io"
"log"
"net/http"
"net/url"
"os"
"sort"
"strings"

"github.com/CircleCI-Public/circleci-cli/api/graphql"
"github.com/CircleCI-Public/circleci-cli/api/rest"
"github.com/CircleCI-Public/circleci-cli/references"
"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/Masterminds/semver"
Expand Down Expand Up @@ -1945,3 +1947,20 @@ func FollowProject(config settings.Config, vcs string, owner string, projectName

return fr, nil
}

type Me struct {
ID string `json:"id"`
Login string `json:"login"`
Name string `json:"name"`
}

func GetMe(client *rest.Client) (Me, error) {
req, err := client.NewRequest("GET", &url.URL{Path: "me"}, nil)
if err != nil {
return Me{}, errors.Wrap(err, "Unable to get user info")
}

var me Me
_, err = client.DoRequest(req, &me)
return me, err
}
22 changes: 18 additions & 4 deletions clitest/clitest.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import (
"runtime"

"github.com/CircleCI-Public/circleci-cli/api/graphql"
"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/onsi/gomega/gexec"
"github.com/onsi/gomega/ghttp"
"github.com/onsi/gomega/types"
"gopkg.in/yaml.v3"

"github.com/onsi/gomega"
)
Expand All @@ -30,10 +32,12 @@ func ShouldFail() types.GomegaMatcher {

// TempSettings contains useful settings for testing the CLI
type TempSettings struct {
Home string
TestServer *ghttp.Server
Config *TmpFile
Update *TmpFile
Home string
TestServer *ghttp.Server
Config *TmpFile
Update *TmpFile
Telemetry *TmpFile
TelemetryDestPath string
}

// Close should be called in an AfterEach and cleans up the temp directory and server process
Expand Down Expand Up @@ -68,6 +72,16 @@ func WithTempSettings() *TempSettings {
gomega.Expect(os.Mkdir(settingsPath, 0700)).To(gomega.Succeed())

tempSettings.Config = OpenTmpFile(settingsPath, "cli.yml")
tempSettings.Telemetry = OpenTmpFile(settingsPath, "telemetry.yml")
content, err := yaml.Marshal(settings.TelemetrySettings{
IsEnabled: false,
HasAnsweredPrompt: true,
})
gomega.Expect(err).ToNot(gomega.HaveOccurred())
_, err = tempSettings.Telemetry.File.Write(content)
gomega.Expect(err).ToNot(gomega.HaveOccurred())
tempSettings.TelemetryDestPath = filepath.Join(tempSettings.Home, "telemetry-content")

tempSettings.Update = OpenTmpFile(settingsPath, "update_check.yml")

tempSettings.TestServer = ghttp.NewServer()
Expand Down
19 changes: 19 additions & 0 deletions clitest/telemetry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package clitest

import (
"encoding/json"
"os"

"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/onsi/gomega"
)

func CompareTelemetryEvent(settings *TempSettings, expected []telemetry.Event) {
content, err := os.ReadFile(settings.TelemetryDestPath)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())

result := []telemetry.Event{}
err = json.Unmarshal(content, &result)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
gomega.Expect(result).To(gomega.Equal(expected))
}
10 changes: 9 additions & 1 deletion cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"github.com/CircleCI-Public/circleci-cli/local"
"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/spf13/cobra"
)

Expand All @@ -16,7 +17,14 @@ func newLocalExecuteCommand(config *settings.Config) *cobra.Command {
return nil
},
RunE: func(cmd *cobra.Command, _ []string) error {
return local.Execute(cmd.Flags(), config, args)
err := local.Execute(cmd.Flags(), config, args)

telemetryClient, ok := telemetry.FromContext(cmd.Context())
if ok {
_ = telemetryClient.Track(telemetry.CreateLocalExecuteEvent(telemetry.GetCommandInformation(cmd, true)))
}

return err
},
Args: cobra.MinimumNArgs(1),
}
Expand Down
3 changes: 3 additions & 0 deletions cmd/cmd_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"testing"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand All @@ -14,6 +15,8 @@ import (
var pathCLI string

var _ = BeforeSuite(func() {
SetDefaultEventuallyTimeout(time.Second * 30)

var err error
pathCLI, err = gexec.Build("github.com/CircleCI-Public/circleci-cli")
Ω(err).ShouldNot(HaveOccurred())
Expand Down
10 changes: 9 additions & 1 deletion cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ package cmd
import (
"os"

"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/spf13/cobra"
)

func newCompletionCommand() *cobra.Command {
func newCompletionCommand(config *settings.Config) *cobra.Command {
completionCmd := &cobra.Command{
Use: "completion",
Short: "Generate shell completion scripts",
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
telemetryClient, ok := telemetry.FromContext(cmd.Context())
if ok {
_ = telemetryClient.Track(telemetry.CreateCompletionCommand(telemetry.GetCommandInformation(cmd, true)))
}
},
Run: func(cmd *cobra.Command, _ []string) {
err := cmd.Help()
if err != nil {
Expand Down
Loading

0 comments on commit 50995b1

Please sign in to comment.