Merge branch 'forgejo' into repocard

This commit is contained in:
JakobDev 2024-12-29 11:20:09 +00:00
commit a82cd18d9a
119 changed files with 6915 additions and 2391 deletions

View file

@ -153,28 +153,34 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
}
func AggregateJobStatus(jobs []*ActionRunJob) Status {
allDone := true
allWaiting := true
hasFailure := false
allSuccessOrSkipped := len(jobs) != 0
allSkipped := len(jobs) != 0
var hasFailure, hasCancelled, hasWaiting, hasRunning, hasBlocked bool
for _, job := range jobs {
if !job.Status.IsDone() {
allDone = false
}
if job.Status != StatusWaiting && !job.Status.IsDone() {
allWaiting = false
}
if job.Status == StatusFailure || job.Status == StatusCancelled {
hasFailure = true
}
allSuccessOrSkipped = allSuccessOrSkipped && (job.Status == StatusSuccess || job.Status == StatusSkipped)
allSkipped = allSkipped && job.Status == StatusSkipped
hasFailure = hasFailure || job.Status == StatusFailure
hasCancelled = hasCancelled || job.Status == StatusCancelled
hasWaiting = hasWaiting || job.Status == StatusWaiting
hasRunning = hasRunning || job.Status == StatusRunning
hasBlocked = hasBlocked || job.Status == StatusBlocked
}
if allDone {
if hasFailure {
return StatusFailure
}
switch {
case allSkipped:
return StatusSkipped
case allSuccessOrSkipped:
return StatusSuccess
}
if allWaiting {
case hasCancelled:
return StatusCancelled
case hasFailure:
return StatusFailure
case hasRunning:
return StatusRunning
case hasWaiting:
return StatusWaiting
case hasBlocked:
return StatusBlocked
default:
return StatusUnknown // it shouldn't happen
}
return StatusRunning
}

View file

@ -0,0 +1,85 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAggregateJobStatus(t *testing.T) {
testStatuses := func(expected Status, statuses []Status) {
t.Helper()
var jobs []*ActionRunJob
for _, v := range statuses {
jobs = append(jobs, &ActionRunJob{Status: v})
}
actual := AggregateJobStatus(jobs)
if !assert.Equal(t, expected, actual) {
var statusStrings []string
for _, s := range statuses {
statusStrings = append(statusStrings, s.String())
}
t.Errorf("AggregateJobStatus(%v) = %v, want %v", statusStrings, statusNames[actual], statusNames[expected])
}
}
cases := []struct {
statuses []Status
expected Status
}{
// unknown cases, maybe it shouldn't happen in real world
{[]Status{}, StatusUnknown},
{[]Status{StatusUnknown, StatusSuccess}, StatusUnknown},
{[]Status{StatusUnknown, StatusSkipped}, StatusUnknown},
{[]Status{StatusUnknown, StatusFailure}, StatusFailure},
{[]Status{StatusUnknown, StatusCancelled}, StatusCancelled},
{[]Status{StatusUnknown, StatusWaiting}, StatusWaiting},
{[]Status{StatusUnknown, StatusRunning}, StatusRunning},
{[]Status{StatusUnknown, StatusBlocked}, StatusBlocked},
// success with other status
{[]Status{StatusSuccess}, StatusSuccess},
{[]Status{StatusSuccess, StatusSkipped}, StatusSuccess}, // skipped doesn't affect success
{[]Status{StatusSuccess, StatusFailure}, StatusFailure},
{[]Status{StatusSuccess, StatusCancelled}, StatusCancelled},
{[]Status{StatusSuccess, StatusWaiting}, StatusWaiting},
{[]Status{StatusSuccess, StatusRunning}, StatusRunning},
{[]Status{StatusSuccess, StatusBlocked}, StatusBlocked},
// any cancelled, then cancelled
{[]Status{StatusCancelled}, StatusCancelled},
{[]Status{StatusCancelled, StatusSuccess}, StatusCancelled},
{[]Status{StatusCancelled, StatusSkipped}, StatusCancelled},
{[]Status{StatusCancelled, StatusFailure}, StatusCancelled},
{[]Status{StatusCancelled, StatusWaiting}, StatusCancelled},
{[]Status{StatusCancelled, StatusRunning}, StatusCancelled},
{[]Status{StatusCancelled, StatusBlocked}, StatusCancelled},
// failure with other status, fail fast
// Should "running" win? Maybe no: old code does make "running" win, but GitHub does fail fast.
{[]Status{StatusFailure}, StatusFailure},
{[]Status{StatusFailure, StatusSuccess}, StatusFailure},
{[]Status{StatusFailure, StatusSkipped}, StatusFailure},
{[]Status{StatusFailure, StatusCancelled}, StatusCancelled},
{[]Status{StatusFailure, StatusWaiting}, StatusFailure},
{[]Status{StatusFailure, StatusRunning}, StatusFailure},
{[]Status{StatusFailure, StatusBlocked}, StatusFailure},
// skipped with other status
// TODO: need to clarify whether a PR with "skipped" job status is considered as "mergeable" or not.
{[]Status{StatusSkipped}, StatusSkipped},
{[]Status{StatusSkipped, StatusSuccess}, StatusSuccess},
{[]Status{StatusSkipped, StatusFailure}, StatusFailure},
{[]Status{StatusSkipped, StatusCancelled}, StatusCancelled},
{[]Status{StatusSkipped, StatusWaiting}, StatusWaiting},
{[]Status{StatusSkipped, StatusRunning}, StatusRunning},
{[]Status{StatusSkipped, StatusBlocked}, StatusBlocked},
}
for _, c := range cases {
testStatuses(c.expected, c.statuses)
}
}

View file

@ -432,6 +432,25 @@
updated: 1683636626
need_approval: 0
approved_by: 0
-
id: 794
title: "job output"
repo_id: 4
owner_id: 1
workflow_id: "test.yaml"
index: 190
trigger_user_id: 1
ref: "refs/heads/test"
commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
event: "push"
is_fork_pull_request: 0
status: 1
started: 1683636528
stopped: 1683636626
created: 1683636108
updated: 1683636626
need_approval: 0
approved_by: 0
-
id: 891
title: "update actions"

View file

@ -45,3 +45,15 @@
is_deleted: false
deleted_by_id: 0
deleted_unix: 0
-
id: 15
repo_id: 4
name: 'master'
commit_id: 'c7cd3cd144e6d23c9d6f3d07e52b2c1a956e0338'
commit_message: 'add Readme'
commit_time: 1588147171
pusher_id: 13
is_deleted: false
deleted_by_id: 0
deleted_unix: 0

View file

@ -20,9 +20,34 @@ import (
func MigrateTwoFactorToKeying(x *xorm.Engine) error {
var err error
// When upgrading from Forgejo v9 to v10, this migration will already be
// called from models/migrations/migrations.go migration 304 and must not
// be run twice.
var version int
_, err = x.Table("version").Where("`id` = 1").Select("version").Get(&version)
if err != nil {
// the version table does not exist when a test environment only applies Forgejo migrations
} else if version > 304 {
return nil
}
switch x.Dialect().URI().DBType {
case schemas.MYSQL:
_, err = x.Exec("ALTER TABLE `two_factor` MODIFY `secret` BLOB")
case schemas.SQLITE:
_, err = x.Exec("ALTER TABLE `two_factor` RENAME COLUMN `secret` TO `secret_backup`")
if err != nil {
return err
}
_, err = x.Exec("ALTER TABLE `two_factor` ADD COLUMN `secret` BLOB")
if err != nil {
return err
}
_, err = x.Exec("UPDATE `two_factor` SET `secret` = `secret_backup`")
if err != nil {
return err
}
_, err = x.Exec("ALTER TABLE `two_factor` DROP COLUMN `secret_backup`")
case schemas.POSTGRES:
_, err = x.Exec("ALTER TABLE `two_factor` ALTER COLUMN `secret` SET DATA TYPE bytea USING secret::text::bytea")
}

View file

@ -362,6 +362,10 @@ func prepareMigrationTasks() []*migration {
newMigration(300, "Add force-push branch protection support", v1_23.AddForcePushBranchProtection),
newMigration(301, "Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable),
newMigration(302, "Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired),
// Migration to Forgejo v10
newMigration(303, "Gitea last drop", v1_23.GiteaLastDrop),
newMigration(304, "Migrate `secret` column to store keying material", forgejo_migrations.MigrateTwoFactorToKeying),
}
return preparedMigrations
}

View file

@ -0,0 +1,33 @@
// Copyright 2024 The Forgejo Authors.
// SPDX-License-Identifier: MIT
package v1_23 //nolint
import (
"code.gitea.io/gitea/models/migrations/base"
"xorm.io/xorm"
)
func GiteaLastDrop(x *xorm.Engine) error {
sess := x.NewSession()
defer sess.Close()
if err := base.DropTableColumns(sess, "badge", "slug"); err != nil {
return err
}
if err := base.DropTableColumns(sess, "oauth2_application", "skip_secondary_authorization"); err != nil {
return err
}
if err := base.DropTableColumns(sess, "repository", "default_wiki_branch"); err != nil {
return err
}
// the migration v297.go that adds everyone_access_mode exists in Gitea >= v1.22 and the column must be dropped
// but it does not exist in Forgejo and a failure to drop the column can be ignored
base.DropTableColumns(sess, "repo_unit", "everyone_access_mode")
if err := base.DropTableColumns(sess, "protected_branch", "can_force_push", "enable_force_push_allowlist", "force_push_allowlist_user_i_ds", "force_push_allowlist_team_i_ds", "force_push_allowlist_deploy_keys"); err != nil {
return err
}
return sess.Commit()
}

View file

@ -29,6 +29,15 @@ const (
MergeStyleRebaseUpdate MergeStyle = "rebase-update-only"
)
type UpdateStyle string
const (
// UpdateStyleMerge create merge commit to update
UpdateStyleMerge UpdateStyle = "merge"
// UpdateStyleRebase rebase to update
UpdateStyleRebase UpdateStyle = "rebase"
)
// UpdateDefaultBranch updates the default branch
func UpdateDefaultBranch(ctx context.Context, repo *Repository) error {
_, err := db.GetEngine(ctx).ID(repo.ID).Cols("default_branch").Update(repo)

View file

@ -159,6 +159,7 @@ type PullRequestsConfig struct {
AllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool
DefaultMergeStyle MergeStyle
DefaultUpdateStyle UpdateStyle
DefaultAllowMaintainerEdit bool
}
@ -197,6 +198,25 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
return MergeStyleMerge
}
// IsUpdateStyleAllowed returns if update style is allowed
func (cfg *PullRequestsConfig) IsUpdateStyleAllowed(updateStyle UpdateStyle) bool {
return updateStyle == UpdateStyleMerge ||
updateStyle == UpdateStyleRebase && cfg.AllowRebaseUpdate
}
// GetDefaultUpdateStyle returns the default update style for this pull request
func (cfg *PullRequestsConfig) GetDefaultUpdateStyle() UpdateStyle {
if len(cfg.DefaultUpdateStyle) != 0 {
return cfg.DefaultUpdateStyle
}
if setting.Repository.PullRequest.DefaultUpdateStyle != "" {
return UpdateStyle(setting.Repository.PullRequest.DefaultUpdateStyle)
}
return UpdateStyleMerge
}
type ActionsConfig struct {
DisabledWorkflows []string
}

View file

@ -7,6 +7,8 @@ import (
"testing"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
)
@ -37,3 +39,50 @@ func TestRepoUnitAccessMode(t *testing.T) {
assert.Equal(t, perm.AccessModeWrite, UnitAccessModeWrite.ToAccessMode(perm.AccessModeAdmin))
assert.Equal(t, perm.AccessModeRead, UnitAccessModeUnset.ToAccessMode(perm.AccessModeRead))
}
func TestRepoPRIsUpdateStyleAllowed(t *testing.T) {
var cfg PullRequestsConfig
cfg = PullRequestsConfig{
AllowRebaseUpdate: true,
}
assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleMerge))
assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleRebase))
cfg = PullRequestsConfig{
AllowRebaseUpdate: false,
}
assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleMerge))
assert.False(t, cfg.IsUpdateStyleAllowed(UpdateStyleRebase))
}
func TestRepoPRGetDefaultUpdateStyle(t *testing.T) {
defer test.MockVariableValue(&setting.Repository.PullRequest.DefaultUpdateStyle, "merge")()
var cfg PullRequestsConfig
cfg = PullRequestsConfig{
DefaultUpdateStyle: "",
}
assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "rebase",
}
assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "merge",
}
assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
setting.Repository.PullRequest.DefaultUpdateStyle = "rebase"
cfg = PullRequestsConfig{
DefaultUpdateStyle: "",
}
assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "rebase",
}
assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "merge",
}
assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
}

View file

@ -18,10 +18,10 @@ import (
)
type Setting struct {
ID int64 `xorm:"pk autoincr"`
SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase
SettingValue string `xorm:"text"`
Version int `xorm:"version"`
ID int64 `xorm:"pk autoincr"`
SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase
SettingValue string `xorm:"text"`
Version int
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"`
}