From 36e42914fa445e28952ebfac2f824507139fd783 Mon Sep 17 00:00:00 2001 From: Harikesh00 Date: Fri, 28 Oct 2022 21:08:53 +0530 Subject: [PATCH] Renamed procs/jobs to steps in code (#1331) Renamed `procs` to `steps` in code for the issue #1288 Co-authored-by: Harikesh Prajapati Co-authored-by: qwerty287 Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com> Co-authored-by: 6543 <6543@obermui.de> --- .gitpod.yml | 2 +- agent/runner.go | 43 +-- cli/deploy/deploy.go | 2 +- cli/exec/exec.go | 10 +- cli/exec/flags.go | 4 +- cli/exec/line.go | 4 +- cli/pipeline/logs.go | 6 +- cli/pipeline/ps.go | 6 +- cli/pipeline/start.go | 4 +- cli/pipeline/stop.go | 12 +- cmd/agent/agent.go | 6 +- cmd/agent/flags.go | 4 +- cmd/server/setup.go | 22 +- docker-compose.example.yml | 2 +- docs/docs/20-usage/50-environment.md | 12 +- docs/docs/30-administration/00-setup.md | 2 +- .../docs/30-administration/15-agent-config.md | 10 +- docs/docs/30-administration/90-prometheus.md | 20 +- docs/docs/91-migrations.md | 3 + docs/docs/92-awesome.md | 2 +- .../docs/92-development/01-getting-started.md | 2 +- pipeline/backend/docker/convert.go | 76 ++--- pipeline/backend/docker/docker.go | 38 +-- pipeline/backend/local/local.go | 20 +- pipeline/backend/ssh/ssh.go | 16 +- pipeline/frontend/drone_compatibility.go | 2 +- pipeline/frontend/metadata.go | 19 +- .../frontend/yaml/constraint/constraint.go | 2 +- pipeline/frontend/yaml/types/ulimit_test.go | 12 +- pipeline/logger.go | 2 +- pipeline/rpc/client_grpc.go | 10 +- pipeline/rpc/line.go | 10 +- pipeline/rpc/line_test.go | 2 +- pipeline/rpc/peer.go | 4 +- pipeline/rpc/proto/woodpecker.pb.go | 22 +- pipeline/rpc/proto/woodpecker.proto | 4 +- pipeline/rpc/proto/woodpecker_grpc.pb.go | 2 +- pipeline/tracer.go | 10 +- server/api/file.go | 8 +- server/api/pipeline.go | 34 +- server/api/stream.go | 12 +- server/config.go | 2 +- server/grpc/rpc.go | 134 ++++---- server/grpc/server.go | 10 +- server/model/file.go | 6 +- server/model/log.go | 2 +- server/model/pipeline.go | 2 +- server/model/{proc.go => step.go} | 110 +++---- server/model/{proc_test.go => step_test.go} | 12 +- server/pipeline/cancel.go | 54 ++-- server/pipeline/create.go | 2 +- server/pipeline/decline.go | 8 +- server/pipeline/filter.go | 2 +- server/pipeline/helper.go | 8 +- server/pipeline/items.go | 2 +- server/pipeline/queue.go | 10 +- server/pipeline/start.go | 4 +- server/pipeline/topic.go | 2 +- server/remote/bitbucket/bitbucket.go | 2 +- server/remote/bitbucket/bitbucket_test.go | 4 +- .../remote/bitbucketserver/bitbucketserver.go | 2 +- server/remote/coding/coding.go | 2 +- server/remote/common/status.go | 10 +- server/remote/common/status_test.go | 10 +- server/remote/gitea/gitea.go | 10 +- server/remote/gitea/gitea_test.go | 4 +- server/remote/github/github.go | 10 +- server/remote/gitlab/gitlab.go | 10 +- server/remote/gogs/gogs.go | 2 +- server/remote/mocks/remote.go | 4 +- server/remote/remote.go | 2 +- server/router/api.go | 7 +- server/shared/procStatus.go | 87 ------ server/shared/procStatus_test.go | 286 ----------------- .../shared/{procBuilder.go => stepBuilder.go} | 70 ++--- ...rocBuilder_test.go => stepBuilder_test.go} | 44 +-- server/shared/stepStatus.go | 88 ++++++ server/shared/stepStatus_test.go | 287 +++++++++++++++++ server/store/datastore/config_test.go | 2 +- server/store/datastore/file.go | 8 +- server/store/datastore/file_test.go | 40 +-- server/store/datastore/log.go | 10 +- server/store/datastore/log_test.go | 18 +- .../010_columns_rename_builds_to_pipeline.go | 12 +- .../011_columns_rename_procs_to_steps.go | 87 ++++++ server/store/datastore/migration/migration.go | 3 +- server/store/datastore/pipeline.go | 22 +- server/store/datastore/pipeline_test.go | 36 +-- server/store/datastore/repo_test.go | 18 +- server/store/datastore/{proc.go => step.go} | 52 ++-- .../datastore/{proc_test.go => step_test.go} | 80 ++--- server/store/datastore/users_test.go | 4 +- server/store/mocks/store.go | 294 +++++++++--------- server/store/store.go | 28 +- web/components.d.ts | 4 +- .../components/repo/pipeline/PipelineLog.vue | 72 ++--- ...cDuration.vue => PipelineStepDuration.vue} | 18 +- ...elineProcList.vue => PipelineStepList.vue} | 62 ++-- web/src/compositions/useEvents.ts | 8 +- web/src/lib/api/index.ts | 16 +- web/src/lib/api/types/pipeline.ts | 12 +- web/src/router.ts | 2 +- web/src/store/pipelines.ts | 10 +- web/src/utils/helpers.ts | 28 +- web/src/views/repo/pipeline/Pipeline.vue | 60 ++-- .../views/repo/pipeline/PipelineWrapper.vue | 12 +- woodpecker-go/woodpecker/client.go | 14 +- woodpecker-go/woodpecker/interface.go | 2 +- woodpecker-go/woodpecker/types.go | 10 +- 109 files changed, 1474 insertions(+), 1364 deletions(-) rename server/model/{proc.go => step.go} (60%) rename server/model/{proc_test.go => step_test.go} (90%) delete mode 100644 server/shared/procStatus.go delete mode 100644 server/shared/procStatus_test.go rename server/shared/{procBuilder.go => stepBuilder.go} (85%) rename server/shared/{procBuilder_test.go => stepBuilder_test.go} (93%) create mode 100644 server/shared/stepStatus.go create mode 100644 server/shared/stepStatus_test.go create mode 100644 server/store/datastore/migration/011_columns_rename_procs_to_steps.go rename server/store/datastore/{proc.go => step.go} (51%) rename server/store/datastore/{proc_test.go => step_test.go} (59%) rename web/src/components/repo/pipeline/{PipelineProcDuration.vue => PipelineStepDuration.vue} (69%) rename web/src/components/repo/pipeline/{PipelineProcList.vue => PipelineStepList.vue} (69%) diff --git a/.gitpod.yml b/.gitpod.yml index e0c7659d8..f5e49152e 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -23,7 +23,7 @@ tasks: env: WOODPECKER_SERVER: localhost:9000 WOODPECKER_SECRET: "1234" - WOODPECKER_MAX_PROCS: 1 + WOODPECKER_MAX_WORKFLOWS: 1 WOODPECKER_HEALTHCHECK: false command: | gp sync-await woodpecker-server diff --git a/agent/runner.go b/agent/runner.go index ee096e139..d974024d4 100644 --- a/agent/runner.go +++ b/agent/runner.go @@ -67,7 +67,7 @@ func (r *Runner) Run(ctx context.Context) error { meta, _ := metadata.FromOutgoingContext(ctx) ctxmeta := metadata.NewOutgoingContext(context.Background(), meta) - // get the next job from the queue + // get the next workflow from the queue work, err := r.client.Next(ctx, r.filter) if err != nil { return err @@ -150,10 +150,10 @@ func (r *Runner) Run(ctx context.Context) error { } var uploads sync.WaitGroup - defaultLogger := pipeline.LogFunc(func(proc *backend.Step, rc multipart.Reader) error { + defaultLogger := pipeline.LogFunc(func(step *backend.Step, rc multipart.Reader) error { loglogger := logger.With(). - Str("image", proc.Image). - Str("stage", proc.Alias). + Str("image", step.Image). + Str("stage", step.Alias). Logger() part, rerr := rc.NextPart() @@ -172,7 +172,7 @@ func (r *Runner) Run(ctx context.Context) error { loglogger.Debug().Msg("log stream opened") limitedPart := io.LimitReader(part, maxLogsUpload) - logStream := rpc.NewLineWriter(r.client, work.ID, proc.Alias, secrets...) + logStream := rpc.NewLineWriter(r.client, work.ID, step.Alias, secrets...) if _, err := io.Copy(logStream, limitedPart); err != nil { log.Error().Err(err).Msg("copy limited logStream part") } @@ -186,7 +186,7 @@ func (r *Runner) Run(ctx context.Context) error { file := &rpc.File{ Mime: "application/json+logs", - Proc: proc.Alias, + Step: step.Alias, Name: "logs.json", Data: data, Size: len(data), @@ -218,7 +218,7 @@ func (r *Runner) Run(ctx context.Context) error { file = &rpc.File{ Mime: part.Header().Get("Content-Type"), - Proc: proc.Alias, + Step: step.Alias, Name: part.FileName(), Data: data, Size: len(data), @@ -250,7 +250,7 @@ func (r *Runner) Run(ctx context.Context) error { }) defaultTracer := pipeline.TraceFunc(func(state *pipeline.State) error { - proclogger := logger.With(). + steplogger := logger.With(). Str("image", state.Pipeline.Step.Image). Str("stage", state.Pipeline.Step.Alias). Err(state.Process.Error). @@ -258,27 +258,27 @@ func (r *Runner) Run(ctx context.Context) error { Bool("exited", state.Process.Exited). Logger() - procState := rpc.State{ - Proc: state.Pipeline.Step.Alias, + stepState := rpc.State{ + Step: state.Pipeline.Step.Alias, Exited: state.Process.Exited, ExitCode: state.Process.ExitCode, Started: time.Now().Unix(), // TODO do not do this Finished: time.Now().Unix(), } if state.Process.Error != nil { - procState.Error = state.Process.Error.Error() + stepState.Error = state.Process.Error.Error() } defer func() { - proclogger.Debug().Msg("update step status") + steplogger.Debug().Msg("update step status") - if uerr := r.client.Update(ctxmeta, work.ID, procState); uerr != nil { - proclogger.Debug(). + if uerr := r.client.Update(ctxmeta, work.ID, stepState); uerr != nil { + steplogger.Debug(). Err(uerr). Msg("update step status error") } - proclogger.Debug().Msg("update step status complete") + steplogger.Debug().Msg("update step status complete") }() if state.Process.Exited { return nil @@ -289,22 +289,29 @@ func (r *Runner) Run(ctx context.Context) error { // TODO: find better way to update this state and move it to pipeline to have the same env in cli-exec state.Pipeline.Step.Environment["CI_MACHINE"] = r.hostname + state.Pipeline.Step.Environment["CI_PIPELINE_STATUS"] = "success" state.Pipeline.Step.Environment["CI_PIPELINE_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) state.Pipeline.Step.Environment["CI_PIPELINE_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) + + state.Pipeline.Step.Environment["CI_STEP_STATUS"] = "success" + state.Pipeline.Step.Environment["CI_STEP_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) + state.Pipeline.Step.Environment["CI_STEP_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) + + state.Pipeline.Step.Environment["CI_SYSTEM_ARCH"] = runtime.GOOS + "/" + runtime.GOARCH + // DEPRECATED state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "success" state.Pipeline.Step.Environment["CI_BUILD_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) state.Pipeline.Step.Environment["CI_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) - state.Pipeline.Step.Environment["CI_JOB_STATUS"] = "success" state.Pipeline.Step.Environment["CI_JOB_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) state.Pipeline.Step.Environment["CI_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) - state.Pipeline.Step.Environment["CI_SYSTEM_ARCH"] = runtime.GOOS + "/" + runtime.GOARCH - if state.Pipeline.Error != nil { state.Pipeline.Step.Environment["CI_PIPELINE_STATUS"] = "failure" + state.Pipeline.Step.Environment["CI_STEP_STATUS"] = "failure" + // DEPRECATED state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "failure" state.Pipeline.Step.Environment["CI_JOB_STATUS"] = "failure" diff --git a/cli/deploy/deploy.go b/cli/deploy/deploy.go index 9d9db3cd6..f9299a352 100644 --- a/cli/deploy/deploy.go +++ b/cli/deploy/deploy.go @@ -53,7 +53,7 @@ var Command = &cli.Command{ &cli.StringSliceFlag{ Name: "param", Aliases: []string{"p"}, - Usage: "custom parameters to be injected into the job environment. Format: KEY=value", + Usage: "custom parameters to be injected into the step environment. Format: KEY=value", }, ), } diff --git a/cli/exec/exec.go b/cli/exec/exec.go index 631ede3b9..babdb50b6 100644 --- a/cli/exec/exec.go +++ b/cli/exec/exec.go @@ -112,7 +112,7 @@ func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error metadata := metadataFromContext(c, axis) environ := metadata.Environ() var secrets []compiler.Secret - for key, val := range metadata.Job.Matrix { + for key, val := range metadata.Step.Matrix { environ[key] = val secrets = append(secrets, compiler.Secret{ Name: key, @@ -289,8 +289,8 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) frontend.Metadata { }, }, }, - Job: frontend.Job{ - Number: c.Int("job-number"), + Step: frontend.Step{ + Number: c.Int("step-number"), Matrix: axis, }, Sys: frontend.System{ @@ -312,13 +312,13 @@ func convertPathForWindows(path string) string { return filepath.ToSlash(path) } -var defaultLogger = pipeline.LogFunc(func(proc *backendTypes.Step, rc multipart.Reader) error { +var defaultLogger = pipeline.LogFunc(func(step *backendTypes.Step, rc multipart.Reader) error { part, err := rc.NextPart() if err != nil { return err } - logStream := NewLineWriter(proc.Alias) + logStream := NewLineWriter(step.Alias) _, err = io.Copy(logStream, part) return err }) diff --git a/cli/exec/flags.go b/cli/exec/flags.go index abfcc95e3..51caca266 100644 --- a/cli/exec/flags.go +++ b/cli/exec/flags.go @@ -260,8 +260,8 @@ var flags = []cli.Flag{ Name: "prev-commit-author-email", }, &cli.IntFlag{ - EnvVars: []string{"CI_JOB_NUMBER"}, - Name: "job-number", + EnvVars: []string{"CI_STEP_NUMBER", "CI_JOB_NUMBER"}, + Name: "step-number", }, &cli.StringSliceFlag{ EnvVars: []string{"CI_ENV"}, diff --git a/cli/exec/line.go b/cli/exec/line.go index 07b96e28a..3ba05b8be 100644 --- a/cli/exec/line.go +++ b/cli/exec/line.go @@ -32,7 +32,7 @@ const ( // Line is a line of console output. type Line struct { - Proc string `json:"proc,omitempty"` + Step string `json:"step,omitempty"` Time int64 `json:"time,omitempty"` Type int `json:"type,omitempty"` Pos int `json:"pos,omitempty"` @@ -66,7 +66,7 @@ func (w *LineWriter) Write(p []byte) (n int, err error) { line := &Line{ Out: out, - Proc: w.name, + Step: w.name, Pos: w.num, Time: int64(time.Since(w.now).Seconds()), Type: LineStdout, diff --git a/cli/pipeline/logs.go b/cli/pipeline/logs.go index f42f4950f..7a72849f0 100644 --- a/cli/pipeline/logs.go +++ b/cli/pipeline/logs.go @@ -27,7 +27,7 @@ import ( var pipelineLogsCmd = &cli.Command{ Name: "logs", Usage: "show pipeline logs", - ArgsUsage: " [pipeline] [job]", + ArgsUsage: " [pipeline] [step]", Action: pipelineLogs, Flags: common.GlobalFlags, } @@ -44,7 +44,7 @@ func pipelineLogs(c *cli.Context) error { return err } - job, err := strconv.Atoi(c.Args().Get(2)) + step, err := strconv.Atoi(c.Args().Get(2)) if err != nil { return err } @@ -54,7 +54,7 @@ func pipelineLogs(c *cli.Context) error { return err } - logs, err := client.PipelineLogs(owner, name, number, job) + logs, err := client.PipelineLogs(owner, name, number, step) if err != nil { return err } diff --git a/cli/pipeline/ps.go b/cli/pipeline/ps.go index 5b57e7e7f..6e7745cb1 100644 --- a/cli/pipeline/ps.go +++ b/cli/pipeline/ps.go @@ -76,8 +76,8 @@ func pipelinePs(c *cli.Context) error { return err } - for _, proc := range pipeline.Procs { - for _, child := range proc.Children { + for _, step := range pipeline.Steps { + for _, child := range step.Children { if err := tmpl.Execute(os.Stdout, child); err != nil { return err } @@ -88,7 +88,7 @@ func pipelinePs(c *cli.Context) error { } // template for pipeline ps information -var tmplPipelinePs = "\x1b[33mProc #{{ .PID }} \x1b[0m" + ` +var tmplPipelinePs = "\x1b[33mStep #{{ .PID }} \x1b[0m" + ` Step: {{ .Name }} State: {{ .State }} ` diff --git a/cli/pipeline/start.go b/cli/pipeline/start.go index 30a341238..a289f546d 100644 --- a/cli/pipeline/start.go +++ b/cli/pipeline/start.go @@ -34,7 +34,7 @@ var pipelineStartCmd = &cli.Command{ &cli.StringSliceFlag{ Name: "param", Aliases: []string{"p"}, - Usage: "custom parameters to be injected into the job environment. Format: KEY=value", + Usage: "custom parameters to be injected into the step environment. Format: KEY=value", }, ), } @@ -62,7 +62,7 @@ func pipelineStart(c *cli.Context) (err error) { number = pipeline.Number } else { if len(pipelineArg) == 0 { - return errors.New("missing job number") + return errors.New("missing step number") } number, err = strconv.Atoi(pipelineArg) if err != nil { diff --git a/cli/pipeline/stop.go b/cli/pipeline/stop.go index 1e333cbd5..ca80298d4 100644 --- a/cli/pipeline/stop.go +++ b/cli/pipeline/stop.go @@ -27,7 +27,7 @@ import ( var pipelineStopCmd = &cli.Command{ Name: "stop", Usage: "stop a pipeline", - ArgsUsage: " [pipeline] [job]", + ArgsUsage: " [pipeline] [step]", Flags: common.GlobalFlags, Action: pipelineStop, } @@ -42,9 +42,9 @@ func pipelineStop(c *cli.Context) (err error) { if err != nil { return err } - job, _ := strconv.Atoi(c.Args().Get(2)) - if job == 0 { - job = 1 + step, _ := strconv.Atoi(c.Args().Get(2)) + if step == 0 { + step = 1 } client, err := internal.NewClient(c) @@ -52,11 +52,11 @@ func pipelineStop(c *cli.Context) (err error) { return err } - err = client.PipelineStop(owner, name, number, job) + err = client.PipelineStop(owner, name, number, step) if err != nil { return err } - fmt.Printf("Stopping pipeline %s/%s#%d.%d\n", owner, name, number, job) + fmt.Printf("Stopping pipeline %s/%s#%d.%d\n", owner, name, number, step) return nil } diff --git a/cmd/agent/agent.go b/cmd/agent/agent.go index 819aeb15b..6b4af32dc 100644 --- a/cmd/agent/agent.go +++ b/cmd/agent/agent.go @@ -85,7 +85,7 @@ func loop(c *cli.Context) error { log.Logger = log.With().Caller().Logger() } - counter.Polling = c.Int("max-procs") + counter.Polling = c.Int("max-workflows") counter.Running = 0 if c.Bool("healthcheck") { @@ -139,7 +139,7 @@ func loop(c *cli.Context) error { backend.Init(context.WithValue(ctx, types.CliContext, c)) var wg sync.WaitGroup - parallel := c.Int("max-procs") + parallel := c.Int("max-workflows") wg.Add(parallel) // new engine @@ -169,7 +169,7 @@ func loop(c *cli.Context) error { return } - log.Debug().Msg("polling new jobs") + log.Debug().Msg("polling new steps") if err := r.Run(ctx); err != nil { log.Error().Err(err).Msg("pipeline done with error") return diff --git a/cmd/agent/flags.go b/cmd/agent/flags.go index a70f0fdf0..23c5e4775 100644 --- a/cmd/agent/flags.go +++ b/cmd/agent/flags.go @@ -79,8 +79,8 @@ var flags = []cli.Flag{ Usage: "List of labels to filter tasks on. An agent must be assigned every tag listed in a task to be selected.", }, &cli.IntFlag{ - EnvVars: []string{"WOODPECKER_MAX_PROCS"}, - Name: "max-procs", + EnvVars: []string{"WOODPECKER_MAX_WORKFLOWS", "WOODPECKER_MAX_PROCS"}, + Name: "max-workflows", Usage: "agent parallel workflows", Value: 1, }, diff --git a/cmd/server/setup.go b/cmd/server/setup.go index 58fb6fb38..4a01ef05d 100644 --- a/cmd/server/setup.go +++ b/cmd/server/setup.go @@ -304,20 +304,20 @@ func setupCoding(c *cli.Context) (remote.Remote, error) { } func setupMetrics(g *errgroup.Group, _store store.Store) { - pendingJobs := promauto.NewGauge(prometheus.GaugeOpts{ + pendingSteps := promauto.NewGauge(prometheus.GaugeOpts{ Namespace: "woodpecker", - Name: "pending_jobs", - Help: "Total number of pending pipeline processes.", + Name: "pending_steps", + Help: "Total number of pending pipeline steps.", }) - waitingJobs := promauto.NewGauge(prometheus.GaugeOpts{ + waitingSteps := promauto.NewGauge(prometheus.GaugeOpts{ Namespace: "woodpecker", - Name: "waiting_jobs", + Name: "waiting_steps", Help: "Total number of pipeline waiting on deps.", }) - runningJobs := promauto.NewGauge(prometheus.GaugeOpts{ + runningSteps := promauto.NewGauge(prometheus.GaugeOpts{ Namespace: "woodpecker", - Name: "running_jobs", - Help: "Total number of running pipeline processes.", + Name: "running_steps", + Help: "Total number of running pipeline steps.", }) workers := promauto.NewGauge(prometheus.GaugeOpts{ Namespace: "woodpecker", @@ -343,9 +343,9 @@ func setupMetrics(g *errgroup.Group, _store store.Store) { g.Go(func() error { for { stats := server.Config.Services.Queue.Info(context.TODO()) - pendingJobs.Set(float64(stats.Stats.Pending)) - waitingJobs.Set(float64(stats.Stats.WaitingOnDeps)) - runningJobs.Set(float64(stats.Stats.Running)) + pendingSteps.Set(float64(stats.Stats.Pending)) + waitingSteps.Set(float64(stats.Stats.WaitingOnDeps)) + runningSteps.Set(float64(stats.Stats.Running)) workers.Set(float64(stats.Stats.Workers)) time.Sleep(500 * time.Millisecond) } diff --git a/docker-compose.example.yml b/docker-compose.example.yml index edd46fed0..bfc2fade5 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -28,4 +28,4 @@ services: environment: - WOODPECKER_SERVER=woodpecker-server:9000 - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET} - - WOODPECKER_MAX_PROCS=2 + - WOODPECKER_MAX_WORKFLOWS=2 diff --git a/docs/docs/20-usage/50-environment.md b/docs/docs/20-usage/50-environment.md index 121f7fef3..f51a4297b 100644 --- a/docs/docs/20-usage/50-environment.md +++ b/docs/docs/20-usage/50-environment.md @@ -75,7 +75,7 @@ This is the reference list of all environment variables available to your pipeli | `CI_COMMIT_AUTHOR_AVATAR` | commit author avatar | | | **Current pipeline** | | `CI_PIPELINE_NUMBER` | pipeline number | -| `CI_PIPELINE_PARENT` | number of parent pipeline | +| `CI_PIPELINE_PARENT` | number of parent pipeline | | `CI_PIPELINE_EVENT` | pipeline event (push, pull_request, tag, deployment) | | `CI_PIPELINE_LINK` | pipeline link in CI | | `CI_PIPELINE_DEPLOY_TARGET` | pipeline deploy target for `deployment` events (ie production) | @@ -83,11 +83,11 @@ This is the reference list of all environment variables available to your pipeli | `CI_PIPELINE_CREATED` | pipeline created UNIX timestamp | | `CI_PIPELINE_STARTED` | pipeline started UNIX timestamp | | `CI_PIPELINE_FINISHED` | pipeline finished UNIX timestamp | -| | **Current job** | -| `CI_JOB_NUMBER` | job number | -| `CI_JOB_STATUS` | job status (success, failure) | -| `CI_JOB_STARTED` | job started UNIX timestamp | -| `CI_JOB_FINISHED` | job finished UNIX timestamp | +| | **Current step** | +| `CI_STEP_NUMBER` | step number | +| `CI_STEP_STATUS` | step status (success, failure) | +| `CI_STEP_STARTED` | step started UNIX timestamp | +| `CI_STEP_FINISHED` | step finished UNIX timestamp | | | **Previous commit** | | `CI_PREV_COMMIT_SHA` | previous commit SHA | | `CI_PREV_COMMIT_REF` | previous commit ref | diff --git a/docs/docs/30-administration/00-setup.md b/docs/docs/30-administration/00-setup.md index fdab5b576..191e1cb85 100644 --- a/docs/docs/30-administration/00-setup.md +++ b/docs/docs/30-administration/00-setup.md @@ -9,7 +9,7 @@ A Woodpecker deployment consists of two parts: > > If you have 4 agents installed and connected to the Woodpecker server, your system will process 4 builds in parallel. > -> You can add more agents to increase the number of parallel builds or set the agent's `WOODPECKER_MAX_PROCS=1` environment variable to increase the number of parallel builds for that agent. +> You can add more agents to increase the number of parallel steps or set the agent's `WOODPECKER_MAX_WORKFLOWS=1` environment variable to increase the number of parallel workflows for that agent. ## Installation diff --git a/docs/docs/30-administration/15-agent-config.md b/docs/docs/30-administration/15-agent-config.md index 63c461b2e..f8a34e234 100644 --- a/docs/docs/30-administration/15-agent-config.md +++ b/docs/docs/30-administration/15-agent-config.md @@ -17,11 +17,11 @@ services: The following are automatically set and can be overridden: - WOODPECKER_HOSTNAME if not set, becomes the OS' hostname -- WOODPECKER_MAX_PROCS if not set, defaults to 1 +- WOODPECKER_MAX_WORKFLOWS if not set, defaults to 1 ## Processes per agent -By default the maximum processes that are run per agent is 1. If required you can add `WOODPECKER_MAX_PROCS` to increase your parallel processing on a per-agent basis. +By default the maximum processes that are run per agent is 1. If required you can add `WOODPECKER_MAX_WORKFLOWS` to increase your parallel processing on a per-agent basis. ```yaml # docker-compose.yml @@ -33,7 +33,7 @@ services: environment: - WOODPECKER_SERVER=localhost:9000 - WOODPECKER_AGENT_SECRET="your-shared-secret-goes-here" -+ - WOODPECKER_MAX_PROCS=4 ++ - WOODPECKER_MAX_WORKFLOWS=4 ``` ## All agent configuration options @@ -80,10 +80,10 @@ Disable colored debug output. Configures the agent hostname. -### `WOODPECKER_MAX_PROCS` +### `WOODPECKER_MAX_WORKFLOWS` > Default: `1` -Configures the number of parallel builds. +Configures the number of parallel workflows. ### `WOODPECKER_FILTER_LABELS` > Default: empty diff --git a/docs/docs/30-administration/90-prometheus.md b/docs/docs/30-administration/90-prometheus.md index d7e6ddee8..8e6e30342 100644 --- a/docs/docs/30-administration/90-prometheus.md +++ b/docs/docs/30-administration/90-prometheus.md @@ -35,7 +35,7 @@ scrape_configs: List of Prometheus metrics specific to Woodpecker: ``` -# HELP woodpecker_pipeline_count Build count. +# HELP woodpecker_pipeline_count Pipeline count. # TYPE woodpecker_pipeline_count counter woodpecker_build_count{branch="master",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 3 woodpecker_build_count{branch="mkdocs",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 3 @@ -46,21 +46,21 @@ woodpecker_build_time{branch="mkdocs",pipeline="total",repo="woodpecker-ci/woodp # HELP woodpecker_pipeline_total_count Total number of builds. # TYPE woodpecker_pipeline_total_count gauge woodpecker_build_total_count 1025 -# HELP woodpecker_pending_jobs Total number of pending build processes. -# TYPE woodpecker_pending_jobs gauge -woodpecker_pending_jobs 0 +# HELP woodpecker_pending_steps Total number of pending pipeline steps. +# TYPE woodpecker_pending_steps gauge +woodpecker_pending_steps 0 # HELP woodpecker_repo_count Total number of repos. # TYPE woodpecker_repo_count gauge woodpecker_repo_count 9 -# HELP woodpecker_running_jobs Total number of running build processes. -# TYPE woodpecker_running_jobs gauge -woodpecker_running_jobs 0 +# HELP woodpecker_running_steps Total number of running pipeline steps. +# TYPE woodpecker_running_steps gauge +woodpecker_running_steps 0 # HELP woodpecker_user_count Total number of users. # TYPE woodpecker_user_count gauge woodpecker_user_count 1 -# HELP woodpecker_waiting_jobs Total number of builds waiting on deps. -# TYPE woodpecker_waiting_jobs gauge -woodpecker_waiting_jobs 0 +# HELP woodpecker_waiting_steps Total number of pipeline waiting on deps. +# TYPE woodpecker_waiting_steps gauge +woodpecker_waiting_steps 0 # HELP woodpecker_worker_count Total number of workers. # TYPE woodpecker_worker_count gauge woodpecker_worker_count 4 diff --git a/docs/docs/91-migrations.md b/docs/docs/91-migrations.md index 1808aa63b..78700436d 100644 --- a/docs/docs/91-migrations.md +++ b/docs/docs/91-migrations.md @@ -8,8 +8,11 @@ Some versions need some changes to the server configuration or the pipeline conf - Refactored support of old agent filter labels and expression. Learn how to use the new [filter](./20-usage/20-pipeline-syntax.md#labels) - Renamed step environment variable `CI_SYSTEM_ARCH` to `CI_SYSTEM_PLATFORM`. Same applies for the cli exec variable. - Renamed environment variables `CI_BUILD_*` and `CI_PREV_BUILD_*` to `CI_PIPELINE_*` and `CI_PREV_PIPELINE_*`, old ones are still available but deprecated +- Renamed environment variables `CI_JOB_*` to `CI_STEP_*`, old ones are still available but deprecated - Renamed API endpoints for pipelines (`//builds/` -> `//pipelines/`), old ones are still available but deprecated - Updated Prometheus gauge `build_*` to `pipeline_*` +- Updated Prometheus gauge `*_job_*` to `*_step_*` +- Renamed config env `WOODPECKER_MAX_PROCS` to `WOODPECKER_MAX_WORKFLOWS` (still available as fallback) ## 0.15.0 diff --git a/docs/docs/92-awesome.md b/docs/docs/92-awesome.md index 12329c511..b04faf9d2 100644 --- a/docs/docs/92-awesome.md +++ b/docs/docs/92-awesome.md @@ -22,7 +22,7 @@ If you have some missing resources, please feel free to [open a pull-request](ht - [Convert Drone CI pipelines to Woodpecker CI](https://codeberg.org/lafriks/woodpecker-pipeline-transform) - [Ansible NAS](https://github.com/davestephens/ansible-nas/) - a homelab Ansible playbook that can set up Woodpecker-CI and Gitea -- [picus](https://github.com/windsource/picus) - Picus connects to a Woodpecker CI server and creates an agent in the cloud when there are pending jobs. +- [picus](https://github.com/windsource/picus) - Picus connects to a Woodpecker CI server and creates an agent in the cloud when there are pending workflows. ## Templates diff --git a/docs/docs/92-development/01-getting-started.md b/docs/docs/92-development/01-getting-started.md index ec117600b..7b9641e57 100644 --- a/docs/docs/92-development/01-getting-started.md +++ b/docs/docs/92-development/01-getting-started.md @@ -58,7 +58,7 @@ WOODPECKER_GITHUB_SECRET= # agent WOODPECKER_SERVER=localhost:9000 WOODPECKER_SECRET=a-long-and-secure-password-used-for-the-local-development-system -WOODPECKER_MAX_PROCS=1 +WOODPECKER_MAX_WORKFLOWS=1 # enable if you want to develop the UI # WOODPECKER_DEV_WWW_PROXY=http://localhost:8010 diff --git a/pipeline/backend/docker/convert.go b/pipeline/backend/docker/convert.go index 8df57a7c7..32103c4d0 100644 --- a/pipeline/backend/docker/convert.go +++ b/pipeline/backend/docker/convert.go @@ -12,73 +12,73 @@ import ( ) // returns a container configuration. -func toConfig(proc *types.Step) *container.Config { +func toConfig(step *types.Step) *container.Config { config := &container.Config{ - Image: proc.Image, - Labels: proc.Labels, - WorkingDir: proc.WorkingDir, + Image: step.Image, + Labels: step.Labels, + WorkingDir: step.WorkingDir, AttachStdout: true, AttachStderr: true, } - if len(proc.Environment) != 0 { - config.Env = toEnv(proc.Environment) + if len(step.Environment) != 0 { + config.Env = toEnv(step.Environment) } - if len(proc.Command) != 0 { - config.Cmd = proc.Command + if len(step.Command) != 0 { + config.Cmd = step.Command } - if len(proc.Entrypoint) != 0 { - config.Entrypoint = proc.Entrypoint + if len(step.Entrypoint) != 0 { + config.Entrypoint = step.Entrypoint } - if len(proc.Volumes) != 0 { - config.Volumes = toVol(proc.Volumes) + if len(step.Volumes) != 0 { + config.Volumes = toVol(step.Volumes) } return config } // returns a container host configuration. -func toHostConfig(proc *types.Step) *container.HostConfig { +func toHostConfig(step *types.Step) *container.HostConfig { config := &container.HostConfig{ Resources: container.Resources{ - CPUQuota: proc.CPUQuota, - CPUShares: proc.CPUShares, - CpusetCpus: proc.CPUSet, - Memory: proc.MemLimit, - MemorySwap: proc.MemSwapLimit, + CPUQuota: step.CPUQuota, + CPUShares: step.CPUShares, + CpusetCpus: step.CPUSet, + Memory: step.MemLimit, + MemorySwap: step.MemSwapLimit, }, LogConfig: container.LogConfig{ Type: "json-file", }, - Privileged: proc.Privileged, - ShmSize: proc.ShmSize, - Sysctls: proc.Sysctls, + Privileged: step.Privileged, + ShmSize: step.ShmSize, + Sysctls: step.Sysctls, } - // if len(proc.VolumesFrom) != 0 { - // config.VolumesFrom = proc.VolumesFrom + // if len(step.VolumesFrom) != 0 { + // config.VolumesFrom = step.VolumesFrom // } - if len(proc.NetworkMode) != 0 { - config.NetworkMode = container.NetworkMode(proc.NetworkMode) + if len(step.NetworkMode) != 0 { + config.NetworkMode = container.NetworkMode(step.NetworkMode) } - if len(proc.IpcMode) != 0 { - config.IpcMode = container.IpcMode(proc.IpcMode) + if len(step.IpcMode) != 0 { + config.IpcMode = container.IpcMode(step.IpcMode) } - if len(proc.DNS) != 0 { - config.DNS = proc.DNS + if len(step.DNS) != 0 { + config.DNS = step.DNS } - if len(proc.DNSSearch) != 0 { - config.DNSSearch = proc.DNSSearch + if len(step.DNSSearch) != 0 { + config.DNSSearch = step.DNSSearch } - if len(proc.ExtraHosts) != 0 { - config.ExtraHosts = proc.ExtraHosts + if len(step.ExtraHosts) != 0 { + config.ExtraHosts = step.ExtraHosts } - if len(proc.Devices) != 0 { - config.Devices = toDev(proc.Devices) + if len(step.Devices) != 0 { + config.Devices = toDev(step.Devices) } - if len(proc.Volumes) != 0 { - config.Binds = proc.Volumes + if len(step.Volumes) != 0 { + config.Binds = step.Volumes } config.Tmpfs = map[string]string{} - for _, path := range proc.Tmpfs { + for _, path := range step.Tmpfs { if !strings.Contains(path, ":") { config.Tmpfs[path] = "" continue diff --git a/pipeline/backend/docker/docker.go b/pipeline/backend/docker/docker.go index 82450c09c..2eb2e1fac 100644 --- a/pipeline/backend/docker/docker.go +++ b/pipeline/backend/docker/docker.go @@ -104,19 +104,19 @@ func (e *docker) Setup(_ context.Context, conf *backend.Config) error { return nil } -func (e *docker) Exec(ctx context.Context, proc *backend.Step) error { - config := toConfig(proc) - hostConfig := toHostConfig(proc) +func (e *docker) Exec(ctx context.Context, step *backend.Step) error { + config := toConfig(step) + hostConfig := toHostConfig(step) // create pull options with encoded authorization credentials. pullopts := types.ImagePullOptions{} - if proc.AuthConfig.Username != "" && proc.AuthConfig.Password != "" { - pullopts.RegistryAuth, _ = encodeAuthToBase64(proc.AuthConfig) + if step.AuthConfig.Username != "" && step.AuthConfig.Password != "" { + pullopts.RegistryAuth, _ = encodeAuthToBase64(step.AuthConfig) } // automatically pull the latest version of the image if requested // by the process configuration. - if proc.Pull { + if step.Pull { responseBody, perr := e.client.ImagePull(ctx, config.Image, pullopts) if perr == nil { defer responseBody.Close() @@ -128,7 +128,7 @@ func (e *docker) Exec(ctx context.Context, proc *backend.Step) error { } // Fix "Show warning when fail to auth to docker registry" // (https://web.archive.org/web/20201023145804/https://github.com/drone/drone/issues/1917) - if perr != nil && proc.AuthConfig.Password != "" { + if perr != nil && step.AuthConfig.Password != "" { return perr } } @@ -136,7 +136,7 @@ func (e *docker) Exec(ctx context.Context, proc *backend.Step) error { // add default volumes to the host configuration hostConfig.Binds = append(hostConfig.Binds, e.volumes...) - _, err := e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, proc.Name) + _, err := e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, step.Name) if client.IsErrNotFound(err) { // automatically pull and try to re-create the image if the // failure is caused because the image does not exist. @@ -150,15 +150,15 @@ func (e *docker) Exec(ctx context.Context, proc *backend.Step) error { log.Error().Err(err).Msg("DisplayJSONMessagesStream") } - _, err = e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, proc.Name) + _, err = e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, step.Name) } if err != nil { return err } - if len(proc.NetworkMode) == 0 { - for _, net := range proc.Networks { - err = e.client.NetworkConnect(ctx, net.Name, proc.Name, &network.EndpointSettings{ + if len(step.NetworkMode) == 0 { + for _, net := range step.Networks { + err = e.client.NetworkConnect(ctx, net.Name, step.Name, &network.EndpointSettings{ Aliases: net.Aliases, }) if err != nil { @@ -168,24 +168,24 @@ func (e *docker) Exec(ctx context.Context, proc *backend.Step) error { // join the container to an existing network if e.network != "" { - err = e.client.NetworkConnect(ctx, e.network, proc.Name, &network.EndpointSettings{}) + err = e.client.NetworkConnect(ctx, e.network, step.Name, &network.EndpointSettings{}) if err != nil { return err } } } - return e.client.ContainerStart(ctx, proc.Name, startOpts) + return e.client.ContainerStart(ctx, step.Name, startOpts) } -func (e *docker) Wait(ctx context.Context, proc *backend.Step) (*backend.State, error) { - wait, errc := e.client.ContainerWait(ctx, proc.Name, "") +func (e *docker) Wait(ctx context.Context, step *backend.Step) (*backend.State, error) { + wait, errc := e.client.ContainerWait(ctx, step.Name, "") select { case <-wait: case <-errc: } - info, err := e.client.ContainerInspect(ctx, proc.Name) + info, err := e.client.ContainerInspect(ctx, step.Name) if err != nil { return nil, err } @@ -200,8 +200,8 @@ func (e *docker) Wait(ctx context.Context, proc *backend.Step) (*backend.State, }, nil } -func (e *docker) Tail(ctx context.Context, proc *backend.Step) (io.ReadCloser, error) { - logs, err := e.client.ContainerLogs(ctx, proc.Name, logsOpts) +func (e *docker) Tail(ctx context.Context, step *backend.Step) (io.ReadCloser, error) { + logs, err := e.client.ContainerLogs(ctx, step.Name, logsOpts) if err != nil { return nil, err } diff --git a/pipeline/backend/local/local.go b/pipeline/backend/local/local.go index dd84b75fa..c9eaaada3 100644 --- a/pipeline/backend/local/local.go +++ b/pipeline/backend/local/local.go @@ -55,33 +55,33 @@ func (e *local) Load() error { } // Setup the pipeline environment. -func (e *local) Setup(ctx context.Context, proc *types.Config) error { +func (e *local) Setup(ctx context.Context, config *types.Config) error { return nil } // Exec the pipeline step. -func (e *local) Exec(ctx context.Context, proc *types.Step) error { +func (e *local) Exec(ctx context.Context, step *types.Step) error { // Get environment variables Env := os.Environ() - for a, b := range proc.Environment { + for a, b := range step.Environment { if a != "HOME" && a != "SHELL" { // Don't override $HOME and $SHELL Env = append(Env, a+"="+b) } } Command := []string{} - if proc.Image == constant.DefaultCloneImage { + if step.Image == constant.DefaultCloneImage { // Default clone step - Env = append(Env, "CI_WORKSPACE="+e.workingdir+"/"+proc.Environment["CI_REPO"]) + Env = append(Env, "CI_WORKSPACE="+e.workingdir+"/"+step.Environment["CI_REPO"]) Command = append(Command, "plugin-git") } else { // Use "image name" as run command - Command = append(Command, proc.Image) + Command = append(Command, step.Image) Command = append(Command, "-c") // Decode script and delete initial lines // Deleting the initial lines removes netrc support but adds compatibility for more shells like fish - Script, _ := base64.RawStdEncoding.DecodeString(proc.Environment["CI_SCRIPT"]) + Script, _ := base64.RawStdEncoding.DecodeString(step.Environment["CI_SCRIPT"]) Command = append(Command, string(Script)[strings.Index(string(Script), "\n\n")+2:]) } @@ -90,10 +90,10 @@ func (e *local) Exec(ctx context.Context, proc *types.Step) error { e.cmd.Env = Env // Prepare working directory - if proc.Image == constant.DefaultCloneImage { - e.cmd.Dir = e.workingdir + "/" + proc.Environment["CI_REPO_OWNER"] + if step.Image == constant.DefaultCloneImage { + e.cmd.Dir = e.workingdir + "/" + step.Environment["CI_REPO_OWNER"] } else { - e.cmd.Dir = e.workingdir + "/" + proc.Environment["CI_REPO"] + e.cmd.Dir = e.workingdir + "/" + step.Environment["CI_REPO"] } err := os.MkdirAll(e.cmd.Dir, 0o700) if err != nil { diff --git a/pipeline/backend/ssh/ssh.go b/pipeline/backend/ssh/ssh.go index 17798ee71..26d8de6ad 100644 --- a/pipeline/backend/ssh/ssh.go +++ b/pipeline/backend/ssh/ssh.go @@ -84,33 +84,33 @@ func (e *ssh) Load() error { } // Setup the pipeline environment. -func (e *ssh) Setup(ctx context.Context, proc *types.Config) error { +func (e *ssh) Setup(ctx context.Context, config *types.Config) error { return nil } // Exec the pipeline step. -func (e *ssh) Exec(ctx context.Context, proc *types.Step) error { +func (e *ssh) Exec(ctx context.Context, step *types.Step) error { // Get environment variables Command := []string{} - for a, b := range proc.Environment { + for a, b := range step.Environment { if a != "HOME" && a != "SHELL" { // Don't override $HOME and $SHELL Command = append(Command, a+"="+b) } } - if proc.Image == constant.DefaultCloneImage { + if step.Image == constant.DefaultCloneImage { // Default clone step - Command = append(Command, "CI_WORKSPACE="+e.workingdir+"/"+proc.Environment["CI_REPO"]) + Command = append(Command, "CI_WORKSPACE="+e.workingdir+"/"+step.Environment["CI_REPO"]) Command = append(Command, "plugin-git") } else { // Use "image name" as run command - Command = append(Command, proc.Image) + Command = append(Command, step.Image) Command = append(Command, "-c") // Decode script and delete initial lines // Deleting the initial lines removes netrc support but adds compatibility for more shells like fish - Script, _ := base64.RawStdEncoding.DecodeString(proc.Environment["CI_SCRIPT"]) - Command = append(Command, "cd "+e.workingdir+"/"+proc.Environment["CI_REPO"]+" && "+string(Script)[strings.Index(string(Script), "\n\n")+2:]) + Script, _ := base64.RawStdEncoding.DecodeString(step.Environment["CI_SCRIPT"]) + Command = append(Command, "cd "+e.workingdir+"/"+step.Environment["CI_REPO"]+" && "+string(Script)[strings.Index(string(Script), "\n\n")+2:]) } // Prepare command diff --git a/pipeline/frontend/drone_compatibility.go b/pipeline/frontend/drone_compatibility.go index 1a9520bae..cd5956868 100644 --- a/pipeline/frontend/drone_compatibility.go +++ b/pipeline/frontend/drone_compatibility.go @@ -55,5 +55,5 @@ func (m *Metadata) setDroneEnviron(env map[string]string) { env["DRONE_GIT_HTTP_URL"] = env["CI_REPO_REMOTE"] // misc env["DRONE_SYSTEM_HOST"] = env["CI_SYSTEM_HOST"] - env["DRONE_STEP_NUMBER"] = env["CI_JOB_NUMBER"] + env["DRONE_STEP_NUMBER"] = env["CI_STEP_NUMBER"] } diff --git a/pipeline/frontend/metadata.go b/pipeline/frontend/metadata.go index 82c403e34..60d4889a0 100644 --- a/pipeline/frontend/metadata.go +++ b/pipeline/frontend/metadata.go @@ -39,7 +39,7 @@ type ( Repo Repo `json:"repo,omitempty"` Curr Pipeline `json:"curr,omitempty"` Prev Pipeline `json:"prev,omitempty"` - Job Job `json:"job,omitempty"` + Step Step `json:"step,omitempty"` Sys System `json:"sys,omitempty"` } @@ -88,8 +88,8 @@ type ( Avatar string `json:"avatar,omitempty"` } - // Job defines runtime metadata for a job. - Job struct { + // Step defines runtime metadata for a step. + Step struct { Number int `json:"number,omitempty"` Matrix map[string]string `json:"matrix,omitempty"` } @@ -171,10 +171,10 @@ func (m *Metadata) Environ() map[string]string { "CI_PIPELINE_STARTED": strconv.FormatInt(m.Curr.Started, 10), "CI_PIPELINE_FINISHED": strconv.FormatInt(m.Curr.Finished, 10), - "CI_JOB_NUMBER": strconv.Itoa(m.Job.Number), - "CI_JOB_STATUS": "", // will be set by agent - "CI_JOB_STARTED": "", // will be set by agent - "CI_JOB_FINISHED": "", // will be set by agent + "CI_STEP_NUMBER": strconv.Itoa(m.Step.Number), + "CI_STEP_STATUS": "", // will be set by agent + "CI_STEP_STARTED": "", // will be set by agent + "CI_STEP_FINISHED": "", // will be set by agent "CI_PREV_COMMIT_SHA": m.Prev.Commit.Sha, "CI_PREV_COMMIT_REF": m.Prev.Commit.Ref, @@ -224,6 +224,11 @@ func (m *Metadata) Environ() map[string]string { "CI_PREV_BUILD_CREATED": strconv.FormatInt(m.Prev.Created, 10), "CI_PREV_BUILD_STARTED": strconv.FormatInt(m.Prev.Started, 10), "CI_PREV_BUILD_FINISHED": strconv.FormatInt(m.Prev.Finished, 10), + // use CI_STEP_* + "CI_JOB_NUMBER": strconv.Itoa(m.Step.Number), + "CI_JOB_STATUS": "", // will be set by agent + "CI_JOB_STARTED": "", // will be set by agent + "CI_JOB_FINISHED": "", // will be set by agent } if m.Curr.Event == EventTag { params["CI_COMMIT_TAG"] = strings.TrimPrefix(m.Curr.Commit.Ref, "refs/tags/") diff --git a/pipeline/frontend/yaml/constraint/constraint.go b/pipeline/frontend/yaml/constraint/constraint.go index 462677b0b..2557e0e13 100644 --- a/pipeline/frontend/yaml/constraint/constraint.go +++ b/pipeline/frontend/yaml/constraint/constraint.go @@ -138,7 +138,7 @@ func (c *Constraint) Match(metadata frontend.Metadata, global bool) (bool, error c.SetDefaultEventFilter() // apply step only filters - match = c.Matrix.Match(metadata.Job.Matrix) + match = c.Matrix.Match(metadata.Step.Matrix) } match = match && c.Platform.Match(metadata.Sys.Platform) && diff --git a/pipeline/frontend/yaml/types/ulimit_test.go b/pipeline/frontend/yaml/types/ulimit_test.go index 06903e773..f9396fb8b 100644 --- a/pipeline/frontend/yaml/types/ulimit_test.go +++ b/pipeline/frontend/yaml/types/ulimit_test.go @@ -21,11 +21,11 @@ func TestMarshalUlimit(t *testing.T) { Soft: 65535, Hard: 65535, }, - Name: "nproc", + Name: "nstep", }, }, }, - expected: `nproc: 65535 + expected: `nstep: 65535 `, }, { @@ -61,11 +61,11 @@ func TestUnmarshalUlimits(t *testing.T) { expected *Ulimits }{ { - yaml: "nproc: 65535", + yaml: "nstep: 65535", expected: &Ulimits{ Elements: []Ulimit{ { - Name: "nproc", + Name: "nstep", ulimitValues: ulimitValues{ Soft: 65535, Hard: 65535, @@ -91,7 +91,7 @@ func TestUnmarshalUlimits(t *testing.T) { }, }, { - yaml: `nproc: 65535 + yaml: `nstep: 65535 nofile: soft: 20000 hard: 40000`, @@ -105,7 +105,7 @@ nofile: }, }, { - Name: "nproc", + Name: "nstep", ulimitValues: ulimitValues{ Soft: 65535, Hard: 65535, diff --git a/pipeline/logger.go b/pipeline/logger.go index 6ac0e6213..281522e2c 100644 --- a/pipeline/logger.go +++ b/pipeline/logger.go @@ -14,7 +14,7 @@ type Logger interface { // function for process logging. type LogFunc func(*backend.Step, multipart.Reader) error -// Log calls f(proc, r). +// Log calls f(step, r). func (f LogFunc) Log(step *backend.Step, r multipart.Reader) error { return f(step, r) } diff --git a/pipeline/rpc/client_grpc.go b/pipeline/rpc/client_grpc.go index 71bdf072f..39f4db600 100644 --- a/pipeline/rpc/client_grpc.go +++ b/pipeline/rpc/client_grpc.go @@ -122,7 +122,7 @@ func (c *client) Init(ctx context.Context, id string, state State) (err error) { req.State.Exited = state.Exited req.State.Finished = state.Finished req.State.Started = state.Started - req.State.Name = state.Proc + req.State.Name = state.Step for { _, err = c.client.Init(ctx, req) if err == nil { @@ -156,7 +156,7 @@ func (c *client) Done(ctx context.Context, id string, state State) (err error) { req.State.Exited = state.Exited req.State.Finished = state.Finished req.State.Started = state.Started - req.State.Name = state.Proc + req.State.Name = state.Step for { _, err = c.client.Done(ctx, req) if err == nil { @@ -217,7 +217,7 @@ func (c *client) Update(ctx context.Context, id string, state State) (err error) req.State.Exited = state.Exited req.State.Finished = state.Finished req.State.Started = state.Started - req.State.Name = state.Proc + req.State.Name = state.Step for { _, err = c.client.Update(ctx, req) if err == nil { @@ -248,7 +248,7 @@ func (c *client) Upload(ctx context.Context, id string, file *File) (err error) req.File = new(proto.File) req.File.Name = file.Name req.File.Mime = file.Mime - req.File.Proc = file.Proc + req.File.Step = file.Step req.File.Size = int32(file.Size) req.File.Time = file.Time req.File.Data = file.Data @@ -283,7 +283,7 @@ func (c *client) Log(ctx context.Context, id string, line *Line) (err error) { req.Line = new(proto.Line) req.Line.Out = line.Out req.Line.Pos = int32(line.Pos) - req.Line.Proc = line.Proc + req.Line.Step = line.Step req.Line.Time = line.Time for { _, err = c.client.Log(ctx, req) diff --git a/pipeline/rpc/line.go b/pipeline/rpc/line.go index a7cd0f342..2147f1148 100644 --- a/pipeline/rpc/line.go +++ b/pipeline/rpc/line.go @@ -22,7 +22,7 @@ const ( // Line is a line of console output. type Line struct { - Proc string `json:"proc,omitempty"` + Step string `json:"step,omitempty"` Time int64 `json:"time,omitempty"` Type int `json:"type,omitempty"` Pos int `json:"pos,omitempty"` @@ -32,9 +32,9 @@ type Line struct { func (l *Line) String() string { switch l.Type { case LineExitCode: - return fmt.Sprintf("[%s] exit code %s", l.Proc, l.Out) + return fmt.Sprintf("[%s] exit code %s", l.Step, l.Out) default: - return fmt.Sprintf("[%s:L%v:%vs] %s", l.Proc, l.Pos, l.Time, l.Out) + return fmt.Sprintf("[%s:L%v:%vs] %s", l.Step, l.Pos, l.Time, l.Out) } } @@ -70,7 +70,7 @@ func (w *LineWriter) Write(p []byte) (n int, err error) { line := &Line{ Out: out, - Proc: w.name, + Step: w.name, Pos: w.num, Time: int64(time.Since(w.now).Seconds()), Type: LineStdout, @@ -83,7 +83,7 @@ func (w *LineWriter) Write(p []byte) (n int, err error) { // for _, part := range bytes.Split(p, []byte{'\n'}) { // line := &Line{ // Out: string(part), - // Proc: w.name, + // Step: w.name, // Pos: w.num, // Time: int64(time.Since(w.now).Seconds()), // Type: LineStdout, diff --git a/pipeline/rpc/line_test.go b/pipeline/rpc/line_test.go index 45e04ef29..15e70db9e 100644 --- a/pipeline/rpc/line_test.go +++ b/pipeline/rpc/line_test.go @@ -6,7 +6,7 @@ import ( func TestLine(t *testing.T) { line := Line{ - Proc: "redis", + Step: "redis", Time: 60, Pos: 1, Out: "starting redis server", diff --git a/pipeline/rpc/peer.go b/pipeline/rpc/peer.go index 177a76205..8ee6d4ef5 100644 --- a/pipeline/rpc/peer.go +++ b/pipeline/rpc/peer.go @@ -14,7 +14,7 @@ type ( // State defines the pipeline state. State struct { - Proc string `json:"proc"` + Step string `json:"step"` Exited bool `json:"exited"` ExitCode int `json:"exit_code"` Started int64 `json:"started"` @@ -32,7 +32,7 @@ type ( // File defines a pipeline artifact. File struct { Name string `json:"name"` - Proc string `json:"proc"` + Step string `json:"step"` Mime string `json:"mime"` Time int64 `json:"time"` Size int `json:"size"` diff --git a/pipeline/rpc/proto/woodpecker.pb.go b/pipeline/rpc/proto/woodpecker.pb.go index 177b8615d..b2a53295a 100644 --- a/pipeline/rpc/proto/woodpecker.pb.go +++ b/pipeline/rpc/proto/woodpecker.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 -// protoc v3.12.4 +// protoc v3.21.7 // source: woodpecker.proto package proto @@ -75,7 +75,7 @@ type File struct { unknownFields protoimpl.UnknownFields Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Proc string `protobuf:"bytes,2,opt,name=proc,proto3" json:"proc,omitempty"` + Step string `protobuf:"bytes,2,opt,name=step,proto3" json:"step,omitempty"` Mime string `protobuf:"bytes,3,opt,name=mime,proto3" json:"mime,omitempty"` Time int64 `protobuf:"varint,4,opt,name=time,proto3" json:"time,omitempty"` Size int32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` @@ -122,9 +122,9 @@ func (x *File) GetName() string { return "" } -func (x *File) GetProc() string { +func (x *File) GetStep() string { if x != nil { - return x.Proc + return x.Step } return "" } @@ -256,7 +256,7 @@ type Line struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Proc string `protobuf:"bytes,1,opt,name=proc,proto3" json:"proc,omitempty"` + Step string `protobuf:"bytes,1,opt,name=step,proto3" json:"step,omitempty"` Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"` Pos int32 `protobuf:"varint,3,opt,name=pos,proto3" json:"pos,omitempty"` Out string `protobuf:"bytes,4,opt,name=out,proto3" json:"out,omitempty"` @@ -294,9 +294,9 @@ func (*Line) Descriptor() ([]byte, []int) { return file_woodpecker_proto_rawDescGZIP(), []int{2} } -func (x *Line) GetProc() string { +func (x *Line) GetStep() string { if x != nil { - return x.Proc + return x.Step } return "" } @@ -1033,8 +1033,8 @@ var file_woodpecker_proto_rawDesc = []byte{ 0x0a, 0x10, 0x77, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe2, 0x01, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x72, 0x6f, 0x63, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x72, 0x6f, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x69, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, @@ -1056,8 +1056,8 @@ var file_woodpecker_proto_rawDesc = []byte{ 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x52, 0x0a, - 0x04, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x72, 0x6f, 0x63, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x72, 0x6f, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, + 0x04, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x75, diff --git a/pipeline/rpc/proto/woodpecker.proto b/pipeline/rpc/proto/woodpecker.proto index 305f8b942..39852c5f4 100644 --- a/pipeline/rpc/proto/woodpecker.proto +++ b/pipeline/rpc/proto/woodpecker.proto @@ -5,7 +5,7 @@ package proto; message File { string name = 1; - string proc = 2; + string step = 2; string mime = 3; int64 time = 4; int32 size = 5; @@ -23,7 +23,7 @@ message State { } message Line { - string proc = 1; + string step = 1; int64 time = 2; int32 pos = 3; string out = 4; diff --git a/pipeline/rpc/proto/woodpecker_grpc.pb.go b/pipeline/rpc/proto/woodpecker_grpc.pb.go index d17bac8d3..c888d003b 100644 --- a/pipeline/rpc/proto/woodpecker_grpc.pb.go +++ b/pipeline/rpc/proto/woodpecker_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 -// - protoc v3.12.4 +// - protoc v3.21.7 // source: woodpecker.proto package proto diff --git a/pipeline/tracer.go b/pipeline/tracer.go index 570b5864c..38c338b80 100644 --- a/pipeline/tracer.go +++ b/pipeline/tracer.go @@ -14,7 +14,7 @@ type Tracer interface { // functions as a Tracer. type TraceFunc func(*State) error -// Trace calls f(proc, state). +// Trace calls f(state). func (f TraceFunc) Trace(state *State) error { return f(state) } @@ -32,20 +32,24 @@ var DefaultTracer = TraceFunc(func(state *State) error { state.Pipeline.Step.Environment["CI_PIPELINE_STATUS"] = "success" state.Pipeline.Step.Environment["CI_PIPELINE_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) state.Pipeline.Step.Environment["CI_PIPELINE_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) + + state.Pipeline.Step.Environment["CI_STEP_STATUS"] = "success" + state.Pipeline.Step.Environment["CI_STEP_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) + state.Pipeline.Step.Environment["CI_STEP_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) + // DEPRECATED state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "success" state.Pipeline.Step.Environment["CI_BUILD_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) state.Pipeline.Step.Environment["CI_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) - state.Pipeline.Step.Environment["CI_JOB_STATUS"] = "success" state.Pipeline.Step.Environment["CI_JOB_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) state.Pipeline.Step.Environment["CI_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) if state.Pipeline.Error != nil { state.Pipeline.Step.Environment["CI_PIPELINE_STATUS"] = "failure" + state.Pipeline.Step.Environment["CI_STEP_STATUS"] = "failure" // DEPRECATED state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "failure" - state.Pipeline.Step.Environment["CI_JOB_STATUS"] = "failure" } return nil diff --git a/server/api/file.go b/server/api/file.go index 4b8893ba3..99ce7dcee 100644 --- a/server/api/file.go +++ b/server/api/file.go @@ -71,7 +71,7 @@ func FileGet(c *gin.Context) { return } - pid, err := strconv.Atoi(c.Param("proc")) + pid, err := strconv.Atoi(c.Param("step")) if err != nil { _ = c.AbortWithError(http.StatusBadRequest, err) return @@ -83,13 +83,13 @@ func FileGet(c *gin.Context) { return } - proc, err := _store.ProcFind(pipeline, pid) + step, err := _store.StepFind(pipeline, pid) if err != nil { _ = c.AbortWithError(http.StatusInternalServerError, err) return } - file, err := _store.FileFind(proc, name) + file, err := _store.FileFind(step, name) if err != nil { c.String(404, "Error getting file %q. %s", name, err) return @@ -100,7 +100,7 @@ func FileGet(c *gin.Context) { return } - rc, err := _store.FileRead(proc, file.Name) + rc, err := _store.FileRead(step, file.Name) if err != nil { c.String(404, "Error getting file stream %q. %s", name, err) return diff --git a/server/api/pipeline.go b/server/api/pipeline.go index c6b7600b7..c17347386 100644 --- a/server/api/pipeline.go +++ b/server/api/pipeline.go @@ -127,8 +127,8 @@ func GetPipeline(c *gin.Context) { return } files, _ := _store.FileList(pl) - procs, _ := _store.ProcList(pl) - if pl.Procs, err = model.Tree(procs); err != nil { + steps, _ := _store.StepList(pl) + if pl.Steps, err = model.Tree(steps); err != nil { _ = c.AbortWithError(http.StatusInternalServerError, err) return } @@ -148,12 +148,12 @@ func GetPipelineLast(c *gin.Context) { return } - procs, err := _store.ProcList(pl) + steps, err := _store.StepList(pl) if err != nil { _ = c.AbortWithError(http.StatusInternalServerError, err) return } - if pl.Procs, err = model.Tree(procs); err != nil { + if pl.Steps, err = model.Tree(steps); err != nil { _ = c.AbortWithError(http.StatusInternalServerError, err) return } @@ -164,11 +164,11 @@ func GetPipelineLogs(c *gin.Context) { _store := store.FromContext(c) repo := session.Repo(c) - // parse the pipeline number and job sequence number from + // parse the pipeline number and step sequence number from // the request parameter. num, _ := strconv.ParseInt(c.Params.ByName("number"), 10, 64) ppid, _ := strconv.Atoi(c.Params.ByName("pid")) - name := c.Params.ByName("proc") + name := c.Params.ByName("step") pl, err := _store.GetPipelineNumber(repo, num) if err != nil { @@ -176,13 +176,13 @@ func GetPipelineLogs(c *gin.Context) { return } - proc, err := _store.ProcChild(pl, ppid, name) + step, err := _store.StepChild(pl, ppid, name) if err != nil { _ = c.AbortWithError(404, err) return } - rc, err := _store.LogFind(proc) + rc, err := _store.LogFind(step) if err != nil { _ = c.AbortWithError(404, err) return @@ -196,11 +196,11 @@ func GetPipelineLogs(c *gin.Context) { } } -func GetProcLogs(c *gin.Context) { +func GetStepLogs(c *gin.Context) { _store := store.FromContext(c) repo := session.Repo(c) - // parse the pipeline number and job sequence number from + // parse the pipeline number and step sequence number from // the request parameter. num, _ := strconv.ParseInt(c.Params.ByName("number"), 10, 64) pid, _ := strconv.Atoi(c.Params.ByName("pid")) @@ -211,13 +211,13 @@ func GetProcLogs(c *gin.Context) { return } - proc, err := _store.ProcFind(pl, pid) + step, err := _store.StepFind(pl, pid) if err != nil { _ = c.AbortWithError(http.StatusNotFound, err) return } - rc, err := _store.LogFind(proc) + rc, err := _store.LogFind(step) if err != nil { _ = c.AbortWithError(http.StatusNotFound, err) return @@ -407,7 +407,7 @@ func DeletePipelineLogs(c *gin.Context) { return } - procs, err := _store.ProcList(pl) + steps, err := _store.StepList(pl) if err != nil { _ = c.AbortWithError(404, err) return @@ -419,10 +419,10 @@ func DeletePipelineLogs(c *gin.Context) { return } - for _, proc := range procs { + for _, step := range steps { t := time.Now().UTC() - buf := bytes.NewBufferString(fmt.Sprintf(deleteStr, proc.Name, user.Login, t.Format(time.UnixDate))) - lerr := _store.LogSave(proc, buf) + buf := bytes.NewBufferString(fmt.Sprintf(deleteStr, step.Name, user.Login, t.Format(time.UnixDate))) + lerr := _store.LogSave(step, buf) if lerr != nil { err = lerr } @@ -437,7 +437,7 @@ func DeletePipelineLogs(c *gin.Context) { var deleteStr = `[ { - "proc": %q, + "step": %q, "pos": 0, "out": "logs purged by %s on %s\n" } diff --git a/server/api/stream.go b/server/api/stream.go index ed148aa4b..68815ae86 100644 --- a/server/api/stream.go +++ b/server/api/stream.go @@ -141,10 +141,10 @@ func LogStreamSSE(c *gin.Context) { repo := session.Repo(c) _store := store.FromContext(c) - // // parse the pipeline number and job sequence number from + // // parse the pipeline number and step sequence number from // // the repquest parameter. pipelinen, _ := strconv.ParseInt(c.Param("pipeline"), 10, 64) - jobn, _ := strconv.Atoi(c.Param("number")) + stepn, _ := strconv.Atoi(c.Param("number")) pipeline, err := _store.GetPipelineNumber(repo, pipelinen) if err != nil { @@ -152,13 +152,13 @@ func LogStreamSSE(c *gin.Context) { logWriteStringErr(io.WriteString(rw, "event: error\ndata: pipeline not found\n\n")) return } - proc, err := _store.ProcFind(pipeline, jobn) + step, err := _store.StepFind(pipeline, stepn) if err != nil { - log.Debug().Msgf("stream cannot get proc number: %v", err) + log.Debug().Msgf("stream cannot get step number: %v", err) logWriteStringErr(io.WriteString(rw, "event: error\ndata: process not found\n\n")) return } - if proc.State != model.StatusRunning { + if step.State != model.StatusRunning { log.Debug().Msg("stream not found.") logWriteStringErr(io.WriteString(rw, "event: error\ndata: stream not found\n\n")) return @@ -179,7 +179,7 @@ func LogStreamSSE(c *gin.Context) { go func() { // TODO remove global variable - err := server.Config.Services.Logs.Tail(ctx, fmt.Sprint(proc.ID), func(entries ...*logging.Entry) { + err := server.Config.Services.Logs.Tail(ctx, fmt.Sprint(step.ID), func(entries ...*logging.Entry) { defer func() { obj := recover() // fix #2480 // TODO: check if it's still needed log.Trace().Msgf("pubsub subscribe recover return: %v", obj) diff --git a/server/config.go b/server/config.go index 5ab6fe3f2..bdcad5773 100644 --- a/server/config.go +++ b/server/config.go @@ -50,7 +50,7 @@ var Config = struct { // Builds model.BuildStore // Logs model.LogStore Files model.FileStore - Procs model.ProcStore + Steps model.StepStore // Registries model.RegistryStore // Secrets model.SecretStore } diff --git a/server/grpc/rpc.go b/server/grpc/rpc.go index 12b43ffd5..19c4ce13c 100644 --- a/server/grpc/rpc.go +++ b/server/grpc/rpc.go @@ -97,26 +97,26 @@ func (s *RPC) Extend(c context.Context, id string) error { // Update implements the rpc.Update function func (s *RPC) Update(c context.Context, id string, state rpc.State) error { - procID, err := strconv.ParseInt(id, 10, 64) + stepID, err := strconv.ParseInt(id, 10, 64) if err != nil { return err } - pproc, err := s.store.ProcLoad(procID) + pstep, err := s.store.StepLoad(stepID) if err != nil { - log.Error().Msgf("error: rpc.update: cannot find pproc with id %d: %s", procID, err) + log.Error().Msgf("error: rpc.update: cannot find step with id %d: %s", stepID, err) return err } - pipeline, err := s.store.GetPipeline(pproc.PipelineID) + pipeline, err := s.store.GetPipeline(pstep.PipelineID) if err != nil { - log.Error().Msgf("error: cannot find pipeline with id %d: %s", pproc.PipelineID, err) + log.Error().Msgf("error: cannot find pipeline with id %d: %s", pstep.PipelineID, err) return err } - proc, err := s.store.ProcChild(pipeline, pproc.PID, state.Proc) + step, err := s.store.StepChild(pipeline, pstep.PID, state.Step) if err != nil { - log.Error().Msgf("error: cannot find proc with name %s: %s", state.Proc, err) + log.Error().Msgf("error: cannot find step with name %s: %s", state.Step, err) return err } @@ -124,7 +124,7 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error { if ok { hostname, ok := metadata["hostname"] if ok && len(hostname) != 0 { - proc.Machine = hostname[0] + step.Machine = hostname[0] } } @@ -134,15 +134,15 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error { return err } - if _, err = shared.UpdateProcStatus(s.store, *proc, state, pipeline.Started); err != nil { - log.Error().Err(err).Msg("rpc.update: cannot update proc") + if _, err = shared.UpdateStepStatus(s.store, *step, state, pipeline.Started); err != nil { + log.Error().Err(err).Msg("rpc.update: cannot update step") } - if pipeline.Procs, err = s.store.ProcList(pipeline); err != nil { - log.Error().Err(err).Msg("can not get proc list from store") + if pipeline.Steps, err = s.store.StepList(pipeline); err != nil { + log.Error().Err(err).Msg("can not get step list from store") } - if pipeline.Procs, err = model.Tree(pipeline.Procs); err != nil { - log.Error().Err(err).Msg("can not build tree from proc list") + if pipeline.Steps, err = model.Tree(pipeline.Steps); err != nil { + log.Error().Err(err).Msg("can not build tree from step list") return err } message := pubsub.Message{ @@ -156,7 +156,7 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error { Pipeline: *pipeline, }) if err := s.pubsub.Publish(c, "topic/events", message); err != nil { - log.Error().Err(err).Msg("can not publish proc list to") + log.Error().Err(err).Msg("can not publish step list to") } return nil @@ -164,40 +164,40 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error { // Upload implements the rpc.Upload function func (s *RPC) Upload(c context.Context, id string, file *rpc.File) error { - procID, err := strconv.ParseInt(id, 10, 64) + stepID, err := strconv.ParseInt(id, 10, 64) if err != nil { return err } - pproc, err := s.store.ProcLoad(procID) + pstep, err := s.store.StepLoad(stepID) if err != nil { - log.Error().Msgf("error: cannot find parent proc with id %d: %s", procID, err) + log.Error().Msgf("error: cannot find parent step with id %d: %s", stepID, err) return err } - pipeline, err := s.store.GetPipeline(pproc.PipelineID) + pipeline, err := s.store.GetPipeline(pstep.PipelineID) if err != nil { - log.Error().Msgf("error: cannot find pipeline with id %d: %s", pproc.PipelineID, err) + log.Error().Msgf("error: cannot find pipeline with id %d: %s", pstep.PipelineID, err) return err } - proc, err := s.store.ProcChild(pipeline, pproc.PID, file.Proc) + step, err := s.store.StepChild(pipeline, pstep.PID, file.Step) if err != nil { - log.Error().Msgf("error: cannot find child proc with name %s: %s", file.Proc, err) + log.Error().Msgf("error: cannot find child step with name %s: %s", file.Step, err) return err } if file.Mime == "application/json+logs" { return s.store.LogSave( - proc, + step, bytes.NewBuffer(file.Data), ) } report := &model.File{ - PipelineID: proc.PipelineID, - ProcID: proc.ID, - PID: proc.PID, + PipelineID: step.PipelineID, + StepID: step.ID, + PID: step.PID, Mime: file.Mime, Name: file.Name, Size: file.Size, @@ -237,27 +237,27 @@ func (s *RPC) Upload(c context.Context, id string, file *rpc.File) error { // Init implements the rpc.Init function func (s *RPC) Init(c context.Context, id string, state rpc.State) error { - procID, err := strconv.ParseInt(id, 10, 64) + stepID, err := strconv.ParseInt(id, 10, 64) if err != nil { return err } - proc, err := s.store.ProcLoad(procID) + step, err := s.store.StepLoad(stepID) if err != nil { - log.Error().Msgf("error: cannot find proc with id %d: %s", procID, err) + log.Error().Msgf("error: cannot find step with id %d: %s", stepID, err) return err } metadata, ok := grpcMetadata.FromIncomingContext(c) if ok { hostname, ok := metadata["hostname"] if ok && len(hostname) != 0 { - proc.Machine = hostname[0] + step.Machine = hostname[0] } } - pipeline, err := s.store.GetPipeline(proc.PipelineID) + pipeline, err := s.store.GetPipeline(step.PipelineID) if err != nil { - log.Error().Msgf("error: cannot find pipeline with id %d: %s", proc.PipelineID, err) + log.Error().Msgf("error: cannot find pipeline with id %d: %s", step.PipelineID, err) return err } @@ -274,7 +274,7 @@ func (s *RPC) Init(c context.Context, id string, state rpc.State) error { } defer func() { - pipeline.Procs, _ = s.store.ProcList(pipeline) + pipeline.Steps, _ = s.store.StepList(pipeline) message := pubsub.Message{ Labels: map[string]string{ "repo": repo.FullName, @@ -286,30 +286,30 @@ func (s *RPC) Init(c context.Context, id string, state rpc.State) error { Pipeline: *pipeline, }) if err := s.pubsub.Publish(c, "topic/events", message); err != nil { - log.Error().Err(err).Msg("can not publish proc list to") + log.Error().Err(err).Msg("can not publish step list to") } }() - _, err = shared.UpdateProcToStatusStarted(s.store, *proc, state) + _, err = shared.UpdateStepToStatusStarted(s.store, *step, state) return err } // Done implements the rpc.Done function func (s *RPC) Done(c context.Context, id string, state rpc.State) error { - procID, err := strconv.ParseInt(id, 10, 64) + stepID, err := strconv.ParseInt(id, 10, 64) if err != nil { return err } - proc, err := s.store.ProcLoad(procID) + step, err := s.store.StepLoad(stepID) if err != nil { - log.Error().Msgf("error: cannot find proc with id %d: %s", procID, err) + log.Error().Msgf("error: cannot find step with id %d: %s", stepID, err) return err } - pipeline, err := s.store.GetPipeline(proc.PipelineID) + pipeline, err := s.store.GetPipeline(step.PipelineID) if err != nil { - log.Error().Msgf("error: cannot find pipeline with id %d: %s", proc.PipelineID, err) + log.Error().Msgf("error: cannot find pipeline with id %d: %s", step.PipelineID, err) return err } @@ -322,42 +322,42 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error { log.Trace(). Str("repo_id", fmt.Sprint(repo.ID)). Str("build_id", fmt.Sprint(pipeline.ID)). - Str("proc_id", id). + Str("step_id", id). Msgf("gRPC Done with state: %#v", state) - if proc, err = shared.UpdateProcStatusToDone(s.store, *proc, state); err != nil { - log.Error().Msgf("error: done: cannot update proc_id %d state: %s", proc.ID, err) + if step, err = shared.UpdateStepStatusToDone(s.store, *step, state); err != nil { + log.Error().Msgf("error: done: cannot update step_id %d state: %s", step.ID, err) } var queueErr error - if proc.Failing() { - queueErr = s.queue.Error(c, id, fmt.Errorf("Proc finished with exitcode %d, %s", state.ExitCode, state.Error)) + if step.Failing() { + queueErr = s.queue.Error(c, id, fmt.Errorf("Step finished with exitcode %d, %s", state.ExitCode, state.Error)) } else { - queueErr = s.queue.Done(c, id, proc.State) + queueErr = s.queue.Done(c, id, step.State) } if queueErr != nil { - log.Error().Msgf("error: done: cannot ack proc_id %d: %s", procID, err) + log.Error().Msgf("error: done: cannot ack step_id %d: %s", stepID, err) } - procs, err := s.store.ProcList(pipeline) + steps, err := s.store.StepList(pipeline) if err != nil { return err } - s.completeChildrenIfParentCompleted(procs, proc) + s.completeChildrenIfParentCompleted(steps, step) - if !model.IsThereRunningStage(procs) { - if pipeline, err = shared.UpdateStatusToDone(s.store, *pipeline, model.PipelineStatus(procs), proc.Stopped); err != nil { + if !model.IsThereRunningStage(steps) { + if pipeline, err = shared.UpdateStatusToDone(s.store, *pipeline, model.PipelineStatus(steps), step.Stopped); err != nil { log.Error().Err(err).Msgf("error: done: cannot update build_id %d final state", pipeline.ID) } } - s.updateRemoteStatus(c, repo, pipeline, proc) + s.updateRemoteStatus(c, repo, pipeline, step) if err := s.logger.Close(c, id); err != nil { - log.Error().Err(err).Msgf("done: cannot close build_id %d logger", proc.ID) + log.Error().Err(err).Msgf("done: cannot close build_id %d logger", step.ID) } - if err := s.notify(c, repo, pipeline, procs); err != nil { + if err := s.notify(c, repo, pipeline, steps); err != nil { return err } @@ -365,8 +365,8 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error { s.pipelineCount.WithLabelValues(repo.FullName, pipeline.Branch, string(pipeline.Status), "total").Inc() s.pipelineTime.WithLabelValues(repo.FullName, pipeline.Branch, string(pipeline.Status), "total").Set(float64(pipeline.Finished - pipeline.Started)) } - if model.IsMultiPipeline(procs) { - s.pipelineTime.WithLabelValues(repo.FullName, pipeline.Branch, string(proc.State), proc.Name).Set(float64(proc.Stopped - proc.Started)) + if model.IsMultiPipeline(steps) { + s.pipelineTime.WithLabelValues(repo.FullName, pipeline.Branch, string(step.State), step.Name).Set(float64(step.Stopped - step.Started)) } return nil @@ -382,17 +382,17 @@ func (s *RPC) Log(c context.Context, id string, line *rpc.Line) error { return nil } -func (s *RPC) completeChildrenIfParentCompleted(procs []*model.Proc, completedProc *model.Proc) { - for _, p := range procs { - if p.Running() && p.PPID == completedProc.PID { - if _, err := shared.UpdateProcToStatusSkipped(s.store, *p, completedProc.Stopped); err != nil { - log.Error().Msgf("error: done: cannot update proc_id %d child state: %s", p.ID, err) +func (s *RPC) completeChildrenIfParentCompleted(steps []*model.Step, completedStep *model.Step) { + for _, p := range steps { + if p.Running() && p.PPID == completedStep.PID { + if _, err := shared.UpdateStepToStatusSkipped(s.store, *p, completedStep.Stopped); err != nil { + log.Error().Msgf("error: done: cannot update step_id %d child state: %s", p.ID, err) } } } } -func (s *RPC) updateRemoteStatus(ctx context.Context, repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) { +func (s *RPC) updateRemoteStatus(ctx context.Context, repo *model.Repo, pipeline *model.Pipeline, step *model.Step) { user, err := s.store.GetUser(repo.UserID) if err != nil { log.Error().Err(err).Msgf("can not get user with id '%d'", repo.UserID) @@ -410,17 +410,17 @@ func (s *RPC) updateRemoteStatus(ctx context.Context, repo *model.Repo, pipeline } } - // only do status updates for parent procs - if proc != nil && proc.IsParent() { - err = s.remote.Status(ctx, user, repo, pipeline, proc) + // only do status updates for parent steps + if step != nil && step.IsParent() { + err = s.remote.Status(ctx, user, repo, pipeline, step) if err != nil { log.Error().Err(err).Msgf("error setting commit status for %s/%d", repo.FullName, pipeline.Number) } } } -func (s *RPC) notify(c context.Context, repo *model.Repo, pipeline *model.Pipeline, procs []*model.Proc) (err error) { - if pipeline.Procs, err = model.Tree(procs); err != nil { +func (s *RPC) notify(c context.Context, repo *model.Repo, pipeline *model.Pipeline, steps []*model.Step) (err error) { + if pipeline.Steps, err = model.Tree(steps); err != nil { return err } message := pubsub.Message{ diff --git a/server/grpc/server.go b/server/grpc/server.go index 38e4a96c4..16e74b867 100644 --- a/server/grpc/server.go +++ b/server/grpc/server.go @@ -88,7 +88,7 @@ func (s *WoodpeckerServer) Init(c context.Context, req *proto.InitRequest) (*pro ExitCode: int(req.GetState().GetExitCode()), Finished: req.GetState().GetFinished(), Started: req.GetState().GetStarted(), - Proc: req.GetState().GetName(), + Step: req.GetState().GetName(), Exited: req.GetState().GetExited(), } res := new(proto.Empty) @@ -102,7 +102,7 @@ func (s *WoodpeckerServer) Update(c context.Context, req *proto.UpdateRequest) ( ExitCode: int(req.GetState().GetExitCode()), Finished: req.GetState().GetFinished(), Started: req.GetState().GetStarted(), - Proc: req.GetState().GetName(), + Step: req.GetState().GetName(), Exited: req.GetState().GetExited(), } res := new(proto.Empty) @@ -115,7 +115,7 @@ func (s *WoodpeckerServer) Upload(c context.Context, req *proto.UploadRequest) ( Data: req.GetFile().GetData(), Mime: req.GetFile().GetMime(), Name: req.GetFile().GetName(), - Proc: req.GetFile().GetProc(), + Step: req.GetFile().GetStep(), Size: int(req.GetFile().GetSize()), Time: req.GetFile().GetTime(), Meta: req.GetFile().GetMeta(), @@ -132,7 +132,7 @@ func (s *WoodpeckerServer) Done(c context.Context, req *proto.DoneRequest) (*pro ExitCode: int(req.GetState().GetExitCode()), Finished: req.GetState().GetFinished(), Started: req.GetState().GetStarted(), - Proc: req.GetState().GetName(), + Step: req.GetState().GetName(), Exited: req.GetState().GetExited(), } res := new(proto.Empty) @@ -157,7 +157,7 @@ func (s *WoodpeckerServer) Log(c context.Context, req *proto.LogRequest) (*proto Out: req.GetLine().GetOut(), Pos: int(req.GetLine().GetPos()), Time: req.GetLine().GetTime(), - Proc: req.GetLine().GetProc(), + Step: req.GetLine().GetStep(), } res := new(proto.Empty) err := s.peer.Log(c, req.GetId(), line) diff --git a/server/model/file.go b/server/model/file.go index 95757bd44..5004f3676 100644 --- a/server/model/file.go +++ b/server/model/file.go @@ -20,8 +20,8 @@ import "io" // FileStore persists pipeline artifacts to storage. type FileStore interface { FileList(*Pipeline) ([]*File, error) - FileFind(*Proc, string) (*File, error) - FileRead(*Proc, string) (io.ReadCloser, error) + FileFind(*Step, string) (*File, error) + FileRead(*Step, string) (io.ReadCloser, error) FileCreate(*File, io.Reader) error } @@ -29,7 +29,7 @@ type FileStore interface { type File struct { ID int64 `json:"id" xorm:"pk autoincr 'file_id'"` PipelineID int64 `json:"-" xorm:"INDEX 'file_pipeline_id'"` - ProcID int64 `json:"proc_id" xorm:"UNIQUE(s) INDEX 'file_proc_id'"` + StepID int64 `json:"step_id" xorm:"UNIQUE(s) INDEX 'file_step_id'"` PID int `json:"pid" xorm:"file_pid"` Name string `json:"name" xorm:"UNIQUE(s) file_name"` Size int `json:"size" xorm:"file_size"` diff --git a/server/model/log.go b/server/model/log.go index b56dda3b6..836c38b60 100644 --- a/server/model/log.go +++ b/server/model/log.go @@ -16,7 +16,7 @@ package model type Logs struct { ID int64 `xorm:"pk autoincr 'log_id'"` - ProcID int64 `xorm:"UNIQUE 'log_job_id'"` + StepID int64 `xorm:"UNIQUE 'log_step_id'"` Data []byte `xorm:"LONGBLOB 'log_data'"` // TODO: add create timestamp } diff --git a/server/model/pipeline.go b/server/model/pipeline.go index 9b1fd469b..a6777cc1f 100644 --- a/server/model/pipeline.go +++ b/server/model/pipeline.go @@ -48,7 +48,7 @@ type Pipeline struct { Verified bool `json:"verified" xorm:"pipeline_verified"` // deprecate Reviewer string `json:"reviewed_by" xorm:"pipeline_reviewer"` Reviewed int64 `json:"reviewed_at" xorm:"pipeline_reviewed"` - Procs []*Proc `json:"procs,omitempty" xorm:"-"` + Steps []*Step `json:"steps,omitempty" xorm:"-"` Files []*File `json:"files,omitempty" xorm:"-"` ChangedFiles []string `json:"changed_files,omitempty" xorm:"json 'changed_files'"` AdditionalVariables map[string]string `json:"variables,omitempty" xorm:"json 'additional_variables'"` diff --git a/server/model/proc.go b/server/model/step.go similarity index 60% rename from server/model/proc.go rename to server/model/step.go index fb4e79594..96894a8bc 100644 --- a/server/model/proc.go +++ b/server/model/step.go @@ -17,66 +17,66 @@ package model import "fmt" -// ProcStore persists process information to storage. -type ProcStore interface { - ProcLoad(int64) (*Proc, error) - ProcFind(*Pipeline, int) (*Proc, error) - ProcChild(*Pipeline, int, string) (*Proc, error) - ProcList(*Pipeline) ([]*Proc, error) - ProcCreate([]*Proc) error - ProcUpdate(*Proc) error - ProcClear(*Pipeline) error +// StepStore persists process information to storage. +type StepStore interface { + StepLoad(int64) (*Step, error) + StepFind(*Pipeline, int) (*Step, error) + StepChild(*Pipeline, int, string) (*Step, error) + StepList(*Pipeline) ([]*Step, error) + StepCreate([]*Step) error + StepUpdate(*Step) error + StepClear(*Pipeline) error } -// Proc represents a process in the pipeline. -// swagger:model proc -type Proc struct { - ID int64 `json:"id" xorm:"pk autoincr 'proc_id'"` - PipelineID int64 `json:"pipeline_id" xorm:"UNIQUE(s) INDEX 'proc_pipeline_id'"` - PID int `json:"pid" xorm:"UNIQUE(s) 'proc_pid'"` - PPID int `json:"ppid" xorm:"proc_ppid"` - PGID int `json:"pgid" xorm:"proc_pgid"` - Name string `json:"name" xorm:"proc_name"` - State StatusValue `json:"state" xorm:"proc_state"` - Error string `json:"error,omitempty" xorm:"VARCHAR(500) proc_error"` - ExitCode int `json:"exit_code" xorm:"proc_exit_code"` - Started int64 `json:"start_time,omitempty" xorm:"proc_started"` - Stopped int64 `json:"end_time,omitempty" xorm:"proc_stopped"` - Machine string `json:"machine,omitempty" xorm:"proc_machine"` - Platform string `json:"platform,omitempty" xorm:"proc_platform"` - Environ map[string]string `json:"environ,omitempty" xorm:"json 'proc_environ'"` - Children []*Proc `json:"children,omitempty" xorm:"-"` +// Step represents a process in the pipeline. +// swagger:model step +type Step struct { + ID int64 `json:"id" xorm:"pk autoincr 'step_id'"` + PipelineID int64 `json:"pipeline_id" xorm:"UNIQUE(s) INDEX 'step_pipeline_id'"` + PID int `json:"pid" xorm:"UNIQUE(s) 'step_pid'"` + PPID int `json:"ppid" xorm:"step_ppid"` + PGID int `json:"pgid" xorm:"step_pgid"` + Name string `json:"name" xorm:"step_name"` + State StatusValue `json:"state" xorm:"step_state"` + Error string `json:"error,omitempty" xorm:"VARCHAR(500) step_error"` + ExitCode int `json:"exit_code" xorm:"step_exit_code"` + Started int64 `json:"start_time,omitempty" xorm:"step_started"` + Stopped int64 `json:"end_time,omitempty" xorm:"step_stopped"` + Machine string `json:"machine,omitempty" xorm:"step_machine"` + Platform string `json:"platform,omitempty" xorm:"step_platform"` + Environ map[string]string `json:"environ,omitempty" xorm:"json 'step_environ'"` + Children []*Step `json:"children,omitempty" xorm:"-"` } -type UpdateProcStore interface { - ProcUpdate(*Proc) error +type UpdateStepStore interface { + StepUpdate(*Step) error } // TableName return database table name for xorm -func (Proc) TableName() string { - return "procs" +func (Step) TableName() string { + return "steps" } // Running returns true if the process state is pending or running. -func (p *Proc) Running() bool { +func (p *Step) Running() bool { return p.State == StatusPending || p.State == StatusRunning } // Failing returns true if the process state is failed, killed or error. -func (p *Proc) Failing() bool { +func (p *Step) Failing() bool { return p.State == StatusError || p.State == StatusKilled || p.State == StatusFailure } // IsParent returns true if the process is a parent process. -func (p *Proc) IsParent() bool { +func (p *Step) IsParent() bool { return p.PPID == 0 } -// IsMultiPipeline checks if proc list contain more than one parent proc -func IsMultiPipeline(procs []*Proc) bool { +// IsMultiPipeline checks if step list contain more than one parent step +func IsMultiPipeline(steps []*Step) bool { c := 0 - for _, proc := range procs { - if proc.IsParent() { + for _, step := range steps { + if step.IsParent() { c++ } if c > 1 { @@ -87,35 +87,35 @@ func IsMultiPipeline(procs []*Proc) bool { } // Tree creates a process tree from a flat process list. -func Tree(procs []*Proc) ([]*Proc, error) { - var nodes []*Proc +func Tree(steps []*Step) ([]*Step, error) { + var nodes []*Step // init parent nodes - for i := range procs { - if procs[i].IsParent() { - nodes = append(nodes, procs[i]) + for i := range steps { + if steps[i].IsParent() { + nodes = append(nodes, steps[i]) } } // assign children to parrents - for i := range procs { - if !procs[i].IsParent() { - parent, err := findNode(nodes, procs[i].PPID) + for i := range steps { + if !steps[i].IsParent() { + parent, err := findNode(nodes, steps[i].PPID) if err != nil { return nil, err } - parent.Children = append(parent.Children, procs[i]) + parent.Children = append(parent.Children, steps[i]) } } return nodes, nil } -// PipelineStatus determine pipeline status based on corresponding proc list -func PipelineStatus(procs []*Proc) StatusValue { +// PipelineStatus determine pipeline status based on corresponding step list +func PipelineStatus(steps []*Step) StatusValue { status := StatusSuccess - for _, p := range procs { + for _, p := range steps { if p.IsParent() && p.Failing() { status = p.State } @@ -124,10 +124,10 @@ func PipelineStatus(procs []*Proc) StatusValue { return status } -// IsThereRunningStage determine if it contains procs running or pending to run +// IsThereRunningStage determine if it contains steps running or pending to run // TODO: return false based on depends_on (https://github.com/woodpecker-ci/woodpecker/pull/730#discussion_r795681697) -func IsThereRunningStage(procs []*Proc) bool { - for _, p := range procs { +func IsThereRunningStage(steps []*Step) bool { + for _, p := range steps { if p.IsParent() { if p.Running() { return true @@ -137,12 +137,12 @@ func IsThereRunningStage(procs []*Proc) bool { return false } -func findNode(nodes []*Proc, pid int) (*Proc, error) { +func findNode(nodes []*Step, pid int) (*Step, error) { for _, node := range nodes { if node.PID == pid { return node, nil } } - return nil, fmt.Errorf("Corrupt proc structure") + return nil, fmt.Errorf("Corrupt step structure") } diff --git a/server/model/proc_test.go b/server/model/step_test.go similarity index 90% rename from server/model/proc_test.go rename to server/model/step_test.go index ace58889e..d87654379 100644 --- a/server/model/proc_test.go +++ b/server/model/step_test.go @@ -21,7 +21,7 @@ import ( ) func TestTree(t *testing.T) { - procs := []*Proc{{ + steps := []*Step{{ ID: 25, PID: 2, PipelineID: 6, @@ -49,12 +49,12 @@ func TestTree(t *testing.T) { State: StatusFailure, Error: "1", }} - procs, err := Tree(procs) + steps, err := Tree(steps) assert.NoError(t, err) - assert.Len(t, procs, 1) - assert.Len(t, procs[0].Children, 2) + assert.Len(t, steps, 1) + assert.Len(t, steps[0].Children, 2) - procs = []*Proc{{ + steps = []*Step{{ ID: 25, PID: 2, PipelineID: 6, @@ -64,6 +64,6 @@ func TestTree(t *testing.T) { State: StatusSuccess, Error: "0", }} - _, err = Tree(procs) + _, err = Tree(steps) assert.Error(t, err) } diff --git a/server/pipeline/cancel.go b/server/pipeline/cancel.go index f494f0772..b52a07a3f 100644 --- a/server/pipeline/cancel.go +++ b/server/pipeline/cancel.go @@ -33,53 +33,53 @@ func Cancel(ctx context.Context, store store.Store, repo *model.Repo, pipeline * return ErrBadRequest{Msg: "Cannot cancel a non-running or non-pending or non-blocked pipeline"} } - procs, err := store.ProcList(pipeline) + steps, err := store.StepList(pipeline) if err != nil { return ErrNotFound{Msg: err.Error()} } - // First cancel/evict procs in the queue in one go + // First cancel/evict steps in the queue in one go var ( - procsToCancel []string - procsToEvict []string + stepsToCancel []string + stepsToEvict []string ) - for _, proc := range procs { - if proc.PPID != 0 { + for _, step := range steps { + if step.PPID != 0 { continue } - if proc.State == model.StatusRunning { - procsToCancel = append(procsToCancel, fmt.Sprint(proc.ID)) + if step.State == model.StatusRunning { + stepsToCancel = append(stepsToCancel, fmt.Sprint(step.ID)) } - if proc.State == model.StatusPending { - procsToEvict = append(procsToEvict, fmt.Sprint(proc.ID)) + if step.State == model.StatusPending { + stepsToEvict = append(stepsToEvict, fmt.Sprint(step.ID)) } } - if len(procsToEvict) != 0 { - if err := server.Config.Services.Queue.EvictAtOnce(ctx, procsToEvict); err != nil { - log.Error().Err(err).Msgf("queue: evict_at_once: %v", procsToEvict) + if len(stepsToEvict) != 0 { + if err := server.Config.Services.Queue.EvictAtOnce(ctx, stepsToEvict); err != nil { + log.Error().Err(err).Msgf("queue: evict_at_once: %v", stepsToEvict) } - if err := server.Config.Services.Queue.ErrorAtOnce(ctx, procsToEvict, queue.ErrCancel); err != nil { - log.Error().Err(err).Msgf("queue: evict_at_once: %v", procsToEvict) + if err := server.Config.Services.Queue.ErrorAtOnce(ctx, stepsToEvict, queue.ErrCancel); err != nil { + log.Error().Err(err).Msgf("queue: evict_at_once: %v", stepsToEvict) } } - if len(procsToCancel) != 0 { - if err := server.Config.Services.Queue.ErrorAtOnce(ctx, procsToCancel, queue.ErrCancel); err != nil { - log.Error().Err(err).Msgf("queue: evict_at_once: %v", procsToCancel) + if len(stepsToCancel) != 0 { + if err := server.Config.Services.Queue.ErrorAtOnce(ctx, stepsToCancel, queue.ErrCancel); err != nil { + log.Error().Err(err).Msgf("queue: evict_at_once: %v", stepsToCancel) } } // Then update the DB status for pending pipelines // Running ones will be set when the agents stop on the cancel signal - for _, proc := range procs { - if proc.State == model.StatusPending { - if proc.PPID != 0 { - if _, err = shared.UpdateProcToStatusSkipped(store, *proc, 0); err != nil { - log.Error().Msgf("error: done: cannot update proc_id %d state: %s", proc.ID, err) + for _, step := range steps { + if step.State == model.StatusPending { + if step.PPID != 0 { + if _, err = shared.UpdateStepToStatusSkipped(store, *step, 0); err != nil { + log.Error().Msgf("error: done: cannot update step_id %d state: %s", step.ID, err) } } else { - if _, err = shared.UpdateProcToStatusKilled(store, *proc); err != nil { - log.Error().Msgf("error: done: cannot update proc_id %d state: %s", proc.ID, err) + if _, err = shared.UpdateStepToStatusKilled(store, *step); err != nil { + log.Error().Msgf("error: done: cannot update step_id %d state: %s", step.ID, err) } } } @@ -91,11 +91,11 @@ func Cancel(ctx context.Context, store store.Store, repo *model.Repo, pipeline * return err } - procs, err = store.ProcList(killedBuild) + steps, err = store.StepList(killedBuild) if err != nil { return ErrNotFound{Msg: err.Error()} } - if killedBuild.Procs, err = model.Tree(procs); err != nil { + if killedBuild.Steps, err = model.Tree(steps); err != nil { return err } if err := publishToTopic(ctx, killedBuild, repo); err != nil { diff --git a/server/pipeline/create.go b/server/pipeline/create.go index a3b759e87..f51c1324c 100644 --- a/server/pipeline/create.go +++ b/server/pipeline/create.go @@ -101,7 +101,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline pipeline.Status = model.StatusBlocked } - err = _store.CreatePipeline(pipeline, pipeline.Procs...) + err = _store.CreatePipeline(pipeline, pipeline.Steps...) if err != nil { msg := fmt.Sprintf("failure to save pipeline for %s", repo.FullName) log.Error().Err(err).Msg(msg) diff --git a/server/pipeline/decline.go b/server/pipeline/decline.go index 3d6965f01..77fd072fa 100644 --- a/server/pipeline/decline.go +++ b/server/pipeline/decline.go @@ -35,11 +35,11 @@ func Decline(ctx context.Context, store store.Store, pipeline *model.Pipeline, u return nil, fmt.Errorf("error updating pipeline. %s", err) } - if pipeline.Procs, err = store.ProcList(pipeline); err != nil { - log.Error().Err(err).Msg("can not get proc list from store") + if pipeline.Steps, err = store.StepList(pipeline); err != nil { + log.Error().Err(err).Msg("can not get step list from store") } - if pipeline.Procs, err = model.Tree(pipeline.Procs); err != nil { - log.Error().Err(err).Msg("can not build tree from proc list") + if pipeline.Steps, err = model.Tree(pipeline.Steps); err != nil { + log.Error().Err(err).Msg("can not build tree from step list") } if err := updatePipelineStatus(ctx, pipeline, repo, user); err != nil { diff --git a/server/pipeline/filter.go b/server/pipeline/filter.go index 15144036e..09b05cc8f 100644 --- a/server/pipeline/filter.go +++ b/server/pipeline/filter.go @@ -27,7 +27,7 @@ import ( ) func zeroSteps(pipeline *model.Pipeline, remoteYamlConfigs []*remote.FileMeta) bool { - b := shared.ProcBuilder{ + b := shared.StepBuilder{ Repo: &model.Repo{}, Curr: pipeline, Last: &model.Pipeline{}, diff --git a/server/pipeline/helper.go b/server/pipeline/helper.go index b6e0b3c44..5741418ad 100644 --- a/server/pipeline/helper.go +++ b/server/pipeline/helper.go @@ -24,13 +24,13 @@ import ( ) func updatePipelineStatus(ctx context.Context, pipeline *model.Pipeline, repo *model.Repo, user *model.User) error { - for _, proc := range pipeline.Procs { - // skip child procs - if !proc.IsParent() { + for _, step := range pipeline.Steps { + // skip child steps + if !step.IsParent() { continue } - err := server.Config.Services.Remote.Status(ctx, user, repo, pipeline, proc) + err := server.Config.Services.Remote.Status(ctx, user, repo, pipeline, step) if err != nil { log.Error().Err(err).Msgf("error setting commit status for %s/%d", repo.FullName, pipeline.Number) return err diff --git a/server/pipeline/items.go b/server/pipeline/items.go index 2f689e060..249ea127a 100644 --- a/server/pipeline/items.go +++ b/server/pipeline/items.go @@ -64,7 +64,7 @@ func createPipelineItems(ctx context.Context, store store.Store, pipeline *model envs[k] = v } - b := shared.ProcBuilder{ + b := shared.StepBuilder{ Repo: repo, Curr: pipeline, Last: last, diff --git a/server/pipeline/queue.go b/server/pipeline/queue.go index 546f9bc0f..4a5f49f39 100644 --- a/server/pipeline/queue.go +++ b/server/pipeline/queue.go @@ -29,11 +29,11 @@ import ( func queueBuild(pipeline *model.Pipeline, repo *model.Repo, pipelineItems []*shared.PipelineItem) error { var tasks []*queue.Task for _, item := range pipelineItems { - if item.Proc.State == model.StatusSkipped { + if item.Step.State == model.StatusSkipped { continue } task := new(queue.Task) - task.ID = fmt.Sprint(item.Proc.ID) + task.ID = fmt.Sprint(item.Step.ID) task.Labels = map[string]string{} for k, v := range item.Labels { task.Labels[k] = v @@ -45,7 +45,7 @@ func queueBuild(pipeline *model.Pipeline, repo *model.Repo, pipelineItems []*sha task.DepStatus = make(map[string]string) task.Data, _ = json.Marshal(rpc.Pipeline{ - ID: fmt.Sprint(item.Proc.ID), + ID: fmt.Sprint(item.Step.ID), Config: item.Config, Timeout: repo.Timeout, }) @@ -61,8 +61,8 @@ func queueBuild(pipeline *model.Pipeline, repo *model.Repo, pipelineItems []*sha func taskIds(dependsOn []string, pipelineItems []*shared.PipelineItem) (taskIds []string) { for _, dep := range dependsOn { for _, pipelineItem := range pipelineItems { - if pipelineItem.Proc.Name == dep { - taskIds = append(taskIds, fmt.Sprint(pipelineItem.Proc.ID)) + if pipelineItem.Step.Name == dep { + taskIds = append(taskIds, fmt.Sprint(pipelineItem.Step.ID)) } } } diff --git a/server/pipeline/start.go b/server/pipeline/start.go index 4d20acd27..29ba8c534 100644 --- a/server/pipeline/start.go +++ b/server/pipeline/start.go @@ -32,8 +32,8 @@ func start(ctx context.Context, store store.Store, activePipeline *model.Pipelin log.Error().Err(err).Msg("Failed to cancel previous pipelines") } - if err := store.ProcCreate(activePipeline.Procs); err != nil { - log.Error().Err(err).Str("repo", repo.FullName).Msgf("error persisting procs for %s#%d", repo.FullName, activePipeline.Number) + if err := store.StepCreate(activePipeline.Steps); err != nil { + log.Error().Err(err).Str("repo", repo.FullName).Msgf("error persisting steps for %s#%d", repo.FullName, activePipeline.Number) return nil, err } diff --git a/server/pipeline/topic.go b/server/pipeline/topic.go index 7930bc715..cbeb641eb 100644 --- a/server/pipeline/topic.go +++ b/server/pipeline/topic.go @@ -33,7 +33,7 @@ func publishToTopic(c context.Context, pipeline *model.Pipeline, repo *model.Rep }, } pipelineCopy := *pipeline - if pipelineCopy.Procs, err = model.Tree(pipelineCopy.Procs); err != nil { + if pipelineCopy.Steps, err = model.Tree(pipelineCopy.Steps); err != nil { return err } diff --git a/server/remote/bitbucket/bitbucket.go b/server/remote/bitbucket/bitbucket.go index d155273ff..5a2f3b397 100644 --- a/server/remote/bitbucket/bitbucket.go +++ b/server/remote/bitbucket/bitbucket.go @@ -227,7 +227,7 @@ func (c *config) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model } // Status creates a pipeline status for the Bitbucket commit. -func (c *config) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) error { +func (c *config) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, step *model.Step) error { status := internal.PipelineStatus{ State: convertStatus(pipeline.Status), Desc: common.GetPipelineStatusDescription(pipeline.Status), diff --git a/server/remote/bitbucket/bitbucket_test.go b/server/remote/bitbucket/bitbucket_test.go index f2b99fbdf..9694c6c53 100644 --- a/server/remote/bitbucket/bitbucket_test.go +++ b/server/remote/bitbucket/bitbucket_test.go @@ -255,7 +255,7 @@ func Test_bitbucket(t *testing.T) { }) g.It("Should update the status", func() { - err := c.Status(ctx, fakeUser, fakeRepo, fakePipeline, fakeProc) + err := c.Status(ctx, fakeUser, fakeRepo, fakePipeline, fakeStep) g.Assert(err).IsNil() }) @@ -355,7 +355,7 @@ var ( Commit: "9ecad50", } - fakeProc = &model.Proc{ + fakeStep = &model.Step{ Name: "test", State: model.StatusSuccess, } diff --git a/server/remote/bitbucketserver/bitbucketserver.go b/server/remote/bitbucketserver/bitbucketserver.go index 2ff408c39..a5805708e 100644 --- a/server/remote/bitbucketserver/bitbucketserver.go +++ b/server/remote/bitbucketserver/bitbucketserver.go @@ -190,7 +190,7 @@ func (c *Config) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model } // Status is not supported by the bitbucketserver driver. -func (c *Config) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) error { +func (c *Config) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, step *model.Step) error { status := internal.PipelineStatus{ State: convertStatus(pipeline.Status), Desc: common.GetPipelineStatusDescription(pipeline.Status), diff --git a/server/remote/coding/coding.go b/server/remote/coding/coding.go index c74bb4340..368692bc2 100644 --- a/server/remote/coding/coding.go +++ b/server/remote/coding/coding.go @@ -249,7 +249,7 @@ func (c *Coding) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model } // Status sends the commit status to the remote system. -func (c *Coding) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, proc *model.Proc) error { +func (c *Coding) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, step *model.Step) error { // EMPTY: not implemented in Coding OAuth API return nil } diff --git a/server/remote/common/status.go b/server/remote/common/status.go index ba41081b3..5743f32e4 100644 --- a/server/remote/common/status.go +++ b/server/remote/common/status.go @@ -23,7 +23,7 @@ import ( "github.com/woodpecker-ci/woodpecker/server/model" ) -func GetPipelineStatusContext(repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) string { +func GetPipelineStatusContext(repo *model.Repo, pipeline *model.Pipeline, step *model.Step) string { event := string(pipeline.Event) switch pipeline.Event { case model.EventPull: @@ -38,7 +38,7 @@ func GetPipelineStatusContext(repo *model.Repo, pipeline *model.Pipeline, proc * err = tmpl.Execute(&ctx, map[string]interface{}{ "context": server.Config.Server.StatusContext, "event": event, - "pipeline": proc.Name, + "pipeline": step.Name, "owner": repo.Owner, "repo": repo.Name, }) @@ -72,10 +72,10 @@ func GetPipelineStatusDescription(status model.StatusValue) string { } } -func GetPipelineStatusLink(repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) string { - if proc == nil { +func GetPipelineStatusLink(repo *model.Repo, pipeline *model.Pipeline, step *model.Step) string { + if step == nil { return fmt.Sprintf("%s/%s/pipeline/%d", server.Config.Server.Host, repo.FullName, pipeline.Number) } - return fmt.Sprintf("%s/%s/pipeline/%d/%d", server.Config.Server.Host, repo.FullName, pipeline.Number, proc.PID) + return fmt.Sprintf("%s/%s/pipeline/%d/%d", server.Config.Server.Host, repo.FullName, pipeline.Number, step.PID) } diff --git a/server/remote/common/status_test.go b/server/remote/common/status_test.go index 31588ca4f..6bc467a7d 100644 --- a/server/remote/common/status_test.go +++ b/server/remote/common/status_test.go @@ -33,17 +33,17 @@ func TestGetPipelineStatusContext(t *testing.T) { repo := &model.Repo{Owner: "user1", Name: "repo1"} pipeline := &model.Pipeline{Event: model.EventPull} - proc := &model.Proc{Name: "lint"} + step := &model.Step{Name: "lint"} - assert.EqualValues(t, "", GetPipelineStatusContext(repo, pipeline, proc)) + assert.EqualValues(t, "", GetPipelineStatusContext(repo, pipeline, step)) server.Config.Server.StatusContext = "ci/woodpecker" server.Config.Server.StatusContextFormat = "{{ .context }}/{{ .event }}/{{ .pipeline }}" - assert.EqualValues(t, "ci/woodpecker/pr/lint", GetPipelineStatusContext(repo, pipeline, proc)) + assert.EqualValues(t, "ci/woodpecker/pr/lint", GetPipelineStatusContext(repo, pipeline, step)) pipeline.Event = model.EventPush - assert.EqualValues(t, "ci/woodpecker/push/lint", GetPipelineStatusContext(repo, pipeline, proc)) + assert.EqualValues(t, "ci/woodpecker/push/lint", GetPipelineStatusContext(repo, pipeline, step)) server.Config.Server.StatusContext = "ci" server.Config.Server.StatusContextFormat = "{{ .context }}:{{ .owner }}/{{ .repo }}:{{ .event }}:{{ .pipeline }}" - assert.EqualValues(t, "ci:user1/repo1:push:lint", GetPipelineStatusContext(repo, pipeline, proc)) + assert.EqualValues(t, "ci:user1/repo1:push:lint", GetPipelineStatusContext(repo, pipeline, step)) } diff --git a/server/remote/gitea/gitea.go b/server/remote/gitea/gitea.go index a13517fce..87ae5d78b 100644 --- a/server/remote/gitea/gitea.go +++ b/server/remote/gitea/gitea.go @@ -326,7 +326,7 @@ func (c *Gitea) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model. } // Status is supported by the Gitea driver. -func (c *Gitea) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) error { +func (c *Gitea) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, step *model.Step) error { client, err := c.newClientToken(ctx, user.Token) if err != nil { return err @@ -337,10 +337,10 @@ func (c *Gitea) Status(ctx context.Context, user *model.User, repo *model.Repo, repo.Name, pipeline.Commit, gitea.CreateStatusOption{ - State: getStatus(proc.State), - TargetURL: common.GetPipelineStatusLink(repo, pipeline, proc), - Description: common.GetPipelineStatusDescription(proc.State), - Context: common.GetPipelineStatusContext(repo, pipeline, proc), + State: getStatus(step.State), + TargetURL: common.GetPipelineStatusLink(repo, pipeline, step), + Description: common.GetPipelineStatusDescription(step.State), + Context: common.GetPipelineStatusContext(repo, pipeline, step), }, ) return err diff --git a/server/remote/gitea/gitea_test.go b/server/remote/gitea/gitea_test.go index 6e8bd3561..7df13d6d7 100644 --- a/server/remote/gitea/gitea_test.go +++ b/server/remote/gitea/gitea_test.go @@ -138,7 +138,7 @@ func Test_gitea(t *testing.T) { }) g.It("Should return nil from send pipeline status", func() { - err := c.Status(ctx, fakeUser, fakeRepo, fakePipeline, fakeProc) + err := c.Status(ctx, fakeUser, fakeRepo, fakePipeline, fakeStep) g.Assert(err).IsNil() }) @@ -186,7 +186,7 @@ var ( Commit: "9ecad50", } - fakeProc = &model.Proc{ + fakeStep = &model.Step{ Name: "test", State: model.StatusSuccess, } diff --git a/server/remote/github/github.go b/server/remote/github/github.go index f3c1a99ed..11c33a4f5 100644 --- a/server/remote/github/github.go +++ b/server/remote/github/github.go @@ -437,7 +437,7 @@ var reDeploy = regexp.MustCompile(`.+/deployments/(\d+)`) // Status sends the commit status to the remote system. // An example would be the GitHub pull request status. -func (c *client) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) error { +func (c *client) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, step *model.Step) error { client := c.newClientToken(ctx, user.Token) if pipeline.Event == model.EventDeploy { @@ -456,10 +456,10 @@ func (c *client) Status(ctx context.Context, user *model.User, repo *model.Repo, } _, _, err := client.Repositories.CreateStatus(ctx, repo.Owner, repo.Name, pipeline.Commit, &github.RepoStatus{ - Context: github.String(common.GetPipelineStatusContext(repo, pipeline, proc)), - State: github.String(convertStatus(proc.State)), - Description: github.String(common.GetPipelineStatusDescription(proc.State)), - TargetURL: github.String(common.GetPipelineStatusLink(repo, pipeline, proc)), + Context: github.String(common.GetPipelineStatusContext(repo, pipeline, step)), + State: github.String(convertStatus(step.State)), + Description: github.String(common.GetPipelineStatusDescription(step.State)), + TargetURL: github.String(common.GetPipelineStatusLink(repo, pipeline, step)), }) return err } diff --git a/server/remote/gitlab/gitlab.go b/server/remote/gitlab/gitlab.go index 233c06e9e..7c57bd384 100644 --- a/server/remote/gitlab/gitlab.go +++ b/server/remote/gitlab/gitlab.go @@ -387,7 +387,7 @@ func (g *Gitlab) Dir(ctx context.Context, user *model.User, repo *model.Repo, pi } // Status sends the commit status back to gitlab. -func (g *Gitlab) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, proc *model.Proc) error { +func (g *Gitlab) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, step *model.Step) error { client, err := newClient(g.URL, user.Token, g.SkipVerify) if err != nil { return err @@ -399,10 +399,10 @@ func (g *Gitlab) Status(ctx context.Context, user *model.User, repo *model.Repo, } _, _, err = client.Commits.SetCommitStatus(_repo.ID, pipeline.Commit, &gitlab.SetCommitStatusOptions{ - State: getStatus(proc.State), - Description: gitlab.String(common.GetPipelineStatusDescription(proc.State)), - TargetURL: gitlab.String(common.GetPipelineStatusLink(repo, pipeline, proc)), - Context: gitlab.String(common.GetPipelineStatusContext(repo, pipeline, proc)), + State: getStatus(step.State), + Description: gitlab.String(common.GetPipelineStatusDescription(step.State)), + TargetURL: gitlab.String(common.GetPipelineStatusLink(repo, pipeline, step)), + Context: gitlab.String(common.GetPipelineStatusContext(repo, pipeline, step)), }, gitlab.WithContext(ctx)) return err diff --git a/server/remote/gogs/gogs.go b/server/remote/gogs/gogs.go index a892320ce..cf48cc1b9 100644 --- a/server/remote/gogs/gogs.go +++ b/server/remote/gogs/gogs.go @@ -214,7 +214,7 @@ func (c *client) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model } // Status is not supported by the Gogs driver. -func (c *client) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, proc *model.Proc) error { +func (c *client) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, step *model.Step) error { return nil } diff --git a/server/remote/mocks/remote.go b/server/remote/mocks/remote.go index 8c00b8d7c..852723ed2 100644 --- a/server/remote/mocks/remote.go +++ b/server/remote/mocks/remote.go @@ -342,11 +342,11 @@ func (_m *Remote) Repos(ctx context.Context, u *model.User) ([]*model.Repo, erro } // Status provides a mock function with given fields: ctx, u, r, b, p -func (_m *Remote) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, p *model.Proc) error { +func (_m *Remote) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, p *model.Step) error { ret := _m.Called(ctx, u, r, b, p) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, *model.Proc) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, *model.Step) error); ok { r0 = rf(ctx, u, r, b, p) } else { r0 = ret.Error(0) diff --git a/server/remote/remote.go b/server/remote/remote.go index 4a760d455..400c35281 100644 --- a/server/remote/remote.go +++ b/server/remote/remote.go @@ -62,7 +62,7 @@ type Remote interface { // Status sends the commit status to the remote system. // An example would be the GitHub pull request status. - Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, p *model.Proc) error + Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, p *model.Step) error // Netrc returns a .netrc file that can be used to clone // private repositories from a remote system. diff --git a/server/router/api.go b/server/router/api.go index 357eb5be8..5dc314193 100644 --- a/server/router/api.go +++ b/server/router/api.go @@ -85,16 +85,15 @@ func apiRoutes(e *gin.Engine) { repo.DELETE("/pipelines/:number", session.MustPush, api.DeletePipeline) repo.POST("/pipelines/:number/approve", session.MustPush, api.PostApproval) repo.POST("/pipelines/:number/decline", session.MustPush, api.PostDecline) - repo.DELETE("/pipelines/:number/:job", session.MustPush, api.DeletePipeline) - repo.GET("/logs/:number/:pid", api.GetProcLogs) - repo.GET("/logs/:number/:pid/:proc", api.GetPipelineLogs) + repo.GET("/logs/:number/:pid", api.GetStepLogs) + repo.GET("/logs/:number/:pid/:step", api.GetPipelineLogs) // requires push permissions repo.DELETE("/logs/:number", session.MustPush, api.DeletePipelineLogs) repo.GET("/files/:number", api.FileList) - repo.GET("/files/:number/:proc/*file", api.FileGet) + repo.GET("/files/:number/:step/*file", api.FileGet) // requires push permissions repo.GET("/secrets", session.MustPush, api.GetSecretList) diff --git a/server/shared/procStatus.go b/server/shared/procStatus.go deleted file mode 100644 index f741608b4..000000000 --- a/server/shared/procStatus.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2019 mhmxs. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package shared - -import ( - "time" - - "github.com/woodpecker-ci/woodpecker/pipeline/rpc" - "github.com/woodpecker-ci/woodpecker/server/model" -) - -// TODO(974) move to server/pipeline/* - -func UpdateProcStatus(store model.UpdateProcStore, proc model.Proc, state rpc.State, started int64) (*model.Proc, error) { - if state.Exited { - proc.Stopped = state.Finished - proc.ExitCode = state.ExitCode - proc.Error = state.Error - proc.State = model.StatusSuccess - if state.ExitCode != 0 || state.Error != "" { - proc.State = model.StatusFailure - } - if state.ExitCode == 137 { - proc.State = model.StatusKilled - } - } else { - proc.Started = state.Started - proc.State = model.StatusRunning - } - - if proc.Started == 0 && proc.Stopped != 0 { - proc.Started = started - } - return &proc, store.ProcUpdate(&proc) -} - -func UpdateProcToStatusStarted(store model.UpdateProcStore, proc model.Proc, state rpc.State) (*model.Proc, error) { - proc.Started = state.Started - proc.State = model.StatusRunning - return &proc, store.ProcUpdate(&proc) -} - -func UpdateProcToStatusSkipped(store model.UpdateProcStore, proc model.Proc, stopped int64) (*model.Proc, error) { - proc.State = model.StatusSkipped - if proc.Started != 0 { - proc.State = model.StatusSuccess // for daemons that are killed - proc.Stopped = stopped - } - return &proc, store.ProcUpdate(&proc) -} - -func UpdateProcStatusToDone(store model.UpdateProcStore, proc model.Proc, state rpc.State) (*model.Proc, error) { - proc.Stopped = state.Finished - proc.Error = state.Error - proc.ExitCode = state.ExitCode - if state.Started == 0 { - proc.State = model.StatusSkipped - } else { - proc.State = model.StatusSuccess - } - if proc.ExitCode != 0 || proc.Error != "" { - proc.State = model.StatusFailure - } - return &proc, store.ProcUpdate(&proc) -} - -func UpdateProcToStatusKilled(store model.UpdateProcStore, proc model.Proc) (*model.Proc, error) { - proc.State = model.StatusKilled - proc.Stopped = time.Now().Unix() - if proc.Started == 0 { - proc.Started = proc.Stopped - } - proc.ExitCode = 137 - return &proc, store.ProcUpdate(&proc) -} diff --git a/server/shared/procStatus_test.go b/server/shared/procStatus_test.go deleted file mode 100644 index 73c5068de..000000000 --- a/server/shared/procStatus_test.go +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2019 mhmxs. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package shared - -import ( - "testing" - "time" - - "github.com/woodpecker-ci/woodpecker/pipeline/rpc" - "github.com/woodpecker-ci/woodpecker/server/model" -) - -// TODO(974) move to server/pipeline/* - -type mockUpdateProcStore struct{} - -func (m *mockUpdateProcStore) ProcUpdate(build *model.Proc) error { - return nil -} - -func TestUpdateProcStatusNotExited(t *testing.T) { - t.Parallel() - - state := rpc.State{ - Started: int64(42), - Exited: false, - // Dummy data - Finished: int64(1), - ExitCode: 137, - Error: "not an error", - } - proc, _ := UpdateProcStatus(&mockUpdateProcStore{}, model.Proc{}, state, int64(1)) - - if proc.State != model.StatusRunning { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusRunning, proc.State) - } else if proc.Started != int64(42) { - t.Errorf("Proc started not equals 42 != %d", proc.Started) - } else if proc.Stopped != int64(0) { - t.Errorf("Proc stopped not equals 0 != %d", proc.Stopped) - } else if proc.ExitCode != 0 { - t.Errorf("Proc exit code not equals 0 != %d", proc.ExitCode) - } else if proc.Error != "" { - t.Errorf("Proc error not equals '' != '%s'", proc.Error) - } -} - -func TestUpdateProcStatusNotExitedButStopped(t *testing.T) { - t.Parallel() - - proc := &model.Proc{Stopped: int64(64)} - - state := rpc.State{ - Exited: false, - // Dummy data - Finished: int64(1), - ExitCode: 137, - Error: "not an error", - } - proc, _ = UpdateProcStatus(&mockUpdateProcStore{}, *proc, state, int64(42)) - - if proc.State != model.StatusRunning { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusRunning, proc.State) - } else if proc.Started != int64(42) { - t.Errorf("Proc started not equals 42 != %d", proc.Started) - } else if proc.Stopped != int64(64) { - t.Errorf("Proc stopped not equals 64 != %d", proc.Stopped) - } else if proc.ExitCode != 0 { - t.Errorf("Proc exit code not equals 0 != %d", proc.ExitCode) - } else if proc.Error != "" { - t.Errorf("Proc error not equals '' != '%s'", proc.Error) - } -} - -func TestUpdateProcStatusExited(t *testing.T) { - t.Parallel() - - state := rpc.State{ - Started: int64(42), - Exited: true, - Finished: int64(34), - ExitCode: 137, - Error: "an error", - } - proc, _ := UpdateProcStatus(&mockUpdateProcStore{}, model.Proc{}, state, int64(42)) - - if proc.State != model.StatusKilled { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusKilled, proc.State) - } else if proc.Started != int64(42) { - t.Errorf("Proc started not equals 42 != %d", proc.Started) - } else if proc.Stopped != int64(34) { - t.Errorf("Proc stopped not equals 34 != %d", proc.Stopped) - } else if proc.ExitCode != 137 { - t.Errorf("Proc exit code not equals 137 != %d", proc.ExitCode) - } else if proc.Error != "an error" { - t.Errorf("Proc error not equals 'an error' != '%s'", proc.Error) - } -} - -func TestUpdateProcStatusExitedButNot137(t *testing.T) { - t.Parallel() - - state := rpc.State{ - Started: int64(42), - Exited: true, - Finished: int64(34), - Error: "an error", - } - proc, _ := UpdateProcStatus(&mockUpdateProcStore{}, model.Proc{}, state, int64(42)) - - if proc.State != model.StatusFailure { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusFailure, proc.State) - } else if proc.Started != int64(42) { - t.Errorf("Proc started not equals 42 != %d", proc.Started) - } else if proc.Stopped != int64(34) { - t.Errorf("Proc stopped not equals 34 != %d", proc.Stopped) - } else if proc.ExitCode != 0 { - t.Errorf("Proc exit code not equals 0 != %d", proc.ExitCode) - } else if proc.Error != "an error" { - t.Errorf("Proc error not equals 'an error' != '%s'", proc.Error) - } -} - -func TestUpdateProcStatusExitedWithCode(t *testing.T) { - t.Parallel() - - state := rpc.State{ - Started: int64(42), - Exited: true, - Finished: int64(34), - ExitCode: 1, - Error: "an error", - } - proc, _ := UpdateProcStatus(&mockUpdateProcStore{}, model.Proc{}, state, int64(42)) - - if proc.State != model.StatusFailure { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusFailure, proc.State) - } else if proc.ExitCode != 1 { - t.Errorf("Proc exit code not equals 1 != %d", proc.ExitCode) - } -} - -func TestUpdateProcToStatusStarted(t *testing.T) { - t.Parallel() - - state := rpc.State{Started: int64(42)} - proc, _ := UpdateProcToStatusStarted(&mockUpdateProcStore{}, model.Proc{}, state) - - if proc.State != model.StatusRunning { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusRunning, proc.State) - } else if proc.Started != int64(42) { - t.Errorf("Proc started not equals 42 != %d", proc.Started) - } -} - -func TestUpdateProcToStatusSkipped(t *testing.T) { - t.Parallel() - - proc, _ := UpdateProcToStatusSkipped(&mockUpdateProcStore{}, model.Proc{}, int64(1)) - - if proc.State != model.StatusSkipped { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusSkipped, proc.State) - } else if proc.Stopped != int64(0) { - t.Errorf("Proc stopped not equals 0 != %d", proc.Stopped) - } -} - -func TestUpdateProcToStatusSkippedButStarted(t *testing.T) { - t.Parallel() - - proc := &model.Proc{ - Started: int64(42), - } - - proc, _ = UpdateProcToStatusSkipped(&mockUpdateProcStore{}, *proc, int64(1)) - - if proc.State != model.StatusSuccess { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusSuccess, proc.State) - } else if proc.Stopped != int64(1) { - t.Errorf("Proc stopped not equals 1 != %d", proc.Stopped) - } -} - -func TestUpdateProcStatusToDoneSkipped(t *testing.T) { - t.Parallel() - - state := rpc.State{ - Finished: int64(34), - } - - proc, _ := UpdateProcStatusToDone(&mockUpdateProcStore{}, model.Proc{}, state) - - if proc.State != model.StatusSkipped { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusSkipped, proc.State) - } else if proc.Stopped != int64(34) { - t.Errorf("Proc stopped not equals 34 != %d", proc.Stopped) - } else if proc.Error != "" { - t.Errorf("Proc error not equals '' != '%s'", proc.Error) - } else if proc.ExitCode != 0 { - t.Errorf("Proc exit code not equals 0 != %d", proc.ExitCode) - } -} - -func TestUpdateProcStatusToDoneSuccess(t *testing.T) { - t.Parallel() - - state := rpc.State{ - Started: int64(42), - Finished: int64(34), - } - - proc, _ := UpdateProcStatusToDone(&mockUpdateProcStore{}, model.Proc{}, state) - - if proc.State != model.StatusSuccess { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusSuccess, proc.State) - } else if proc.Stopped != int64(34) { - t.Errorf("Proc stopped not equals 34 != %d", proc.Stopped) - } else if proc.Error != "" { - t.Errorf("Proc error not equals '' != '%s'", proc.Error) - } else if proc.ExitCode != 0 { - t.Errorf("Proc exit code not equals 0 != %d", proc.ExitCode) - } -} - -func TestUpdateProcStatusToDoneFailureWithError(t *testing.T) { - t.Parallel() - - state := rpc.State{Error: "an error"} - - proc, _ := UpdateProcStatusToDone(&mockUpdateProcStore{}, model.Proc{}, state) - - if proc.State != model.StatusFailure { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusFailure, proc.State) - } -} - -func TestUpdateProcStatusToDoneFailureWithExitCode(t *testing.T) { - t.Parallel() - - state := rpc.State{ExitCode: 43} - - proc, _ := UpdateProcStatusToDone(&mockUpdateProcStore{}, model.Proc{}, state) - - if proc.State != model.StatusFailure { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusFailure, proc.State) - } -} - -func TestUpdateProcToStatusKilledStarted(t *testing.T) { - t.Parallel() - - now := time.Now().Unix() - - proc, _ := UpdateProcToStatusKilled(&mockUpdateProcStore{}, model.Proc{}) - - if proc.State != model.StatusKilled { - t.Errorf("Proc status not equals '%s' != '%s'", model.StatusKilled, proc.State) - } else if proc.Stopped < now { - t.Errorf("Proc stopped not equals %d < %d", now, proc.Stopped) - } else if proc.Started != proc.Stopped { - t.Errorf("Proc started not equals %d != %d", proc.Stopped, proc.Started) - } else if proc.ExitCode != 137 { - t.Errorf("Proc exit code not equals 137 != %d", proc.ExitCode) - } -} - -func TestUpdateProcToStatusKilledNotStarted(t *testing.T) { - t.Parallel() - - proc, _ := UpdateProcToStatusKilled(&mockUpdateProcStore{}, model.Proc{Started: int64(1)}) - - if proc.Started != int64(1) { - t.Errorf("Proc started not equals 1 != %d", proc.Started) - } -} diff --git a/server/shared/procBuilder.go b/server/shared/stepBuilder.go similarity index 85% rename from server/shared/procBuilder.go rename to server/shared/stepBuilder.go index b098b0da3..83dee0717 100644 --- a/server/shared/procBuilder.go +++ b/server/shared/stepBuilder.go @@ -39,8 +39,8 @@ import ( // TODO(974) move to pipeline/* -// ProcBuilder Takes the hook data and the yaml and returns in internal data model -type ProcBuilder struct { +// StepBuilder Takes the hook data and the yaml and returns in internal data model +type StepBuilder struct { Repo *model.Repo Curr *model.Pipeline Last *model.Pipeline @@ -53,7 +53,7 @@ type ProcBuilder struct { } type PipelineItem struct { - Proc *model.Proc + Step *model.Step Platform string Labels map[string]string DependsOn []string @@ -61,7 +61,7 @@ type PipelineItem struct { Config *backend.Config } -func (b *ProcBuilder) Build() ([]*PipelineItem, error) { +func (b *StepBuilder) Build() ([]*PipelineItem, error) { var items []*PipelineItem sort.Sort(remote.ByName(b.Yamls)) @@ -79,7 +79,7 @@ func (b *ProcBuilder) Build() ([]*PipelineItem, error) { } for _, axis := range axes { - proc := &model.Proc{ + step := &model.Step{ PipelineID: b.Curr.ID, PID: pidSequence, PGID: pidSequence, @@ -88,7 +88,7 @@ func (b *ProcBuilder) Build() ([]*PipelineItem, error) { Name: SanitizePath(y.Name), } - metadata := metadataFromStruct(b.Repo, b.Curr, b.Last, proc, b.Link) + metadata := metadataFromStruct(b.Repo, b.Curr, b.Last, step, b.Link) environ := b.environmentVariables(metadata, axis) // add global environment variables for substituting @@ -121,12 +121,12 @@ func (b *ProcBuilder) Build() ([]*PipelineItem, error) { // checking if filtered. if match, err := parsed.When.Match(metadata, true); !match && err == nil { - log.Debug().Str("pipeline", proc.Name).Msg( + log.Debug().Str("pipeline", step.Name).Msg( "Marked as skipped, dose not match metadata", ) - proc.State = model.StatusSkipped + step.State = model.StatusSkipped } else if err != nil { - log.Debug().Str("pipeline", proc.Name).Msg( + log.Debug().Str("pipeline", step.Name).Msg( "Pipeline config could not be parsed", ) return nil, err @@ -134,13 +134,13 @@ func (b *ProcBuilder) Build() ([]*PipelineItem, error) { // TODO: deprecated branches filter => remove after some time if !parsed.Branches.Match(b.Curr.Branch) && (b.Curr.Event != model.EventDeploy && b.Curr.Event != model.EventTag) { - log.Debug().Str("pipeline", proc.Name).Msg( + log.Debug().Str("pipeline", step.Name).Msg( "Marked as skipped, dose not match branch", ) - proc.State = model.StatusSkipped + step.State = model.StatusSkipped } - ir, err := b.toInternalRepresentation(parsed, environ, metadata, proc.ID) + ir, err := b.toInternalRepresentation(parsed, environ, metadata, step.ID) if err != nil { return nil, err } @@ -150,7 +150,7 @@ func (b *ProcBuilder) Build() ([]*PipelineItem, error) { } item := &PipelineItem{ - Proc: proc, + Step: step, Config: ir, Labels: parsed.Labels, DependsOn: parsed.DependsOn, @@ -168,17 +168,17 @@ func (b *ProcBuilder) Build() ([]*PipelineItem, error) { items = filterItemsWithMissingDependencies(items) - // check if at least one proc can start, if list is not empty - if len(items) > 0 && !procListContainsItemsToRun(items) { + // check if at least one step can start, if list is not empty + if len(items) > 0 && !stepListContainsItemsToRun(items) { return nil, fmt.Errorf("pipeline has no startpoint") } return items, nil } -func procListContainsItemsToRun(items []*PipelineItem) bool { +func stepListContainsItemsToRun(items []*PipelineItem) bool { for i := range items { - if items[i].Proc.State == model.StatusPending { + if items[i].Step.State == model.StatusPending { return true } } @@ -199,7 +199,7 @@ func filterItemsWithMissingDependencies(items []*PipelineItem) []*PipelineItem { if len(itemsToRemove) > 0 { filtered := make([]*PipelineItem, 0) for _, item := range items { - if !containsItemWithName(item.Proc.Name, itemsToRemove) { + if !containsItemWithName(item.Step.Name, itemsToRemove) { filtered = append(filtered, item) } } @@ -212,14 +212,14 @@ func filterItemsWithMissingDependencies(items []*PipelineItem) []*PipelineItem { func containsItemWithName(name string, items []*PipelineItem) bool { for _, item := range items { - if name == item.Proc.Name { + if name == item.Step.Name { return true } } return false } -func (b *ProcBuilder) envsubst(y string, environ map[string]string) (string, error) { +func (b *StepBuilder) envsubst(y string, environ map[string]string) (string, error) { return envsubst.Eval(y, func(name string) string { env := environ[name] if strings.Contains(env, "\n") { @@ -229,7 +229,7 @@ func (b *ProcBuilder) envsubst(y string, environ map[string]string) (string, err }) } -func (b *ProcBuilder) environmentVariables(metadata frontend.Metadata, axis matrix.Axis) map[string]string { +func (b *StepBuilder) environmentVariables(metadata frontend.Metadata, axis matrix.Axis) map[string]string { environ := metadata.Environ() for k, v := range axis { environ[k] = v @@ -237,7 +237,7 @@ func (b *ProcBuilder) environmentVariables(metadata frontend.Metadata, axis matr return environ } -func (b *ProcBuilder) toInternalRepresentation(parsed *yaml.Config, environ map[string]string, metadata frontend.Metadata, procID int64) (*backend.Config, error) { +func (b *StepBuilder) toInternalRepresentation(parsed *yaml.Config, environ map[string]string, metadata frontend.Metadata, stepID int64) (*backend.Config, error) { var secrets []compiler.Secret for _, sec := range b.Secs { if !sec.Match(b.Curr.Event) { @@ -283,7 +283,7 @@ func (b *ProcBuilder) toInternalRepresentation(parsed *yaml.Config, environ map[ compiler.WithPrefix( fmt.Sprintf( "wp_%d_%d", - procID, + stepID, rand.Int(), ), ), @@ -296,9 +296,9 @@ func (b *ProcBuilder) toInternalRepresentation(parsed *yaml.Config, environ map[ func SetPipelineStepsOnPipeline(pipeline *model.Pipeline, pipelineItems []*PipelineItem) *model.Pipeline { var pidSequence int for _, item := range pipelineItems { - pipeline.Procs = append(pipeline.Procs, item.Proc) - if pidSequence < item.Proc.PID { - pidSequence = item.Proc.PID + pipeline.Steps = append(pipeline.Steps, item.Step) + if pidSequence < item.Step.PID { + pidSequence = item.Step.PID } } @@ -310,18 +310,18 @@ func SetPipelineStepsOnPipeline(pipeline *model.Pipeline, pipelineItems []*Pipel if gid == 0 { gid = pidSequence } - proc := &model.Proc{ + step := &model.Step{ PipelineID: pipeline.ID, Name: step.Alias, PID: pidSequence, - PPID: item.Proc.PID, + PPID: item.Step.PID, PGID: gid, State: model.StatusPending, } - if item.Proc.State == model.StatusSkipped { - proc.State = model.StatusSkipped + if item.Step.State == model.StatusSkipped { + step.State = model.StatusSkipped } - pipeline.Procs = append(pipeline.Procs, proc) + pipeline.Steps = append(pipeline.Steps, step) } } } @@ -330,7 +330,7 @@ func SetPipelineStepsOnPipeline(pipeline *model.Pipeline, pipelineItems []*Pipel } // return the metadata from the cli context. -func metadataFromStruct(repo *model.Repo, pipeline, last *model.Pipeline, proc *model.Proc, link string) frontend.Metadata { +func metadataFromStruct(repo *model.Repo, pipeline, last *model.Pipeline, step *model.Step, link string) frontend.Metadata { host := link uri, err := url.Parse(link) if err == nil { @@ -346,9 +346,9 @@ func metadataFromStruct(repo *model.Repo, pipeline, last *model.Pipeline, proc * }, Curr: metadataPipelineFromModelPipeline(pipeline, true), Prev: metadataPipelineFromModelPipeline(last, false), - Job: frontend.Job{ - Number: proc.PID, - Matrix: proc.Environ, + Step: frontend.Step{ + Number: step.PID, + Matrix: step.Environ, }, Sys: frontend.System{ Name: "woodpecker", diff --git a/server/shared/procBuilder_test.go b/server/shared/stepBuilder_test.go similarity index 93% rename from server/shared/procBuilder_test.go rename to server/shared/stepBuilder_test.go index 3603d6e28..2e8662845 100644 --- a/server/shared/procBuilder_test.go +++ b/server/shared/stepBuilder_test.go @@ -28,7 +28,7 @@ import ( func TestGlobalEnvsubst(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Envs: map[string]string{ "KEY_K": "VALUE_V", "IMAGE": "scratch", @@ -62,7 +62,7 @@ pipeline: func TestMissingGlobalEnvsubst(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Envs: map[string]string{ "KEY_K": "VALUE_V", "NO_IMAGE": "scratch", @@ -96,7 +96,7 @@ pipeline: func TestMultilineEnvsubst(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: &model.Pipeline{ Message: `aaa @@ -133,7 +133,7 @@ pipeline: func TestMultiPipeline(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: &model.Pipeline{}, Last: &model.Pipeline{}, @@ -167,7 +167,7 @@ pipeline: func TestDependsOn(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: &model.Pipeline{}, Last: &model.Pipeline{}, @@ -213,7 +213,7 @@ depends_on: func TestRunsOn(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: &model.Pipeline{}, Last: &model.Pipeline{}, @@ -249,7 +249,7 @@ runs_on: func TestPipelineName(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{Config: ".woodpecker"}, Curr: &model.Pipeline{}, Last: &model.Pipeline{}, @@ -275,7 +275,7 @@ pipeline: if err != nil { t.Fatal(err) } - pipelineNames := []string{pipelineItems[0].Proc.Name, pipelineItems[1].Proc.Name} + pipelineNames := []string{pipelineItems[0].Step.Name, pipelineItems[1].Step.Name} if !containsItemWithName("lint", pipelineItems) || !containsItemWithName("test", pipelineItems) { t.Fatalf("Pipeline name should be 'lint' and 'test' but are '%v'", pipelineNames) } @@ -284,7 +284,7 @@ pipeline: func TestBranchFilter(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: &model.Pipeline{Branch: "dev"}, Last: &model.Pipeline{}, @@ -314,15 +314,15 @@ pipeline: if len(pipelineItems) != 2 { t.Fatal("Should have generated 2 pipeline") } - if pipelineItems[0].Proc.State != model.StatusSkipped { + if pipelineItems[0].Step.State != model.StatusSkipped { t.Fatal("Should not run on dev branch") } - for _, child := range pipelineItems[0].Proc.Children { + for _, child := range pipelineItems[0].Step.Children { if child.State != model.StatusSkipped { t.Fatal("Children should skipped status too") } } - if pipelineItems[1].Proc.State != model.StatusPending { + if pipelineItems[1].Step.State != model.StatusPending { t.Fatal("Should run on dev branch") } } @@ -330,7 +330,7 @@ pipeline: func TestRootWhenFilter(t *testing.T) { t.Parallel() - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: &model.Pipeline{Event: "tester"}, Last: &model.Pipeline{}, @@ -378,7 +378,7 @@ func TestZeroSteps(t *testing.T) { pipeline := &model.Pipeline{Branch: "dev"} - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: pipeline, Last: &model.Pipeline{}, @@ -412,7 +412,7 @@ func TestZeroStepsAsMultiPipelineDeps(t *testing.T) { pipeline := &model.Pipeline{Branch: "dev"} - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: pipeline, Last: &model.Pipeline{}, @@ -450,7 +450,7 @@ depends_on: [ zerostep ] if len(pipelineItems) != 1 { t.Fatal("Zerostep and the step that depends on it should not generate a pipeline item") } - if pipelineItems[0].Proc.Name != "justastep" { + if pipelineItems[0].Step.Name != "justastep" { t.Fatal("justastep should have been generated") } } @@ -460,7 +460,7 @@ func TestZeroStepsAsMultiPipelineTransitiveDeps(t *testing.T) { pipeline := &model.Pipeline{Branch: "dev"} - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: pipeline, Last: &model.Pipeline{}, @@ -504,7 +504,7 @@ depends_on: [ shouldbefiltered ] if len(pipelineItems) != 1 { t.Fatal("Zerostep and the step that depends on it, and the one depending on it should not generate a pipeline item") } - if pipelineItems[0].Proc.Name != "justastep" { + if pipelineItems[0].Step.Name != "justastep" { t.Fatal("justastep should have been generated") } } @@ -516,7 +516,7 @@ func TestTree(t *testing.T) { Event: model.EventPush, } - b := ProcBuilder{ + b := StepBuilder{ Repo: &model.Repo{}, Curr: pipeline, Last: &model.Pipeline{}, @@ -538,13 +538,13 @@ pipeline: if err != nil { t.Fatal(err) } - if len(pipeline.Procs) != 3 { + if len(pipeline.Steps) != 3 { t.Fatal("Should generate three in total") } - if pipeline.Procs[1].PPID != 1 { + if pipeline.Steps[1].PPID != 1 { t.Fatal("Clone step should be a children of the stage") } - if pipeline.Procs[2].PPID != 1 { + if pipeline.Steps[2].PPID != 1 { t.Fatal("Pipeline step should be a children of the stage") } } diff --git a/server/shared/stepStatus.go b/server/shared/stepStatus.go new file mode 100644 index 000000000..9482670fa --- /dev/null +++ b/server/shared/stepStatus.go @@ -0,0 +1,88 @@ +// Copyright 2022 Woodpecker Authors +// Copyright 2019 mhmxs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shared + +import ( + "time" + + "github.com/woodpecker-ci/woodpecker/pipeline/rpc" + "github.com/woodpecker-ci/woodpecker/server/model" +) + +// TODO(974) move to server/pipeline/* + +func UpdateStepStatus(store model.UpdateStepStore, step model.Step, state rpc.State, started int64) (*model.Step, error) { + if state.Exited { + step.Stopped = state.Finished + step.ExitCode = state.ExitCode + step.Error = state.Error + step.State = model.StatusSuccess + if state.ExitCode != 0 || state.Error != "" { + step.State = model.StatusFailure + } + if state.ExitCode == 137 { + step.State = model.StatusKilled + } + } else { + step.Started = state.Started + step.State = model.StatusRunning + } + + if step.Started == 0 && step.Stopped != 0 { + step.Started = started + } + return &step, store.StepUpdate(&step) +} + +func UpdateStepToStatusStarted(store model.UpdateStepStore, step model.Step, state rpc.State) (*model.Step, error) { + step.Started = state.Started + step.State = model.StatusRunning + return &step, store.StepUpdate(&step) +} + +func UpdateStepToStatusSkipped(store model.UpdateStepStore, step model.Step, stopped int64) (*model.Step, error) { + step.State = model.StatusSkipped + if step.Started != 0 { + step.State = model.StatusSuccess // for daemons that are killed + step.Stopped = stopped + } + return &step, store.StepUpdate(&step) +} + +func UpdateStepStatusToDone(store model.UpdateStepStore, step model.Step, state rpc.State) (*model.Step, error) { + step.Stopped = state.Finished + step.Error = state.Error + step.ExitCode = state.ExitCode + if state.Started == 0 { + step.State = model.StatusSkipped + } else { + step.State = model.StatusSuccess + } + if step.ExitCode != 0 || step.Error != "" { + step.State = model.StatusFailure + } + return &step, store.StepUpdate(&step) +} + +func UpdateStepToStatusKilled(store model.UpdateStepStore, step model.Step) (*model.Step, error) { + step.State = model.StatusKilled + step.Stopped = time.Now().Unix() + if step.Started == 0 { + step.Started = step.Stopped + } + step.ExitCode = 137 + return &step, store.StepUpdate(&step) +} diff --git a/server/shared/stepStatus_test.go b/server/shared/stepStatus_test.go new file mode 100644 index 000000000..453baa868 --- /dev/null +++ b/server/shared/stepStatus_test.go @@ -0,0 +1,287 @@ +// Copyright 2022 Woodpecker Authors +// Copyright 2019 mhmxs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shared + +import ( + "testing" + "time" + + "github.com/woodpecker-ci/woodpecker/pipeline/rpc" + "github.com/woodpecker-ci/woodpecker/server/model" +) + +// TODO(974) move to server/pipeline/* + +type mockUpdateStepStore struct{} + +func (m *mockUpdateStepStore) StepUpdate(build *model.Step) error { + return nil +} + +func TestUpdateStepStatusNotExited(t *testing.T) { + t.Parallel() + + state := rpc.State{ + Started: int64(42), + Exited: false, + // Dummy data + Finished: int64(1), + ExitCode: 137, + Error: "not an error", + } + step, _ := UpdateStepStatus(&mockUpdateStepStore{}, model.Step{}, state, int64(1)) + + if step.State != model.StatusRunning { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusRunning, step.State) + } else if step.Started != int64(42) { + t.Errorf("Step started not equals 42 != %d", step.Started) + } else if step.Stopped != int64(0) { + t.Errorf("Step stopped not equals 0 != %d", step.Stopped) + } else if step.ExitCode != 0 { + t.Errorf("Step exit code not equals 0 != %d", step.ExitCode) + } else if step.Error != "" { + t.Errorf("Step error not equals '' != '%s'", step.Error) + } +} + +func TestUpdateStepStatusNotExitedButStopped(t *testing.T) { + t.Parallel() + + step := &model.Step{Stopped: int64(64)} + + state := rpc.State{ + Exited: false, + // Dummy data + Finished: int64(1), + ExitCode: 137, + Error: "not an error", + } + step, _ = UpdateStepStatus(&mockUpdateStepStore{}, *step, state, int64(42)) + + if step.State != model.StatusRunning { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusRunning, step.State) + } else if step.Started != int64(42) { + t.Errorf("Step started not equals 42 != %d", step.Started) + } else if step.Stopped != int64(64) { + t.Errorf("Step stopped not equals 64 != %d", step.Stopped) + } else if step.ExitCode != 0 { + t.Errorf("Step exit code not equals 0 != %d", step.ExitCode) + } else if step.Error != "" { + t.Errorf("Step error not equals '' != '%s'", step.Error) + } +} + +func TestUpdateStepStatusExited(t *testing.T) { + t.Parallel() + + state := rpc.State{ + Started: int64(42), + Exited: true, + Finished: int64(34), + ExitCode: 137, + Error: "an error", + } + step, _ := UpdateStepStatus(&mockUpdateStepStore{}, model.Step{}, state, int64(42)) + + if step.State != model.StatusKilled { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusKilled, step.State) + } else if step.Started != int64(42) { + t.Errorf("Step started not equals 42 != %d", step.Started) + } else if step.Stopped != int64(34) { + t.Errorf("Step stopped not equals 34 != %d", step.Stopped) + } else if step.ExitCode != 137 { + t.Errorf("Step exit code not equals 137 != %d", step.ExitCode) + } else if step.Error != "an error" { + t.Errorf("Step error not equals 'an error' != '%s'", step.Error) + } +} + +func TestUpdateStepStatusExitedButNot137(t *testing.T) { + t.Parallel() + + state := rpc.State{ + Started: int64(42), + Exited: true, + Finished: int64(34), + Error: "an error", + } + step, _ := UpdateStepStatus(&mockUpdateStepStore{}, model.Step{}, state, int64(42)) + + if step.State != model.StatusFailure { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusFailure, step.State) + } else if step.Started != int64(42) { + t.Errorf("Step started not equals 42 != %d", step.Started) + } else if step.Stopped != int64(34) { + t.Errorf("Step stopped not equals 34 != %d", step.Stopped) + } else if step.ExitCode != 0 { + t.Errorf("Step exit code not equals 0 != %d", step.ExitCode) + } else if step.Error != "an error" { + t.Errorf("Step error not equals 'an error' != '%s'", step.Error) + } +} + +func TestUpdateStepStatusExitedWithCode(t *testing.T) { + t.Parallel() + + state := rpc.State{ + Started: int64(42), + Exited: true, + Finished: int64(34), + ExitCode: 1, + Error: "an error", + } + step, _ := UpdateStepStatus(&mockUpdateStepStore{}, model.Step{}, state, int64(42)) + + if step.State != model.StatusFailure { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusFailure, step.State) + } else if step.ExitCode != 1 { + t.Errorf("Step exit code not equals 1 != %d", step.ExitCode) + } +} + +func TestUpdateStepPToStatusStarted(t *testing.T) { + t.Parallel() + + state := rpc.State{Started: int64(42)} + step, _ := UpdateStepToStatusStarted(&mockUpdateStepStore{}, model.Step{}, state) + + if step.State != model.StatusRunning { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusRunning, step.State) + } else if step.Started != int64(42) { + t.Errorf("Step started not equals 42 != %d", step.Started) + } +} + +func TestUpdateStepToStatusSkipped(t *testing.T) { + t.Parallel() + + step, _ := UpdateStepToStatusSkipped(&mockUpdateStepStore{}, model.Step{}, int64(1)) + + if step.State != model.StatusSkipped { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusSkipped, step.State) + } else if step.Stopped != int64(0) { + t.Errorf("Step stopped not equals 0 != %d", step.Stopped) + } +} + +func TestUpdateStepToStatusSkippedButStarted(t *testing.T) { + t.Parallel() + + step := &model.Step{ + Started: int64(42), + } + + step, _ = UpdateStepToStatusSkipped(&mockUpdateStepStore{}, *step, int64(1)) + + if step.State != model.StatusSuccess { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusSuccess, step.State) + } else if step.Stopped != int64(1) { + t.Errorf("Step stopped not equals 1 != %d", step.Stopped) + } +} + +func TestUpdateStepStatusToDoneSkipped(t *testing.T) { + t.Parallel() + + state := rpc.State{ + Finished: int64(34), + } + + step, _ := UpdateStepStatusToDone(&mockUpdateStepStore{}, model.Step{}, state) + + if step.State != model.StatusSkipped { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusSkipped, step.State) + } else if step.Stopped != int64(34) { + t.Errorf("Step stopped not equals 34 != %d", step.Stopped) + } else if step.Error != "" { + t.Errorf("Step error not equals '' != '%s'", step.Error) + } else if step.ExitCode != 0 { + t.Errorf("Step exit code not equals 0 != %d", step.ExitCode) + } +} + +func TestUpdateStepStatusToDoneSuccess(t *testing.T) { + t.Parallel() + + state := rpc.State{ + Started: int64(42), + Finished: int64(34), + } + + step, _ := UpdateStepStatusToDone(&mockUpdateStepStore{}, model.Step{}, state) + + if step.State != model.StatusSuccess { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusSuccess, step.State) + } else if step.Stopped != int64(34) { + t.Errorf("Step stopped not equals 34 != %d", step.Stopped) + } else if step.Error != "" { + t.Errorf("Step error not equals '' != '%s'", step.Error) + } else if step.ExitCode != 0 { + t.Errorf("Step exit code not equals 0 != %d", step.ExitCode) + } +} + +func TestUpdateStepStatusToDoneFailureWithError(t *testing.T) { + t.Parallel() + + state := rpc.State{Error: "an error"} + + step, _ := UpdateStepStatusToDone(&mockUpdateStepStore{}, model.Step{}, state) + + if step.State != model.StatusFailure { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusFailure, step.State) + } +} + +func TestUpdateStepStatusToDoneFailureWithExitCode(t *testing.T) { + t.Parallel() + + state := rpc.State{ExitCode: 43} + + step, _ := UpdateStepStatusToDone(&mockUpdateStepStore{}, model.Step{}, state) + + if step.State != model.StatusFailure { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusFailure, step.State) + } +} + +func TestUpdateStepToStatusKilledStarted(t *testing.T) { + t.Parallel() + + now := time.Now().Unix() + + step, _ := UpdateStepToStatusKilled(&mockUpdateStepStore{}, model.Step{}) + + if step.State != model.StatusKilled { + t.Errorf("Step status not equals '%s' != '%s'", model.StatusKilled, step.State) + } else if step.Stopped < now { + t.Errorf("Step stopped not equals %d < %d", now, step.Stopped) + } else if step.Started != step.Stopped { + t.Errorf("Step started not equals %d != %d", step.Stopped, step.Started) + } else if step.ExitCode != 137 { + t.Errorf("Step exit code not equals 137 != %d", step.ExitCode) + } +} + +func TestUpdateStepToStatusKilledNotStarted(t *testing.T) { + t.Parallel() + + step, _ := UpdateStepToStatusKilled(&mockUpdateStepStore{}, model.Step{Started: int64(1)}) + + if step.Started != int64(1) { + t.Errorf("Step started not equals 1 != %d", step.Started) + } +} diff --git a/server/store/datastore/config_test.go b/server/store/datastore/config_test.go index b7830495b..a776b5122 100644 --- a/server/store/datastore/config_test.go +++ b/server/store/datastore/config_test.go @@ -200,7 +200,7 @@ func TestConfigApproved(t *testing.T) { } func TestConfigIndexes(t *testing.T) { - store, closer := newTestStore(t, new(model.Config), new(model.Proc), new(model.Pipeline), new(model.Repo)) + store, closer := newTestStore(t, new(model.Config), new(model.Step), new(model.Pipeline), new(model.Repo)) defer closer() var ( diff --git a/server/store/datastore/file.go b/server/store/datastore/file.go index c117683cd..91c6e96ac 100644 --- a/server/store/datastore/file.go +++ b/server/store/datastore/file.go @@ -26,16 +26,16 @@ func (s storage) FileList(pipeline *model.Pipeline) ([]*model.File, error) { return files, s.engine.Where("file_pipeline_id = ?", pipeline.ID).Find(&files) } -func (s storage) FileFind(proc *model.Proc, name string) (*model.File, error) { +func (s storage) FileFind(step *model.Step, name string) (*model.File, error) { file := &model.File{ - ProcID: proc.ID, + StepID: step.ID, Name: name, } return file, wrapGet(s.engine.Get(file)) } -func (s storage) FileRead(proc *model.Proc, name string) (io.ReadCloser, error) { - file, err := s.FileFind(proc, name) +func (s storage) FileRead(step *model.Step, name string) (io.ReadCloser, error) { + file, err := s.FileFind(step, name) if err != nil { return nil, err } diff --git a/server/store/datastore/file_test.go b/server/store/datastore/file_test.go index 02540cf24..407e7e296 100644 --- a/server/store/datastore/file_test.go +++ b/server/store/datastore/file_test.go @@ -25,13 +25,13 @@ import ( ) func TestFileFind(t *testing.T) { - store, closer := newTestStore(t, new(model.File), new(model.Proc)) + store, closer := newTestStore(t, new(model.File), new(model.Step)) defer closer() if err := store.FileCreate( &model.File{ PipelineID: 2, - ProcID: 1, + StepID: 1, Name: "hello.txt", Mime: "text/plain", Size: 11, @@ -42,7 +42,7 @@ func TestFileFind(t *testing.T) { return } - file, err := store.FileFind(&model.Proc{ID: 1}, "hello.txt") + file, err := store.FileFind(&model.Step{ID: 1}, "hello.txt") if err != nil { t.Error(err) return @@ -53,8 +53,8 @@ func TestFileFind(t *testing.T) { if got, want := file.PipelineID, int64(2); got != want { t.Errorf("Want file pipeline id %d, got %d", want, got) } - if got, want := file.ProcID, int64(1); got != want { - t.Errorf("Want file proc id %d, got %d", want, got) + if got, want := file.StepID, int64(1); got != want { + t.Errorf("Want file step id %d, got %d", want, got) } if got, want := file.Name, "hello.txt"; got != want { t.Errorf("Want file name %s, got %s", want, got) @@ -66,7 +66,7 @@ func TestFileFind(t *testing.T) { t.Errorf("Want file size %d, got %d", want, got) } - rc, err := store.FileRead(&model.Proc{ID: 1}, "hello.txt") + rc, err := store.FileRead(&model.Step{ID: 1}, "hello.txt") if err != nil { t.Error(err) return @@ -84,7 +84,7 @@ func TestFileList(t *testing.T) { assert.NoError(t, store.FileCreate( &model.File{ PipelineID: 1, - ProcID: 1, + StepID: 1, Name: "hello.txt", Mime: "text/plain", Size: 11, @@ -94,7 +94,7 @@ func TestFileList(t *testing.T) { assert.NoError(t, store.FileCreate( &model.File{ PipelineID: 1, - ProcID: 1, + StepID: 1, Name: "hola.txt", Mime: "text/plain", Size: 11, @@ -120,7 +120,7 @@ func TestFileIndexes(t *testing.T) { if err := store.FileCreate( &model.File{ PipelineID: 1, - ProcID: 1, + StepID: 1, Name: "hello.txt", Size: 11, Mime: "text/plain", @@ -135,7 +135,7 @@ func TestFileIndexes(t *testing.T) { if err := store.FileCreate( &model.File{ PipelineID: 1, - ProcID: 1, + StepID: 1, Name: "hello.txt", Mime: "text/plain", Size: 11, @@ -147,23 +147,23 @@ func TestFileIndexes(t *testing.T) { } func TestFileCascade(t *testing.T) { - store, closer := newTestStore(t, new(model.File), new(model.Proc), new(model.Pipeline)) + store, closer := newTestStore(t, new(model.File), new(model.Step), new(model.Pipeline)) defer closer() - procOne := &model.Proc{ + stepOne := &model.Step{ PipelineID: 1, PID: 1, PGID: 1, Name: "build", State: "success", } - err1 := store.ProcCreate([]*model.Proc{procOne}) - assert.EqualValues(t, int64(1), procOne.ID) + err1 := store.StepCreate([]*model.Step{stepOne}) + assert.EqualValues(t, int64(1), stepOne.ID) err2 := store.FileCreate( &model.File{ PipelineID: 1, - ProcID: 1, + StepID: 1, Name: "hello.txt", Mime: "text/plain", Size: 11, @@ -172,19 +172,19 @@ func TestFileCascade(t *testing.T) { ) if err1 != nil { - t.Errorf("Unexpected error: cannot insert proc: %s", err1) + t.Errorf("Unexpected error: cannot insert step: %s", err1) } else if err2 != nil { t.Errorf("Unexpected error: cannot insert file: %s", err2) } - if _, err3 := store.ProcFind(&model.Pipeline{ID: 1}, 1); err3 != nil { - t.Errorf("Unexpected error: cannot get inserted proc: %s", err3) + if _, err3 := store.StepFind(&model.Pipeline{ID: 1}, 1); err3 != nil { + t.Errorf("Unexpected error: cannot get inserted step: %s", err3) } - err := store.ProcClear(&model.Pipeline{ID: 1, Procs: []*model.Proc{procOne}}) + err := store.StepClear(&model.Pipeline{ID: 1, Steps: []*model.Step{stepOne}}) assert.NoError(t, err) - file, err4 := store.FileFind(&model.Proc{ID: 1}, "hello.txt") + file, err4 := store.FileFind(&model.Step{ID: 1}, "hello.txt") if err4 == nil { t.Errorf("Expected no rows in result set error") t.Log(file) diff --git a/server/store/datastore/log.go b/server/store/datastore/log.go index 82fc93b52..dbd60cfbc 100644 --- a/server/store/datastore/log.go +++ b/server/store/datastore/log.go @@ -21,9 +21,9 @@ import ( "github.com/woodpecker-ci/woodpecker/server/model" ) -func (s storage) LogFind(proc *model.Proc) (io.ReadCloser, error) { +func (s storage) LogFind(step *model.Step) (io.ReadCloser, error) { logs := &model.Logs{ - ProcID: proc.ID, + StepID: step.ID, } if err := wrapGet(s.engine.Get(logs)); err != nil { return nil, err @@ -32,7 +32,7 @@ func (s storage) LogFind(proc *model.Proc) (io.ReadCloser, error) { return io.NopCloser(buf), nil } -func (s storage) LogSave(proc *model.Proc, reader io.Reader) error { +func (s storage) LogSave(step *model.Step, reader io.Reader) error { data, _ := io.ReadAll(reader) sess := s.engine.NewSession() @@ -42,7 +42,7 @@ func (s storage) LogSave(proc *model.Proc, reader io.Reader) error { } logs := new(model.Logs) - exist, err := sess.Where("log_job_id = ?", proc.ID).Get(logs) + exist, err := sess.Where("log_step_id = ?", step.ID).Get(logs) if err != nil { return err } @@ -53,7 +53,7 @@ func (s storage) LogSave(proc *model.Proc, reader io.Reader) error { } } else { if _, err := sess.Insert(&model.Logs{ - ProcID: proc.ID, + StepID: step.ID, Data: data, }); err != nil { return err diff --git a/server/store/datastore/log_test.go b/server/store/datastore/log_test.go index 020060913..d62b20620 100644 --- a/server/store/datastore/log_test.go +++ b/server/store/datastore/log_test.go @@ -23,19 +23,19 @@ import ( ) func TestLogCreateFind(t *testing.T) { - store, closer := newTestStore(t, new(model.Proc), new(model.Logs)) + store, closer := newTestStore(t, new(model.Step), new(model.Logs)) defer closer() - proc := model.Proc{ + step := model.Step{ ID: 1, } buf := bytes.NewBufferString("echo hi") - err := store.LogSave(&proc, buf) + err := store.LogSave(&step, buf) if err != nil { t.Errorf("Unexpected error: log create: %s", err) } - rc, err := store.LogFind(&proc) + rc, err := store.LogFind(&step) if err != nil { t.Errorf("Unexpected error: log create: %s", err) } @@ -48,16 +48,16 @@ func TestLogCreateFind(t *testing.T) { } func TestLogUpdate(t *testing.T) { - store, closer := newTestStore(t, new(model.Proc), new(model.Logs)) + store, closer := newTestStore(t, new(model.Step), new(model.Logs)) defer closer() - proc := model.Proc{ + step := model.Step{ ID: 1, } buf1 := bytes.NewBufferString("echo hi") buf2 := bytes.NewBufferString("echo allo?") - err1 := store.LogSave(&proc, buf1) - err2 := store.LogSave(&proc, buf2) + err1 := store.LogSave(&step, buf1) + err2 := store.LogSave(&step, buf2) if err1 != nil { t.Errorf("Unexpected error: log create: %s", err1) } @@ -65,7 +65,7 @@ func TestLogUpdate(t *testing.T) { t.Errorf("Unexpected error: log update: %s", err2) } - rc, err := store.LogFind(&proc) + rc, err := store.LogFind(&step) if err != nil { t.Errorf("Unexpected error: log create: %s", err) } diff --git a/server/store/datastore/migration/010_columns_rename_builds_to_pipeline.go b/server/store/datastore/migration/010_columns_rename_builds_to_pipeline.go index 87a987be1..dd4ca2e68 100644 --- a/server/store/datastore/migration/010_columns_rename_builds_to_pipeline.go +++ b/server/store/datastore/migration/010_columns_rename_builds_to_pipeline.go @@ -20,7 +20,7 @@ import ( "xorm.io/xorm" ) -type oldBuildColumn struct { +type oldTable struct { table string columns []string } @@ -29,9 +29,9 @@ var renameColumnsBuildsToPipeline = task{ name: "rename-columns-builds-to-pipeline", required: true, fn: func(sess *xorm.Session) error { - var oldColumns []*oldBuildColumn + var oldColumns []*oldTable - oldColumns = append(oldColumns, &oldBuildColumn{ + oldColumns = append(oldColumns, &oldTable{ table: "pipelines", columns: []string{ "build_id", @@ -68,17 +68,17 @@ var renameColumnsBuildsToPipeline = task{ }, ) - oldColumns = append(oldColumns, &oldBuildColumn{ + oldColumns = append(oldColumns, &oldTable{ table: "pipeline_config", columns: []string{"build_id"}, }) - oldColumns = append(oldColumns, &oldBuildColumn{ + oldColumns = append(oldColumns, &oldTable{ table: "files", columns: []string{"file_build_id"}, }) - oldColumns = append(oldColumns, &oldBuildColumn{ + oldColumns = append(oldColumns, &oldTable{ table: "procs", columns: []string{"proc_build_id"}, }) diff --git a/server/store/datastore/migration/011_columns_rename_procs_to_steps.go b/server/store/datastore/migration/011_columns_rename_procs_to_steps.go new file mode 100644 index 000000000..8af344e64 --- /dev/null +++ b/server/store/datastore/migration/011_columns_rename_procs_to_steps.go @@ -0,0 +1,87 @@ +// Copyright 2022 Woodpecker Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package migration + +import ( + "strings" + + "xorm.io/xorm" +) + +var renameTableProcsToSteps = task{ + name: "rename-procs-to-steps", + required: true, + fn: func(sess *xorm.Session) error { + err := renameTable(sess, "procs", "steps") + if err != nil { + return err + } + + oldProcColumns := []*oldTable{ + { + table: "steps", + columns: []string{ + "proc_id", + "proc_pipeline_id", + "proc_pid", + "proc_ppid", + "proc_pgid", + "proc_name", + "proc_state", + "proc_error", + "proc_exit_code", + "proc_started", + "proc_stopped", + "proc_machine", + "proc_platform", + "proc_environ", + }, + }, + { + table: "files", + columns: []string{"file_proc_id"}, + }, + } + + for _, table := range oldProcColumns { + for _, column := range table.columns { + err := renameColumn(sess, table.table, column, strings.Replace(column, "proc_", "step_", 1)) + if err != nil { + return err + } + } + } + + oldJobColumns := []*oldTable{ + { + table: "logs", + columns: []string{ + "log_job_id", + }, + }, + } + + for _, table := range oldJobColumns { + for _, column := range table.columns { + err := renameColumn(sess, table.table, column, strings.Replace(column, "job_", "step_", 1)) + if err != nil { + return err + } + } + } + + return nil + }, +} diff --git a/server/store/datastore/migration/migration.go b/server/store/datastore/migration/migration.go index 43a90cee0..970a219c8 100644 --- a/server/store/datastore/migration/migration.go +++ b/server/store/datastore/migration/migration.go @@ -38,6 +38,7 @@ var migrationTasks = []*task{ &lowercaseSecretNames, &renameBuildsToPipeline, &renameColumnsBuildsToPipeline, + &renameTableProcsToSteps, } var allBeans = []interface{}{ @@ -48,7 +49,7 @@ var allBeans = []interface{}{ new(model.File), new(model.Logs), new(model.Perm), - new(model.Proc), + new(model.Step), new(model.Registry), new(model.Repo), new(model.Secret), diff --git a/server/store/datastore/pipeline.go b/server/store/datastore/pipeline.go index 5ea47e857..4ca4c8a88 100644 --- a/server/store/datastore/pipeline.go +++ b/server/store/datastore/pipeline.go @@ -97,7 +97,7 @@ func (s storage) GetPipelineCount() (int64, error) { return s.engine.Count(new(model.Pipeline)) } -func (s storage) CreatePipeline(pipeline *model.Pipeline, procList ...*model.Proc) error { +func (s storage) CreatePipeline(pipeline *model.Pipeline, stepList ...*model.Step) error { sess := s.engine.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { @@ -127,10 +127,10 @@ func (s storage) CreatePipeline(pipeline *model.Pipeline, procList ...*model.Pro return err } - for i := range procList { - procList[i].PipelineID = pipeline.ID + for i := range stepList { + stepList[i].PipelineID = pipeline.ID // only Insert set auto created ID back to object - if _, err := sess.Insert(procList[i]); err != nil { + if _, err := sess.Insert(stepList[i]); err != nil { return err } } @@ -144,18 +144,18 @@ func (s storage) UpdatePipeline(pipeline *model.Pipeline) error { } func deletePipeline(sess *xorm.Session, pipelineID int64) error { - // delete related procs - for startProcs := 0; ; startProcs += perPage { - procIDs := make([]int64, 0, perPage) - if err := sess.Limit(perPage, startProcs).Table("procs").Cols("proc_id").Where("proc_pipeline_id = ?", pipelineID).Find(&procIDs); err != nil { + // delete related steps + for startSteps := 0; ; startSteps += perPage { + stepIDs := make([]int64, 0, perPage) + if err := sess.Limit(perPage, startSteps).Table("steps").Cols("step_id").Where("step_pipeline_id = ?", pipelineID).Find(&stepIDs); err != nil { return err } - if len(procIDs) == 0 { + if len(stepIDs) == 0 { break } - for i := range procIDs { - if err := deleteProc(sess, procIDs[i]); err != nil { + for i := range stepIDs { + if err := deleteStep(sess, stepIDs[i]); err != nil { return err } } diff --git a/server/store/datastore/pipeline_test.go b/server/store/datastore/pipeline_test.go index 1a17beb2a..02722a352 100644 --- a/server/store/datastore/pipeline_test.go +++ b/server/store/datastore/pipeline_test.go @@ -33,7 +33,7 @@ func TestPipelines(t *testing.T) { Name: "test", } - store, closer := newTestStore(t, new(model.Repo), new(model.Proc), new(model.Pipeline)) + store, closer := newTestStore(t, new(model.Repo), new(model.Step), new(model.Pipeline)) defer closer() g := goblin.Goblin(t) @@ -53,7 +53,7 @@ func TestPipelines(t *testing.T) { g.BeforeEach(func() { _, err := store.engine.Exec("DELETE FROM pipelines") g.Assert(err).IsNil() - _, err = store.engine.Exec("DELETE FROM procs") + _, err = store.engine.Exec("DELETE FROM steps") g.Assert(err).IsNil() }) @@ -114,7 +114,7 @@ func TestPipelines(t *testing.T) { RepoID: repo.ID, Status: model.StatusSuccess, } - err := store.CreatePipeline(&pipeline, []*model.Proc{}...) + err := store.CreatePipeline(&pipeline, []*model.Step{}...) g.Assert(err).IsNil() GetPipeline, err := store.GetPipeline(pipeline.ID) g.Assert(err).IsNil() @@ -132,9 +132,9 @@ func TestPipelines(t *testing.T) { RepoID: repo.ID, Status: model.StatusPending, } - err1 := store.CreatePipeline(pipeline1, []*model.Proc{}...) + err1 := store.CreatePipeline(pipeline1, []*model.Step{}...) g.Assert(err1).IsNil() - err2 := store.CreatePipeline(pipeline2, []*model.Proc{}...) + err2 := store.CreatePipeline(pipeline2, []*model.Step{}...) g.Assert(err2).IsNil() GetPipeline, err3 := store.GetPipelineNumber(&model.Repo{ID: 1}, pipeline2.Number) g.Assert(err3).IsNil() @@ -154,9 +154,9 @@ func TestPipelines(t *testing.T) { Status: model.StatusPending, Ref: "refs/pull/6", } - err1 := store.CreatePipeline(pipeline1, []*model.Proc{}...) + err1 := store.CreatePipeline(pipeline1, []*model.Step{}...) g.Assert(err1).IsNil() - err2 := store.CreatePipeline(pipeline2, []*model.Proc{}...) + err2 := store.CreatePipeline(pipeline2, []*model.Step{}...) g.Assert(err2).IsNil() GetPipeline, err3 := store.GetPipelineRef(&model.Repo{ID: 1}, "refs/pull/6") g.Assert(err3).IsNil() @@ -177,9 +177,9 @@ func TestPipelines(t *testing.T) { Status: model.StatusPending, Ref: "refs/pull/6", } - err1 := store.CreatePipeline(pipeline1, []*model.Proc{}...) + err1 := store.CreatePipeline(pipeline1, []*model.Step{}...) g.Assert(err1).IsNil() - err2 := store.CreatePipeline(pipeline2, []*model.Proc{}...) + err2 := store.CreatePipeline(pipeline2, []*model.Step{}...) g.Assert(err2).IsNil() GetPipeline, err3 := store.GetPipelineRef(&model.Repo{ID: 1}, "refs/pull/6") g.Assert(err3).IsNil() @@ -202,9 +202,9 @@ func TestPipelines(t *testing.T) { Branch: "dev", Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa", } - err1 := store.CreatePipeline(pipeline1, []*model.Proc{}...) + err1 := store.CreatePipeline(pipeline1, []*model.Step{}...) g.Assert(err1).IsNil() - err2 := store.CreatePipeline(pipeline2, []*model.Proc{}...) + err2 := store.CreatePipeline(pipeline2, []*model.Step{}...) g.Assert(err2).IsNil() GetPipeline, err3 := store.GetPipelineCommit(&model.Repo{ID: 1}, pipeline2.Commit, pipeline2.Branch) g.Assert(err3).IsNil() @@ -230,8 +230,8 @@ func TestPipelines(t *testing.T) { Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa", Event: model.EventPush, } - err1 := store.CreatePipeline(pipeline1, []*model.Proc{}...) - err2 := store.CreatePipeline(pipeline2, []*model.Proc{}...) + err1 := store.CreatePipeline(pipeline1, []*model.Step{}...) + err2 := store.CreatePipeline(pipeline2, []*model.Step{}...) GetPipeline, err3 := store.GetPipelineLast(&model.Repo{ID: 1}, pipeline2.Branch) g.Assert(err1).IsNil() g.Assert(err2).IsNil() @@ -263,11 +263,11 @@ func TestPipelines(t *testing.T) { Branch: "master", Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa", } - err1 := store.CreatePipeline(pipeline1, []*model.Proc{}...) + err1 := store.CreatePipeline(pipeline1, []*model.Step{}...) g.Assert(err1).IsNil() - err2 := store.CreatePipeline(pipeline2, []*model.Proc{}...) + err2 := store.CreatePipeline(pipeline2, []*model.Step{}...) g.Assert(err2).IsNil() - err3 := store.CreatePipeline(pipeline3, []*model.Proc{}...) + err3 := store.CreatePipeline(pipeline3, []*model.Step{}...) g.Assert(err3).IsNil() GetPipeline, err4 := store.GetPipelineLastBefore(&model.Repo{ID: 1}, pipeline3.Branch, pipeline3.ID) g.Assert(err4).IsNil() @@ -288,9 +288,9 @@ func TestPipelines(t *testing.T) { RepoID: repo.ID, Status: model.StatusSuccess, } - err1 := store.CreatePipeline(pipeline1, []*model.Proc{}...) + err1 := store.CreatePipeline(pipeline1, []*model.Step{}...) g.Assert(err1).IsNil() - err2 := store.CreatePipeline(pipeline2, []*model.Proc{}...) + err2 := store.CreatePipeline(pipeline2, []*model.Step{}...) g.Assert(err2).IsNil() pipelines, err3 := store.GetPipelineList(&model.Repo{ID: 1}, 1) g.Assert(err3).IsNil() diff --git a/server/store/datastore/repo_test.go b/server/store/datastore/repo_test.go index 26f856820..ae2748eab 100644 --- a/server/store/datastore/repo_test.go +++ b/server/store/datastore/repo_test.go @@ -383,7 +383,7 @@ func TestRepoCrud(t *testing.T) { new(model.Pipeline), new(model.PipelineConfig), new(model.Logs), - new(model.Proc), + new(model.Step), new(model.File), new(model.Secret), new(model.Registry), @@ -401,10 +401,10 @@ func TestRepoCrud(t *testing.T) { pipeline := model.Pipeline{ RepoID: repo.ID, } - proc := model.Proc{ - Name: "a proc", + step := model.Step{ + Name: "a step", } - assert.NoError(t, store.CreatePipeline(&pipeline, &proc)) + assert.NoError(t, store.CreatePipeline(&pipeline, &step)) // create unrelated repoUnrelated := model.Repo{ @@ -417,10 +417,10 @@ func TestRepoCrud(t *testing.T) { pipelineUnrelated := model.Pipeline{ RepoID: repoUnrelated.ID, } - procUnrelated := model.Proc{ - Name: "a unrelated proc", + stepUnrelated := model.Step{ + Name: "a unrelated step", } - assert.NoError(t, store.CreatePipeline(&pipelineUnrelated, &procUnrelated)) + assert.NoError(t, store.CreatePipeline(&pipelineUnrelated, &stepUnrelated)) _, err := store.GetRepo(repo.ID) assert.NoError(t, err) @@ -428,9 +428,9 @@ func TestRepoCrud(t *testing.T) { _, err = store.GetRepo(repo.ID) assert.Error(t, err) - procCount, err := store.engine.Count(new(model.Proc)) + stepCount, err := store.engine.Count(new(model.Step)) assert.NoError(t, err) - assert.EqualValues(t, 1, procCount) + assert.EqualValues(t, 1, stepCount) pipelineCount, err := store.engine.Count(new(model.Pipeline)) assert.NoError(t, err) assert.EqualValues(t, 1, pipelineCount) diff --git a/server/store/datastore/proc.go b/server/store/datastore/step.go similarity index 51% rename from server/store/datastore/proc.go rename to server/store/datastore/step.go index e4aa1d6dd..d833febc2 100644 --- a/server/store/datastore/proc.go +++ b/server/store/datastore/step.go @@ -20,46 +20,46 @@ import ( "github.com/woodpecker-ci/woodpecker/server/model" ) -func (s storage) ProcLoad(id int64) (*model.Proc, error) { - proc := new(model.Proc) - return proc, wrapGet(s.engine.ID(id).Get(proc)) +func (s storage) StepLoad(id int64) (*model.Step, error) { + step := new(model.Step) + return step, wrapGet(s.engine.ID(id).Get(step)) } -func (s storage) ProcFind(pipeline *model.Pipeline, pid int) (*model.Proc, error) { - proc := &model.Proc{ +func (s storage) StepFind(pipeline *model.Pipeline, pid int) (*model.Step, error) { + step := &model.Step{ PipelineID: pipeline.ID, PID: pid, } - return proc, wrapGet(s.engine.Get(proc)) + return step, wrapGet(s.engine.Get(step)) } -func (s storage) ProcChild(pipeline *model.Pipeline, ppid int, child string) (*model.Proc, error) { - proc := &model.Proc{ +func (s storage) StepChild(pipeline *model.Pipeline, ppid int, child string) (*model.Step, error) { + step := &model.Step{ PipelineID: pipeline.ID, PPID: ppid, Name: child, } - return proc, wrapGet(s.engine.Get(proc)) + return step, wrapGet(s.engine.Get(step)) } -func (s storage) ProcList(pipeline *model.Pipeline) ([]*model.Proc, error) { - procList := make([]*model.Proc, 0, perPage) - return procList, s.engine. - Where("proc_pipeline_id = ?", pipeline.ID). - OrderBy("proc_pid"). - Find(&procList) +func (s storage) StepList(pipeline *model.Pipeline) ([]*model.Step, error) { + stepList := make([]*model.Step, 0, perPage) + return stepList, s.engine. + Where("step_pipeline_id = ?", pipeline.ID). + OrderBy("step_pid"). + Find(&stepList) } -func (s storage) ProcCreate(procs []*model.Proc) error { +func (s storage) StepCreate(steps []*model.Step) error { sess := s.engine.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } - for i := range procs { + for i := range steps { // only Insert on single object ref set auto created ID back to object - if _, err := sess.Insert(procs[i]); err != nil { + if _, err := sess.Insert(steps[i]); err != nil { return err } } @@ -67,12 +67,12 @@ func (s storage) ProcCreate(procs []*model.Proc) error { return sess.Commit() } -func (s storage) ProcUpdate(proc *model.Proc) error { - _, err := s.engine.ID(proc.ID).AllCols().Update(proc) +func (s storage) StepUpdate(step *model.Step) error { + _, err := s.engine.ID(step.ID).AllCols().Update(step) return err } -func (s storage) ProcClear(pipeline *model.Pipeline) error { +func (s storage) StepClear(pipeline *model.Pipeline) error { sess := s.engine.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { @@ -83,20 +83,20 @@ func (s storage) ProcClear(pipeline *model.Pipeline) error { return err } - if _, err := sess.Where("proc_pipeline_id = ?", pipeline.ID).Delete(new(model.Proc)); err != nil { + if _, err := sess.Where("step_pipeline_id = ?", pipeline.ID).Delete(new(model.Step)); err != nil { return err } return sess.Commit() } -func deleteProc(sess *xorm.Session, procID int64) error { - if _, err := sess.Where("log_job_id = ?", procID).Delete(new(model.Logs)); err != nil { +func deleteStep(sess *xorm.Session, stepID int64) error { + if _, err := sess.Where("log_step_id = ?", stepID).Delete(new(model.Logs)); err != nil { return err } - if _, err := sess.Where("file_proc_id = ?", procID).Delete(new(model.File)); err != nil { + if _, err := sess.Where("file_step_id = ?", stepID).Delete(new(model.File)); err != nil { return err } - _, err := sess.ID(procID).Delete(new(model.Proc)) + _, err := sess.ID(stepID).Delete(new(model.Step)) return err } diff --git a/server/store/datastore/proc_test.go b/server/store/datastore/step_test.go similarity index 59% rename from server/store/datastore/proc_test.go rename to server/store/datastore/step_test.go index fd1a074f7..c25772f14 100644 --- a/server/store/datastore/proc_test.go +++ b/server/store/datastore/step_test.go @@ -23,11 +23,11 @@ import ( "github.com/woodpecker-ci/woodpecker/server/model" ) -func TestProcFind(t *testing.T) { - store, closer := newTestStore(t, new(model.Proc), new(model.Pipeline)) +func TestStepFind(t *testing.T) { + store, closer := newTestStore(t, new(model.Step), new(model.Pipeline)) defer closer() - procs := []*model.Proc{ + steps := []*model.Step{ { PipelineID: 1000, PID: 1, @@ -42,22 +42,22 @@ func TestProcFind(t *testing.T) { Environ: map[string]string{"GOLANG": "tip"}, }, } - assert.NoError(t, store.ProcCreate(procs)) - assert.EqualValues(t, 1, procs[0].ID) - assert.Error(t, store.ProcCreate(procs)) + assert.NoError(t, store.StepCreate(steps)) + assert.EqualValues(t, 1, steps[0].ID) + assert.Error(t, store.StepCreate(steps)) - proc, err := store.ProcFind(&model.Pipeline{ID: 1000}, 1) + step, err := store.StepFind(&model.Pipeline{ID: 1000}, 1) if !assert.NoError(t, err) { return } - assert.Equal(t, procs[0], proc) + assert.Equal(t, steps[0], step) } -func TestProcChild(t *testing.T) { - store, closer := newTestStore(t, new(model.Proc), new(model.Pipeline)) +func TestStepChild(t *testing.T) { + store, closer := newTestStore(t, new(model.Step), new(model.Pipeline)) defer closer() - err := store.ProcCreate([]*model.Proc{ + err := store.StepCreate([]*model.Step{ { PipelineID: 1, PID: 1, @@ -75,28 +75,28 @@ func TestProcChild(t *testing.T) { }, }) if err != nil { - t.Errorf("Unexpected error: insert procs: %s", err) + t.Errorf("Unexpected error: insert steps: %s", err) return } - proc, err := store.ProcChild(&model.Pipeline{ID: 1}, 1, "build") + step, err := store.StepChild(&model.Pipeline{ID: 1}, 1, "build") if err != nil { t.Error(err) return } - if got, want := proc.PID, 2; got != want { - t.Errorf("Want proc pid %d, got %d", want, got) + if got, want := step.PID, 2; got != want { + t.Errorf("Want step pid %d, got %d", want, got) } - if got, want := proc.Name, "build"; got != want { - t.Errorf("Want proc name %s, got %s", want, got) + if got, want := step.Name, "build"; got != want { + t.Errorf("Want step name %s, got %s", want, got) } } -func TestProcList(t *testing.T) { - store, closer := newTestStore(t, new(model.Proc), new(model.Pipeline)) +func TestStepList(t *testing.T) { + store, closer := newTestStore(t, new(model.Step), new(model.Pipeline)) defer closer() - err := store.ProcCreate([]*model.Proc{ + err := store.StepCreate([]*model.Step{ { PipelineID: 2, PID: 1, @@ -121,24 +121,24 @@ func TestProcList(t *testing.T) { }, }) if err != nil { - t.Errorf("Unexpected error: insert procs: %s", err) + t.Errorf("Unexpected error: insert steps: %s", err) return } - procs, err := store.ProcList(&model.Pipeline{ID: 1}) + steps, err := store.StepList(&model.Pipeline{ID: 1}) if err != nil { t.Error(err) return } - if got, want := len(procs), 2; got != want { - t.Errorf("Want %d procs, got %d", want, got) + if got, want := len(steps), 2; got != want { + t.Errorf("Want %d steps, got %d", want, got) } } -func TestProcUpdate(t *testing.T) { - store, closer := newTestStore(t, new(model.Proc), new(model.Pipeline)) +func TestStepUpdate(t *testing.T) { + store, closer := newTestStore(t, new(model.Step), new(model.Pipeline)) defer closer() - proc := &model.Proc{ + step := &model.Step{ PipelineID: 1, PID: 1, PPID: 2, @@ -151,30 +151,30 @@ func TestProcUpdate(t *testing.T) { Platform: "linux/amd64", Environ: map[string]string{"GOLANG": "tip"}, } - if err := store.ProcCreate([]*model.Proc{proc}); err != nil { - t.Errorf("Unexpected error: insert proc: %s", err) + if err := store.StepCreate([]*model.Step{step}); err != nil { + t.Errorf("Unexpected error: insert step: %s", err) return } - proc.State = "running" - if err := store.ProcUpdate(proc); err != nil { - t.Errorf("Unexpected error: update proc: %s", err) + step.State = "running" + if err := store.StepUpdate(step); err != nil { + t.Errorf("Unexpected error: update step: %s", err) return } - updated, err := store.ProcFind(&model.Pipeline{ID: 1}, 1) + updated, err := store.StepFind(&model.Pipeline{ID: 1}, 1) if err != nil { t.Error(err) return } if got, want := updated.State, model.StatusRunning; got != want { - t.Errorf("Want proc name %s, got %s", want, got) + t.Errorf("Want step name %s, got %s", want, got) } } -func TestProcIndexes(t *testing.T) { - store, closer := newTestStore(t, new(model.Proc), new(model.Pipeline)) +func TestStepIndexes(t *testing.T) { + store, closer := newTestStore(t, new(model.Step), new(model.Pipeline)) defer closer() - if err := store.ProcCreate([]*model.Proc{ + if err := store.StepCreate([]*model.Step{ { PipelineID: 1, PID: 1, @@ -184,12 +184,12 @@ func TestProcIndexes(t *testing.T) { Name: "build", }, }); err != nil { - t.Errorf("Unexpected error: insert procs: %s", err) + t.Errorf("Unexpected error: insert steps: %s", err) return } // fail due to duplicate pid - if err := store.ProcCreate([]*model.Proc{ + if err := store.StepCreate([]*model.Step{ { PipelineID: 1, PID: 1, @@ -203,4 +203,4 @@ func TestProcIndexes(t *testing.T) { } } -// TODO: func TestProcCascade(t *testing.T) {} +// TODO: func TestStepCascade(t *testing.T) {} diff --git a/server/store/datastore/users_test.go b/server/store/datastore/users_test.go index de3a7ab8b..10f28a8d0 100644 --- a/server/store/datastore/users_test.go +++ b/server/store/datastore/users_test.go @@ -24,7 +24,7 @@ import ( ) func TestUsers(t *testing.T) { - store, closer := newTestStore(t, new(model.User), new(model.Repo), new(model.Pipeline), new(model.Proc), new(model.Perm)) + store, closer := newTestStore(t, new(model.User), new(model.Repo), new(model.Pipeline), new(model.Step), new(model.Perm)) defer closer() g := goblin.Goblin(t) @@ -38,7 +38,7 @@ func TestUsers(t *testing.T) { g.Assert(err).IsNil() _, err = store.engine.Exec("DELETE FROM pipelines") g.Assert(err).IsNil() - _, err = store.engine.Exec("DELETE FROM procs") + _, err = store.engine.Exec("DELETE FROM steps") g.Assert(err).IsNil() }) diff --git a/server/store/mocks/store.go b/server/store/mocks/store.go index 337b62f02..bcc2be205 100644 --- a/server/store/mocks/store.go +++ b/server/store/mocks/store.go @@ -110,7 +110,7 @@ func (_m *Store) ConfigsForPipeline(pipelineID int64) ([]*model.Config, error) { } // CreatePipeline provides a mock function with given fields: _a0, _a1 -func (_m *Store) CreatePipeline(_a0 *model.Pipeline, _a1 ...*model.Proc) error { +func (_m *Store) CreatePipeline(_a0 *model.Pipeline, _a1 ...*model.Step) error { _va := make([]interface{}, len(_a1)) for _i := range _a1 { _va[_i] = _a1[_i] @@ -121,7 +121,7 @@ func (_m *Store) CreatePipeline(_a0 *model.Pipeline, _a1 ...*model.Proc) error { ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(*model.Pipeline, ...*model.Proc) error); ok { + if rf, ok := ret.Get(0).(func(*model.Pipeline, ...*model.Step) error); ok { r0 = rf(_a0, _a1...) } else { r0 = ret.Error(0) @@ -347,11 +347,11 @@ func (_m *Store) FileCreate(_a0 *model.File, _a1 io.Reader) error { } // FileFind provides a mock function with given fields: _a0, _a1 -func (_m *Store) FileFind(_a0 *model.Proc, _a1 string) (*model.File, error) { +func (_m *Store) FileFind(_a0 *model.Step, _a1 string) (*model.File, error) { ret := _m.Called(_a0, _a1) var r0 *model.File - if rf, ok := ret.Get(0).(func(*model.Proc, string) *model.File); ok { + if rf, ok := ret.Get(0).(func(*model.Step, string) *model.File); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -360,7 +360,7 @@ func (_m *Store) FileFind(_a0 *model.Proc, _a1 string) (*model.File, error) { } var r1 error - if rf, ok := ret.Get(1).(func(*model.Proc, string) error); ok { + if rf, ok := ret.Get(1).(func(*model.Step, string) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -393,11 +393,11 @@ func (_m *Store) FileList(_a0 *model.Pipeline) ([]*model.File, error) { } // FileRead provides a mock function with given fields: _a0, _a1 -func (_m *Store) FileRead(_a0 *model.Proc, _a1 string) (io.ReadCloser, error) { +func (_m *Store) FileRead(_a0 *model.Step, _a1 string) (io.ReadCloser, error) { ret := _m.Called(_a0, _a1) var r0 io.ReadCloser - if rf, ok := ret.Get(0).(func(*model.Proc, string) io.ReadCloser); ok { + if rf, ok := ret.Get(0).(func(*model.Step, string) io.ReadCloser); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -406,7 +406,7 @@ func (_m *Store) FileRead(_a0 *model.Proc, _a1 string) (io.ReadCloser, error) { } var r1 error - if rf, ok := ret.Get(1).(func(*model.Proc, string) error); ok { + if rf, ok := ret.Get(1).(func(*model.Step, string) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -937,11 +937,11 @@ func (_m *Store) HasRedirectionForRepo(_a0 int64, _a1 string) (bool, error) { } // LogFind provides a mock function with given fields: _a0 -func (_m *Store) LogFind(_a0 *model.Proc) (io.ReadCloser, error) { +func (_m *Store) LogFind(_a0 *model.Step) (io.ReadCloser, error) { ret := _m.Called(_a0) var r0 io.ReadCloser - if rf, ok := ret.Get(0).(func(*model.Proc) io.ReadCloser); ok { + if rf, ok := ret.Get(0).(func(*model.Step) io.ReadCloser); ok { r0 = rf(_a0) } else { if ret.Get(0) != nil { @@ -950,7 +950,7 @@ func (_m *Store) LogFind(_a0 *model.Proc) (io.ReadCloser, error) { } var r1 error - if rf, ok := ret.Get(1).(func(*model.Proc) error); ok { + if rf, ok := ret.Get(1).(func(*model.Step) error); ok { r1 = rf(_a0) } else { r1 = ret.Error(1) @@ -960,11 +960,11 @@ func (_m *Store) LogFind(_a0 *model.Proc) (io.ReadCloser, error) { } // LogSave provides a mock function with given fields: _a0, _a1 -func (_m *Store) LogSave(_a0 *model.Proc, _a1 io.Reader) error { +func (_m *Store) LogSave(_a0 *model.Step, _a1 io.Reader) error { ret := _m.Called(_a0, _a1) var r0 error - if rf, ok := ret.Get(0).(func(*model.Proc, io.Reader) error); ok { + if rf, ok := ret.Get(0).(func(*model.Step, io.Reader) error); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Error(0) @@ -1126,140 +1126,6 @@ func (_m *Store) PipelineConfigCreate(_a0 *model.PipelineConfig) error { return r0 } -// ProcChild provides a mock function with given fields: _a0, _a1, _a2 -func (_m *Store) ProcChild(_a0 *model.Pipeline, _a1 int, _a2 string) (*model.Proc, error) { - ret := _m.Called(_a0, _a1, _a2) - - var r0 *model.Proc - if rf, ok := ret.Get(0).(func(*model.Pipeline, int, string) *model.Proc); ok { - r0 = rf(_a0, _a1, _a2) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.Proc) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*model.Pipeline, int, string) error); ok { - r1 = rf(_a0, _a1, _a2) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProcClear provides a mock function with given fields: _a0 -func (_m *Store) ProcClear(_a0 *model.Pipeline) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(*model.Pipeline) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ProcCreate provides a mock function with given fields: _a0 -func (_m *Store) ProcCreate(_a0 []*model.Proc) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func([]*model.Proc) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ProcFind provides a mock function with given fields: _a0, _a1 -func (_m *Store) ProcFind(_a0 *model.Pipeline, _a1 int) (*model.Proc, error) { - ret := _m.Called(_a0, _a1) - - var r0 *model.Proc - if rf, ok := ret.Get(0).(func(*model.Pipeline, int) *model.Proc); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.Proc) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*model.Pipeline, int) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProcList provides a mock function with given fields: _a0 -func (_m *Store) ProcList(_a0 *model.Pipeline) ([]*model.Proc, error) { - ret := _m.Called(_a0) - - var r0 []*model.Proc - if rf, ok := ret.Get(0).(func(*model.Pipeline) []*model.Proc); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*model.Proc) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*model.Pipeline) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProcLoad provides a mock function with given fields: _a0 -func (_m *Store) ProcLoad(_a0 int64) (*model.Proc, error) { - ret := _m.Called(_a0) - - var r0 *model.Proc - if rf, ok := ret.Get(0).(func(int64) *model.Proc); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.Proc) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProcUpdate provides a mock function with given fields: _a0 -func (_m *Store) ProcUpdate(_a0 *model.Proc) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(*model.Proc) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // RegistryCreate provides a mock function with given fields: _a0 func (_m *Store) RegistryCreate(_a0 *model.Registry) error { ret := _m.Called(_a0) @@ -1531,6 +1397,140 @@ func (_m *Store) ServerConfigSet(_a0 string, _a1 string) error { return r0 } +// StepChild provides a mock function with given fields: _a0, _a1, _a2 +func (_m *Store) StepChild(_a0 *model.Pipeline, _a1 int, _a2 string) (*model.Step, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *model.Step + if rf, ok := ret.Get(0).(func(*model.Pipeline, int, string) *model.Step); ok { + r0 = rf(_a0, _a1, _a2) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.Step) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*model.Pipeline, int, string) error); ok { + r1 = rf(_a0, _a1, _a2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StepClear provides a mock function with given fields: _a0 +func (_m *Store) StepClear(_a0 *model.Pipeline) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*model.Pipeline) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// StepCreate provides a mock function with given fields: _a0 +func (_m *Store) StepCreate(_a0 []*model.Step) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func([]*model.Step) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// StepFind provides a mock function with given fields: _a0, _a1 +func (_m *Store) StepFind(_a0 *model.Pipeline, _a1 int) (*model.Step, error) { + ret := _m.Called(_a0, _a1) + + var r0 *model.Step + if rf, ok := ret.Get(0).(func(*model.Pipeline, int) *model.Step); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.Step) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*model.Pipeline, int) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StepList provides a mock function with given fields: _a0 +func (_m *Store) StepList(_a0 *model.Pipeline) ([]*model.Step, error) { + ret := _m.Called(_a0) + + var r0 []*model.Step + if rf, ok := ret.Get(0).(func(*model.Pipeline) []*model.Step); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Step) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*model.Pipeline) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StepLoad provides a mock function with given fields: _a0 +func (_m *Store) StepLoad(_a0 int64) (*model.Step, error) { + ret := _m.Called(_a0) + + var r0 *model.Step + if rf, ok := ret.Get(0).(func(int64) *model.Step); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.Step) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(int64) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StepUpdate provides a mock function with given fields: _a0 +func (_m *Store) StepUpdate(_a0 *model.Step) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*model.Step) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // TaskDelete provides a mock function with given fields: _a0 func (_m *Store) TaskDelete(_a0 string) error { ret := _m.Called(_a0) diff --git a/server/store/store.go b/server/store/store.go index 8d91a5a88..95144db5f 100644 --- a/server/store/store.go +++ b/server/store/store.go @@ -91,8 +91,8 @@ type Store interface { GetPipelineQueue() ([]*model.Feed, error) // GetPipelineCount gets a count of all pipelines in the system. GetPipelineCount() (int64, error) - // CreatePipeline creates a new pipeline and jobs. - CreatePipeline(*model.Pipeline, ...*model.Proc) error + // CreatePipeline creates a new pipeline and steps. + CreatePipeline(*model.Pipeline, ...*model.Step) error // UpdatePipeline updates a pipeline. UpdatePipeline(*model.Pipeline) error @@ -137,25 +137,25 @@ type Store interface { RegistryUpdate(*model.Registry) error RegistryDelete(repo *model.Repo, addr string) error - // Procs - ProcLoad(int64) (*model.Proc, error) - ProcFind(*model.Pipeline, int) (*model.Proc, error) - ProcChild(*model.Pipeline, int, string) (*model.Proc, error) - ProcList(*model.Pipeline) ([]*model.Proc, error) - ProcCreate([]*model.Proc) error - ProcUpdate(*model.Proc) error - ProcClear(*model.Pipeline) error + // Steps + StepLoad(int64) (*model.Step, error) + StepFind(*model.Pipeline, int) (*model.Step, error) + StepChild(*model.Pipeline, int, string) (*model.Step, error) + StepList(*model.Pipeline) ([]*model.Step, error) + StepCreate([]*model.Step) error + StepUpdate(*model.Step) error + StepClear(*model.Pipeline) error // Logs - LogFind(*model.Proc) (io.ReadCloser, error) + LogFind(*model.Step) (io.ReadCloser, error) // TODO: since we do ReadAll in any case a ioReader is not the best idear // so either find a way to write log in chunks by xorm ... - LogSave(*model.Proc, io.Reader) error + LogSave(*model.Step, io.Reader) error // Files FileList(*model.Pipeline) ([]*model.File, error) - FileFind(*model.Proc, string) (*model.File, error) - FileRead(*model.Proc, string) (io.ReadCloser, error) + FileFind(*model.Step, string) (*model.File, error) + FileRead(*model.Step, string) (io.ReadCloser, error) FileCreate(*model.File, io.Reader) error // Tasks diff --git a/web/components.d.ts b/web/components.d.ts index 83cc1dfd8..ca1170ced 100644 --- a/web/components.d.ts +++ b/web/components.d.ts @@ -76,10 +76,10 @@ declare module '@vue/runtime-core' { PipelineItem: typeof import('./src/components/repo/pipeline/PipelineItem.vue')['default'] PipelineList: typeof import('./src/components/repo/pipeline/PipelineList.vue')['default'] PipelineLog: typeof import('./src/components/repo/pipeline/PipelineLog.vue')['default'] - PipelineProcDuration: typeof import('./src/components/repo/pipeline/PipelineProcDuration.vue')['default'] - PipelineProcList: typeof import('./src/components/repo/pipeline/PipelineProcList.vue')['default'] PipelineRunningIcon: typeof import('./src/components/repo/pipeline/PipelineRunningIcon.vue')['default'] PipelineStatusIcon: typeof import('./src/components/repo/pipeline/PipelineStatusIcon.vue')['default'] + PipelineStepDuration: typeof import('./src/components/repo/pipeline/PipelineStepDuration.vue')['default'] + PipelineStepList: typeof import('./src/components/repo/pipeline/PipelineStepList.vue')['default'] Popup: typeof import('./src/components/layout/Popup.vue')['default'] RadioField: typeof import('./src/components/form/RadioField.vue')['default'] RegistriesTab: typeof import('./src/components/repo/settings/RegistriesTab.vue')['default'] diff --git a/web/src/components/repo/pipeline/PipelineLog.vue b/web/src/components/repo/pipeline/PipelineLog.vue index 66877d464..1b8b3ff9a 100644 --- a/web/src/components/repo/pipeline/PipelineLog.vue +++ b/web/src/components/repo/pipeline/PipelineLog.vue @@ -2,9 +2,9 @@
- {{ proc?.name }} + {{ step?.name }}
@@ -15,14 +15,14 @@ >
@@ -78,7 +78,7 @@ import Icon from '~/components/atomic/Icon.vue'; import useApiClient from '~/compositions/useApiClient'; import useNotifications from '~/compositions/useNotifications'; import { Pipeline, Repo } from '~/lib/api/types'; -import { findProc, isProcFinished, isProcRunning } from '~/utils/helpers'; +import { findStep, isStepFinished, isStepRunning } from '~/utils/helpers'; type LogLine = { index: number; @@ -97,7 +97,7 @@ export default defineComponent({ required: true, }, - procId: { + stepId: { type: Number, required: true, }, @@ -105,22 +105,22 @@ export default defineComponent({ emits: { // eslint-disable-next-line @typescript-eslint/no-unused-vars - 'update:proc-id': (procId: number | null) => true, + 'update:step-id': (stepId: number | null) => true, }, setup(props) { const notifications = useNotifications(); const i18n = useI18n(); const pipeline = toRef(props, 'pipeline'); - const procId = toRef(props, 'procId'); + const stepId = toRef(props, 'stepId'); const repo = inject>('repo'); const apiClient = useApiClient(); - const loadedProcSlug = ref(); - const procSlug = computed( - () => `${repo?.value.owner} - ${repo?.value.name} - ${pipeline.value.id} - ${procId.value}`, + const loadedStepSlug = ref(); + const stepSlug = computed( + () => `${repo?.value.owner} - ${repo?.value.name} - ${pipeline.value.id} - ${stepId.value}`, ); - const proc = computed(() => pipeline.value && findProc(pipeline.value.procs || [], procId.value)); + const step = computed(() => pipeline.value && findStep(pipeline.value.steps || [], stepId.value)); const stream = ref(); const log = ref(); const consoleElement = ref(); @@ -128,8 +128,8 @@ export default defineComponent({ const loadedLogs = computed(() => !!log.value); const hasLogs = computed( () => - // we do not have logs for skipped jobs - repo?.value && pipeline.value && proc.value && proc.value.state !== 'skipped' && proc.value.state !== 'killed', + // we do not have logs for skipped steps + repo?.value && pipeline.value && step.value && step.value.state !== 'skipped' && step.value.state !== 'killed', ); const autoScroll = useStorage('log-auto-scroll', false); const showActions = ref(false); @@ -200,13 +200,13 @@ export default defineComponent({ }, 500); async function download() { - if (!repo?.value || !pipeline.value || !proc.value) { - throw new Error('The repository, pipeline or proc was undefined'); + if (!repo?.value || !pipeline.value || !step.value) { + throw new Error('The repository, pipeline or step was undefined'); } let logs; try { downloadInProgress.value = true; - logs = await apiClient.getLogs(repo.value.owner, repo.value.name, pipeline.value.number, proc.value.pid); + logs = await apiClient.getLogs(repo.value.owner, repo.value.name, pipeline.value.number, step.value.pid); } catch (e) { notifications.notifyError(e, i18n.t('repo.pipeline.log_download_error')); return; @@ -223,7 +223,7 @@ export default defineComponent({ fileLink.href = fileURL; fileLink.setAttribute( 'download', - `${repo.value.owner}-${repo.value.name}-${pipeline.value.number}-${proc.value.name}.log`, + `${repo.value.owner}-${repo.value.name}-${pipeline.value.number}-${step.value.name}.log`, ); document.body.appendChild(fileLink); @@ -233,10 +233,10 @@ export default defineComponent({ } async function loadLogs() { - if (loadedProcSlug.value === procSlug.value) { + if (loadedStepSlug.value === stepSlug.value) { return; } - loadedProcSlug.value = procSlug.value; + loadedStepSlug.value = stepSlug.value; log.value = undefined; logBuffer.value = []; ansiUp.value = new AnsiUp(); @@ -250,26 +250,26 @@ export default defineComponent({ stream.value.close(); } - if (!hasLogs.value || !proc.value) { + if (!hasLogs.value || !step.value) { return; } - if (isProcFinished(proc.value)) { - const logs = await apiClient.getLogs(repo.value.owner, repo.value.name, pipeline.value.number, proc.value.pid); + if (isStepFinished(step.value)) { + const logs = await apiClient.getLogs(repo.value.owner, repo.value.name, pipeline.value.number, step.value.pid); logs?.forEach((line) => writeLog({ index: line.pos, text: line.out, time: line.time })); flushLogs(false); } - if (isProcRunning(proc.value)) { + if (isStepRunning(step.value)) { // load stream of parent process (which receives all child processes logs) // TODO: change stream to only send data of single child process stream.value = apiClient.streamLogs( repo.value.owner, repo.value.name, pipeline.value.number, - proc.value.ppid, + step.value.ppid, (line) => { - if (line?.proc !== proc.value?.name) { + if (line?.step !== step.value?.name) { return; } writeLog({ index: line.pos, text: line.out, time: line.time }); @@ -283,12 +283,12 @@ export default defineComponent({ loadLogs(); }); - watch(procSlug, () => { + watch(stepSlug, () => { loadLogs(); }); - watch(proc, (oldProc, newProc) => { - if (oldProc && oldProc.name === newProc?.name && oldProc?.end_time !== newProc?.end_time) { + watch(step, (oldStep, newStep) => { + if (oldStep && oldStep.name === newStep?.name && oldStep?.end_time !== newStep?.end_time) { if (autoScroll.value) { scrollDown(); } @@ -297,7 +297,7 @@ export default defineComponent({ return { consoleElement, - proc, + step, log, loadedLogs, hasLogs, diff --git a/web/src/components/repo/pipeline/PipelineProcDuration.vue b/web/src/components/repo/pipeline/PipelineStepDuration.vue similarity index 69% rename from web/src/components/repo/pipeline/PipelineProcDuration.vue rename to web/src/components/repo/pipeline/PipelineStepDuration.vue index 06070c021..5d336eed9 100644 --- a/web/src/components/repo/pipeline/PipelineProcDuration.vue +++ b/web/src/components/repo/pipeline/PipelineStepDuration.vue @@ -1,30 +1,30 @@ diff --git a/web/src/compositions/useEvents.ts b/web/src/compositions/useEvents.ts index 63a297d61..3c0c99d7b 100644 --- a/web/src/compositions/useEvents.ts +++ b/web/src/compositions/useEvents.ts @@ -32,11 +32,11 @@ export default () => { pipelineStore.setPipeline(repo.owner, repo.name, pipeline); pipelineStore.setPipelineFeedItem({ ...pipeline, name: repo.name, owner: repo.owner, full_name: repoSlug(repo) }); - // contains proc update - if (!data.proc) { + // contains step update + if (!data.step) { return; } - const { proc } = data; - pipelineStore.setProc(repo.owner, repo.name, pipeline.number, proc); + const { step } = data; + pipelineStore.setStep(repo.owner, repo.name, pipeline.number, step); }); }; diff --git a/web/src/lib/api/index.ts b/web/src/lib/api/index.ts index 16ac6bac0..036446f3e 100644 --- a/web/src/lib/api/index.ts +++ b/web/src/lib/api/index.ts @@ -5,7 +5,7 @@ import { PipelineConfig, PipelineFeed, PipelineLog, - PipelineProc, + PipelineStep, Registry, Repo, RepoPermissions, @@ -102,12 +102,12 @@ export default class WoodpeckerClient extends ApiClient { return this._post(`/api/repos/${owner}/${repo}/pipelines/${pipeline}?${query}`); } - getLogs(owner: string, repo: string, pipeline: number, proc: number): Promise { - return this._get(`/api/repos/${owner}/${repo}/logs/${pipeline}/${proc}`) as Promise; + getLogs(owner: string, repo: string, pipeline: number, step: number): Promise { + return this._get(`/api/repos/${owner}/${repo}/logs/${pipeline}/${step}`) as Promise; } - getArtifact(owner: string, repo: string, pipeline: string, proc: string, file: string): Promise { - return this._get(`/api/repos/${owner}/${repo}/files/${pipeline}/${proc}/${file}?raw=true`); + getArtifact(owner: string, repo: string, pipeline: string, step: string, file: string): Promise { + return this._get(`/api/repos/${owner}/${repo}/files/${pipeline}/${step}/${file}?raw=true`); } getArtifactList(owner: string, repo: string, pipeline: string): Promise { @@ -211,7 +211,7 @@ export default class WoodpeckerClient extends ApiClient { } // eslint-disable-next-line promise/prefer-await-to-callbacks - on(callback: (data: { pipeline?: Pipeline; repo?: Repo; proc?: PipelineProc }) => void): EventSource { + on(callback: (data: { pipeline?: Pipeline; repo?: Repo; step?: PipelineStep }) => void): EventSource { return this._subscribe('/stream/events', callback, { reconnect: true, }); @@ -221,11 +221,11 @@ export default class WoodpeckerClient extends ApiClient { owner: string, repo: string, pipeline: number, - proc: number, + step: number, // eslint-disable-next-line promise/prefer-await-to-callbacks callback: (data: PipelineLog) => void, ): EventSource { - return this._subscribe(`/stream/logs/${owner}/${repo}/${pipeline}/${proc}`, callback, { + return this._subscribe(`/stream/logs/${owner}/${repo}/${pipeline}/${step}`, callback, { reconnect: true, }); } diff --git a/web/src/lib/api/types/pipeline.ts b/web/src/lib/api/types/pipeline.ts index 1163abb1a..3ba82f3ba 100644 --- a/web/src/lib/api/types/pipeline.ts +++ b/web/src/lib/api/types/pipeline.ts @@ -79,9 +79,9 @@ export type Pipeline = { reviewed_at: number; - // The jobs associated with this pipeline. - // A pipeline will have multiple jobs if a matrix pipeline was used or if a rebuild was requested. - procs?: PipelineProc[]; + // The steps associated with this pipeline. + // A pipeline will have multiple steps if a matrix pipeline was used or if a rebuild was requested. + steps?: PipelineStep[]; changed_files?: string[]; }; @@ -98,7 +98,7 @@ export type PipelineStatus = | 'started' | 'success'; -export type PipelineProc = { +export type PipelineStep = { id: number; pipeline_id: number; pid: number; @@ -112,11 +112,11 @@ export type PipelineProc = { end_time?: number; machine?: string; error?: string; - children?: PipelineProc[]; + children?: PipelineStep[]; }; export type PipelineLog = { - proc: string; + step: string; pos: number; out: string; time?: number; diff --git a/web/src/router.ts b/web/src/router.ts index fcdb05e6a..7afa4e36e 100644 --- a/web/src/router.ts +++ b/web/src/router.ts @@ -79,7 +79,7 @@ const routes: RouteRecordRaw[] = [ props: true, children: [ { - path: ':procId?', + path: ':stepId?', name: 'repo-pipeline', component: (): Component => import('~/views/repo/pipeline/Pipeline.vue'), props: true, diff --git a/web/src/store/pipelines.ts b/web/src/store/pipelines.ts index bf90fea71..ff59726d7 100644 --- a/web/src/store/pipelines.ts +++ b/web/src/store/pipelines.ts @@ -2,7 +2,7 @@ import { defineStore } from 'pinia'; import { computed, Ref, ref, toRef } from 'vue'; import useApiClient from '~/compositions/useApiClient'; -import { Pipeline, PipelineFeed, PipelineProc } from '~/lib/api/types'; +import { Pipeline, PipelineFeed, PipelineStep } from '~/lib/api/types'; import { comparePipelines, isPipelineActive, repoSlug } from '~/utils/helpers'; const apiClient = useApiClient(); @@ -43,17 +43,17 @@ export default defineStore({ [_repoSlug]: repoPipelines, }; }, - setProc(owner: string, repo: string, pipelineNumber: number, proc: PipelineProc) { + setStep(owner: string, repo: string, pipelineNumber: number, step: PipelineStep) { const pipeline = this.getPipeline(ref(owner), ref(repo), ref(pipelineNumber.toString())).value; if (!pipeline) { throw new Error("Can't find pipeline"); } - if (!pipeline.procs) { - pipeline.procs = []; + if (!pipeline.steps) { + pipeline.steps = []; } - pipeline.procs = [...pipeline.procs.filter((p) => p.pid !== proc.pid), proc]; + pipeline.steps = [...pipeline.steps.filter((p) => p.pid !== step.pid), step]; this.setPipeline(owner, repo, pipeline); }, setPipelineFeedItem(pipeline: PipelineFeed) { diff --git a/web/src/utils/helpers.ts b/web/src/utils/helpers.ts index 1c40141aa..25816f2bf 100644 --- a/web/src/utils/helpers.ts +++ b/web/src/utils/helpers.ts @@ -1,40 +1,40 @@ -import { Pipeline, PipelineProc, Repo } from '~/lib/api/types'; +import { Pipeline, PipelineStep, Repo } from '~/lib/api/types'; -export function findProc(procs: PipelineProc[], pid: number): PipelineProc | undefined { - return procs.reduce((prev, proc) => { - if (proc.pid === pid) { - return proc; +export function findStep(steps: PipelineStep[], pid: number): PipelineStep | undefined { + return steps.reduce((prev, step) => { + if (step.pid === pid) { + return step; } - if (proc.children) { - const result = findProc(proc.children, pid); + if (step.children) { + const result = findStep(step.children, pid); if (result) { return result; } } return prev; - }, undefined as PipelineProc | undefined); + }, undefined as PipelineStep | undefined); } /** * Returns true if the process is in a completed state. * - * @param {Object} proc - The process object. + * @param {Object} step - The process object. * @returns {boolean} */ -export function isProcFinished(proc: PipelineProc): boolean { - return proc.state !== 'running' && proc.state !== 'pending'; +export function isStepFinished(step: PipelineStep): boolean { + return step.state !== 'running' && step.state !== 'pending'; } /** * Returns true if the process is running. * - * @param {Object} proc - The process object. + * @param {Object} step - The process object. * @returns {boolean} */ -export function isProcRunning(proc: PipelineProc): boolean { - return proc.state === 'running'; +export function isStepRunning(step: PipelineStep): boolean { + return step.state === 'running'; } /** diff --git a/web/src/views/repo/pipeline/Pipeline.vue b/web/src/views/repo/pipeline/Pipeline.vue index 956aca087..7ad2aa166 100644 --- a/web/src/views/repo/pipeline/Pipeline.vue +++ b/web/src/views/repo/pipeline/Pipeline.vue @@ -1,8 +1,8 @@