in tools/version-tracker/pkg/github/github.go [102:217]
func GetLatestRevision(client *github.Client, org, repo, currentRevision, branchName string, isTrackedUsingCommitHash, releaseBranched bool) (string, bool, error) {
logger.V(6).Info(fmt.Sprintf("Getting latest revision for [%s/%s] repository", org, repo))
var currentRevisionCommit, latestRevision string
var needsUpgrade bool
projectFullName := fmt.Sprintf("%s/%s", org, repo)
// Get all GitHub tags for this project.
allTags, err := getTagsForRepo(client, org, repo)
if err != nil {
return "", false, fmt.Errorf("getting all tags for [%s/%s] repository: %v", org, repo, err)
}
// Get commit hash corresponding to current revision tag.
if isTrackedUsingCommitHash {
currentRevisionCommit = currentRevision
} else {
currentRevisionCommit = getCommitForTag(allTags, currentRevision)
}
// Get Unix timestamp for current revision's commit.
currentRevisionCommitEpoch, err := getCommitDateEpoch(client, org, repo, currentRevisionCommit)
if err != nil {
return "", false, fmt.Errorf("getting epoch time corresponding to current revision commit: %v", err)
}
// If the project is tracked using a commit hash, upgrade to the latest commit.
if isTrackedUsingCommitHash {
// If the project does not have Github tags, pick the latest commit.
allCommits, err := getCommitsForRepo(client, org, repo)
if err != nil {
return "", false, fmt.Errorf("getting all commits for [%s/%s] repository: %v", org, repo, err)
}
latestRevision = *allCommits[0].SHA
needsUpgrade = true
} else {
semverRegex := regexp.MustCompile(constants.SemverRegex)
currentRevisionForSemver := version.EnsurePatchVersion(semverRegex.FindString(currentRevision))
// Get SemVer construct corresponding to the current revision tag.
currentRevisionSemver, err := semver.New(currentRevisionForSemver)
if err != nil {
return "", false, fmt.Errorf("getting semver for current version %s: %v", currentRevisionForSemver, err)
}
for _, tag := range allTags {
tagName := *tag.Name
if strings.Contains(tagName, "chart") || strings.Contains(tagName, "helm") {
continue
}
if org == "kubernetes" && repo == "autoscaler" {
if !strings.HasPrefix(tagName, "cluster-autoscaler-") {
continue
}
}
detectedSemver := semverRegex.FindString(tagName)
if detectedSemver == "" {
continue
}
tagNameForSemver := version.EnsurePatchVersion(detectedSemver)
if releaseBranched {
releaseBranch := os.Getenv(constants.ReleaseBranchEnvvar)
releaseNumber := strings.Split(releaseBranch, "-")[1]
tagRegex := regexp.MustCompile(fmt.Sprintf(`^v?1(\.|_)%s(\.|_)\d+$`, releaseNumber))
if !tagRegex.MatchString(tagNameForSemver) {
continue
}
}
if branchName != constants.MainBranchName {
tagRegex := regexp.MustCompile(fmt.Sprintf(`^v?%d(\.|_)%d(\.|_)\d+`, currentRevisionSemver.Major, currentRevisionSemver.Minor))
if !tagRegex.MatchString(tagNameForSemver) {
continue
}
}
revisionSemver, err := semver.New(tagNameForSemver)
if err != nil {
return "", false, fmt.Errorf("getting semver for the version under consideration: %v", err)
}
if !slices.Contains(constants.ProjectsSupportingPrereleaseTags, projectFullName) && revisionSemver.Prerelease != "" {
continue
}
if _, ok := constants.ProjectMaximumSemvers[projectFullName]; ok {
maximumAllowedVersion := constants.ProjectMaximumSemvers[projectFullName]
numDots := strings.Count(maximumAllowedVersion, ".")
for range 2 - numDots {
maximumAllowedVersion += fmt.Sprintf(".%s", strconv.Itoa(math.MaxInt))
}
maximumSemver, err := semver.New(maximumAllowedVersion)
if err != nil {
return "", false, fmt.Errorf("getting semver for the maximum allowed version: %v", err)
}
if revisionSemver.GreaterThan(maximumSemver) {
continue
}
}
latestRevision = tagName
// Determine if upgrade is required based on current and latest revisions
upgradeRequired, shouldBreak, err := isUpgradeRequired(client, org, repo, latestRevision, currentRevisionCommitEpoch, currentRevisionSemver, allTags)
if err != nil {
return "", false, fmt.Errorf("determining if upgrade is required for project: %v", err)
}
if shouldBreak {
needsUpgrade = upgradeRequired
break
}
}
}
return latestRevision, needsUpgrade, nil
}