staging: use status line in PRs

This commit is contained in:
2025-05-05 13:52:46 +02:00
parent 23e2566843
commit f52d72e04a
4 changed files with 90 additions and 36 deletions

View File

@@ -124,18 +124,12 @@ const (
CommitStatus_Error = "error"
)
type CommitStatus struct {
Context string
Description string
CommitStatus string
}
type GiteaCommitStatusSetter interface {
SetCommitStatus(org, repo, hash string, status *CommitStatus) error
SetCommitStatus(org, repo, hash string, status *models.CommitStatus) (*models.CommitStatus, error)
}
type GiteaCommitStatusGetter interface {
GetCommitStatus(org, repo, hash string) ([]*CommitStatus, error)
GetCommitStatus(org, repo, hash string) ([]*models.CommitStatus, error)
}
type Gitea interface {
@@ -148,6 +142,8 @@ type Gitea interface {
GiteaCommentFetcher
GiteaMaintainershipReader
GiteaFileContentReader
GiteaCommitStatusGetter
GiteaCommitStatusSetter
GetPullNotifications(since *time.Time) ([]*models.NotificationThread, error)
SetNotificationRead(notificationId int64) error
@@ -205,6 +201,47 @@ func (gitea *GiteaTransport) GetPullRequest(org, project string, num int64) (*mo
return pr.Payload, err
}
func (gitea *GiteaTransport) GetCommitStatus(org, repo, hash string) ([]*models.CommitStatus, error) {
page := int64(1)
limit := int64(10)
var res []*models.CommitStatus
for {
r, err := gitea.client.Repository.RepoListStatuses(
repository.NewRepoListStatusesParams().WithDefaults().WithOwner(org).WithRepo(repo).WithSha(hash).WithPage(&page).WithLimit(&limit),
gitea.transport.DefaultAuthentication)
if err != nil {
return res, err
}
res = append(res, r.Payload...)
if len(r.Payload) < int(limit) {
break
}
}
return res, nil
}
func (gitea *GiteaTransport) SetCommitStatus(org, repo, hash string, status *models.CommitStatus) (*models.CommitStatus, error) {
res, err := gitea.client.Repository.RepoCreateStatus(
repository.NewRepoCreateStatusParams().
WithDefaults().
WithOwner(org).
WithRepo(repo).
WithSha(hash).
WithBody(&models.CreateStatusOption{
TargetURL: status.TargetURL,
Description: status.Description,
Context: status.Context,
State: models.CommitStatusState(status.Status),
}),
gitea.transport.DefaultAuthentication,
)
return res.Payload, err
}
func (gitea *GiteaTransport) GetRepository(org, pkg string) (*models.Repository, error) {
repo, err := gitea.client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner(org).WithRepo(pkg), gitea.transport.DefaultAuthentication)
if err != nil {

View File

@@ -98,10 +98,7 @@ func ParseGitRemoteUrl(urlString string) (*GitUrl, error) {
}
org := e[0]
repo := e[1]
if len(repo) > 4 && repo[len(repo)-4:] == ".git" {
repo = repo[0 : len(repo)-4]
}
repo := strings.TrimSuffix(e[1], ".git")
u := GitUrl{
Org: org,

View File

@@ -677,15 +677,14 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
common.LogDebug("ObsProject:", stagingConfig.ObsProject)
stagingProject := GetObsProjectAssociatedWithPr(stagingConfig, obsClient.HomeProject, pr)
change, err := StartOrUpdateBuild(stagingConfig, git, gitea, pr, obsClient)
status := &models.CommitStatus{
Context: BotName,
Description: "OBS Staging build",
Status: common.CommitStatus_Pending,
TargetURL: ObsWebHost + "/project/show/" + stagingProject,
}
if change != RequestModificationNoChange {
msg := "Changed source updated for build"
if change == RequestModificationProjectCreated {
msg = "Build is started in https://" + ObsWebHost + "/project/show/" +
stagingProject
}
if !IsDryRun {
gitea.AddComment(pr, msg)
}
gitea.SetCommitStatus(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Head.Sha, status)
}
if change == RequestModificationProjectCreated {
@@ -707,14 +706,18 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
}
buildStatus := ProcessBuildStatus(stagingResult, baseResult)
if !IsDryRun {
switch buildStatus {
case BuildStatusSummarySuccess:
switch buildStatus {
case BuildStatusSummarySuccess:
status.Status = common.CommitStatus_Success
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateApproved, "Build successful")
if err != nil {
common.LogError(err)
}
case BuildStatusSummaryFailed:
}
case BuildStatusSummaryFailed:
status.Status = common.CommitStatus_Fail
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Build failed")
if err != nil {
common.LogError(err)
@@ -722,6 +725,8 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
}
}
common.LogInfo("Build status:", buildStatus)
gitea.SetCommitStatus(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Head.Sha, status)
// waiting for build results -- nothing to do
} else if err == NonActionableReviewError || err == NoReviewsFoundError {
@@ -769,11 +774,16 @@ var IsDryRun bool
var ProcessPROnly string
func ObsWebHostFromApiHost(apihost string) string {
if len(apihost) > 4 && apihost[0:4] == "api." {
return "build" + apihost[3:]
u, err := url.Parse(apihost)
if err != nil {
common.LogError("Cannot parse OBS API URL")
panic(err)
}
if len(u.Host) > 4 && u.Host[0:4] == "api." {
u.Host = "build" + u.Host[3:]
}
return apihost
return u.String()
}
func main() {
@@ -782,7 +792,7 @@ func main() {
flag.StringVar(&BuildRoot, "build-root", "", "Default build location for staging projects. Default is bot's home project")
flag.StringVar(&GiteaUrl, "gitea-url", "https://src.opensuse.org", "Gitea instance")
flag.BoolVar(&GiteaUseSshClone, "use-ssh-clone", false, "enforce cloning via ssh")
flag.StringVar(&ObsApiHost, "obs", "api.opensuse.org", "API for OBS instance")
flag.StringVar(&ObsApiHost, "obs", "https://api.opensuse.org", "API for OBS instance")
flag.StringVar(&ObsWebHost, "obs-web", "", "Web OBS instance, if not derived from the obs config")
flag.BoolVar(&IsDryRun, "dry", false, "Dry-run, don't actually create any build projects or review changes")
debug := flag.Bool("debug", false, "Turns on debug logging")

View File

@@ -17,23 +17,33 @@ func TestObsAPIHostFromWebHost(t *testing.T) {
}{
{
name: "api host",
api: "api.suse.de",
web: "build.suse.de",
api: "https://api.suse.de",
web: "https://build.suse.de",
},
{
name: "api host",
api: "api.opensuse.org",
web: "build.opensuse.org",
api: "https://api.opensuse.org",
web: "https://build.opensuse.org",
},
{
name: "other host",
api: "someapi.suse.de",
web: "someapi.suse.de",
api: "https://someapi.suse.de",
web: "https://someapi.suse.de",
},
{
name: "short host",
api: "s",
web: "s",
api: "https://s",
web: "https://s",
},
{
name: "other schema works",
api: "s://stuffhere",
web: "s://stuffhere",
},
{
name: "other schema works",
api: "s://api.stuffhere/foo",
web: "s://build.stuffhere/foo",
},
}