github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/jenkins/build.go (about)

     1  package jenkins
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"time"
     8  
     9  	"github.com/bndr/gojenkins"
    10  )
    11  
    12  // Build is an interface to abstract gojenkins.Build.
    13  // mock generated with: mockery --name Build --dir pkg/jenkins --output pkg/jenkins/mocks
    14  type Build interface {
    15  	GetArtifacts() []gojenkins.Artifact
    16  	IsRunning(ctx context.Context) bool
    17  	Poll(ctx context.Context, options ...interface{}) (int, error)
    18  }
    19  
    20  // WaitForBuildToFinish waits till a build is finished.
    21  func WaitForBuildToFinish(ctx context.Context, build Build, pollInterval time.Duration) error {
    22  	//TODO: handle timeout?
    23  	maxRetries := 4
    24  
    25  	for build.IsRunning(ctx) {
    26  		time.Sleep(pollInterval)
    27  		//TODO: add 404/503 response code handling
    28  		_, err := build.Poll(ctx)
    29  
    30  		if err == nil {
    31  			continue
    32  		}
    33  
    34  		fmt.Printf("Error occurred while waiting for build to finish: %v. Retrying...\n", err)
    35  
    36  		for i := 0; i < maxRetries; i++ {
    37  			time.Sleep(pollInterval)
    38  			_, err = build.Poll(ctx)
    39  
    40  			if err == nil {
    41  				break
    42  			}
    43  
    44  			fmt.Printf("Error occurred while waiting for build to finish: %v. Retrying...\n", err)
    45  		}
    46  
    47  		if err != nil {
    48  			return fmt.Errorf("Max retries (%v) exceeded while waiting for build to finish. Last error: %w", maxRetries, err)
    49  		}
    50  	}
    51  
    52  	return nil
    53  }
    54  
    55  // FetchBuildArtifact is fetching a build artifact from a finished build with a certain name.
    56  // Fails if build is running or no artifact is with the given name is found.
    57  func FetchBuildArtifact(ctx context.Context, build Build, fileName string) (Artifact, error) {
    58  	if build.IsRunning(ctx) {
    59  		return &ArtifactImpl{}, errors.New("failed to fetch artifact: Job is still running")
    60  	}
    61  	for _, artifact := range build.GetArtifacts() {
    62  		if artifact.FileName == fileName {
    63  			return &ArtifactImpl{artifact: artifact}, nil
    64  		}
    65  	}
    66  	return &ArtifactImpl{}, fmt.Errorf("failed to fetch artifact: Artifact '%s' not found", fileName)
    67  }