Skip to content

Commit

Permalink
add gitlab update
Browse files Browse the repository at this point in the history
Signed-off-by: debasishbsws <[email protected]>
  • Loading branch information
debasishbsws committed Jul 2, 2024
1 parent fe418e0 commit 694c357
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ require (
github.com/stretchr/testify v1.9.0
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c
github.com/tmc/dot v0.0.0-20210901225022-f9bc17da75c0
github.com/xanzy/go-gitlab v0.105.0
go.lsp.dev/uri v0.3.0
go.opentelemetry.io/otel v1.27.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,8 @@ github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 h1:jIVmlAFIq
github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651/go.mod h1:b26F2tHLqaoRQf8DywqzVaV1MQ9yvjb0OMcNl7Nxu20=
github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0 h1:0KGbf+0SMg+UFy4e1A/CPVvXn21f1qtWdeJwxZFoQG8=
github.com/wagoodman/go-progress v0.0.0-20230925121702-07e42b3cdba0/go.mod h1:jLXFoL31zFaHKAAyZUh+sxiTDFe1L1ZHrcK2T1itVKA=
github.com/xanzy/go-gitlab v0.105.0 h1:3nyLq0ESez0crcaM19o5S//SvezOQguuIHZ3wgX64hM=
github.com/xanzy/go-gitlab v0.105.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
Expand Down
215 changes: 215 additions & 0 deletions pkg/update/gitlabRelease.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
package update

import (
"errors"
"fmt"
"log"
"os"
"regexp"
"strings"

"chainguard.dev/melange/pkg/config"
"github.com/wolfi-dev/wolfictl/pkg/melange"
"github.com/xanzy/go-gitlab"
)

const (
gitlabBaseURL = "https://gitlab.com"
)

type GitLabReleaseOptions struct {
PackageConfigs map[string]*melange.Packages
gitlabClient *gitlab.Client
Logger *log.Logger

ErrorMessages map[string]string
}
type VersionComit struct {
Version string
Commit string
}

func NewGitlabReleaseOptions(packageConfigs map[string]*melange.Packages) GitLabReleaseOptions {

token := os.Getenv("GITLAB_TOKEN")
if token == "" {
log.Fatalf("GITLAB_TOKEN environment variable not set")
}

client, err := gitlab.NewClient(token, gitlab.WithBaseURL(gitlabBaseURL))
if err != nil {
log.Fatalf("Failed to create gitlab client: %v", err)
}

o := GitLabReleaseOptions{
PackageConfigs: packageConfigs,
gitlabClient: client,
Logger: log.New(log.Writer(), "wolfictl check update: ", log.LstdFlags|log.Lmsgprefix),
ErrorMessages: make(map[string]string),
}

return o
}

func (o GitLabReleaseOptions) getLatestGitLabVersions() (map[string]NewVersionResults, map[string]string, error) {
if len(o.PackageConfigs) == 0 {
return nil, o.ErrorMessages, errors.New("No package configs provided")
}

releaseRepoList, tagRepoList := o.getSeparateRepoLists()

latestVersionResults := make(map[string]NewVersionResults)

if len(releaseRepoList) > 0 {
o.Logger.Println("Checking for latest new releases")
for packageName, identifier := range releaseRepoList {
o.Logger.Printf("Checking for latest release on %s using identifier %s\n", packageName, identifier)
listReleaseOption := &gitlab.ListReleasesOptions{
ListOptions: gitlab.ListOptions{
PerPage: 20,
Page: 1,
},
}
releases, resp, err := o.gitlabClient.Releases.ListReleases(identifier, listReleaseOption)
if err != nil || resp.StatusCode != 200 {
o.ErrorMessages[packageName] = fmt.Sprintf("Failed to list releases for %s: %v", packageName, err)
continue
}
if len(releases) == 0 {
o.ErrorMessages[packageName] = fmt.Sprintf("No releases found for %s", packageName)
continue
}

// filter out releases that match the ignore regex patterns and other filters
allReleaseList := []VersionComit{}
for _, release := range releases {
allReleaseList = append(allReleaseList, VersionComit{
Version: release.TagName,
Commit: release.Commit.ID,
})
}
properVersionList, err := prepareVersion(allReleaseList, &o.PackageConfigs[packageName].Config)
if err != nil {
o.ErrorMessages[packageName] = fmt.Sprintf("Failed to prepare version for %s: %v", packageName, err)
continue
}
if len(properVersionList) > 0 {
latestVersionResults[packageName] = NewVersionResults{
Version: properVersionList[0].Version,
Commit: properVersionList[0].Commit,
}
}
}
}

if len(tagRepoList) > 0 {
o.Logger.Println("Checking for latest new tags")
listTagsOption := &gitlab.ListTagsOptions{
ListOptions: gitlab.ListOptions{
PerPage: 50,
Page: 1,
OrderBy: "version",
},
}
for packageName, identifier := range tagRepoList {
o.Logger.Printf("Checking for latest tag on %s using projectID %s\n", packageName, identifier)
tags, resp, err := o.gitlabClient.Tags.ListTags(identifier, listTagsOption)
if err != nil || resp.StatusCode != 200 {
o.ErrorMessages[packageName] = fmt.Sprintf("Failed to list tags for %s: %v", packageName, err)
continue
}
if len(tags) == 0 {
o.ErrorMessages[packageName] = fmt.Sprintf("No tags found for %s", packageName)
continue
}

// filter out releases that match the ignore regex patterns and other filters
allTagsList := []VersionComit{}
for _, tag := range tags {
allTagsList = append(allTagsList, VersionComit{
Version: tag.Name,
Commit: tag.Commit.ID,
})
}
properVersionList, err := prepareVersion(allTagsList, &o.PackageConfigs[packageName].Config)
if err != nil {
o.ErrorMessages[packageName] = fmt.Sprintf("Failed to prepare version for %s: %v", packageName, err)
continue
}
if len(properVersionList) > 0 {
latestVersionResults[packageName] = NewVersionResults{
Version: properVersionList[0].Version,
Commit: properVersionList[0].Commit,
}
}
}
}

return latestVersionResults, o.ErrorMessages, nil
}

func prepareVersion(versionList []VersionComit, packageConfig *config.Configuration) ([]VersionComit, error) {
properVersionList := []VersionComit{}
if len(versionList) == 0 {
return properVersionList, errors.New("No versions found, empty list")
}

glm := packageConfig.Update.GitLabMonitor
if glm == nil {
return properVersionList, errors.New("No GitLab update configuration found for package")
}

for _, vc := range versionList {
if len(packageConfig.Update.IgnoreRegexPatterns) > 0 {
for _, pattern := range packageConfig.Update.IgnoreRegexPatterns {
regex, err := regexp.Compile(pattern)
if err != nil {
return properVersionList, fmt.Errorf("Failed to compile regex %s", pattern)
}
if regex.MatchString(vc.Version) {
continue
}
}
}
if glm.TagFilterPrefix != "" {
if !strings.HasPrefix(vc.Version, glm.TagFilterPrefix) {
continue
}
}
if glm.TagFilterContains != "" {
if !strings.Contains(vc.Version, glm.TagFilterContains) {
continue
}
}

version := vc.Version
if glm.StripPrefix != "" {
version = strings.TrimPrefix(version, glm.StripPrefix)
}
if glm.StripSuffix != "" {
version = strings.TrimSuffix(version, glm.StripSuffix)
}
properVersionList = append(properVersionList, VersionComit{
Version: version,
Commit: vc.Commit,
})
}

return properVersionList, nil
}
func (o GitLabReleaseOptions) getSeparateRepoLists() (releaseRepoList, tagRepoList map[string]string) {
tagRepoList = make(map[string]string)
releaseRepoList = make(map[string]string)
for _, pc := range o.PackageConfigs {
if monitor := pc.Config.Update.GitLabMonitor; monitor != nil {
identifire := monitor.Identifier
if monitor.UseTags {
tagRepoList[pc.Config.Package.Name] = identifire
} else {
releaseRepoList[pc.Config.Package.Name] = identifire
}
}
}

return releaseRepoList, tagRepoList
}

0 comments on commit 694c357

Please sign in to comment.