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

     1  package ado
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/microsoft/azure-devops-go-api/azuredevops"
     8  	"github.com/microsoft/azure-devops-go-api/azuredevops/build"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  const azureUrl = "https://dev.azure.com"
    13  
    14  type BuildClient interface {
    15  	UpdateVariables(variables []Variable) error
    16  }
    17  
    18  type BuildClientImpl struct {
    19  	ctx         context.Context
    20  	buildClient build.Client
    21  	project     string
    22  	pipelineID  int
    23  }
    24  
    25  type Variable struct {
    26  	Name          string
    27  	Value         string
    28  	IsSecret      bool
    29  	AllowOverride bool
    30  }
    31  
    32  // UpdateVariables updates variables in build definition or creates them if they are missing
    33  func (bc *BuildClientImpl) UpdateVariables(variables []Variable) error {
    34  	if len(variables) == 0 {
    35  		return errors.New("error: slice variables must not be empty")
    36  	}
    37  	getDefinitionArgs := build.GetDefinitionArgs{
    38  		Project:      &bc.project,
    39  		DefinitionId: &bc.pipelineID,
    40  	}
    41  
    42  	// Get a build definition
    43  	buildDefinition, err := bc.buildClient.GetDefinition(bc.ctx, getDefinitionArgs)
    44  	if err != nil {
    45  		return errors.Wrapf(err, "error: get definition failed")
    46  	}
    47  
    48  	buildDefinitionVars := map[string]build.BuildDefinitionVariable{}
    49  	if buildDefinition.Variables != nil {
    50  		buildDefinitionVars = *buildDefinition.Variables
    51  	}
    52  
    53  	for _, variable := range variables {
    54  		buildDefinitionVars[variable.Name] = build.BuildDefinitionVariable{
    55  			Value:         &variable.Value,
    56  			IsSecret:      &variable.IsSecret,
    57  			AllowOverride: &variable.AllowOverride,
    58  		}
    59  	}
    60  
    61  	buildDefinition.Variables = &buildDefinitionVars
    62  
    63  	updateDefinitionArgs := build.UpdateDefinitionArgs{
    64  		Definition:   buildDefinition,
    65  		Project:      &bc.project,
    66  		DefinitionId: &bc.pipelineID,
    67  	}
    68  
    69  	_, err = bc.buildClient.UpdateDefinition(bc.ctx, updateDefinitionArgs)
    70  	if err != nil {
    71  		return errors.Wrapf(err, "error: update definition failed")
    72  	}
    73  
    74  	return nil
    75  }
    76  
    77  // NewBuildClient Create a client to interact with the Build area
    78  func NewBuildClient(organization string, personalAccessToken string, project string, pipelineID int) (BuildClient, error) {
    79  	if organization == "" {
    80  		return nil, errors.New("error: organization must not be empty")
    81  	}
    82  	if personalAccessToken == "" {
    83  		return nil, errors.New("error: personal access token must not be empty")
    84  	}
    85  	if project == "" {
    86  		return nil, errors.New("error: project must not be empty")
    87  	}
    88  
    89  	organizationUrl := fmt.Sprintf("%s/%s", azureUrl, organization)
    90  	// Create a connection to your organization
    91  	connection := azuredevops.NewPatConnection(organizationUrl, personalAccessToken)
    92  
    93  	ctx := context.Background()
    94  
    95  	// Create a client to interact with the Core area
    96  	buildClient, err := build.NewClient(ctx, connection)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	buildClientImpl := &BuildClientImpl{
   102  		ctx:         ctx,
   103  		buildClient: buildClient,
   104  		project:     project,
   105  		pipelineID:  pipelineID,
   106  	}
   107  
   108  	return buildClientImpl, nil
   109  }