Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ jobs:

- uses: actions/setup-go@v5
with:
go-version: "1.22"
go-version: "1.26.6"
cache: true

- name: vet
run: make vet
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.12.2

- name: test
run: make test
Expand Down
54 changes: 54 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: "2"
formatters:
enable:
- golines # checks if code is formatted, and fixes long lines
- gofumpt # enforces a stricter format than 'gofmt', while being backwards compatible
settings:
golines:
max-len: 130
reformat-tags: false
linters:
enable:
- copyloopvar # Detects variable copies in loops that could cause bugs
- exhaustive # Ensures enum switch statements are exhaustive
- gocyclo # Checks cyclomatic complexity of functions
- gosec # Inspects source code for security problems
- misspell # Finds commonly misspelled English words
#- mnd # Detects magic numbers (constants with no explanation)
- nakedret # Finds naked returns in functions longer than a few lines
- revive # A fast, configurable, extensible, flexible, and beautiful linter for Go
- staticcheck # The advanced Go linter (go vet on steroids)
- modernize # Suggests simplifications to Go code, using modern language and library features
- errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
- testifylint # checks usage of github.com/stretchr/testify
- sloglint # ensure consistent code style when using log/slog
- nolintlint # reports ill-formed or insufficient nolint directives
- mirror # reports wrong mirror patterns of bytes/strings usage
- intrange # finds places where for loops could make use of an integer range
- gocritic # provides diagnostics that check for bugs, performance and style issues
- funcorder # checks the order of functions, methods, and constructors
- exptostd # detects functions from golang.org/x/exp/ that can be replaced by std functions
- errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error
- errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases
- embeddedstructfieldcheck # checks embedded types in structs
- asciicheck # checks that your code does not contain non-ASCII identifiers
- prealloc # [premature optimization, but can be used in some cases] finds slice declarations that could potentially be preallocated
#- wrapcheck # checks that errors returned from external packages are wrapped
#- goconst # finds repeated strings that could be replaced by a constant
- testpackage # Linter that makes you use a separate _test package.
settings:
gocyclo:
min-complexity: 40
exhaustive:
default-signifies-exhaustive: true
exclusions:
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- path: '_test\.go'
linters:
- goconst
- gosec
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ publishes it, and `eds wf app status` (or the lower-level `eds wf run`/
make build # build for current platform -> ./bin/eds
make build-all # cross-compile darwin/linux x amd64/arm64 -> ./dist/
make test # go test ./...
make vet # go vet ./...
make lint
make tidy # go mod tidy
make clean # remove ./bin and ./dist
```

There are currently no `_test.go` files in the repo, so `make test` is a no-op
until tests are added. `make all` runs `vet test build` in sequence.
until tests are added. `make all` runs `lint test build` in sequence.

Building directly without make:

Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ Go 1.22+ is required. Target platforms are Linux + macOS only.
Useful targets:

```bash
make vet # go vet ./...
make lint
make test # go test ./...
make build # current platform into ./bin/
make build-all # full matrix into ./dist/
```

Run `make vet` and `make test` before opening a PR — CI runs the same checks.
Run `make lint` and `make test` before opening a PR — CI runs the same checks.

## Code conventions

Expand All @@ -54,7 +54,7 @@ In short:

1. Fork the repo and create a branch off `main`.
2. Make your change, with tests where it makes sense.
3. Run `make vet` and `make test`.
3. Run `make lint` and `make test`.
4. Open a pull request describing what changed and why.

## Reporting a security issue
Expand Down
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# make build-one - helper invoked by build-all (GOOS=... GOARCH=...)
# make clean - remove ./bin and ./dist
# make test - run `go test ./...`
# make vet - run `go vet ./...`
# make tidy - run `go mod tidy`
# make install - `go install` into $GOBIN
# make release - build-all + sha256 sums
Expand Down Expand Up @@ -47,7 +46,7 @@ LDFLAGS := -s -w -X main.version=$(VERSION)
# ---- targets --------------------------------------------------------------

.PHONY: all
all: vet test build
all: lint test build

.PHONY: build
build:
Expand Down Expand Up @@ -155,10 +154,6 @@ install:
test:
go test $(GOFLAGS) ./...

.PHONY: vet
vet:
go vet ./...

.PHONY: tidy
tidy:
go mod tidy
Expand All @@ -177,8 +172,13 @@ help:
@echo " upload build-all + publish to S3 (BUCKET=... VERSION=...)"
@echo " upload-latest only update the 'latest' pointer in the bucket"
@echo " install go install into \$$GOBIN"
@echo " test, vet, tidy standard Go targets"
@echo " lint run golangci-lint"
@echo " test, tidy standard Go targets"
@echo " clean remove ./bin and ./dist"

openapi-generator:
openapi-generator-cli generate -i openapi-public.yaml -g go -o ./internal/workflow_client -c .openapi-generator.yaml

.PHONY: lint
lint:
golangci-lint run --fix
15 changes: 5 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,9 @@ eds wf app deployments <id> list publish history
eds wf app status <id> run status + live URL

eds wf run show <id> show a run's status, stages and jobs
eds wf run list [--pipeline-id ID] list runs
eds wf run stop <id> stop a running run

eds wf job show <id> show job details
eds wf job list --run-id ID list jobs for a run
eds wf job logs <id> stream a job's logs
eds wf job retry <id> retry a failed/canceled job
eds wf job stop <id> stop a running job
eds wf job logs <id> get logs for a job
```

### Login
Expand Down Expand Up @@ -209,7 +204,7 @@ eds wf app status "$APP_ID" --json | jq -r '.application.run.stages[].jobs[] | s

`eds wf run` and `eds wf job` are the lower-level primitives behind `eds wf
app status` — use them directly when you need to inspect or control a
particular run/job (e.g. `eds wf run stop`, `eds wf job retry`).
particular run (e.g. `eds wf run stop`) or stream job logs (`eds wf job logs`).

## File upload / push

Expand Down Expand Up @@ -258,7 +253,7 @@ curl -fsSL https://storage.cloud.ru/my-bucket/evolution-devservices-cli/install.
## Development

```bash
make vet # go vet ./...
make lint
make test # go test ./...
make build # current platform into ./bin/
make build-all # full matrix into ./dist/
Expand All @@ -279,8 +274,8 @@ cmd/
repo.go # `eds repo list|create|show|delete|clone`
wf.go # `eds wf` parent command (groups app/run/job)
app.go # `eds wf app create|list|show|update|delete|deploy|deployments|status`
run.go # `eds wf run show|list|stop`
job.go # `eds wf job show|list|logs|retry|stop`
run.go # `eds wf run show|stop`
job.go # `eds wf job logs`
internal/
config/ # disk config + env overrides
output/ # JSON / table formatting
Expand Down
142 changes: 1 addition & 141 deletions cmd/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import (

workflowclient "github.com/cloud-ru/evolution-devservices-cli/internal/workflow_client"
"github.com/spf13/cobra"

"github.com/cloud-ru/evolution-devservices-cli/internal/output"
"github.com/cloud-ru/evolution-devservices-cli/internal/workflowapi"
)

// newJobCmd creates the parent `eds wf job` command and all its subcommands.
Expand All @@ -19,98 +16,9 @@ func newJobCmd() *cobra.Command {
Use: "job",
Short: "Inspect and control Workflow Studio jobs",
}
cmd.AddCommand(newJobShowCmd())
cmd.AddCommand(newJobListCmd())
cmd.AddCommand(newJobLogsCmd())
cmd.AddCommand(newJobRetryCmd())
cmd.AddCommand(newJobStopCmd())
return cmd
}

func newJobShowCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "show <job-id>",
Short: "Show job details",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
ctx, err := resolveContext(cmd)
if err != nil {
return err
}
if err := ctx.ensureWorkflowAuth(cmd.Context()); err != nil {
return err
}

job, err := ctx.WorkflowAPI.GetJob(cmd.Context(), args[0])
if err != nil {
return err
}

if ctx.Printer.Format == output.FormatJSON {
return ctx.Printer.PrintJSON(job)
}
ctx.Printer.KeyValue([][2]string{
{"id", job.ID},
{"name", job.Name},
{"run_id", job.RunID},
{"stage_id", job.StageID},
{"type", job.Type},
{"status", string(job.Status)},
{"updated_at", output.HumanTime(job.UpdatedAt)},
})
return nil
},
}
return cmd
}

func newJobListCmd() *cobra.Command {
var (
runID string
limit int
offset int
)

cmd := &cobra.Command{
Use: "list",
Short: "List jobs for a run",
Example: ` eds wf job list --run-id my-run-id
eds wf job list --run-id my-run-id --json | jq '.[].status'`,
RunE: func(cmd *cobra.Command, _ []string) error {
ctx, err := resolveContext(cmd)
if err != nil {
return err
}
if err := ctx.ensureWorkflowAuth(cmd.Context()); err != nil {
return err
}

jobs, err := ctx.WorkflowAPI.ListJobs(cmd.Context(), workflowapi.ListJobsOptions{
RunID: runID,
Limit: limit,
Offset: offset,
})
if err != nil {
return err
}

if ctx.Printer.Format == output.FormatJSON {
return ctx.Printer.PrintJSON(jobs)
}

headers := []string{"ID", "NAME", "STAGE_ID", "STATUS", "UPDATED"}
rows := make([][]string, 0, len(jobs))
for _, j := range jobs {
rows = append(rows, []string{j.ID, j.Name, j.StageID, string(j.Status), output.HumanTime(j.UpdatedAt)})
}
ctx.Printer.Table(headers, rows)
return nil
},
}
cmd.AddCommand(newJobLogsCmd())

cmd.Flags().StringVar(&runID, "run-id", "", "run id to list jobs for (required)")
cmd.Flags().IntVar(&limit, "limit", 50, "page size")
cmd.Flags().IntVar(&offset, "offset", 0, "offset")
return cmd
}

Expand Down Expand Up @@ -157,51 +65,3 @@ func newJobLogsCmd() *cobra.Command {

return cmd
}

func newJobRetryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "retry <job-id>",
Short: "Retry a failed or canceled job",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
ctx, err := resolveContext(cmd)
if err != nil {
return err
}
if err := ctx.ensureWorkflowAuth(cmd.Context()); err != nil {
return err
}

if err := ctx.WorkflowAPI.RetryJob(cmd.Context(), args[0]); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "Retrying job %s\n", args[0])
return nil
},
}
return cmd
}

func newJobStopCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "stop <job-id>",
Short: "Stop a running job",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
ctx, err := resolveContext(cmd)
if err != nil {
return err
}
if err := ctx.ensureWorkflowAuth(cmd.Context()); err != nil {
return err
}

if err := ctx.WorkflowAPI.StopJob(cmd.Context(), args[0]); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "Stopped job %s\n", args[0])
return nil
},
}
return cmd
}
19 changes: 3 additions & 16 deletions cmd/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/exec"
"strings"

"github.com/google/uuid"
"github.com/spf13/cobra"

"github.com/cloud-ru/evolution-devservices-cli/internal/output"
Expand Down Expand Up @@ -341,20 +342,6 @@ func resolveRepoID(ctx context.Context, r *runtimeContext, ref string) (string,
}

func looksLikeUUID(s string) bool {
if len(s) != 36 {
return false
}
for i, c := range s {
switch i {
case 8, 13, 18, 23:
if c != '-' {
return false
}
default:
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
return false
}
}
}
return true
_, err := uuid.Parse(s)
return err == nil
}
Loading
Loading