mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-01 04:12:10 +00:00
Merge branch 'forgejo' into repocard
This commit is contained in:
commit
a82cd18d9a
119 changed files with 6915 additions and 2391 deletions
|
@ -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
|
||||
}
|
||||
|
|
85
models/actions/run_job_status_test.go
Normal file
85
models/actions/run_job_status_test.go
Normal 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)
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
33
models/migrations/v1_23/v303.go
Normal file
33
models/migrations/v1_23/v303.go
Normal 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()
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue