forked from evergreen-ci/evergreen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
project_triggers.go
156 lines (144 loc) · 5.3 KB
/
project_triggers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package trigger
import (
"context"
"github.com/evergreen-ci/evergreen"
"github.com/evergreen-ci/evergreen/model"
"github.com/evergreen-ci/evergreen/model/user"
"github.com/evergreen-ci/evergreen/repotracker"
"github.com/pkg/errors"
)
// TriggerDownstreamVersion assumes that you definitely want to create a downstream version
// and will go through the process of version creation given a triggering version.
// If the trigger is a push event, the triggering version will be nonexistent.
func TriggerDownstreamVersion(ctx context.Context, args ProcessorArgs) (*model.Version, error) {
if args.SourceVersion == nil && args.TriggerType != model.ProjectTriggerLevelPush {
return nil, errors.Errorf("unable to find source version in downstream project '%s'", args.DownstreamProject.Id)
}
// propagate version metadata to the downstream version
metadata, err := getMetadataFromArgs(args)
if err != nil {
return nil, err
}
// get the downstream config
projectInfo := model.ProjectInfo{}
if args.ConfigFile != "" {
projectInfo, err = makeDownstreamProjectFromFile(ctx, args.DownstreamProject, args.ConfigFile)
if err != nil {
return nil, errors.WithStack(err)
}
} else {
return nil, errors.New("must specify a file to define downstream project config")
}
// create version
projectInfo.Ref = &args.DownstreamProject
v, err := repotracker.CreateVersionFromConfig(context.Background(), &projectInfo, metadata, false, nil)
if err != nil {
return nil, errors.Wrap(err, "creating version")
}
if args.SourceVersion != nil {
if err = args.SourceVersion.AddSatisfiedTrigger(args.DefinitionID); err != nil {
return nil, err
}
}
settings, err := evergreen.GetConfig(ctx)
if err != nil {
return nil, errors.Wrap(err, "getting Evergreen settings")
}
// Since push triggers have no source version (unlike build and task level triggers), we need to
// extract the project ID from the trigger definition's project ID, which is populated in the TriggerID field
// for push triggers.
var versionID, projectID string
if args.TriggerType == model.ProjectTriggerLevelPush {
projectID = args.TriggerID
} else {
projectID = args.SourceVersion.Identifier
versionID = args.SourceVersion.Id
}
upstreamProject, err := model.FindMergedProjectRef(projectID, versionID, true)
if err != nil {
return nil, errors.Wrapf(err, "finding project ref '%s' for source version '%s'", projectID, versionID)
}
if upstreamProject == nil {
return nil, errors.Errorf("upstream project '%s' not found", projectID)
}
moduleList := projectInfo.Project.Modules
for i, module := range moduleList {
owner, repo, err := module.GetOwnerAndRepo()
if err != nil {
return nil, errors.Wrapf(err, "getting owner and repo for '%s'", module.Name)
}
if owner == upstreamProject.Owner && repo == upstreamProject.Repo && module.Branch == upstreamProject.Branch {
if args.TriggerType == model.ProjectTriggerLevelPush {
moduleList[i].Ref = metadata.SourceCommit
}
_, err = model.CreateManifest(v, moduleList, projectInfo.Ref, settings)
if err != nil {
return nil, errors.WithStack(err)
}
break
}
}
err = model.UpdateLastRevision(v.Identifier, v.Revision)
if err != nil {
return nil, errors.Wrap(err, "updating last revision")
}
err = repotracker.AddBuildBreakSubscriptions(v, &args.DownstreamProject)
if err != nil {
return nil, errors.Wrap(err, "adding build break subscriptions")
}
return v, nil
}
func getMetadataFromArgs(args ProcessorArgs) (model.VersionMetadata, error) {
metadata := model.VersionMetadata{
SourceVersion: args.SourceVersion,
Activate: !args.UnscheduleDownstreamVersions,
TriggerID: args.TriggerID,
TriggerType: args.TriggerType,
EventID: args.EventID,
TriggerDefinitionID: args.DefinitionID,
Alias: args.Alias,
}
if args.SourceVersion != nil {
metadata.Revision = model.Revision{
Author: args.SourceVersion.Author,
AuthorEmail: args.SourceVersion.AuthorEmail,
CreateTime: args.SourceVersion.CreateTime,
RevisionMessage: args.SourceVersion.Message,
}
author, err := user.FindOneById(args.SourceVersion.AuthorID)
if err != nil {
return metadata, errors.Wrapf(err, "finding version author '%s'", args.SourceVersion.AuthorID)
}
if author != nil {
metadata.Revision.AuthorGithubUID = author.Settings.GithubUser.UID
}
} else {
metadata.Revision = args.PushRevision
metadata.SourceCommit = args.PushRevision.Revision
}
repo, err := model.FindRepository(args.DownstreamProject.Id)
if err != nil {
return metadata, errors.Wrapf(err, "finding most recent revision for '%s'", args.DownstreamProject.Id)
}
if repo == nil {
return metadata, errors.Errorf("repo '%s' not found", args.DownstreamProject.Id)
}
metadata.Revision.Revision = repo.LastRevision
return metadata, nil
}
func makeDownstreamProjectFromFile(ctx context.Context, ref model.ProjectRef, file string) (model.ProjectInfo, error) {
opts := model.GetProjectOpts{
Ref: &ref,
RemotePath: file,
Revision: ref.Branch,
}
settings, err := evergreen.GetConfig(ctx)
if err != nil {
return model.ProjectInfo{}, errors.Wrap(err, "getting Evergreen settings")
}
opts.Token, err = settings.GetGithubOauthToken()
if err != nil {
return model.ProjectInfo{}, err
}
return model.GetProjectFromFile(context.Background(), opts)
}