github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/scripts/ci/target-version-pr/main.go (about) 1 package main 2 3 import ( 4 "os" 5 "strconv" 6 "strings" 7 8 "github.com/ActiveState/cli/internal/errs" 9 wc "github.com/ActiveState/cli/scripts/internal/workflow-controllers" 10 wh "github.com/ActiveState/cli/scripts/internal/workflow-helpers" 11 "github.com/andygrunwald/go-jira" 12 "github.com/blang/semver" 13 "github.com/google/go-github/v45/github" 14 "golang.org/x/net/context" 15 ) 16 17 func main() { 18 if err := run(); err != nil { 19 wc.Print("Error: %s\n", errs.JoinMessage(err)) 20 os.Exit(1) 21 } 22 } 23 24 type Meta struct { 25 Repo *github.Repository 26 ActivePR *github.PullRequest 27 ActiveStory *jira.Issue 28 ActiveVersion wh.Version 29 ActiveJiraVersion string 30 VersionPRName string 31 TargetBranchName string 32 VersionPR *github.PullRequest 33 IsVersionPR bool 34 } 35 36 func (m Meta) GetVersion() semver.Version { 37 return m.ActiveVersion.Version 38 } 39 40 func (m Meta) GetJiraVersion() string { 41 return m.ActiveJiraVersion 42 } 43 44 func (m Meta) GetVersionBranchName() string { 45 return m.TargetBranchName 46 } 47 48 func (m Meta) GetVersionPRName() string { 49 return m.VersionPRName 50 } 51 52 func run() error { 53 finish := wc.PrintStart("Initializing clients") 54 // Initialize Clients 55 ghClient := wh.InitGHClient() 56 jiraClient, err := wh.InitJiraClient() 57 if err != nil { 58 return errs.Wrap(err, "failed to initialize Jira client") 59 } 60 finish() 61 62 // Grab input 63 if len(os.Args) != 2 { 64 return errs.New("Usage: target-version-branch <pr-number>") 65 } 66 prNumber, err := strconv.Atoi(os.Args[1]) 67 if err != nil { 68 return errs.Wrap(err, "pr number should be numeric") 69 } 70 71 finish = wc.PrintStart("Fetching meta for PR %d", prNumber) 72 // Collect meta information about the PR and all it's related resources 73 meta, err := fetchMeta(ghClient, jiraClient, prNumber) 74 if err != nil { 75 return errs.Wrap(err, "failed to fetch meta") 76 } 77 finish() 78 79 // Create version PR if it doesn't exist yet 80 if !meta.IsVersionPR && meta.VersionPR == nil && !meta.ActiveVersion.EQ(wh.VersionMaster) { 81 finish = wc.PrintStart("Creating version PR for fixVersion %s", meta.ActiveVersion) 82 err := wc.CreateVersionPR(ghClient, jiraClient, meta) 83 if err != nil { 84 return errs.Wrap(err, "failed to create version PR") 85 } 86 finish() 87 } 88 89 // Set the target branch for our PR 90 finish = wc.PrintStart("Setting target branch to %s", meta.TargetBranchName) 91 if strings.HasSuffix(meta.ActivePR.GetBase().GetRef(), meta.TargetBranchName) { 92 wc.Print("PR already targets version branch %s", meta.TargetBranchName) 93 } else { 94 if os.Getenv("DRYRUN") != "true" { 95 if err := wh.UpdatePRTargetBranch(ghClient, meta.ActivePR.GetNumber(), meta.TargetBranchName); err != nil { 96 return errs.Wrap(err, "failed to update PR target branch") 97 } 98 } else { 99 wc.Print("DRYRUN: would update PR target branch to %s", meta.TargetBranchName) 100 } 101 } 102 finish() 103 104 // Set the fixVersion 105 if !meta.IsVersionPR { 106 finish = wc.PrintStart("Setting fixVersion to %s", meta.ActiveVersion) 107 if len(meta.ActiveStory.Fields.FixVersions) == 0 || meta.ActiveStory.Fields.FixVersions[0].ID != meta.ActiveVersion.JiraID { 108 if os.Getenv("DRYRUN") != "true" { 109 if err := wh.UpdateJiraFixVersion(jiraClient, meta.ActiveStory, meta.ActiveVersion.JiraID); err != nil { 110 return errs.Wrap(err, "failed to update Jira fixVersion") 111 } 112 } else { 113 wc.Print("DRYRUN: would set fixVersion to %s", meta.ActiveVersion.String()) 114 } 115 } else { 116 wc.Print("Jira issue already has fixVersion %s", meta.ActiveVersion.String()) 117 } 118 finish() 119 } 120 121 wc.Print("All Done") 122 123 return nil 124 } 125 126 func fetchMeta(ghClient *github.Client, jiraClient *jira.Client, prNumber int) (Meta, error) { 127 // Grab PR information about the PR that this automation is being ran on 128 finish := wc.PrintStart("Fetching Active PR %d", prNumber) 129 prBeingHandled, _, err := ghClient.PullRequests.Get(context.Background(), "ActiveState", "cli", prNumber) 130 if err != nil { 131 return Meta{}, errs.Wrap(err, "failed to get PR") 132 } 133 wc.Print("PR retrieved: %s", prBeingHandled.GetTitle()) 134 finish() 135 136 if wh.IsVersionBranch(prBeingHandled.Head.GetRef()) { 137 return Meta{ 138 Repo: &github.Repository{}, 139 ActivePR: prBeingHandled, 140 TargetBranchName: "beta", 141 IsVersionPR: true, 142 }, nil 143 } 144 finish = wc.PrintStart("Extracting Jira Issue ID from Active PR: %s", prBeingHandled.GetTitle()) 145 jiraIssueID, err := wh.ExtractJiraIssueID(prBeingHandled) 146 if err != nil { 147 return Meta{}, errs.Wrap(err, "PR does not have Jira issue ID associated with it: %s", prBeingHandled.Links.GetHTML().GetHRef()) 148 } 149 wc.Print("Extracted Jira Issue ID: %s", jiraIssueID) 150 finish() 151 152 // Retrieve Relevant Jira Issue for PR being handled 153 finish = wc.PrintStart("Fetching Jira issue") 154 jiraIssue, err := wh.FetchJiraIssue(jiraClient, jiraIssueID) 155 if err != nil { 156 return Meta{}, errs.Wrap(err, "failed to get Jira issue") 157 } 158 finish() 159 160 finish = wc.PrintStart("Fetching Jira Versions") 161 availableVersions, err := wh.FetchAvailableVersions(jiraClient) 162 if err != nil { 163 return Meta{}, errs.Wrap(err, "Failed to fetch JIRA issue") 164 } 165 finish() 166 167 // Retrieve Relevant Fixversion 168 finish = wc.PrintStart("Extracting target fixVersion from Jira issue") 169 fixVersion, jiraVersion, err := wh.ParseTargetFixVersion(jiraIssue, availableVersions) 170 if err != nil { 171 return Meta{}, errs.Wrap(err, "failed to get fixVersion") 172 } 173 wc.Print("Extracted fixVersion: %s", fixVersion) 174 finish() 175 176 var versionPRName string 177 var versionPR *github.PullRequest 178 if fixVersion.NE(wh.VersionMaster) { 179 versionPRName := wh.VersionedPRTitle(fixVersion.Version) 180 181 // Retrieve Relevant Fixversion Pr 182 finish = wc.PrintStart("Fetching Version PR by name: '%s'", versionPRName) 183 versionPR, err = wh.FetchPRByTitle(ghClient, versionPRName) 184 if err != nil { 185 return Meta{}, errs.Wrap(err, "failed to get target PR") 186 } 187 if versionPR != nil && versionPR.GetState() != "open" { 188 return Meta{}, errs.New("PR status for %s is not open, make sure your jira fixVersion is targeting an unreleased version", versionPR.GetTitle()) 189 } 190 if versionPR == nil { 191 wc.Print("No version PR found") 192 } 193 finish() 194 } 195 196 result := Meta{ 197 Repo: &github.Repository{}, 198 ActivePR: prBeingHandled, 199 ActiveStory: jiraIssue, 200 ActiveVersion: fixVersion, 201 ActiveJiraVersion: jiraVersion.Name, 202 VersionPRName: versionPRName, 203 TargetBranchName: wh.VersionedBranchName(fixVersion.Version), 204 VersionPR: versionPR, 205 } 206 207 return result, nil 208 }