diff --git a/.gitignore b/.gitignore index eb47e0f..e38e706 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ .DS_Store /swagger/ -openapi* \ No newline at end of file +openapi* +internal/workflow_client/*.md diff --git a/CLAUDE.md b/CLAUDE.md index ddcc1a0..fccd894 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,7 +21,7 @@ stable `--json` output, config comes from env vars, and `skill/SKILL.md` documents the CLI's contract for AI agents driving it. The primary agent-facing scenario is *ship a vibe-coded app*: `eds repo create` + `git push` gets code hosted, `eds wf app create` publishes it (auto-deploy -on create), and `eds wf app status` (or the lower-level `eds wf run`/ +on create), and `eds wf app show` (or the lower-level `eds wf run`/ `eds wf job`) tracks the rollout. ## Commands @@ -59,19 +59,20 @@ genuinely internal and not tied to where the repo lives. ## Architecture -Cobra-based CLI, one command per file under `cmd/`, thin API clients under -`internal/repoapi/` (Repo product) and `internal/workflowapi/` (Workflow -Studio). +Cobra-based CLI, one command per file under `cmd/`, thin API client under +`internal/repoapi/` (Repo product) and generated OpenAPI client under +`internal/workflow_client/` (Workflow Studio). - `main.go` — entry point, wires `main.version` (ldflags) into `cmd.SetVersion`. - `cmd/root.go` — builds the root `eds` command, registers global persistent flags. Product-scoped: `--repo-api-url`, `--repo-git-host` (Repo product); `--wf-api-url` (Workflow Studio). Platform-level (shared, unprefixed): `--project`, `--api-key`. Plus `--json`, `--quiet`. +the API client and printer. - `cmd/helpers.go` — `resolveContext(cmd)` is the entry point every subcommand calls first. It loads config, layers flag overrides on top (flags > env > - file > defaults), and builds a `runtimeContext{Cfg, API, WorkflowAPI, - Printer, Quiet}`. `requireAPIKey()` guards Repo-product commands. + file > defaults), and builds a `runtimeContext{Cfg, API, Printer, Quiet, + ProjectID, WorkflowClient}`. `requireAPIKey()` guards Repo-product commands. `ensureWorkflowAuth(ctx)` guards Workflow Studio commands: it validates that `APIKey` is set (the same key is used for both products). Both helpers return the same friendly error when the key is missing. @@ -84,15 +85,11 @@ Studio). `newRunCmd()`, `newJobCmd()` as children. Doesn't hold any logic itself. - `cmd/app.go`, `cmd/run.go`, `cmd/job.go` — Workflow Studio subcommand trees, nested under `eds wf`. `app.go` holds `eds wf app create|list|show| - update|delete|deploy|deployments|status` (an **application** wires a + update|delete|deploy|deployments` (an **application** wires a repo+branch to a deploy pipeline; a **deployment** runs that pipeline and publishes it). `app create --repository` reuses `resolveRepoID` from - `repo.go` to accept either a Repo-product UUID or name. `app status` is a - convenience wrapper: it fetches the application (whose `run` field already - embeds stage/job status) plus its most recent deployment (for the live - URL) in one call. `run.go`/`job.go` are the lower-level primitives behind - it. `job.go`'s `logs` command reads the job-logs endpoint as SSE and - prints each `data:` line to stdout. + `repo.go` to accept either a Repo-product UUID or name. `run.go`/`job.go` + are the lower-level primitives behind it. Note (observed empirically, not documented in the spec): `application.status` and `application.run.status` are separate lifecycles. Creating an application auto-triggers its first run; even after `run.status` reaches @@ -133,18 +130,13 @@ Studio). `/project/{projectID}/repository[ies]`. `ListRepositories` omits the `search` query param entirely when empty — the API treats an empty string as a literal (matches nothing) rather than a wildcard. -- `internal/workflowapi/client.go` — the Workflow Studio counterpart to - `repoapi/client.go`: same `Do`/`APIError`/request-id shape, sends - `X-API-KEY` (the same key as Repo), has no built-in request timeout - (bounded by the caller's context instead, since `logs` can stay open for - a running job), and adds `Stream` for reading an SSE response body - line-by-line. -- `internal/workflowapi/application.go`, `run.go`, `job.go` — - application/deployment, run/stage, and job request/response types plus - the API calls, all scoped under `/project/{projectID}/...`. -- `openapi-user.yaml` — OpenAPI (Swagger 2.0) spec for the Workflow Studio - user API; the source of truth for request/response shapes when extending +- `internal/workflow_client/` — generated OpenAPI client for the Workflow + Studio user API (from `openapi-public.yaml`). Covers services, pipelines, + and workflows APIs. `cmd/` calls into this instead of the older hand-written `internal/workflowapi`. +- `openapi-public.yaml` — OpenAPI (Swagger 2.0) spec for the Workflow Studio + user API; the source of truth for request/response shapes and for regenerating + `internal/workflow_client`. - `swagger/swagger.yaml` — OpenAPI spec for the upstream Repo API; the source of truth for request/response shapes when extending `internal/repoapi`. `swagger/swagger.ru.yaml` is a Russian-translated copy (all `summary`/ @@ -167,9 +159,9 @@ Studio). If it hits a Repo-product API, call `ctx.requireAPIKey()`. If it hits a Workflow Studio API, call `ctx.ensureWorkflowAuth(cmd.Context())` — both validate that `EDS_API_KEY` is set. -- Every subcommand that returns structured data should support both table - (default on TTY) and `--json` output via `ctx.Printer`, not ad-hoc - `fmt.Println`. +- Repo subcommands that return structured data support both table (default + on TTY) and `--json` output via `ctx.Printer`. Workflow Studio subcommands + currently output JSON only. - `eds repo` commands (and `eds wf app create --repository`) accept either a repository UUID or a name (`resolveRepoID` / `looksLikeUUID`); don't require callers to look up IDs first. diff --git a/README.md b/README.md index 4c9f6c0..b4284a8 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,6 @@ eds wf app update --branch B [--name N] update name/branch eds wf app delete [--force] delete an application eds wf app deploy run the pipeline and publish eds wf app deployments list publish history -eds wf app status run status + live URL eds wf run show show a run's status, stages and jobs eds wf run stop stop a running run @@ -193,23 +192,24 @@ APP_ID=$(eds wf app create my-site --repository "$REPO_ID" --branch main --json # status) because "publishing" can last well after the run already reports # "done". for i in $(seq 1 20); do - STATUS=$(eds wf app status "$APP_ID" --json | jq -r '.application.status') + STATUS=$(eds wf app show "$APP_ID" --json | jq -r '.status') echo "status: $STATUS" [ "$STATUS" = "running" ] || [ "$STATUS" = "error" ] && break sleep 15 done -eds wf app status "$APP_ID" --json | jq '{status: .application.status, url: .latest_deployment.url}' +URL=$(eds wf app deployments "$APP_ID" --json | jq -r '.deployments[0].url') +echo "url: $URL" ``` If a deployment fails, drill into the failing job's logs: ```bash -eds wf app status "$APP_ID" --json | jq -r '.application.run.stages[].jobs[] | select(.status=="failed") | .id' \ +eds wf app show "$APP_ID" --json | jq -r '.run.stages[].jobs[] | select(.status=="failed") | .id' \ | xargs -I{} eds wf job logs {} ``` `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 +app show` — use them directly when you need to inspect or control a particular run (e.g. `eds wf run stop`) or stream job logs (`eds wf job logs`). ## File upload / push @@ -279,14 +279,14 @@ cmd/ version.go # `eds version` 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` + app.go # `eds wf app create|list|show|update|delete|deploy|deployments` run.go # `eds wf run show|stop` job.go # `eds wf job logs` internal/ config/ # disk config + env overrides output/ # JSON / table formatting repoapi/ # thin HTTP client for the Repo product API - workflowapi/ # thin HTTP client for the Workflow Studio product API + workflow_client/ # generated OpenAPI client for Workflow Studio scripts/ install.sh # one-liner installer (GitHub Releases by default) skill/ diff --git a/cmd/app.go b/cmd/app.go index dd61e3c..9e3d41f 100644 --- a/cmd/app.go +++ b/cmd/app.go @@ -6,10 +6,8 @@ import ( "os" "strings" + 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" ) // newAppCmd creates the parent `eds wf app` command and all its subcommands. @@ -28,7 +26,6 @@ func newAppCmd() *cobra.Command { cmd.AddCommand(newAppDeleteCmd()) cmd.AddCommand(newAppDeployCmd()) cmd.AddCommand(newAppDeploymentsCmd()) - cmd.AddCommand(newAppStatusCmd()) return cmd } @@ -76,20 +73,22 @@ accepts either its id or its name) or an external git URL (--repository-url).`, } } - req := workflowapi.CreateApplicationRequest{ - Name: args[0], - Branch: branch, - RepositoryID: repositoryID, - RepositoryURL: repositoryURL, + req := workflowclient.GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestApplicationCreate{ + Branch: branch, + Name: &args[0], + } + if repositoryID != "" { + req.RepositoryId = &repositoryID + } + if repositoryURL != "" { + req.RepositoryUrl = &repositoryURL } - app, err := ctx.WorkflowAPI.CreateApplication(cmd.Context(), req) + app, _, err := ctx.WorkflowClient.ServicesAPI.ProjectProjectIdApplicationPost(cmd.Context(), ctx.ProjectID). + Request(req).Execute() if err != nil { - return err + return fmt.Errorf("workflow client application post: %w", err) } - if !ctx.Quiet { - fmt.Fprintf(cmd.OutOrStdout(), "Created application %q (id=%s)\n", app.Name, app.ID) - } return ctx.Printer.PrintJSON(app) }, } @@ -123,28 +122,17 @@ func newAppListCmd() *cobra.Command { return err } - resp, err := ctx.WorkflowAPI.ListApplications(cmd.Context(), workflowapi.ListApplicationsOptions{ - Search: search, - Sort: workflowapi.SortOrder(sort), - Limit: limit, - Offset: offset, - }) + resp, _, err := ctx.WorkflowClient.ServicesAPI.ListApplications(cmd.Context(), ctx.ProjectID). + Sort(sort). + Limit(limit). + Offset(offset). + Search(search). + Execute() if err != nil { - return err - } - - if ctx.Printer.Format == output.FormatJSON { - return ctx.Printer.PrintJSON(resp) + return fmt.Errorf("workflow client application list: %w", err) } - headers := []string{"ID", "NAME", "BRANCH", "STATUS", "UPDATED"} - rows := make([][]string, 0, len(resp.Applications)) - for _, a := range resp.Applications { - rows = append(rows, []string{a.ID, a.Name, a.Branch, a.Status, output.HumanTime(a.UpdatedAt)}) - } - ctx.Printer.Table(headers, rows) - fmt.Fprintf(cmd.OutOrStdout(), "Showing %d of %d\n", len(resp.Applications), resp.Total) - return nil + return ctx.Printer.PrintJSON(resp) }, } @@ -169,28 +157,13 @@ func newAppShowCmd() *cobra.Command { return err } - app, err := ctx.WorkflowAPI.GetApplication(cmd.Context(), args[0]) + app, _, err := ctx.WorkflowClient.ServicesAPI.ProjectProjectIdApplicationApplicationIdGet(cmd.Context(), ctx.ProjectID, args[0]). + Execute() if err != nil { - return err + return fmt.Errorf("workflow client get app: %w", err) } - if ctx.Printer.Format == output.FormatJSON { - return ctx.Printer.PrintJSON(app) - } - pairs := [][2]string{ - {"id", app.ID}, - {"name", app.Name}, - {"branch", app.Branch}, - {"repository_id", app.RepositoryID}, - {"repository_url", app.RepositoryURL}, - {"status", app.Status}, - {"run_id", app.RunID}, - {"pipeline_id", app.PipelineID}, - {"created_at", output.HumanTime(app.CreatedAt)}, - {"updated_at", output.HumanTime(app.UpdatedAt)}, - } - ctx.Printer.KeyValue(pairs) - return nil + return ctx.Printer.PrintJSON(app) }, } return cmd @@ -204,7 +177,7 @@ func newAppUpdateCmd() *cobra.Command { cmd := &cobra.Command{ Use: "update ", - Short: "Update an application's name or branch", + Short: "Update an application's branch (optionally name)", Args: cobra.ExactArgs(1), Example: ` eds wf app update my-app-id --branch release eds wf app update my-app-id --name new-name --branch main`, @@ -220,14 +193,18 @@ func newAppUpdateCmd() *cobra.Command { return fmt.Errorf("--branch is required") } - if err := ctx.WorkflowAPI.UpdateApplication(cmd.Context(), args[0], workflowapi.UpdateApplicationRequest{ - Name: name, - Branch: branch, - }); err != nil { - return err + req := workflowclient.GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestApplicationUpdate{ + Branch: branch, + SpaceId: "", } - if !ctx.Quiet { - fmt.Fprintf(cmd.OutOrStdout(), "Updated application %s\n", args[0]) + if name != "" { + req.Name = &name + } + _, err = ctx.WorkflowClient.ServicesAPI.ProjectProjectIdApplicationApplicationIdPatch(cmd.Context(), ctx.ProjectID, args[0]). + Request(req). + Execute() + if err != nil { + return fmt.Errorf("workflow client update application: %w", err) } return nil }, @@ -266,10 +243,12 @@ func newAppDeleteCmd() *cobra.Command { } } - if err := ctx.WorkflowAPI.DeleteApplication(cmd.Context(), args[0]); err != nil { - return err + _, err = ctx.WorkflowClient.ServicesAPI.ProjectProjectIdApplicationApplicationIdDelete(cmd.Context(), ctx.ProjectID, args[0]). + Execute() + if err != nil { + return fmt.Errorf("workflow client delete application: %w", err) } - fmt.Fprintf(cmd.OutOrStdout(), "Deleted application %s\n", args[0]) + return nil }, } @@ -284,9 +263,9 @@ func newAppDeployCmd() *cobra.Command { Short: "Run the application's pipeline and publish it", Args: cobra.ExactArgs(1), Long: `deploy triggers a new run of the application's deploy pipeline. -Use the returned run_id with "eds wf run show" or "eds wf app status" to +Use the returned run_id with "eds wf run show" to follow progress, and check the "url" field once it succeeds.`, - Example: ` eds wf app deploy my-app-id --json | jq -r '.run_id'`, + Example: ` eds wf app deploy my-app-id --json | jq -r '.deployment.run_id'`, RunE: func(cmd *cobra.Command, args []string) error { ctx, err := resolveContext(cmd) if err != nil { @@ -296,13 +275,13 @@ follow progress, and check the "url" field once it succeeds.`, return err } - dep, err := ctx.WorkflowAPI.CreateDeployment(cmd.Context(), args[0]) + dep, _, err := ctx.WorkflowClient.ServicesAPI.ProjectProjectIdApplicationApplicationIdDeploymentPost(cmd.Context(), ctx.ProjectID, args[0]). + Request(map[string]any{}). + Execute() if err != nil { - return err - } - if !ctx.Quiet { - fmt.Fprintf(cmd.OutOrStdout(), "Deploying application %s (run_id=%s)\n", args[0], dep.RunID) + return fmt.Errorf("workflow client deploy application: %w", err) } + return ctx.Printer.PrintJSON(dep) }, } @@ -332,28 +311,17 @@ func newAppDeploymentsCmd() *cobra.Command { return err } - resp, err := ctx.WorkflowAPI.ListDeployments(cmd.Context(), args[0], workflowapi.ListDeploymentsOptions{ - Search: search, - Sort: workflowapi.SortOrder(sort), - Limit: limit, - Offset: offset, - }) + resp, _, err := ctx.WorkflowClient.ServicesAPI.ProjectProjectIdApplicationApplicationIdDeploymentListGet(cmd.Context(), ctx.ProjectID, args[0]). + Limit(limit). + Offset(offset). + Search(search). + Sort(sort). + Execute() if err != nil { - return err + return fmt.Errorf("workflow client list application: %w", err) } - if ctx.Printer.Format == output.FormatJSON { - return ctx.Printer.PrintJSON(resp) - } - - headers := []string{"ID", "RUN_ID", "URL", "CREATED"} - rows := make([][]string, 0, len(resp.Deployments)) - for _, d := range resp.Deployments { - rows = append(rows, []string{d.ID, d.RunID, d.URL, output.HumanTime(d.CreatedAt)}) - } - ctx.Printer.Table(headers, rows) - fmt.Fprintf(cmd.OutOrStdout(), "Showing %d of %d\n", len(resp.Deployments), resp.Total) - return nil + return ctx.Printer.PrintJSON(resp) }, } @@ -363,68 +331,3 @@ func newAppDeploymentsCmd() *cobra.Command { cmd.Flags().IntVar(&offset, "offset", 0, "offset") return cmd } - -func newAppStatusCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "status ", - Short: "Show publish status: current run, stages/jobs and the live URL", - Args: cobra.ExactArgs(1), - Long: `status is a convenience wrapper around "eds wf app show" + the -application's latest run and deployment: it resolves the application's -current run (with its stage/job breakdown) and its most recent deployment -URL in one call. Useful for polling after "eds wf app deploy".`, - 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 - } - - app, err := ctx.WorkflowAPI.GetApplication(cmd.Context(), args[0]) - if err != nil { - return err - } - - var latest *workflowapi.Deployment - deps, err := ctx.WorkflowAPI.ListDeployments(cmd.Context(), args[0], workflowapi.ListDeploymentsOptions{ - Sort: workflowapi.SortCreatedAtDesc, - Limit: 1, - }) - if err == nil && len(deps.Deployments) > 0 { - latest = &deps.Deployments[0] - } - - if ctx.Printer.Format == output.FormatJSON { - return ctx.Printer.PrintJSON(map[string]any{ - "application": app, - "latest_deployment": latest, - }) - } - - ctx.Printer.KeyValue([][2]string{ - {"id", app.ID}, - {"name", app.Name}, - {"status", app.Status}, - {"run_id", app.RunID}, - }) - - if app.Run != nil { - fmt.Fprintf(cmd.OutOrStdout(), "\nRun %s: %s\n", app.Run.ID, app.Run.Status) - for _, stage := range app.Run.Stages { - fmt.Fprintf(cmd.OutOrStdout(), " stage %-24s %s\n", stage.Name, stage.Status) - for _, job := range stage.Jobs { - fmt.Fprintf(cmd.OutOrStdout(), " job %-22s %s\n", job.Name, job.Status) - } - } - } - - if latest != nil && latest.URL != "" { - fmt.Fprintf(cmd.OutOrStdout(), "\nurl: %s\n", latest.URL) - } - return nil - }, - } - return cmd -} diff --git a/cmd/helpers.go b/cmd/helpers.go index 8887627..de0307f 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -10,7 +10,6 @@ import ( "github.com/cloud-ru/evolution-devservices-cli/internal/config" "github.com/cloud-ru/evolution-devservices-cli/internal/output" "github.com/cloud-ru/evolution-devservices-cli/internal/repoapi" - "github.com/cloud-ru/evolution-devservices-cli/internal/workflowapi" ) // runtimeContext holds the resolved configuration, API clients and printer @@ -18,7 +17,6 @@ import ( type runtimeContext struct { Cfg *config.Config API *repoapi.Client - WorkflowAPI *workflowapi.Client Printer *output.Printer Quiet bool ProjectID string @@ -30,7 +28,7 @@ type runtimeContext struct { func resolveContext(cmd *cobra.Command) (*runtimeContext, error) { cfg, err := config.Load() if err != nil { - return nil, err + return nil, fmt.Errorf("cannot load config: %w", err) } // Apply flag overrides on top of config (flags > env > file > defaults). @@ -65,7 +63,6 @@ func resolveContext(cmd *cobra.Command) (*runtimeContext, error) { rt := &runtimeContext{ Cfg: cfg, API: repoapi.New(cfg.APIURL, cfg.APIKey, cfg.ProjectID), - WorkflowAPI: workflowapi.New(cfg.WorkflowAPIURL, cfg.APIKey, cfg.ProjectID), Printer: output.New(format), Quiet: quiet, ProjectID: cfg.ProjectID, diff --git a/cmd/job.go b/cmd/job.go index a0a057b..2d76e5a 100644 --- a/cmd/job.go +++ b/cmd/job.go @@ -42,7 +42,7 @@ func newJobLogsCmd() *cobra.Command { } resp, _, err := ctx.WorkflowClient.WorkflowsAPI. - ProjectProjectIdJobJobIdLogListGet(cmd.Context(), ctx.ProjectID, args[0]). + GetJobLogs(cmd.Context(), ctx.ProjectID, args[0]). Request(workflowclient.GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestJobLogList{ BeforeTime: &beforeTime, Limit: &limit, diff --git a/cmd/login.go b/cmd/login.go index 5fd2522..58fb4cd 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -40,7 +40,7 @@ permissions.`, RunE: func(cmd *cobra.Command, _ []string) error { cfg, err := config.Load() if err != nil { - return err + return fmt.Errorf("cannot load config: %w", err) } // Read from stdin if requested. @@ -71,7 +71,7 @@ permissions.`, } if err := cfg.Save(); err != nil { - return err + return fmt.Errorf("save config: %w", err) } fmt.Fprintln(cmd.OutOrStdout(), "Credentials saved.") return nil diff --git a/cmd/repo.go b/cmd/repo.go index 5afdf7e..dfe94c9 100644 --- a/cmd/repo.go +++ b/cmd/repo.go @@ -68,10 +68,10 @@ func newRepoListCmd() *cobra.Command { resp, err := ctx.API.ListRepositories(cmd.Context(), opts) if err != nil { - return err + return fmt.Errorf("api list repositories: %w", err) } - if ctx.Printer.Format == 1 /* FormatJSON */ { + if ctx.Printer.Format == output.FormatJSON { return ctx.Printer.PrintJSON(resp) } @@ -130,7 +130,7 @@ func newRepoCreateCmd() *cobra.Command { r, err := ctx.API.CreateRepository(cmd.Context(), req) if err != nil { - return err + return fmt.Errorf("api create repository: %w", err) } if !ctx.Quiet { @@ -170,10 +170,10 @@ func newRepoShowCmd() *cobra.Command { info, err := ctx.API.GetRepository(cmd.Context(), id) if err != nil { - return err + return fmt.Errorf("api get repository: %w", err) } - if ctx.Printer.Format == 1 /* FormatJSON */ { + if ctx.Printer.Format == output.FormatJSON { return ctx.Printer.PrintJSON(info) } ctx.Printer.KeyValue([][2]string{ @@ -230,7 +230,7 @@ func newRepoDeleteCmd() *cobra.Command { } if err := ctx.API.DeleteRepository(cmd.Context(), id); err != nil { - return err + return fmt.Errorf("api delete repository: %w", err) } fmt.Fprintf(cmd.OutOrStdout(), "Deleted repository %s\n", args[0]) return nil @@ -276,7 +276,7 @@ the clone, as you would with any other git server.`, info, err := ctx.API.GetRepository(cmd.Context(), id) if err != nil { - return err + return fmt.Errorf("api get repository: %w", err) } cloneURL := info.Clone.HTTPS @@ -331,7 +331,7 @@ func resolveRepoID(ctx context.Context, r *runtimeContext, ref string) (string, Limit: 10, }) if err != nil { - return "", err + return "", fmt.Errorf("api list repositories: %w", err) } for _, repo := range resp.Repositories { if strings.EqualFold(repo.Name, ref) { diff --git a/cmd/run.go b/cmd/run.go index 0e2a070..3c1c54a 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -4,8 +4,6 @@ import ( "fmt" "github.com/spf13/cobra" - - "github.com/cloud-ru/evolution-devservices-cli/internal/output" ) // newRunCmd creates the parent `eds wf run` command and all its subcommands. @@ -37,29 +35,17 @@ func newRunShowCmd() *cobra.Command { return err } - run, err := ctx.WorkflowAPI.GetRun(cmd.Context(), args[0]) + run, _, err := ctx.WorkflowClient.WorkflowsAPI.GetRun(cmd.Context(), ctx.ProjectID, args[0]). + Execute() if err != nil { - return err + return fmt.Errorf("workflow client get run: %w", err) } - if ctx.Printer.Format == output.FormatJSON { - return ctx.Printer.PrintJSON(run) + err = ctx.Printer.PrintJSON(run) + if err != nil { + return fmt.Errorf("print json run: %w", err) } - ctx.Printer.KeyValue([][2]string{ - {"id", run.ID}, - {"pipeline_id", run.PipelineID}, - {"branch", run.Branch}, - {"status", string(run.Status)}, - {"status_message", run.StatusMessage}, - {"updated_at", output.HumanTime(run.UpdatedAt)}, - }) - for _, stage := range run.Stages { - fmt.Fprintf(cmd.OutOrStdout(), "\nstage %-24s %s\n", stage.Name, stage.Status) - for _, job := range stage.Jobs { - fmt.Fprintf(cmd.OutOrStdout(), " job %-22s %s\n", job.Name, job.Status) - } - } return nil }, } @@ -80,9 +66,11 @@ func newRunStopCmd() *cobra.Command { return err } - if err := ctx.WorkflowAPI.StopRun(cmd.Context(), args[0]); err != nil { - return err + _, _, err = ctx.WorkflowClient.WorkflowsAPI.StopRun(cmd.Context(), ctx.ProjectID, args[0]).Execute() + if err != nil { + return fmt.Errorf("stop run: %w", err) } + fmt.Fprintf(cmd.OutOrStdout(), "Stopped run %s\n", args[0]) return nil }, diff --git a/internal/output/output.go b/internal/output/output.go index ef0acbe..0061c34 100644 --- a/internal/output/output.go +++ b/internal/output/output.go @@ -45,7 +45,13 @@ func New(format Format) *Printer { func (p *Printer) PrintJSON(v any) error { enc := json.NewEncoder(p.W) enc.SetIndent("", " ") - return enc.Encode(v) + + err := enc.Encode(v) + if err != nil { + return fmt.Errorf("json encode %w", err) + } + + return nil } // Table renders a human-readable table. Headers is the header row, diff --git a/internal/workflow_client/README.md b/internal/workflow_client/README.md index 0366626..1afa88e 100644 --- a/internal/workflow_client/README.md +++ b/internal/workflow_client/README.md @@ -71,21 +71,21 @@ All URIs are relative to *https://pipeline.cloud.ru/public-api/v1* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -*PipelinesAPI* | [**ProjectProjectIdJobJobIdLogListGet**](docs/PipelinesAPI.md#projectprojectidjobjobidloglistget) | **Get** /project/{project_id}/job/{job_id}/log/list | Get job logs -*PipelinesAPI* | [**ProjectProjectIdPipelinePipelineIdRunPost**](docs/PipelinesAPI.md#projectprojectidpipelinepipelineidrunpost) | **Post** /project/{project_id}/pipeline/{pipeline_id}/run | Run pipeline -*PipelinesAPI* | [**ProjectProjectIdRunRunIdGet**](docs/PipelinesAPI.md#projectprojectidrunrunidget) | **Get** /project/{project_id}/run/{run_id} | Get run -*PipelinesAPI* | [**ProjectProjectIdRunRunIdStopPost**](docs/PipelinesAPI.md#projectprojectidrunrunidstoppost) | **Post** /project/{project_id}/run/{run_id}/stop | Stop run +*PipelinesAPI* | [**GetJobLogs**](docs/PipelinesAPI.md#getjoblogs) | **Get** /project/{project_id}/job/{job_id}/log/list | Get job logs +*PipelinesAPI* | [**GetRun**](docs/PipelinesAPI.md#getrun) | **Get** /project/{project_id}/run/{run_id} | Get run +*PipelinesAPI* | [**RunPipeline**](docs/PipelinesAPI.md#runpipeline) | **Post** /project/{project_id}/pipeline/{pipeline_id}/run | Run pipeline +*PipelinesAPI* | [**StopRun**](docs/PipelinesAPI.md#stoprun) | **Post** /project/{project_id}/run/{run_id}/stop | Stop run +*ServicesAPI* | [**ListApplications**](docs/ServicesAPI.md#listapplications) | **Get** /project/{project_id}/application/list | List applications *ServicesAPI* | [**ProjectProjectIdApplicationApplicationIdDelete**](docs/ServicesAPI.md#projectprojectidapplicationapplicationiddelete) | **Delete** /project/{project_id}/application/{application_id} | Delete application *ServicesAPI* | [**ProjectProjectIdApplicationApplicationIdDeploymentListGet**](docs/ServicesAPI.md#projectprojectidapplicationapplicationiddeploymentlistget) | **Get** /project/{project_id}/application/{application_id}/deployment/list | List deployments *ServicesAPI* | [**ProjectProjectIdApplicationApplicationIdDeploymentPost**](docs/ServicesAPI.md#projectprojectidapplicationapplicationiddeploymentpost) | **Post** /project/{project_id}/application/{application_id}/deployment | Create deployment *ServicesAPI* | [**ProjectProjectIdApplicationApplicationIdGet**](docs/ServicesAPI.md#projectprojectidapplicationapplicationidget) | **Get** /project/{project_id}/application/{application_id} | Get application *ServicesAPI* | [**ProjectProjectIdApplicationApplicationIdPatch**](docs/ServicesAPI.md#projectprojectidapplicationapplicationidpatch) | **Patch** /project/{project_id}/application/{application_id} | Update application -*ServicesAPI* | [**ProjectProjectIdApplicationListGet**](docs/ServicesAPI.md#projectprojectidapplicationlistget) | **Get** /project/{project_id}/application/list | List applications *ServicesAPI* | [**ProjectProjectIdApplicationPost**](docs/ServicesAPI.md#projectprojectidapplicationpost) | **Post** /project/{project_id}/application | Create application -*WorkflowsAPI* | [**ProjectProjectIdJobJobIdLogListGet**](docs/WorkflowsAPI.md#projectprojectidjobjobidloglistget) | **Get** /project/{project_id}/job/{job_id}/log/list | Get job logs -*WorkflowsAPI* | [**ProjectProjectIdPipelinePipelineIdRunPost**](docs/WorkflowsAPI.md#projectprojectidpipelinepipelineidrunpost) | **Post** /project/{project_id}/pipeline/{pipeline_id}/run | Run pipeline -*WorkflowsAPI* | [**ProjectProjectIdRunRunIdGet**](docs/WorkflowsAPI.md#projectprojectidrunrunidget) | **Get** /project/{project_id}/run/{run_id} | Get run -*WorkflowsAPI* | [**ProjectProjectIdRunRunIdStopPost**](docs/WorkflowsAPI.md#projectprojectidrunrunidstoppost) | **Post** /project/{project_id}/run/{run_id}/stop | Stop run +*WorkflowsAPI* | [**GetJobLogs**](docs/WorkflowsAPI.md#getjoblogs) | **Get** /project/{project_id}/job/{job_id}/log/list | Get job logs +*WorkflowsAPI* | [**GetRun**](docs/WorkflowsAPI.md#getrun) | **Get** /project/{project_id}/run/{run_id} | Get run +*WorkflowsAPI* | [**RunPipeline**](docs/WorkflowsAPI.md#runpipeline) | **Post** /project/{project_id}/pipeline/{pipeline_id}/run | Run pipeline +*WorkflowsAPI* | [**StopRun**](docs/WorkflowsAPI.md#stoprun) | **Post** /project/{project_id}/run/{run_id}/stop | Stop run ## Documentation For Models diff --git a/internal/workflow_client/api_pipelines.go b/internal/workflow_client/api_pipelines.go index d86574b..91c5a59 100644 --- a/internal/workflow_client/api_pipelines.go +++ b/internal/workflow_client/api_pipelines.go @@ -22,7 +22,7 @@ import ( // PipelinesAPIService PipelinesAPI service type PipelinesAPIService service -type PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest struct { +type PipelinesAPIGetJobLogsRequest struct { ctx context.Context ApiService *PipelinesAPIService projectId string @@ -31,27 +31,27 @@ type PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest struct { } // Request body -func (r PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest) Request(request GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestJobLogList) PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest { +func (r PipelinesAPIGetJobLogsRequest) Request(request GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestJobLogList) PipelinesAPIGetJobLogsRequest { r.request = &request return r } -func (r PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { - return r.ApiService.ProjectProjectIdJobJobIdLogListGetExecute(r) +func (r PipelinesAPIGetJobLogsRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { + return r.ApiService.GetJobLogsExecute(r) } /* -ProjectProjectIdJobJobIdLogListGet Get job logs +GetJobLogs Get job logs Get job logs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID @param jobId Job ID - @return PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest + @return PipelinesAPIGetJobLogsRequest */ -func (a *PipelinesAPIService) ProjectProjectIdJobJobIdLogListGet(ctx context.Context, projectId string, jobId string) PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest { - return PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest{ +func (a *PipelinesAPIService) GetJobLogs(ctx context.Context, projectId string, jobId string) PipelinesAPIGetJobLogsRequest { + return PipelinesAPIGetJobLogsRequest{ ApiService: a, ctx: ctx, projectId: projectId, @@ -62,7 +62,7 @@ func (a *PipelinesAPIService) ProjectProjectIdJobJobIdLogListGet(ctx context.Con // Execute executes the request // // @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList -func (a *PipelinesAPIService) ProjectProjectIdJobJobIdLogListGetExecute(r PipelinesAPIProjectProjectIdJobJobIdLogListGetRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { +func (a *PipelinesAPIService) GetJobLogsExecute(r PipelinesAPIGetJobLogsRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -70,7 +70,7 @@ func (a *PipelinesAPIService) ProjectProjectIdJobJobIdLogListGetExecute(r Pipeli localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.ProjectProjectIdJobJobIdLogListGet") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.GetJobLogs") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -199,71 +199,60 @@ func (a *PipelinesAPIService) ProjectProjectIdJobJobIdLogListGetExecute(r Pipeli return localVarReturnValue, localVarHTTPResponse, nil } -type PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest struct { +type PipelinesAPIGetRunRequest struct { ctx context.Context ApiService *PipelinesAPIService projectId string - pipelineId string - branch *string -} - -// Branch -func (r PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest) Branch(branch string) PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest { - r.branch = &branch - return r + runId string } -func (r PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { - return r.ApiService.ProjectProjectIdPipelinePipelineIdRunPostExecute(r) +func (r PipelinesAPIGetRunRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { + return r.ApiService.GetRunExecute(r) } /* -ProjectProjectIdPipelinePipelineIdRunPost Run pipeline +GetRun Get run -Run pipeline +Get run @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID - @param pipelineId Pipeline ID - @return PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest + @param runId Run ID + @return PipelinesAPIGetRunRequest */ -func (a *PipelinesAPIService) ProjectProjectIdPipelinePipelineIdRunPost(ctx context.Context, projectId string, pipelineId string) PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest { - return PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest{ +func (a *PipelinesAPIService) GetRun(ctx context.Context, projectId string, runId string) PipelinesAPIGetRunRequest { + return PipelinesAPIGetRunRequest{ ApiService: a, ctx: ctx, projectId: projectId, - pipelineId: pipelineId, + runId: runId, } } // Execute executes the request // -// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun -func (a *PipelinesAPIService) ProjectProjectIdPipelinePipelineIdRunPostExecute(r PipelinesAPIProjectProjectIdPipelinePipelineIdRunPostRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { +// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet +func (a *PipelinesAPIService) GetRunExecute(r PipelinesAPIGetRunRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost + localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun + localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.ProjectProjectIdPipelinePipelineIdRunPost") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.GetRun") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project/{project_id}/pipeline/{pipeline_id}/run" + localVarPath := localBasePath + "/project/{project_id}/run/{run_id}" localVarPath = strings.Replace(localVarPath, "{"+"project_id"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"pipeline_id"+"}", url.PathEscape(parameterValueToString(r.pipelineId, "pipelineId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"run_id"+"}", url.PathEscape(parameterValueToString(r.runId, "runId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.branch == nil { - return localVarReturnValue, nil, reportError("branch is required and must be specified") - } - parameterAddToHeaderOrQuery(localVarQueryParams, "branch", r.branch, "", "") // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -375,60 +364,71 @@ func (a *PipelinesAPIService) ProjectProjectIdPipelinePipelineIdRunPostExecute(r return localVarReturnValue, localVarHTTPResponse, nil } -type PipelinesAPIProjectProjectIdRunRunIdGetRequest struct { +type PipelinesAPIRunPipelineRequest struct { ctx context.Context ApiService *PipelinesAPIService projectId string - runId string + pipelineId string + branch *string +} + +// Branch +func (r PipelinesAPIRunPipelineRequest) Branch(branch string) PipelinesAPIRunPipelineRequest { + r.branch = &branch + return r } -func (r PipelinesAPIProjectProjectIdRunRunIdGetRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { - return r.ApiService.ProjectProjectIdRunRunIdGetExecute(r) +func (r PipelinesAPIRunPipelineRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { + return r.ApiService.RunPipelineExecute(r) } /* -ProjectProjectIdRunRunIdGet Get run +RunPipeline Run pipeline -Get run +Run pipeline @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID - @param runId Run ID - @return PipelinesAPIProjectProjectIdRunRunIdGetRequest + @param pipelineId Pipeline ID + @return PipelinesAPIRunPipelineRequest */ -func (a *PipelinesAPIService) ProjectProjectIdRunRunIdGet(ctx context.Context, projectId string, runId string) PipelinesAPIProjectProjectIdRunRunIdGetRequest { - return PipelinesAPIProjectProjectIdRunRunIdGetRequest{ +func (a *PipelinesAPIService) RunPipeline(ctx context.Context, projectId string, pipelineId string) PipelinesAPIRunPipelineRequest { + return PipelinesAPIRunPipelineRequest{ ApiService: a, ctx: ctx, projectId: projectId, - runId: runId, + pipelineId: pipelineId, } } // Execute executes the request // -// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet -func (a *PipelinesAPIService) ProjectProjectIdRunRunIdGetExecute(r PipelinesAPIProjectProjectIdRunRunIdGetRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { +// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun +func (a *PipelinesAPIService) RunPipelineExecute(r PipelinesAPIRunPipelineRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet + localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile - localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet + localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.ProjectProjectIdRunRunIdGet") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.RunPipeline") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project/{project_id}/run/{run_id}" + localVarPath := localBasePath + "/project/{project_id}/pipeline/{pipeline_id}/run" localVarPath = strings.Replace(localVarPath, "{"+"project_id"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"run_id"+"}", url.PathEscape(parameterValueToString(r.runId, "runId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"pipeline_id"+"}", url.PathEscape(parameterValueToString(r.pipelineId, "pipelineId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.branch == nil { + return localVarReturnValue, nil, reportError("branch is required and must be specified") + } + parameterAddToHeaderOrQuery(localVarQueryParams, "branch", r.branch, "", "") // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -540,29 +540,29 @@ func (a *PipelinesAPIService) ProjectProjectIdRunRunIdGetExecute(r PipelinesAPIP return localVarReturnValue, localVarHTTPResponse, nil } -type PipelinesAPIProjectProjectIdRunRunIdStopPostRequest struct { +type PipelinesAPIStopRunRequest struct { ctx context.Context ApiService *PipelinesAPIService projectId string runId string } -func (r PipelinesAPIProjectProjectIdRunRunIdStopPostRequest) Execute() (map[string]interface{}, *http.Response, error) { - return r.ApiService.ProjectProjectIdRunRunIdStopPostExecute(r) +func (r PipelinesAPIStopRunRequest) Execute() (map[string]interface{}, *http.Response, error) { + return r.ApiService.StopRunExecute(r) } /* -ProjectProjectIdRunRunIdStopPost Stop run +StopRun Stop run Stop run @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID @param runId Run ID - @return PipelinesAPIProjectProjectIdRunRunIdStopPostRequest + @return PipelinesAPIStopRunRequest */ -func (a *PipelinesAPIService) ProjectProjectIdRunRunIdStopPost(ctx context.Context, projectId string, runId string) PipelinesAPIProjectProjectIdRunRunIdStopPostRequest { - return PipelinesAPIProjectProjectIdRunRunIdStopPostRequest{ +func (a *PipelinesAPIService) StopRun(ctx context.Context, projectId string, runId string) PipelinesAPIStopRunRequest { + return PipelinesAPIStopRunRequest{ ApiService: a, ctx: ctx, projectId: projectId, @@ -573,7 +573,7 @@ func (a *PipelinesAPIService) ProjectProjectIdRunRunIdStopPost(ctx context.Conte // Execute executes the request // // @return map[string]interface{} -func (a *PipelinesAPIService) ProjectProjectIdRunRunIdStopPostExecute(r PipelinesAPIProjectProjectIdRunRunIdStopPostRequest) (map[string]interface{}, *http.Response, error) { +func (a *PipelinesAPIService) StopRunExecute(r PipelinesAPIStopRunRequest) (map[string]interface{}, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} @@ -581,7 +581,7 @@ func (a *PipelinesAPIService) ProjectProjectIdRunRunIdStopPostExecute(r Pipeline localVarReturnValue map[string]interface{} ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.ProjectProjectIdRunRunIdStopPost") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PipelinesAPIService.StopRun") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/internal/workflow_client/api_services.go b/internal/workflow_client/api_services.go index ebe04d8..14212c8 100644 --- a/internal/workflow_client/api_services.go +++ b/internal/workflow_client/api_services.go @@ -22,6 +22,217 @@ import ( // ServicesAPIService ServicesAPI service type ServicesAPIService service +type ServicesAPIListApplicationsRequest struct { + ctx context.Context + ApiService *ServicesAPIService + projectId string + limit *int + offset *int + search *string + sort *string + spaceId *string +} + +// Limit +func (r ServicesAPIListApplicationsRequest) Limit(limit int) ServicesAPIListApplicationsRequest { + r.limit = &limit + return r +} + +// Offset +func (r ServicesAPIListApplicationsRequest) Offset(offset int) ServicesAPIListApplicationsRequest { + r.offset = &offset + return r +} + +// Search +func (r ServicesAPIListApplicationsRequest) Search(search string) ServicesAPIListApplicationsRequest { + r.search = &search + return r +} + +// Sort Order +func (r ServicesAPIListApplicationsRequest) Sort(sort string) ServicesAPIListApplicationsRequest { + r.sort = &sort + return r +} + +// Space ID (default: Default space) +func (r ServicesAPIListApplicationsRequest) SpaceId(spaceId string) ServicesAPIListApplicationsRequest { + r.spaceId = &spaceId + return r +} + +func (r ServicesAPIListApplicationsRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList, *http.Response, error) { + return r.ApiService.ListApplicationsExecute(r) +} + +/* +ListApplications List applications + +List applications + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param projectId Project ID + @return ServicesAPIListApplicationsRequest +*/ +func (a *ServicesAPIService) ListApplications(ctx context.Context, projectId string) ServicesAPIListApplicationsRequest { + return ServicesAPIListApplicationsRequest{ + ApiService: a, + ctx: ctx, + projectId: projectId, + } +} + +// Execute executes the request +// +// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList +func (a *ServicesAPIService) ListApplicationsExecute(r ServicesAPIListApplicationsRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServicesAPIService.ListApplications") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/project/{project_id}/application/list" + localVarPath = strings.Replace(localVarPath, "{"+"project_id"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.limit != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "limit", r.limit, "", "") + } + if r.offset != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "offset", r.offset, "", "") + } + if r.search != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "search", r.search, "", "") + } + if r.sort != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sort", r.sort, "", "") + } + if r.spaceId != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "space_id", r.spaceId, "", "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["BearerAuth"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsBadRequest + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsUnauthorized + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsNotFound + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsInternal + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + type ServicesAPIProjectProjectIdApplicationApplicationIdDeleteRequest struct { ctx context.Context ApiService *ServicesAPIService @@ -898,217 +1109,6 @@ func (a *ServicesAPIService) ProjectProjectIdApplicationApplicationIdPatchExecut return localVarHTTPResponse, nil } -type ServicesAPIProjectProjectIdApplicationListGetRequest struct { - ctx context.Context - ApiService *ServicesAPIService - projectId string - limit *int - offset *int - search *string - sort *string - spaceId *string -} - -// Limit -func (r ServicesAPIProjectProjectIdApplicationListGetRequest) Limit(limit int) ServicesAPIProjectProjectIdApplicationListGetRequest { - r.limit = &limit - return r -} - -// Offset -func (r ServicesAPIProjectProjectIdApplicationListGetRequest) Offset(offset int) ServicesAPIProjectProjectIdApplicationListGetRequest { - r.offset = &offset - return r -} - -// Search -func (r ServicesAPIProjectProjectIdApplicationListGetRequest) Search(search string) ServicesAPIProjectProjectIdApplicationListGetRequest { - r.search = &search - return r -} - -// Sort Order -func (r ServicesAPIProjectProjectIdApplicationListGetRequest) Sort(sort string) ServicesAPIProjectProjectIdApplicationListGetRequest { - r.sort = &sort - return r -} - -// Space ID (default: Default space) -func (r ServicesAPIProjectProjectIdApplicationListGetRequest) SpaceId(spaceId string) ServicesAPIProjectProjectIdApplicationListGetRequest { - r.spaceId = &spaceId - return r -} - -func (r ServicesAPIProjectProjectIdApplicationListGetRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList, *http.Response, error) { - return r.ApiService.ProjectProjectIdApplicationListGetExecute(r) -} - -/* -ProjectProjectIdApplicationListGet List applications - -List applications - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param projectId Project ID - @return ServicesAPIProjectProjectIdApplicationListGetRequest -*/ -func (a *ServicesAPIService) ProjectProjectIdApplicationListGet(ctx context.Context, projectId string) ServicesAPIProjectProjectIdApplicationListGetRequest { - return ServicesAPIProjectProjectIdApplicationListGetRequest{ - ApiService: a, - ctx: ctx, - projectId: projectId, - } -} - -// Execute executes the request -// -// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList -func (a *ServicesAPIService) ProjectProjectIdApplicationListGetExecute(r ServicesAPIProjectProjectIdApplicationListGetRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList, *http.Response, error) { - var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseApplicationList - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServicesAPIService.ProjectProjectIdApplicationListGet") - if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/project/{project_id}/application/list" - localVarPath = strings.Replace(localVarPath, "{"+"project_id"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - if r.limit != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "limit", r.limit, "", "") - } - if r.offset != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "offset", r.offset, "", "") - } - if r.search != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "search", r.search, "", "") - } - if r.sort != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "sort", r.sort, "", "") - } - if r.spaceId != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "space_id", r.spaceId, "", "") - } - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["BearerAuth"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarReturnValue, localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - if localVarHTTPResponse.StatusCode == 400 { - var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsBadRequest - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 401 { - var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsUnauthorized - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 404 { - var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsNotFound - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 500 { - var v GitSbercloudTechDsworksServicesPipelineSrcInternalErrorsInternal - err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) - newErr.model = v - } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - return localVarReturnValue, localVarHTTPResponse, nil -} - type ServicesAPIProjectProjectIdApplicationPostRequest struct { ctx context.Context ApiService *ServicesAPIService @@ -1116,7 +1116,7 @@ type ServicesAPIProjectProjectIdApplicationPostRequest struct { request *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestApplicationCreate } -// Application create request +// Application create request; repository_url must be an HTTPS git clone URL (cloning uses HTTPS, not SSH), branch must exist, repository root must contain Dockerfile func (r ServicesAPIProjectProjectIdApplicationPostRequest) Request(request GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestApplicationCreate) ServicesAPIProjectProjectIdApplicationPostRequest { r.request = &request return r @@ -1129,7 +1129,7 @@ func (r ServicesAPIProjectProjectIdApplicationPostRequest) Execute() (*GitSbercl /* ProjectProjectIdApplicationPost Create application -Create application from repository URL +Create application from repository and immediately start the initial deployment (pipeline run) @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID diff --git a/internal/workflow_client/api_workflows.go b/internal/workflow_client/api_workflows.go index a7634f4..2ed2cf3 100644 --- a/internal/workflow_client/api_workflows.go +++ b/internal/workflow_client/api_workflows.go @@ -22,7 +22,7 @@ import ( // WorkflowsAPIService WorkflowsAPI service type WorkflowsAPIService service -type WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest struct { +type WorkflowsAPIGetJobLogsRequest struct { ctx context.Context ApiService *WorkflowsAPIService projectId string @@ -31,27 +31,27 @@ type WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest struct { } // Request body -func (r WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest) Request(request GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestJobLogList) WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest { +func (r WorkflowsAPIGetJobLogsRequest) Request(request GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationRequestJobLogList) WorkflowsAPIGetJobLogsRequest { r.request = &request return r } -func (r WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { - return r.ApiService.ProjectProjectIdJobJobIdLogListGetExecute(r) +func (r WorkflowsAPIGetJobLogsRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { + return r.ApiService.GetJobLogsExecute(r) } /* -ProjectProjectIdJobJobIdLogListGet Get job logs +GetJobLogs Get job logs Get job logs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID @param jobId Job ID - @return WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest + @return WorkflowsAPIGetJobLogsRequest */ -func (a *WorkflowsAPIService) ProjectProjectIdJobJobIdLogListGet(ctx context.Context, projectId string, jobId string) WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest { - return WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest{ +func (a *WorkflowsAPIService) GetJobLogs(ctx context.Context, projectId string, jobId string) WorkflowsAPIGetJobLogsRequest { + return WorkflowsAPIGetJobLogsRequest{ ApiService: a, ctx: ctx, projectId: projectId, @@ -62,7 +62,7 @@ func (a *WorkflowsAPIService) ProjectProjectIdJobJobIdLogListGet(ctx context.Con // Execute executes the request // // @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList -func (a *WorkflowsAPIService) ProjectProjectIdJobJobIdLogListGetExecute(r WorkflowsAPIProjectProjectIdJobJobIdLogListGetRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { +func (a *WorkflowsAPIService) GetJobLogsExecute(r WorkflowsAPIGetJobLogsRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -70,7 +70,7 @@ func (a *WorkflowsAPIService) ProjectProjectIdJobJobIdLogListGetExecute(r Workfl localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseJobLogList ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.ProjectProjectIdJobJobIdLogListGet") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.GetJobLogs") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -199,71 +199,60 @@ func (a *WorkflowsAPIService) ProjectProjectIdJobJobIdLogListGetExecute(r Workfl return localVarReturnValue, localVarHTTPResponse, nil } -type WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest struct { +type WorkflowsAPIGetRunRequest struct { ctx context.Context ApiService *WorkflowsAPIService projectId string - pipelineId string - branch *string -} - -// Branch -func (r WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest) Branch(branch string) WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest { - r.branch = &branch - return r + runId string } -func (r WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { - return r.ApiService.ProjectProjectIdPipelinePipelineIdRunPostExecute(r) +func (r WorkflowsAPIGetRunRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { + return r.ApiService.GetRunExecute(r) } /* -ProjectProjectIdPipelinePipelineIdRunPost Run pipeline +GetRun Get run -Run pipeline +Get run @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID - @param pipelineId Pipeline ID - @return WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest + @param runId Run ID + @return WorkflowsAPIGetRunRequest */ -func (a *WorkflowsAPIService) ProjectProjectIdPipelinePipelineIdRunPost(ctx context.Context, projectId string, pipelineId string) WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest { - return WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest{ +func (a *WorkflowsAPIService) GetRun(ctx context.Context, projectId string, runId string) WorkflowsAPIGetRunRequest { + return WorkflowsAPIGetRunRequest{ ApiService: a, ctx: ctx, projectId: projectId, - pipelineId: pipelineId, + runId: runId, } } // Execute executes the request // -// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun -func (a *WorkflowsAPIService) ProjectProjectIdPipelinePipelineIdRunPostExecute(r WorkflowsAPIProjectProjectIdPipelinePipelineIdRunPostRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { +// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet +func (a *WorkflowsAPIService) GetRunExecute(r WorkflowsAPIGetRunRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost + localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun + localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.ProjectProjectIdPipelinePipelineIdRunPost") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.GetRun") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project/{project_id}/pipeline/{pipeline_id}/run" + localVarPath := localBasePath + "/project/{project_id}/run/{run_id}" localVarPath = strings.Replace(localVarPath, "{"+"project_id"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"pipeline_id"+"}", url.PathEscape(parameterValueToString(r.pipelineId, "pipelineId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"run_id"+"}", url.PathEscape(parameterValueToString(r.runId, "runId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.branch == nil { - return localVarReturnValue, nil, reportError("branch is required and must be specified") - } - parameterAddToHeaderOrQuery(localVarQueryParams, "branch", r.branch, "", "") // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -375,60 +364,71 @@ func (a *WorkflowsAPIService) ProjectProjectIdPipelinePipelineIdRunPostExecute(r return localVarReturnValue, localVarHTTPResponse, nil } -type WorkflowsAPIProjectProjectIdRunRunIdGetRequest struct { +type WorkflowsAPIRunPipelineRequest struct { ctx context.Context ApiService *WorkflowsAPIService projectId string - runId string + pipelineId string + branch *string +} + +// Branch +func (r WorkflowsAPIRunPipelineRequest) Branch(branch string) WorkflowsAPIRunPipelineRequest { + r.branch = &branch + return r } -func (r WorkflowsAPIProjectProjectIdRunRunIdGetRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { - return r.ApiService.ProjectProjectIdRunRunIdGetExecute(r) +func (r WorkflowsAPIRunPipelineRequest) Execute() (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { + return r.ApiService.RunPipelineExecute(r) } /* -ProjectProjectIdRunRunIdGet Get run +RunPipeline Run pipeline -Get run +Run pipeline @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID - @param runId Run ID - @return WorkflowsAPIProjectProjectIdRunRunIdGetRequest + @param pipelineId Pipeline ID + @return WorkflowsAPIRunPipelineRequest */ -func (a *WorkflowsAPIService) ProjectProjectIdRunRunIdGet(ctx context.Context, projectId string, runId string) WorkflowsAPIProjectProjectIdRunRunIdGetRequest { - return WorkflowsAPIProjectProjectIdRunRunIdGetRequest{ +func (a *WorkflowsAPIService) RunPipeline(ctx context.Context, projectId string, pipelineId string) WorkflowsAPIRunPipelineRequest { + return WorkflowsAPIRunPipelineRequest{ ApiService: a, ctx: ctx, projectId: projectId, - runId: runId, + pipelineId: pipelineId, } } // Execute executes the request // -// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet -func (a *WorkflowsAPIService) ProjectProjectIdRunRunIdGetExecute(r WorkflowsAPIProjectProjectIdRunRunIdGetRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet, *http.Response, error) { +// @return GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun +func (a *WorkflowsAPIService) RunPipelineExecute(r WorkflowsAPIRunPipelineRequest) (*GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet + localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile - localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponseRunGet + localVarReturnValue *GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationResponsePipelineRun ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.ProjectProjectIdRunRunIdGet") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.RunPipeline") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project/{project_id}/run/{run_id}" + localVarPath := localBasePath + "/project/{project_id}/pipeline/{pipeline_id}/run" localVarPath = strings.Replace(localVarPath, "{"+"project_id"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"run_id"+"}", url.PathEscape(parameterValueToString(r.runId, "runId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"pipeline_id"+"}", url.PathEscape(parameterValueToString(r.pipelineId, "pipelineId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.branch == nil { + return localVarReturnValue, nil, reportError("branch is required and must be specified") + } + parameterAddToHeaderOrQuery(localVarQueryParams, "branch", r.branch, "", "") // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -540,29 +540,29 @@ func (a *WorkflowsAPIService) ProjectProjectIdRunRunIdGetExecute(r WorkflowsAPIP return localVarReturnValue, localVarHTTPResponse, nil } -type WorkflowsAPIProjectProjectIdRunRunIdStopPostRequest struct { +type WorkflowsAPIStopRunRequest struct { ctx context.Context ApiService *WorkflowsAPIService projectId string runId string } -func (r WorkflowsAPIProjectProjectIdRunRunIdStopPostRequest) Execute() (map[string]interface{}, *http.Response, error) { - return r.ApiService.ProjectProjectIdRunRunIdStopPostExecute(r) +func (r WorkflowsAPIStopRunRequest) Execute() (map[string]interface{}, *http.Response, error) { + return r.ApiService.StopRunExecute(r) } /* -ProjectProjectIdRunRunIdStopPost Stop run +StopRun Stop run Stop run @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param projectId Project ID @param runId Run ID - @return WorkflowsAPIProjectProjectIdRunRunIdStopPostRequest + @return WorkflowsAPIStopRunRequest */ -func (a *WorkflowsAPIService) ProjectProjectIdRunRunIdStopPost(ctx context.Context, projectId string, runId string) WorkflowsAPIProjectProjectIdRunRunIdStopPostRequest { - return WorkflowsAPIProjectProjectIdRunRunIdStopPostRequest{ +func (a *WorkflowsAPIService) StopRun(ctx context.Context, projectId string, runId string) WorkflowsAPIStopRunRequest { + return WorkflowsAPIStopRunRequest{ ApiService: a, ctx: ctx, projectId: projectId, @@ -573,7 +573,7 @@ func (a *WorkflowsAPIService) ProjectProjectIdRunRunIdStopPost(ctx context.Conte // Execute executes the request // // @return map[string]interface{} -func (a *WorkflowsAPIService) ProjectProjectIdRunRunIdStopPostExecute(r WorkflowsAPIProjectProjectIdRunRunIdStopPostRequest) (map[string]interface{}, *http.Response, error) { +func (a *WorkflowsAPIService) StopRunExecute(r WorkflowsAPIStopRunRequest) (map[string]interface{}, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} @@ -581,7 +581,7 @@ func (a *WorkflowsAPIService) ProjectProjectIdRunRunIdStopPostExecute(r Workflow localVarReturnValue map[string]interface{} ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.ProjectProjectIdRunRunIdStopPost") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkflowsAPIService.StopRun") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/internal/workflow_client/model_git_sbercloud_tech_dsworks_services_pipeline_src_internal_application_model_job_status.go b/internal/workflow_client/model_git_sbercloud_tech_dsworks_services_pipeline_src_internal_application_model_job_status.go index 0c5e65b..9a081f4 100644 --- a/internal/workflow_client/model_git_sbercloud_tech_dsworks_services_pipeline_src_internal_application_model_job_status.go +++ b/internal/workflow_client/model_git_sbercloud_tech_dsworks_services_pipeline_src_internal_application_model_job_status.go @@ -20,6 +20,7 @@ type GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatus // List of git_sbercloud_tech_dsworks_services_pipeline_src_internal_application_model.JobStatus const ( + JobStatusEmpty GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatus = "" JobStatusPending GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatus = "pending" JobStatusRunning GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatus = "running" JobStatusDone GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatus = "done" @@ -29,6 +30,7 @@ const ( // All allowed values of GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatus enum var AllowedGitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatusEnumValues = []GitSbercloudTechDsworksServicesPipelineSrcInternalApplicationModelJobStatus{ + "", "pending", "running", "done", diff --git a/internal/workflowapi/application.go b/internal/workflowapi/application.go deleted file mode 100644 index e40349b..0000000 --- a/internal/workflowapi/application.go +++ /dev/null @@ -1,214 +0,0 @@ -package workflowapi - -import ( - "context" - "fmt" - "net/url" - "strconv" -) - -// SortOrder is the sort parameter accepted by the application/deployment -// list endpoints. -type SortOrder string - -const ( - SortCreatedAtAsc SortOrder = "created_at_asc" - SortCreatedAtDesc SortOrder = "created_at_desc" -) - -// Application is a Workflow Studio service: a repository + branch wired to a -// deploy pipeline. Creating a deployment for it runs that pipeline and -// publishes the result. -type Application struct { - ID string `json:"id"` - Name string `json:"name"` - Branch string `json:"branch"` - ProjectID string `json:"project_id"` - RepositoryID string `json:"repository_id"` - RepositoryURL string `json:"repository_url"` - PipelineID string `json:"pipeline_id"` - TemplateID string `json:"template_id"` - RunID string `json:"run_id"` - Run *Run `json:"run,omitempty"` - Status string `json:"status"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` -} - -// ApplicationListResponse is the response payload of GET /application/list. -type ApplicationListResponse struct { - Applications []Application `json:"applications"` - Total int `json:"total"` -} - -// CreateApplicationRequest is the body for POST /application. Either -// RepositoryID (a repo already known to the Repo service, see -// internal/repoapi) or RepositoryURL (an external git URL) must be set. -type CreateApplicationRequest struct { - Name string `json:"name,omitempty"` - Branch string `json:"branch"` - RepositoryID string `json:"repository_id,omitempty"` - RepositoryURL string `json:"repository_url,omitempty"` -} - -// UpdateApplicationRequest is the body for PATCH /application/{id}. -type UpdateApplicationRequest struct { - Name string `json:"name,omitempty"` - Branch string `json:"branch"` -} - -// Deployment represents a single publish/run of an application's pipeline. -// URL is the published site/service URL once the deployment succeeds. -type Deployment struct { - ID string `json:"id"` - ApplicationID string `json:"application_id"` - Application *Application `json:"application,omitempty"` - RunID string `json:"run_id"` - Run *Run `json:"run,omitempty"` - ShortName string `json:"short_name"` - URL string `json:"url"` - CreatedAt string `json:"created_at"` -} - -// CreateDeploymentResponse is the response payload of POST /application/{id}/deployment. -type CreateDeploymentResponse struct { - Deployment Deployment `json:"deployment"` -} - -// DeploymentListResponse is the response payload of GET /application/{id}/deployment/list. -type DeploymentListResponse struct { - Deployments []Deployment `json:"deployments"` - Total int `json:"total"` -} - -// ListApplicationsOptions configures ListApplications. -type ListApplicationsOptions struct { - Search string - Sort SortOrder - Limit int - Offset int -} - -// ListDeploymentsOptions configures ListDeployments. -type ListDeploymentsOptions struct { - Search string - Sort SortOrder - Limit int - Offset int -} - -// ListApplications lists applications in the configured project. -func (c *Client) ListApplications(ctx context.Context, opts ListApplicationsOptions) (*ApplicationListResponse, error) { - if c.projectID == "" { - return nil, fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - q := url.Values{} - if opts.Search != "" { - q.Set("search", opts.Search) - } - if opts.Sort != "" { - q.Set("sort", string(opts.Sort)) - } - if opts.Limit > 0 { - q.Set("limit", strconv.Itoa(opts.Limit)) - } - if opts.Offset > 0 { - q.Set("offset", strconv.Itoa(opts.Offset)) - } - - var out ApplicationListResponse - if err := c.Do(ctx, "GET", fmt.Sprintf("/project/%s/application/list", c.projectID), q, nil, &out); err != nil { - return nil, err - } - return &out, nil -} - -// GetApplication fetches a single application by id, including its latest run. -func (c *Client) GetApplication(ctx context.Context, id string) (*Application, error) { - if c.projectID == "" { - return nil, fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - var out Application - if err := c.Do(ctx, "GET", fmt.Sprintf("/project/%s/application/%s", c.projectID, id), nil, nil, &out); err != nil { - return nil, err - } - return &out, nil -} - -// CreateApplication creates a new application from a repository + branch. -func (c *Client) CreateApplication(ctx context.Context, req CreateApplicationRequest) (*Application, error) { - if c.projectID == "" { - return nil, fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - var out Application - if err := c.Do(ctx, "POST", fmt.Sprintf("/project/%s/application", c.projectID), nil, req, &out); err != nil { - return nil, err - } - return &out, nil -} - -// UpdateApplication updates an application's name/branch. -func (c *Client) UpdateApplication(ctx context.Context, id string, req UpdateApplicationRequest) error { - if c.projectID == "" { - return fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - return c.Do(ctx, "PATCH", fmt.Sprintf("/project/%s/application/%s", c.projectID, id), nil, req, nil) -} - -// DeleteApplication removes an application and its deployments. -func (c *Client) DeleteApplication(ctx context.Context, id string) error { - if c.projectID == "" { - return fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - return c.Do(ctx, "DELETE", fmt.Sprintf("/project/%s/application/%s", c.projectID, id), nil, nil, nil) -} - -// CreateDeployment runs the application's pipeline and publishes the result. -// This is the "deploy" / "publish" action for a Workflow Studio application. -func (c *Client) CreateDeployment(ctx context.Context, applicationID string) (*Deployment, error) { - if c.projectID == "" { - return nil, fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - var out CreateDeploymentResponse - err := c.Do(ctx, "POST", - fmt.Sprintf("/project/%s/application/%s/deployment", c.projectID, applicationID), - nil, struct{}{}, &out) - if err != nil { - return nil, err - } - return &out.Deployment, nil -} - -// ListDeployments lists deployments for an application, most recent first -// when Sort is SortCreatedAtDesc. -func (c *Client) ListDeployments( - ctx context.Context, - applicationID string, - opts ListDeploymentsOptions, -) (*DeploymentListResponse, error) { - if c.projectID == "" { - return nil, fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - q := url.Values{} - if opts.Search != "" { - q.Set("search", opts.Search) - } - if opts.Sort != "" { - q.Set("sort", string(opts.Sort)) - } - if opts.Limit > 0 { - q.Set("limit", strconv.Itoa(opts.Limit)) - } - if opts.Offset > 0 { - q.Set("offset", strconv.Itoa(opts.Offset)) - } - - var out DeploymentListResponse - err := c.Do(ctx, "GET", - fmt.Sprintf("/project/%s/application/%s/deployment/list", c.projectID, applicationID), - q, nil, &out) - if err != nil { - return nil, err - } - return &out, nil -} diff --git a/internal/workflowapi/client.go b/internal/workflowapi/client.go deleted file mode 100644 index b233523..0000000 --- a/internal/workflowapi/client.go +++ /dev/null @@ -1,187 +0,0 @@ -// Package workflowapi provides a thin client for the Workflow Studio user API -// (cloud.ru "developer tools" -> Workflow Studio). Both products use the same -// API key sent as X-API-KEY. -package workflowapi - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "strings" -) - -// Client talks to the Workflow Studio API and authenticates with X-API-KEY. -type Client struct { - baseURL string - token string - projectID string - http *http.Client -} - -// New returns a configured API client. The underlying http.Client has no -// timeout: requests are bounded by the caller's context instead, since -// Stream (used for job log tailing) may need to stay open for a running job. -func New(baseURL, token, projectID string) *Client { - return &Client{ - baseURL: strings.TrimRight(baseURL, "/"), - token: token, - projectID: projectID, - http: &http.Client{}, - } -} - -// ProjectID returns the configured project ID. -func (c *Client) ProjectID() string { return c.projectID } - -// SetToken updates the API key used for subsequent requests. -func (c *Client) SetToken(token string) { c.token = token } - -// APIError is a non-2xx response from the API. -type APIError struct { - StatusCode int - Message string - Body string - // RequestID is the server-assigned request id (from a response header - // such as X-Request-Id), when present. Include it when reporting bugs - // to the API team -- it lets them find the request in their logs even - // when the body carries no useful detail (e.g. a bare 500 "{}"). - RequestID string -} - -func (e *APIError) Error() string { - msg := e.Message - if msg == "" { - msg = strings.TrimSpace(e.Body) - } - if msg == "" || msg == "{}" { - msg = "(empty response body)" - } - if e.RequestID != "" { - return fmt.Sprintf("workflow api error %d: %s (request-id: %s)", e.StatusCode, msg, e.RequestID) - } - return fmt.Sprintf("workflow api error %d: %s", e.StatusCode, msg) -} - -// Do performs an authenticated HTTP request and decodes JSON into out (if non-nil). -func (c *Client) Do(ctx context.Context, method, path string, query url.Values, body any, out any) error { - u, err := c.buildURL(path, query) - if err != nil { - return err - } - - var reqBody io.Reader - if body != nil { - buf, err := json.Marshal(body) - if err != nil { - return fmt.Errorf("marshal request: %w", err) - } - reqBody = bytes.NewReader(buf) - } - - req, err := http.NewRequestWithContext(ctx, method, u, reqBody) - if err != nil { - return fmt.Errorf("build request: %w", err) - } - req.Header.Set("X-API-KEY", c.token) - if body != nil { - req.Header.Set("Content-Type", "application/json") - } - req.Header.Set("Accept", "application/json") - - resp, err := c.http.Do(req) - if err != nil { - return fmt.Errorf("http %s %s: %w", method, u, err) - } - defer resp.Body.Close() - - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("read response: %w", err) - } - - requestID := requestIDFromHeader(resp.Header) - - if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return parseError(resp.StatusCode, respBody, requestID) - } - - if out != nil && len(respBody) > 0 { - if err := json.Unmarshal(respBody, out); err != nil { - if requestID != "" { - return fmt.Errorf( - "decode response: %w (body: %s, request-id: %s)", - err, - truncate(string(respBody), 256), - requestID, - ) - } - return fmt.Errorf("decode response: %w (body: %s)", err, truncate(string(respBody), 256)) - } - } - return nil -} - -// requestIDFromHeader looks for a server-assigned request id under a few -// common header names. http.Header.Get canonicalizes header names, so this -// also matches any casing the server sends (x-request-id, X-REQUEST-ID, ...). -func requestIDFromHeader(h http.Header) string { - for _, name := range []string{"X-Request-Id", "X-Trace-Id", "Trace-Id", "Request-Id", "X-Correlation-Id"} { - if v := h.Get(name); v != "" { - return v - } - } - return "" -} - -func (c *Client) buildURL(path string, query url.Values) (string, error) { - u, err := url.Parse(c.baseURL) - if err != nil { - return "", fmt.Errorf("invalid base url %q: %w", c.baseURL, err) - } - u.Path = strings.TrimRight(u.Path, "/") + "/" + strings.TrimLeft(path, "/") - if query != nil { - u.RawQuery = query.Encode() - } - return u.String(), nil -} - -func parseError(status int, body []byte, requestID string) error { - var errResp struct { - Error string `json:"error"` - } - _ = json.Unmarshal(body, &errResp) - - var msgResp struct { - Message string `json:"message"` - } - _ = json.Unmarshal(body, &msgResp) - - var validResp struct { - Errors map[string][]string `json:"errors"` - } - _ = json.Unmarshal(body, &validResp) - - msg := msgResp.Message - if msg == "" { - msg = errResp.Error - } - if msg == "" && len(validResp.Errors) > 0 { - parts := make([]string, 0, len(validResp.Errors)) - for field, errs := range validResp.Errors { - parts = append(parts, fmt.Sprintf("%s: %s", field, strings.Join(errs, ", "))) - } - msg = strings.Join(parts, "; ") - } - return &APIError{StatusCode: status, Message: msg, Body: string(body), RequestID: requestID} -} - -func truncate(s string, maxLen int) string { - if len(s) <= maxLen { - return s - } - return s[:maxLen] + "…" -} diff --git a/internal/workflowapi/job.go b/internal/workflowapi/job.go deleted file mode 100644 index 8aa5446..0000000 --- a/internal/workflowapi/job.go +++ /dev/null @@ -1,28 +0,0 @@ -package workflowapi - -// JobStatus is the lifecycle state of a job. -type JobStatus string - -const ( - JobStatusPending JobStatus = "pending" - JobStatusRunning JobStatus = "running" - JobStatusDone JobStatus = "done" - JobStatusCanceled JobStatus = "canceled" - JobStatusFailed JobStatus = "failed" -) - -// Job is a single unit of work within a pipeline run stage. -type Job struct { - ID string `json:"id"` - Name string `json:"name"` - RunID string `json:"run_id"` - StageID string `json:"stage_id"` - Status JobStatus `json:"status"` - Type string `json:"type"` - SequenceNumber int `json:"sequence_number"` - DataPlaneExecName string `json:"data_plane_exec_name"` - DataPlaneJobName string `json:"data_plane_job_name"` - TemporalWorkflowID string `json:"temporal_workflow_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` -} diff --git a/internal/workflowapi/run.go b/internal/workflowapi/run.go deleted file mode 100644 index 3c2f301..0000000 --- a/internal/workflowapi/run.go +++ /dev/null @@ -1,66 +0,0 @@ -package workflowapi - -import ( - "context" - "fmt" -) - -// RunStatus is the lifecycle state of a pipeline run. -type RunStatus string - -const ( - RunStatusPending RunStatus = "pending" - RunStatusRunning RunStatus = "running" - RunStatusDone RunStatus = "done" - RunStatusCanceled RunStatus = "canceled" - RunStatusFailed RunStatus = "failed" -) - -// Stage is a group of jobs executed together within a run. -type Stage struct { - ID string `json:"id"` - Name string `json:"name"` - RunID string `json:"run_id"` - Status JobStatus `json:"status"` - Jobs []Job `json:"jobs"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` -} - -// Run is a single execution of a pipeline. -type Run struct { - ID string `json:"id"` - Branch string `json:"branch"` - PipelineID string `json:"pipeline_id"` - Status RunStatus `json:"status"` - StatusMessage string `json:"status_message"` - Stages []Stage `json:"stages"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` -} - -// RunListResponse is the response payload of GET /run/list. -type RunListResponse struct { - Runs []Run `json:"runs"` - Total int `json:"total"` -} - -// GetRun fetches a single run by id, including its stages and jobs. -func (c *Client) GetRun(ctx context.Context, id string) (*Run, error) { - if c.projectID == "" { - return nil, fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - var out Run - if err := c.Do(ctx, "GET", fmt.Sprintf("/project/%s/run/%s", c.projectID, id), nil, nil, &out); err != nil { - return nil, err - } - return &out, nil -} - -// StopRun cancels a running run. -func (c *Client) StopRun(ctx context.Context, id string) error { - if c.projectID == "" { - return fmt.Errorf("project id is not configured; use --project or EDS_PROJECT_ID") - } - return c.Do(ctx, "POST", fmt.Sprintf("/project/%s/run/%s/stop", c.projectID, id), nil, nil, nil) -} diff --git a/skill/SKILL.md b/skill/SKILL.md index 68655b6..b3d4d96 100644 --- a/skill/SKILL.md +++ b/skill/SKILL.md @@ -66,8 +66,7 @@ Errors go to stderr and the process exits non-zero. | `eds wf app delete [--force] [--json]` | Delete an application and its deployments (irreversible) | | `eds wf app deploy [--json]` | Run the pipeline and publish (the "deploy" action) | | `eds wf app deployments [--json]` | List publish history for an application | -| `eds wf app status [--json]` | Convenience: run status + stage/job breakdown + live URL | -| `eds wf run show [--json]` / `eds wf run stop ` | Inspect/control a pipeline run | +| `eds wf run show [--json]` / `eds wf run stop ` | Inspect/control a pipeline run | | `eds wf job logs ` | Stream job logs | | `eds login --api-key --project [--repo-api-url URL]` | Persist credentials (one-time setup) | @@ -209,12 +208,13 @@ APP_ID=$(eds wf app create my-site --repository "$REPO_ID" --branch main --json # -> running (live) or error, and "publishing" can last well after the # underlying run already reports "done" (the container is still starting). for i in $(seq 1 20); do - STATUS=$(eds wf app status "$APP_ID" --json | jq -r '.application.status') + STATUS=$(eds wf app show "$APP_ID" --json | jq -r '.status') echo "status: $STATUS" [ "$STATUS" = "running" ] || [ "$STATUS" = "error" ] && break sleep 15 done -eds wf app status "$APP_ID" --json | jq '{status: .application.status, url: .latest_deployment.url}' +URL=$(eds wf app deployments "$APP_ID" --json | jq -r '.deployments[0].url') +echo "url: $URL" ``` To redeploy later (e.g. after a new push), skip straight to `eds wf app @@ -245,15 +245,15 @@ built for unprivileged operation. ### Debug a failed deployment ```bash -eds wf app status "$APP_ID" --json | \ - jq -r '.application.run.stages[].jobs[] | select(.status=="failed") | .id' | \ +eds wf app show "$APP_ID" --json | \ + jq -r '.run.stages[].jobs[] | select(.status=="failed") | .id' | \ while read -r JOB_ID; do eds wf job logs "$JOB_ID"; done ``` ### Redeploy an existing application (e.g. after a new push) ```bash -eds wf app deploy "$APP_ID" --json | jq -r '.run_id' +eds wf app deploy "$APP_ID" --json | jq -r '.deployment.run_id' ``` ## Error handling @@ -310,5 +310,5 @@ NEW_REPO=$(eds repo create my-app --json | jq -r '.id') # 4. deploy (create auto-triggers the first deploy) APP_ID=$(eds wf app create my-app --repository "$NEW_REPO" --branch main --json | jq -r '.id') -eds wf app status "$APP_ID" --json | jq '{status: .application.status, url: .latest_deployment.url}' +eds wf app show "$APP_ID" --json | jq '{status: .status, run_id: .run_id}' ```