From e90caed9c4a4c453e0a335d23e68d5b8b07c2578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20BARRAS=20HAMPEL?= Date: Thu, 12 Feb 2026 12:25:25 +0100 Subject: [PATCH 1/2] fix(pipelines): fix pipeline status and include child pipeline jobs --- .gitignore | 1 + features/pipeline/out.go | 81 +++++++++++++++++++++++++++----------- features/pipeline/utils.go | 2 - 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 7d606eb..8a578b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .direnv/ ./build +test.json diff --git a/features/pipeline/out.go b/features/pipeline/out.go index e55de47..8921b71 100644 --- a/features/pipeline/out.go +++ b/features/pipeline/out.go @@ -3,10 +3,12 @@ package pipeline import ( "fmt" "path" + "slices" "strconv" "github.com/cycloidio/gitlab-resource/internal" "github.com/cycloidio/gitlab-resource/models" + "github.com/sanity-io/litter" gitlab "gitlab.com/gitlab-org/api/client-go" ) @@ -61,44 +63,73 @@ func (h *Handler) Out(outDir string) error { return fmt.Errorf("failed to trigger pipeline with ref %q: %w", *h.cfg.Params.Ref, err) } } else { - return fmt.Errorf("Either params.pipeline.merge_request_iid or params.pipeline.ref is required to trigger a pipeline") + return fmt.Errorf("either params.pipeline.merge_request_iid or params.pipeline.ref is required to trigger a pipeline") } - h.logger.Info("Created pipeline succeeded", "id", pipeline.ID, "url", pipeline.WebURL) + h.logger.Info("create pipeline succeeded", "id", pipeline.ID, "url", pipeline.WebURL) - for { - jobsPending, _, err := h.glab.Jobs.ListPipelineJobs(h.cfg.Source.ProjectID, pipeline.ID, &gitlab.ListJobsOptions{ - Scope: &[]gitlab.BuildStateValue{ - gitlab.Running, - gitlab.Pending, - gitlab.Preparing, - gitlab.Created, - }, - }) + pipelineStatus := pipeline.Status + for !slices.Contains([]string{"success", "failed", "canceled", "skipped", "manual"}, pipelineStatus) { + // watch and refresh pipeline status + pipeline, _, err := h.glab.Pipelines.GetPipeline(h.cfg.Source.ProjectID, pipeline.ID) if err != nil { - return fmt.Errorf("failed to list jobs from pipeline %q: %w", strconv.Itoa(pipeline.ID), err) + return fmt.Errorf("failed to get pipeline status for %q: %w", strconv.Itoa(pipeline.ID), err) } + pipelineStatus = pipeline.Status + h.logger.Debug("pipeline", "status", pipelineStatus) - jobsRunning, _, err := h.glab.Jobs.ListPipelineJobs(h.cfg.Source.ProjectID, pipeline.ID, &gitlab.ListJobsOptions{ - Scope: &[]gitlab.BuildStateValue{ - gitlab.Running, - }, - }) + // list the pending jobs of the current pipeline + jobsPending, _, err := h.glab.Jobs.ListPipelineJobs(h.cfg.Source.ProjectID, pipeline.ID, + nil, + // &gitlab.ListJobsOptions{ + // ListOptions: gitlab.ListOptions{}, + // Scope: &[]gitlab.BuildStateValue{ + // gitlab.Running, + // gitlab.Pending, + // gitlab.Preparing, + // gitlab.Created, + // }, + // }, + ) if err != nil { return fmt.Errorf("failed to list jobs from pipeline %q: %w", strconv.Itoa(pipeline.ID), err) } + // List jobs that trigger child pipelines + jobsTriggerBridges, _, err := h.glab.Jobs.ListPipelineBridges(h.cfg.Source.ProjectID, pipeline.ID, &gitlab.ListJobsOptions{}) + if err != nil { + return fmt.Errorf("failed to list trigger jobs from pipeline %q: %w", strconv.Itoa(pipeline.ID), err) + } + + for _, bridge := range jobsTriggerBridges { + litter.D(bridge) + if bridge.DownstreamPipeline == nil { + h.logger.Debug("trigger job not started yet", "status", bridge.Status, "downstream pipeline", bridge.DownstreamPipeline) + continue + } + + childJobs, _, err := h.glab.Jobs.ListPipelineJobs(bridge.DownstreamPipeline.ProjectID, bridge.DownstreamPipeline.ID, &gitlab.ListJobsOptions{}) + if err != nil { + return fmt.Errorf("failed to list jobs from child pipeline: %w", err) + } + litter.D(childJobs) + + jobsPending = append(jobsPending, childJobs...) + } + + var jobsRunning = []*gitlab.Job{} + for _, job := range jobsPending { + if job.Status == "running" { + jobsRunning = append(jobsRunning, job) + } + } + jobNames := make([]string, len(jobsPending)) for i, job := range jobsPending { jobNames[i] = job.Name } h.logger.Debug("Jobs pending", "jobs", jobNames) - if len(jobsPending) == 0 { - h.logger.Debug("jobs are done", "jobs", jobsPending) - break - } - for _, job := range jobsRunning { err := h.traceJob(job) if err != nil { @@ -107,6 +138,12 @@ func (h *Handler) Out(outDir string) error { } } + // refresh the status + pipeline, _, err = h.glab.Pipelines.GetPipeline(h.cfg.Source.ProjectID, pipeline.ID) + if err != nil { + return fmt.Errorf("failed to get pipeline status for %q: %w", strconv.Itoa(pipeline.ID), err) + } + output := &models.Output{ Version: PipelinetoVersion(pipeline), Metadata: PipelinetoMetadatas(pipeline), diff --git a/features/pipeline/utils.go b/features/pipeline/utils.go index e12758e..63b1438 100644 --- a/features/pipeline/utils.go +++ b/features/pipeline/utils.go @@ -16,7 +16,6 @@ func PipelinetoVersion(pipeline *gitlab.Pipeline) map[string]string { version["ref"] = pipeline.Ref version["status"] = pipeline.Status version["web_url"] = pipeline.WebURL - version["before_sha"] = pipeline.BeforeSHA version["tag"] = strconv.FormatBool(pipeline.Tag) if pipeline.CreatedAt != nil { version["created_at"] = pipeline.CreatedAt.String() @@ -39,7 +38,6 @@ func PipelinetoMetadatas(pipeline *gitlab.Pipeline) models.Metadatas { {Name: "ref", Value: pipeline.Ref}, {Name: "status", Value: pipeline.Status}, {Name: "web_url", Value: pipeline.WebURL}, - {Name: "before_sha", Value: pipeline.BeforeSHA}, {Name: "tag", Value: strconv.FormatBool(pipeline.Tag)}, } if pipeline.CreatedAt != nil { From 45bd4d8feabc0010bd3a76153847090a128a4d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20BARRAS=20HAMPEL?= Date: Fri, 13 Feb 2026 10:14:50 +0100 Subject: [PATCH 2/2] fix: & in output --- features/pipeline/out.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/features/pipeline/out.go b/features/pipeline/out.go index 8921b71..c646f80 100644 --- a/features/pipeline/out.go +++ b/features/pipeline/out.go @@ -8,7 +8,6 @@ import ( "github.com/cycloidio/gitlab-resource/internal" "github.com/cycloidio/gitlab-resource/models" - "github.com/sanity-io/litter" gitlab "gitlab.com/gitlab-org/api/client-go" ) @@ -39,7 +38,6 @@ func (h *Handler) Out(outDir string) error { var pipeline *gitlab.Pipeline var err error if h.cfg.Params.MergeRequestIID != nil { - h.logger.Debug("trigger mr pipeline", "id", h.cfg.Params.MergeRequestIID, "project", h.cfg.Source.ProjectID) ppInfo, _, err := h.glab.MergeRequests.CreateMergeRequestPipeline( h.cfg.Source.ProjectID, *h.cfg.Params.MergeRequestIID, ) @@ -76,20 +74,10 @@ func (h *Handler) Out(outDir string) error { return fmt.Errorf("failed to get pipeline status for %q: %w", strconv.Itoa(pipeline.ID), err) } pipelineStatus = pipeline.Status - h.logger.Debug("pipeline", "status", pipelineStatus) // list the pending jobs of the current pipeline jobsPending, _, err := h.glab.Jobs.ListPipelineJobs(h.cfg.Source.ProjectID, pipeline.ID, nil, - // &gitlab.ListJobsOptions{ - // ListOptions: gitlab.ListOptions{}, - // Scope: &[]gitlab.BuildStateValue{ - // gitlab.Running, - // gitlab.Pending, - // gitlab.Preparing, - // gitlab.Created, - // }, - // }, ) if err != nil { return fmt.Errorf("failed to list jobs from pipeline %q: %w", strconv.Itoa(pipeline.ID), err) @@ -102,7 +90,6 @@ func (h *Handler) Out(outDir string) error { } for _, bridge := range jobsTriggerBridges { - litter.D(bridge) if bridge.DownstreamPipeline == nil { h.logger.Debug("trigger job not started yet", "status", bridge.Status, "downstream pipeline", bridge.DownstreamPipeline) continue @@ -112,7 +99,6 @@ func (h *Handler) Out(outDir string) error { if err != nil { return fmt.Errorf("failed to list jobs from child pipeline: %w", err) } - litter.D(childJobs) jobsPending = append(jobsPending, childJobs...) }