github.com/profzone/eden-framework@v1.0.10/internal/project/gitlab_ci.go (about)

     1  package project
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  
     8  	"gopkg.in/yaml.v2"
     9  )
    10  
    11  type CICache struct {
    12  	UnTracked bool     `yaml:"untracked,omitempty"`
    13  	Key       string   `yaml:"key,omitempty"`
    14  	Paths     []string `yaml:"paths,omitempty"`
    15  }
    16  
    17  type CIEnv struct {
    18  	Name string `yaml:"name"`
    19  }
    20  
    21  type CIArtifact struct {
    22  	UnTracked bool     `yaml:"untracked,omitempty"`
    23  	When      string   `yaml:"when,omitempty"`
    24  	Name      string   `yaml:"name,omitempty"`
    25  	Paths     []string `yaml:"paths,omitempty"`
    26  	ExpireIn  string   `yaml:"expire_in,omitempty"`
    27  }
    28  
    29  func NewCIJob(stage string) *CIJob {
    30  	return &CIJob{
    31  		Stage: stage,
    32  	}
    33  }
    34  
    35  type CIJob struct {
    36  	Stage string `yaml:"stage,omitempty"`
    37  
    38  	Image        string   `yaml:"image,omitempty"`
    39  	Tags         []string `yaml:"tags,omitempty"`
    40  	Services     []string `yaml:"services,omitempty"`
    41  	Dependencies []string `yaml:"dependencies,omitempty"`
    42  
    43  	Variables map[string]string `yaml:"variables,omitempty"`
    44  
    45  	Environment CIEnv `yaml:"environment,omitempty"`
    46  
    47  	BeforeScript []string `yaml:"before_script,omitempty"`
    48  	AfterScript  []string `yaml:"after_script,omitempty"`
    49  	Script       []string `yaml:"script,omitempty"`
    50  
    51  	AllowFailure bool `yaml:"allow_failure,omitempty"`
    52  
    53  	Artifacts *CIArtifact `yaml:"artifacts,omitempty"`
    54  
    55  	Only     []string `yaml:"only,omitempty"`
    56  	Except   []string `yaml:"except,omitempty"`
    57  	When     string   `yaml:"when,omitempty"`
    58  	Coverage string   `yaml:"coverage,omitempty"`
    59  }
    60  
    61  func (c CIJob) WithTags(tags ...string) *CIJob {
    62  	c.Tags = append(c.Tags, tags...)
    63  	return &c
    64  }
    65  
    66  func (c CIJob) WithDependencies(dependencies ...string) *CIJob {
    67  	c.Dependencies = dependencies
    68  	return &c
    69  }
    70  
    71  func (c CIJob) WithScript(script ...string) *CIJob {
    72  	c.Script = append(c.Script, script...)
    73  	return &c
    74  }
    75  
    76  func (c CIJob) WithEnv(name string) *CIJob {
    77  	c.Environment = CIEnv{
    78  		Name: name,
    79  	}
    80  	return &c
    81  }
    82  
    83  func (c CIJob) AllowFail() *CIJob {
    84  	c.AllowFailure = true
    85  	return &c
    86  }
    87  
    88  func (c CIJob) WithArtifacts(artifact *CIArtifact) *CIJob {
    89  	c.Artifacts = artifact
    90  	return &c
    91  }
    92  
    93  func (c CIJob) WithOnly(only ...string) *CIJob {
    94  	c.Only = only
    95  	return &c
    96  }
    97  
    98  func (c CIJob) WithExcept(except ...string) *CIJob {
    99  	c.Except = except
   100  	return &c
   101  }
   102  
   103  func (c CIJob) WithWhen(when string) *CIJob {
   104  	c.When = when
   105  	return &c
   106  }
   107  
   108  func (c CIJob) WithImage(image string) *CIJob {
   109  	c.Image = image
   110  	return &c
   111  }
   112  
   113  func (c CIJob) WithVariable(key string, value string) CIJob {
   114  	if c.Variables == nil {
   115  		c.Variables = map[string]string{}
   116  	}
   117  	c.Variables[key] = value
   118  	return c
   119  }
   120  
   121  type CIJobMap map[string]*CIJob
   122  
   123  func NewCIConfig() *CIConfig {
   124  	return &CIConfig{}
   125  }
   126  
   127  type CIConfig struct {
   128  	Stages    []string `yaml:"stages"`
   129  	Cache     CICache  `yaml:"cache,omitempty"`
   130  	CommonJob CIJob    `yaml:"common_job,inline,omitempty"`
   131  	CIJobMap  `yaml:"jobs,inline"`
   132  }
   133  
   134  func (c *CIConfig) hasStage(stage string) bool {
   135  	for _, s := range c.Stages {
   136  		if s == stage {
   137  			return true
   138  		}
   139  	}
   140  	return false
   141  }
   142  
   143  func prefixJobName(name string) string {
   144  	return "job_" + name
   145  }
   146  
   147  func (c CIConfig) WithStages(stages ...string) *CIConfig {
   148  	c.Stages = append(c.Stages, stages...)
   149  	return &c
   150  }
   151  
   152  func (c CIConfig) WithCache(cache CICache) *CIConfig {
   153  	c.Cache = cache
   154  	return &c
   155  }
   156  
   157  func (c CIConfig) WithCommon(job *CIJob) *CIConfig {
   158  	c.CommonJob = CIJob{
   159  		Image:        job.Image,
   160  		Services:     job.Services,
   161  		Variables:    job.Variables,
   162  		BeforeScript: job.BeforeScript,
   163  		AfterScript:  job.AfterScript,
   164  	}
   165  	return &c
   166  }
   167  
   168  func (c CIConfig) AddJob(name string, job *CIJob) *CIConfig {
   169  	if !c.hasStage(job.Stage) {
   170  		panic(fmt.Errorf("missing stage %s", job.Stage))
   171  	}
   172  
   173  	if c.CIJobMap == nil {
   174  		c.CIJobMap = map[string]*CIJob{}
   175  	}
   176  
   177  	c.CIJobMap[prefixJobName(name)] = job
   178  
   179  	return &c
   180  }
   181  
   182  func (c CIConfig) AddJobWithDependencies(name string, job *CIJob, dependencies ...string) *CIConfig {
   183  	finalDependencies := []string{}
   184  	for _, d := range dependencies {
   185  		prefixedName := prefixJobName(d)
   186  		if _, ok := c.CIJobMap[prefixedName]; !ok {
   187  			panic(fmt.Errorf("job %s should defined first", d))
   188  		}
   189  		finalDependencies = append(finalDependencies, prefixedName)
   190  	}
   191  	return c.AddJob(name, job.WithDependencies(finalDependencies...))
   192  }
   193  
   194  func (c *CIConfig) WriteToFile() {
   195  	bytes, err := yaml.Marshal(c)
   196  	if err != nil {
   197  		panic(err)
   198  	}
   199  	ioutil.WriteFile(".gitlab-ci.yml", bytes, os.ModePerm)
   200  }