Merge pull request '[v1.22/gitea] week 16 cherry pick to v7.0' (#3235) from earl-warren/forgejo:wip-v7.0-gitea-cherry-pick into v7.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3235 Reviewed-by: Gergely Nagy <algernon@noreply.codeberg.org>
This commit is contained in:
commit
335abbbc9d
60 changed files with 341 additions and 311 deletions
|
@ -114,7 +114,7 @@ func showWebStartupMessage(msg string) {
|
|||
log.Info("* WorkPath: %s", setting.AppWorkPath)
|
||||
log.Info("* CustomPath: %s", setting.CustomPath)
|
||||
log.Info("* ConfigFile: %s", setting.CustomConf)
|
||||
log.Info("%s", msg)
|
||||
log.Info("%s", msg) // show startup message
|
||||
}
|
||||
|
||||
func serveInstall(ctx *cli.Context) error {
|
||||
|
|
|
@ -44,6 +44,9 @@ func (schedules ScheduleList) LoadTriggerUser(ctx context.Context) error {
|
|||
schedule.TriggerUser = user_model.NewActionsUser()
|
||||
} else {
|
||||
schedule.TriggerUser = users[schedule.TriggerUserID]
|
||||
if schedule.TriggerUser == nil {
|
||||
schedule.TriggerUser = user_model.NewGhostUser()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -227,7 +228,9 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
|
|||
if runner.RepoID != 0 {
|
||||
jobCond = builder.Eq{"repo_id": runner.RepoID}
|
||||
} else if runner.OwnerID != 0 {
|
||||
jobCond = builder.In("repo_id", builder.Select("id").From("repository").Where(builder.Eq{"owner_id": runner.OwnerID}))
|
||||
jobCond = builder.In("repo_id", builder.Select("`repository`.id").From("repository").
|
||||
Join("INNER", "repo_unit", "`repository`.id = `repo_unit`.repo_id").
|
||||
Where(builder.Eq{"`repository`.owner_id": runner.OwnerID, "`repo_unit`.type": unit.TypeActions}))
|
||||
}
|
||||
if jobCond.IsValid() {
|
||||
jobCond = builder.In("run_id", builder.Select("id").From("action_run").Where(jobCond))
|
||||
|
|
|
@ -76,23 +76,14 @@ func calcFingerprintNative(publicKeyContent string) (string, error) {
|
|||
// CalcFingerprint calculate public key's fingerprint
|
||||
func CalcFingerprint(publicKeyContent string) (string, error) {
|
||||
// Call the method based on configuration
|
||||
var (
|
||||
fnName, fp string
|
||||
err error
|
||||
)
|
||||
if len(setting.SSH.KeygenPath) == 0 {
|
||||
fnName = "calcFingerprintNative"
|
||||
fp, err = calcFingerprintNative(publicKeyContent)
|
||||
} else {
|
||||
fnName = "calcFingerprintSSHKeygen"
|
||||
fp, err = calcFingerprintSSHKeygen(publicKeyContent)
|
||||
}
|
||||
useNative := setting.SSH.KeygenPath == ""
|
||||
calcFn := util.Iif(useNative, calcFingerprintNative, calcFingerprintSSHKeygen)
|
||||
fp, err := calcFn(publicKeyContent)
|
||||
if err != nil {
|
||||
if IsErrKeyUnableVerify(err) {
|
||||
log.Info("%s", publicKeyContent)
|
||||
return "", err
|
||||
}
|
||||
return "", fmt.Errorf("%s: %w", fnName, err)
|
||||
return "", fmt.Errorf("CalcFingerprint(%s): %w", util.Iif(useNative, "native", "ssh-keygen"), err)
|
||||
}
|
||||
return fp, nil
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ func (repo *Repository) IsDependenciesEnabled(ctx context.Context) bool {
|
|||
var u *RepoUnit
|
||||
var err error
|
||||
if u, err = repo.GetUnit(ctx, unit.TypeIssues); err != nil {
|
||||
log.Trace("%s", err)
|
||||
log.Trace("IsDependenciesEnabled: %v", err)
|
||||
return setting.Service.DefaultEnableDependencies
|
||||
}
|
||||
return u.IssuesConfig().EnableDependencies
|
||||
|
|
|
@ -142,35 +142,39 @@ type remoteAddress struct {
|
|||
Password string
|
||||
}
|
||||
|
||||
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string, ignoreOriginalURL bool) remoteAddress {
|
||||
a := remoteAddress{}
|
||||
|
||||
remoteURL := m.OriginalURL
|
||||
if ignoreOriginalURL || remoteURL == "" {
|
||||
var err error
|
||||
remoteURL, err = git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
|
||||
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress {
|
||||
ret := remoteAddress{}
|
||||
remoteURL, err := git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
|
||||
if err != nil {
|
||||
log.Error("GetRemoteURL %v", err)
|
||||
return a
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
u, err := giturl.Parse(remoteURL)
|
||||
if err != nil {
|
||||
log.Error("giturl.Parse %v", err)
|
||||
return a
|
||||
return ret
|
||||
}
|
||||
|
||||
if u.Scheme != "ssh" && u.Scheme != "file" {
|
||||
if u.User != nil {
|
||||
a.Username = u.User.Username()
|
||||
a.Password, _ = u.User.Password()
|
||||
ret.Username = u.User.Username()
|
||||
ret.Password, _ = u.User.Password()
|
||||
}
|
||||
u.User = nil
|
||||
}
|
||||
a.Address = u.String()
|
||||
|
||||
return a
|
||||
// The URL stored in the git repo could contain authentication,
|
||||
// erase it, or it will be shown in the UI.
|
||||
u.User = nil
|
||||
ret.Address = u.String()
|
||||
// Why not use m.OriginalURL to set ret.Address?
|
||||
// It should be OK to use it, since m.OriginalURL should be the same as the authentication-erased URL from the Git repository.
|
||||
// However, the old code has already stored authentication in m.OriginalURL when updating mirror settings.
|
||||
// That means we need to use "giturl.Parse" for m.OriginalURL again to ensure authentication is erased.
|
||||
// Instead of doing this, why not directly use the authentication-erased URL from the Git repository?
|
||||
// It should be the same as long as there are no bugs.
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func FilenameIsImage(filename string) bool {
|
||||
|
|
|
@ -212,3 +212,11 @@ func ToFloat64(number any) (float64, error) {
|
|||
func ToPointer[T any](val T) *T {
|
||||
return &val
|
||||
}
|
||||
|
||||
// Iif is an "inline-if", it returns "trueVal" if "condition" is true, otherwise "falseVal"
|
||||
func Iif[T any](condition bool, trueVal, falseVal T) T {
|
||||
if condition {
|
||||
return trueVal
|
||||
}
|
||||
return falseVal
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ func SearchIssues(ctx *context.APIContext) {
|
|||
|
||||
ctx.SetLinkHeader(int(total), limit)
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
// ListIssues list the issues of a repository
|
||||
|
@ -548,7 +548,7 @@ func ListIssues(ctx *context.APIContext) {
|
|||
|
||||
ctx.SetLinkHeader(int(total), listOptions.PageSize)
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
func getUserIDForFilter(ctx *context.APIContext, queryName string) int64 {
|
||||
|
@ -614,7 +614,7 @@ func GetIssue(ctx *context.APIContext) {
|
|||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
// CreateIssue create an issue of a repository
|
||||
|
@ -737,7 +737,7 @@ func CreateIssue(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "GetIssueByID", err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
// EditIssue modify an issue of a repository
|
||||
|
@ -913,7 +913,7 @@ func EditIssue(ctx *context.APIContext) {
|
|||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
func DeleteIssue(ctx *context.APIContext) {
|
||||
|
|
|
@ -108,7 +108,7 @@ func ListIssueAttachments(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue).Attachments)
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, ctx.Doer, issue).Attachments)
|
||||
}
|
||||
|
||||
// CreateIssueAttachment creates an attachment and saves the given file
|
||||
|
|
|
@ -153,7 +153,7 @@ func GetIssueDependencies(ctx *context.APIContext) {
|
|||
blockerIssues = append(blockerIssues, &blocker.Issue)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, blockerIssues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, blockerIssues))
|
||||
}
|
||||
|
||||
// CreateIssueDependency create a new issue dependencies
|
||||
|
@ -214,7 +214,7 @@ func CreateIssueDependency(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, target))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, target))
|
||||
}
|
||||
|
||||
// RemoveIssueDependency remove an issue dependency
|
||||
|
@ -275,7 +275,7 @@ func RemoveIssueDependency(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, target))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, target))
|
||||
}
|
||||
|
||||
// GetIssueBlocks list issues that are blocked by this issue
|
||||
|
@ -381,7 +381,7 @@ func GetIssueBlocks(ctx *context.APIContext) {
|
|||
issues = append(issues, &depMeta.Issue)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
// CreateIssueBlocking block the issue given in the body by the issue in path
|
||||
|
@ -438,7 +438,7 @@ func CreateIssueBlocking(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, dependency))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, dependency))
|
||||
}
|
||||
|
||||
// RemoveIssueBlocking unblock the issue given in the body by the issue in path
|
||||
|
@ -495,7 +495,7 @@ func RemoveIssueBlocking(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, dependency))
|
||||
ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, dependency))
|
||||
}
|
||||
|
||||
func getParamsIssue(ctx *context.APIContext) *issues_model.Issue {
|
||||
|
|
|
@ -207,7 +207,7 @@ func ListPinnedIssues(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
// ListPinnedPullRequests returns a list of all pinned PRs
|
||||
|
|
|
@ -138,7 +138,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
||||
// AddTime add time manual to the given issue
|
||||
|
@ -225,7 +225,7 @@ func AddTime(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTime(ctx, trackedTime))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTime(ctx, user, trackedTime))
|
||||
}
|
||||
|
||||
// ResetIssueTime reset time manual to the given issue
|
||||
|
@ -455,7 +455,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
||||
// ListTrackedTimesByRepository lists all tracked times of the repository
|
||||
|
@ -567,7 +567,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
||||
// ListMyTrackedTimes lists all tracked times of the current user
|
||||
|
@ -629,5 +629,5 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, trackedTimes))
|
||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes))
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ func GenerateActionsRunnerToken(ctx *context.PrivateContext) {
|
|||
defer rd.Close()
|
||||
|
||||
if err := json.NewDecoder(rd).Decode(&genRequest); err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("JSON Decode failed: %v", err)
|
||||
ctx.JSON(http.StatusInternalServerError, private.Response{
|
||||
Err: err.Error(),
|
||||
})
|
||||
|
@ -36,7 +36,7 @@ func GenerateActionsRunnerToken(ctx *context.PrivateContext) {
|
|||
|
||||
owner, repo, err := parseScope(ctx, genRequest.Scope)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("parseScope failed: %v", err)
|
||||
ctx.JSON(http.StatusInternalServerError, private.Response{
|
||||
Err: err.Error(),
|
||||
})
|
||||
|
@ -46,18 +46,18 @@ func GenerateActionsRunnerToken(ctx *context.PrivateContext) {
|
|||
if errors.Is(err, util.ErrNotExist) || (token != nil && !token.IsActive) {
|
||||
token, err = actions_model.NewRunnerToken(ctx, owner, repo)
|
||||
if err != nil {
|
||||
err := fmt.Sprintf("error while creating runner token: %v", err)
|
||||
log.Error("%v", err)
|
||||
errMsg := fmt.Sprintf("error while creating runner token: %v", err)
|
||||
log.Error("NewRunnerToken failed: %v", errMsg)
|
||||
ctx.JSON(http.StatusInternalServerError, private.Response{
|
||||
Err: err,
|
||||
Err: errMsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
err := fmt.Sprintf("could not get unactivated runner token: %v", err)
|
||||
log.Error("%v", err)
|
||||
errMsg := fmt.Sprintf("could not get unactivated runner token: %v", err)
|
||||
log.Error("GetLatestRunnerToken failed: %v", errMsg)
|
||||
ctx.JSON(http.StatusInternalServerError, private.Response{
|
||||
Err: err,
|
||||
Err: errMsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
|
|||
_ = stdoutWriter.Close()
|
||||
err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("readAndVerifyCommitsFromShaReader failed: %v", err)
|
||||
cancel()
|
||||
}
|
||||
_ = stdoutReader.Close()
|
||||
|
@ -66,7 +66,6 @@ func readAndVerifyCommitsFromShaReader(input io.ReadCloser, repo *git.Repository
|
|||
line := scanner.Text()
|
||||
err := readAndVerifyCommit(line, repo, env)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func SendEmail(ctx *context.PrivateContext) {
|
|||
defer rd.Close()
|
||||
|
||||
if err := json.NewDecoder(rd).Decode(&mail); err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("JSON Decode failed: %v", err)
|
||||
ctx.JSON(http.StatusInternalServerError, private.Response{
|
||||
Err: err.Error(),
|
||||
})
|
||||
|
|
|
@ -403,7 +403,6 @@ func EditUserPost(ctx *context.Context) {
|
|||
ctx.Data["Err_Password"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("auth.password_pwned"), tplUserEdit, &form)
|
||||
case password.IsErrIsPwnedRequest(err):
|
||||
log.Error("%s", err.Error())
|
||||
ctx.Data["Err_Password"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("auth.password_pwned_err"), tplUserEdit, &form)
|
||||
default:
|
||||
|
|
|
@ -215,7 +215,6 @@ func ResetPasswdPost(ctx *context.Context) {
|
|||
case errors.Is(err, password.ErrIsPwned):
|
||||
ctx.RenderWithErr(ctx.Tr("auth.password_pwned"), tplResetPassword, nil)
|
||||
case password.IsErrIsPwnedRequest(err):
|
||||
log.Error("%s", err.Error())
|
||||
ctx.RenderWithErr(ctx.Tr("auth.password_pwned_err"), tplResetPassword, nil)
|
||||
default:
|
||||
ctx.ServerError("UpdateAuth", err)
|
||||
|
@ -299,7 +298,6 @@ func MustChangePasswordPost(ctx *context.Context) {
|
|||
ctx.Data["Err_Password"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("auth.password_pwned"), tplMustChangePassword, &form)
|
||||
case password.IsErrIsPwnedRequest(err):
|
||||
log.Error("%s", err.Error())
|
||||
ctx.Data["Err_Password"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("auth.password_pwned_err"), tplMustChangePassword, &form)
|
||||
default:
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -195,14 +194,15 @@ func NewProjectPost(ctx *context.Context) {
|
|||
|
||||
// ChangeProjectStatus updates the status of a project between "open" and "close"
|
||||
func ChangeProjectStatus(ctx *context.Context) {
|
||||
toClose := false
|
||||
var toClose bool
|
||||
switch ctx.Params(":action") {
|
||||
case "open":
|
||||
toClose = false
|
||||
case "close":
|
||||
toClose = true
|
||||
default:
|
||||
ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects")
|
||||
ctx.JSONRedirect(ctx.ContextUser.HomeLink() + "/-/projects")
|
||||
return
|
||||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
|
@ -210,7 +210,7 @@ func ChangeProjectStatus(ctx *context.Context) {
|
|||
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
|
||||
return
|
||||
}
|
||||
ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects?state=" + url.QueryEscape(ctx.Params(":action")))
|
||||
ctx.JSONRedirect(fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), id))
|
||||
}
|
||||
|
||||
// DeleteProject delete a project
|
||||
|
|
|
@ -2179,7 +2179,7 @@ func GetIssueInfo(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToIssue(ctx, issue))
|
||||
ctx.JSON(http.StatusOK, convert.ToIssue(ctx, ctx.Doer, issue))
|
||||
}
|
||||
|
||||
// UpdateIssueTitle change issue's title
|
||||
|
@ -2713,7 +2713,7 @@ func SearchIssues(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
func getUserIDForFilter(ctx *context.Context, queryName string) int64 {
|
||||
|
@ -2883,7 +2883,7 @@ func ListIssues(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, issues))
|
||||
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, ctx.Doer, issues))
|
||||
}
|
||||
|
||||
func BatchDeleteIssues(ctx *context.Context) {
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
@ -180,14 +179,10 @@ func ChangeProjectStatus(ctx *context.Context) {
|
|||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, ctx.Repo.Repository.ID, id, toClose); err != nil {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", err)
|
||||
} else {
|
||||
ctx.ServerError("ChangeProjectStatusByIDAndRepoID", err)
|
||||
}
|
||||
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
|
||||
return
|
||||
}
|
||||
ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects?state=" + url.QueryEscape(ctx.Params(":action")))
|
||||
ctx.JSONRedirect(fmt.Sprintf("%s/projects/%d", ctx.Repo.RepoLink, id))
|
||||
}
|
||||
|
||||
// DeleteProject delete a project
|
||||
|
|
|
@ -74,7 +74,6 @@ func AccountPost(ctx *context.Context) {
|
|||
case errors.Is(err, password.ErrIsPwned):
|
||||
ctx.Flash.Error(ctx.Tr("auth.password_pwned"))
|
||||
case password.IsErrIsPwnedRequest(err):
|
||||
log.Error("%s", err.Error())
|
||||
ctx.Flash.Error(ctx.Tr("auth.password_pwned_err"))
|
||||
default:
|
||||
ctx.ServerError("UpdateAuth", err)
|
||||
|
|
|
@ -49,7 +49,7 @@ func (n *actionsNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu
|
|||
newNotifyInputFromIssue(issue, webhook_module.HookEventIssues).WithPayload(&api.IssuePayload{
|
||||
Action: api.HookIssueOpened,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, issue.Poster, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, issue.Poster, nil),
|
||||
}).Notify(withMethod(ctx, "NewIssue"))
|
||||
|
@ -89,7 +89,7 @@ func (n *actionsNotifier) IssueChangeContent(ctx context.Context, doer *user_mod
|
|||
WithPayload(&api.IssuePayload{
|
||||
Action: api.HookIssueEdited,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}).
|
||||
|
@ -127,7 +127,7 @@ func (n *actionsNotifier) IssueChangeStatus(ctx context.Context, doer *user_mode
|
|||
}
|
||||
apiIssue := &api.IssuePayload{
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues
|
|||
WithPayload(&api.IssuePayload{
|
||||
Action: action,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}).
|
||||
|
@ -293,7 +293,7 @@ func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, commen
|
|||
|
||||
payload := &api.IssueCommentPayload{
|
||||
Action: action,
|
||||
Issue: convert.ToAPIIssue(ctx, comment.Issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, comment.Issue),
|
||||
Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment),
|
||||
Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
|
|
|
@ -560,12 +560,9 @@ func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository)
|
|||
}
|
||||
|
||||
// We need a notifyInput to call handleSchedules
|
||||
// Here we use the commit author as the Doer of the notifyInput
|
||||
commitUser, err := user_model.GetUserByEmail(ctx, commit.Author.Email)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get user by email: %w", err)
|
||||
}
|
||||
notifyInput := newNotifyInput(repo, commitUser, webhook_module.HookEventSchedule)
|
||||
// if repo is a mirror, commit author maybe an external user,
|
||||
// so we use action user as the Doer of the notifyInput
|
||||
notifyInput := newNotifyInput(repo, user_model.NewActionsUser(), webhook_module.HookEventSchedule)
|
||||
|
||||
return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
|
||||
}
|
||||
|
|
|
@ -79,11 +79,11 @@ func VerifyCaptcha(ctx *Context, tpl base.TplName, form any) {
|
|||
case setting.CfTurnstile:
|
||||
valid, err = turnstile.Verify(ctx, ctx.Req.Form.Get(cfTurnstileResponseField))
|
||||
default:
|
||||
ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType))
|
||||
ctx.ServerError("Unknown Captcha Type", fmt.Errorf("unknown Captcha Type: %s", setting.Service.CaptchaType))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Debug("%v", err)
|
||||
log.Debug("Captcha Verify failed: %v", err)
|
||||
}
|
||||
|
||||
if !valid {
|
||||
|
|
|
@ -18,19 +18,19 @@ import (
|
|||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
func ToIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, issue, WebAssetDownloadURL)
|
||||
func ToIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, doer, issue, WebAssetDownloadURL)
|
||||
}
|
||||
|
||||
// ToAPIIssue converts an Issue to API format
|
||||
// it assumes some fields assigned with values:
|
||||
// Required - Poster, Labels,
|
||||
// Optional - Milestone, Assignee, PullRequest
|
||||
func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, issue, APIAssetDownloadURL)
|
||||
func ToAPIIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) *api.Issue {
|
||||
return toIssue(ctx, doer, issue, APIAssetDownloadURL)
|
||||
}
|
||||
|
||||
func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) *api.Issue {
|
||||
func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) *api.Issue {
|
||||
if err := issue.LoadLabels(ctx); err != nil {
|
||||
return &api.Issue{}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func
|
|||
apiIssue := &api.Issue{
|
||||
ID: issue.ID,
|
||||
Index: issue.Index,
|
||||
Poster: ToUser(ctx, issue.Poster, nil),
|
||||
Poster: ToUser(ctx, issue.Poster, doer),
|
||||
Title: issue.Title,
|
||||
Body: issue.Content,
|
||||
Attachments: toAttachments(issue.Repo, issue.Attachments, getDownloadURL),
|
||||
|
@ -114,25 +114,25 @@ func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func
|
|||
}
|
||||
|
||||
// ToIssueList converts an IssueList to API format
|
||||
func ToIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue {
|
||||
func ToIssueList(ctx context.Context, doer *user_model.User, il issues_model.IssueList) []*api.Issue {
|
||||
result := make([]*api.Issue, len(il))
|
||||
for i := range il {
|
||||
result[i] = ToIssue(ctx, il[i])
|
||||
result[i] = ToIssue(ctx, doer, il[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ToAPIIssueList converts an IssueList to API format
|
||||
func ToAPIIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue {
|
||||
func ToAPIIssueList(ctx context.Context, doer *user_model.User, il issues_model.IssueList) []*api.Issue {
|
||||
result := make([]*api.Issue, len(il))
|
||||
for i := range il {
|
||||
result[i] = ToAPIIssue(ctx, il[i])
|
||||
result[i] = ToAPIIssue(ctx, doer, il[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ToTrackedTime converts TrackedTime to API format
|
||||
func ToTrackedTime(ctx context.Context, t *issues_model.TrackedTime) (apiT *api.TrackedTime) {
|
||||
func ToTrackedTime(ctx context.Context, doer *user_model.User, t *issues_model.TrackedTime) (apiT *api.TrackedTime) {
|
||||
apiT = &api.TrackedTime{
|
||||
ID: t.ID,
|
||||
IssueID: t.IssueID,
|
||||
|
@ -141,7 +141,7 @@ func ToTrackedTime(ctx context.Context, t *issues_model.TrackedTime) (apiT *api.
|
|||
Created: t.Created,
|
||||
}
|
||||
if t.Issue != nil {
|
||||
apiT.Issue = ToAPIIssue(ctx, t.Issue)
|
||||
apiT.Issue = ToAPIIssue(ctx, doer, t.Issue)
|
||||
}
|
||||
if t.User != nil {
|
||||
apiT.UserName = t.User.Name
|
||||
|
@ -192,10 +192,10 @@ func ToStopWatches(ctx context.Context, sws []*issues_model.Stopwatch) (api.Stop
|
|||
}
|
||||
|
||||
// ToTrackedTimeList converts TrackedTimeList to API format
|
||||
func ToTrackedTimeList(ctx context.Context, tl issues_model.TrackedTimeList) api.TrackedTimeList {
|
||||
func ToTrackedTimeList(ctx context.Context, doer *user_model.User, tl issues_model.TrackedTimeList) api.TrackedTimeList {
|
||||
result := make([]*api.TrackedTime, 0, len(tl))
|
||||
for _, t := range tl {
|
||||
result = append(result, ToTrackedTime(ctx, t))
|
||||
result = append(result, ToTrackedTime(ctx, doer, t))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issu
|
|||
return nil
|
||||
}
|
||||
|
||||
comment.TrackedTime = ToTrackedTime(ctx, c.Time)
|
||||
comment.TrackedTime = ToTrackedTime(ctx, doer, c.Time)
|
||||
}
|
||||
|
||||
if c.RefIssueID != 0 {
|
||||
|
@ -129,7 +129,7 @@ func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issu
|
|||
log.Error("GetIssueByID(%d): %v", c.RefIssueID, err)
|
||||
return nil
|
||||
}
|
||||
comment.RefIssue = ToAPIIssue(ctx, issue)
|
||||
comment.RefIssue = ToAPIIssue(ctx, doer, issue)
|
||||
}
|
||||
|
||||
if c.RefCommentID != 0 {
|
||||
|
@ -180,7 +180,7 @@ func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issu
|
|||
}
|
||||
|
||||
if c.DependentIssue != nil {
|
||||
comment.DependentIssue = ToAPIIssue(ctx, c.DependentIssue)
|
||||
comment.DependentIssue = ToAPIIssue(ctx, doer, c.DependentIssue)
|
||||
}
|
||||
|
||||
return comment
|
||||
|
|
|
@ -33,7 +33,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
|
|||
return nil
|
||||
}
|
||||
|
||||
apiIssue := ToAPIIssue(ctx, pr.Issue)
|
||||
apiIssue := ToAPIIssue(ctx, doer, pr.Issue)
|
||||
if err := pr.LoadBaseRepo(ctx); err != nil {
|
||||
log.Error("GetRepositoryById[%d]: %v", pr.ID, err)
|
||||
return nil
|
||||
|
|
|
@ -72,6 +72,11 @@ func (g *GitBucketDownloader) LogString() string {
|
|||
// NewGitBucketDownloader creates a GitBucket downloader
|
||||
func NewGitBucketDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GitBucketDownloader {
|
||||
githubDownloader := NewGithubDownloaderV3(ctx, baseURL, userName, password, token, repoOwner, repoName)
|
||||
// Gitbucket 4.40 uses different internal hard-coded perPage values.
|
||||
// Issues, PRs, and other major parts use 25. Release page uses 10.
|
||||
// Some API doesn't support paging yet. Sounds difficult, but using
|
||||
// minimum number among them worked out very well.
|
||||
githubDownloader.maxPerPage = 10
|
||||
githubDownloader.SkipReactions = true
|
||||
githubDownloader.SkipReviews = true
|
||||
return &GitBucketDownloader{
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
giturl "code.gitea.io/gitea/modules/git/url"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/lfs"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
@ -30,10 +31,15 @@ const gitShortEmptySha = "0000000"
|
|||
|
||||
// UpdateAddress writes new address to Git repository and database
|
||||
func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error {
|
||||
u, err := giturl.Parse(addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid addr: %v", err)
|
||||
}
|
||||
|
||||
remoteName := m.GetRemoteName()
|
||||
repoPath := m.GetRepository(ctx).RepoPath()
|
||||
// Remove old remote
|
||||
_, _, err := git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath})
|
||||
_, _, err = git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath})
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||
return err
|
||||
}
|
||||
|
@ -70,7 +76,9 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error
|
|||
}
|
||||
}
|
||||
|
||||
m.Repo.OriginalURL = addr
|
||||
// erase authentication before storing in database
|
||||
u.User = nil
|
||||
m.Repo.OriginalURL = u.String()
|
||||
return repo_model.UpdateRepositoryCols(ctx, m.Repo, "original_url")
|
||||
}
|
||||
|
||||
|
@ -449,19 +457,17 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
var gitRepo *git.Repository
|
||||
if len(results) == 0 {
|
||||
log.Trace("SyncMirrors [repo: %-v]: no branches updated", m.Repo)
|
||||
} else {
|
||||
log.Trace("SyncMirrors [repo: %-v]: %d branches updated", m.Repo, len(results))
|
||||
gitRepo, err = gitrepo.OpenRepository(ctx, m.Repo)
|
||||
gitRepo, err := gitrepo.OpenRepository(ctx, m.Repo)
|
||||
if err != nil {
|
||||
log.Error("SyncMirrors [repo: %-v]: unable to OpenRepository: %v", m.Repo, err)
|
||||
return false
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
|
||||
log.Trace("SyncMirrors [repo: %-v]: %d branches updated", m.Repo, len(results))
|
||||
if len(results) > 0 {
|
||||
if ok := checkAndUpdateEmptyRepository(ctx, m, gitRepo, results); !ok {
|
||||
log.Error("SyncMirrors [repo: %-v]: checkAndUpdateEmptyRepository: %v", m.Repo, err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -534,6 +540,12 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
|
|||
}
|
||||
log.Trace("SyncMirrors [repo: %-v]: done notifying updated branches/tags - now updating last commit time", m.Repo)
|
||||
|
||||
isEmpty, err := gitRepo.IsEmpty()
|
||||
if err != nil {
|
||||
log.Error("SyncMirrors [repo: %-v]: unable to check empty git repo: %v", m.Repo, err)
|
||||
return false
|
||||
}
|
||||
if !isEmpty {
|
||||
// Get latest commit date and update to current repository updated time
|
||||
commitDate, err := git.GetLatestCommitTime(ctx, m.Repo.RepoPath())
|
||||
if err != nil {
|
||||
|
@ -546,6 +558,8 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
log.Trace("SyncMirrors [repo: %-v]: Successfully updated", m.Repo)
|
||||
|
||||
return true
|
||||
|
|
|
@ -91,7 +91,7 @@ func AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues
|
|||
// NewPullRequest notifies new pull request to notifiers
|
||||
func NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) {
|
||||
if err := pr.LoadIssue(ctx); err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("LoadIssue failed: %v", err)
|
||||
return
|
||||
}
|
||||
if err := pr.Issue.LoadPoster(ctx); err != nil {
|
||||
|
@ -112,7 +112,7 @@ func PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *iss
|
|||
// PullRequestReview notifies new pull request review
|
||||
func PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
|
||||
if err := review.LoadReviewer(ctx); err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("LoadReviewer failed: %v", err)
|
||||
return
|
||||
}
|
||||
for _, notifier := range notifiers {
|
||||
|
|
|
@ -28,7 +28,7 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod
|
|||
|
||||
t, err := NewTemporaryUploadRepository(ctx, repo)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("NewTemporaryUploadRepository failed: %v", err)
|
||||
}
|
||||
defer t.Close()
|
||||
if err := t.Clone(opts.OldBranch, false); err != nil {
|
||||
|
|
|
@ -111,7 +111,7 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user
|
|||
|
||||
t, err := NewTemporaryUploadRepository(ctx, repo)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("NewTemporaryUploadRepository failed: %v", err)
|
||||
}
|
||||
defer t.Close()
|
||||
if err := t.Clone(opts.OldBranch, true); err != nil {
|
||||
|
|
|
@ -143,7 +143,7 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
|
|||
|
||||
t, err := NewTemporaryUploadRepository(ctx, repo)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("NewTemporaryUploadRepository failed: %v", err)
|
||||
}
|
||||
defer t.Close()
|
||||
hasOldBranch := true
|
||||
|
|
|
@ -67,7 +67,7 @@ func (m *webhookNotifier) IssueClearLabels(ctx context.Context, doer *user_model
|
|||
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueLabel, &api.IssuePayload{
|
||||
Action: api.HookIssueLabelCleared,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -168,7 +168,7 @@ func (m *webhookNotifier) IssueChangeAssignee(ctx context.Context, doer *user_mo
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer)
|
||||
apiIssue := &api.IssuePayload{
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ func (m *webhookNotifier) IssueChangeTitle(ctx context.Context, doer *user_model
|
|||
From: oldTitle,
|
||||
},
|
||||
},
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -250,7 +250,7 @@ func (m *webhookNotifier) IssueChangeStatus(ctx context.Context, doer *user_mode
|
|||
} else {
|
||||
apiIssue := &api.IssuePayload{
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
CommitID: commitID,
|
||||
|
@ -281,7 +281,7 @@ func (m *webhookNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu
|
|||
if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssues, &api.IssuePayload{
|
||||
Action: api.HookIssueOpened,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, issue.Poster, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, issue.Poster, nil),
|
||||
}); err != nil {
|
||||
|
@ -349,7 +349,7 @@ func (m *webhookNotifier) IssueChangeContent(ctx context.Context, doer *user_mod
|
|||
From: oldContent,
|
||||
},
|
||||
},
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -384,7 +384,7 @@ func (m *webhookNotifier) UpdateComment(ctx context.Context, doer *user_model.Us
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, c.Issue.Repo, doer)
|
||||
if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{
|
||||
Action: api.HookIssueCommentEdited,
|
||||
Issue: convert.ToAPIIssue(ctx, c.Issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, c.Issue),
|
||||
Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c),
|
||||
Changes: &api.ChangesPayload{
|
||||
Body: &api.ChangesFromPayload{
|
||||
|
@ -412,7 +412,7 @@ func (m *webhookNotifier) CreateIssueComment(ctx context.Context, doer *user_mod
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer)
|
||||
if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{
|
||||
Action: api.HookIssueCommentCreated,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Comment: convert.ToAPIComment(ctx, repo, comment),
|
||||
Repository: convert.ToRepo(ctx, repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
|
@ -449,7 +449,7 @@ func (m *webhookNotifier) DeleteComment(ctx context.Context, doer *user_model.Us
|
|||
permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer)
|
||||
if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{
|
||||
Action: api.HookIssueCommentDeleted,
|
||||
Issue: convert.ToAPIIssue(ctx, comment.Issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, comment.Issue),
|
||||
Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment),
|
||||
Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
|
@ -533,7 +533,7 @@ func (m *webhookNotifier) IssueChangeLabels(ctx context.Context, doer *user_mode
|
|||
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueLabel, &api.IssuePayload{
|
||||
Action: api.HookIssueLabelUpdated,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
@ -575,7 +575,7 @@ func (m *webhookNotifier) IssueChangeMilestone(ctx context.Context, doer *user_m
|
|||
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueMilestone, &api.IssuePayload{
|
||||
Action: hookAction,
|
||||
Index: issue.Index,
|
||||
Issue: convert.ToAPIIssue(ctx, issue),
|
||||
Issue: convert.ToAPIIssue(ctx, doer, issue),
|
||||
Repository: convert.ToRepo(ctx, issue.Repo, permission),
|
||||
Sender: convert.ToUser(ctx, doer, nil),
|
||||
})
|
||||
|
|
|
@ -209,7 +209,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
|
|||
if isOldWikiExist {
|
||||
err := gitRepo.RemoveFilesFromIndex(oldWikiPath)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("RemoveFilesFromIndex failed: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -219,18 +219,18 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
|
|||
|
||||
objectHash, err := gitRepo.HashObject(strings.NewReader(content))
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("HashObject failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gitRepo.AddObjectToIndex("100644", objectHash, newWikiPath); err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("AddObjectToIndex failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
tree, err := gitRepo.WriteTree()
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("WriteTree failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
|
|||
|
||||
commitHash, err := gitRepo.CommitTree(doer.NewGitSig(), committer, tree, commitTreeOpts)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("CommitTree failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -270,11 +270,11 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
|
|||
0,
|
||||
),
|
||||
}); err != nil {
|
||||
log.Error("%v", err)
|
||||
log.Error("Push failed: %v", err)
|
||||
if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("Push: %w", err)
|
||||
return fmt.Errorf("failed to push: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -62,10 +62,7 @@
|
|||
|
||||
<div class="ui modal admin" id="detail-modal">
|
||||
<div class="header">{{ctx.Locale.Tr "admin.notices.view_detail_header"}}</div>
|
||||
<div class="content">
|
||||
<div class="sub header"></div>
|
||||
<pre></pre>
|
||||
</div>
|
||||
<div class="content"><pre></pre></div>
|
||||
</div>
|
||||
|
||||
{{template "admin/layout_footer" .}}
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
<div class="ui four wide column">
|
||||
{{template "shared/user/profile_big_avatar" .}}
|
||||
</div>
|
||||
<div class="ui twelve wide column">
|
||||
<div class="tw-mb-4">
|
||||
<div class="ui twelve wide column tw-mb-4">
|
||||
{{template "user/overview/header" .}}
|
||||
</div>
|
||||
{{template "projects/list" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{template "base/head" .}}
|
||||
<div role="main" aria-label="{{.Title}}" class="page-content repository projects view-project">
|
||||
{{template "shared/user/org_profile_avatar" .}}
|
||||
<div class="ui container">
|
||||
<div class="ui container tw-mb-4">
|
||||
{{template "user/overview/header" .}}
|
||||
</div>
|
||||
<div class="ui container fluid padded">
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
{{end}}
|
||||
{{end}}
|
||||
<div class="ui top attached header clearing segment tw-relative commit-header {{$class}}">
|
||||
<div class="tw-flex tw-mb-4 tw-flex-wrap">
|
||||
<div class="tw-flex tw-mb-4 tw-gap-1">
|
||||
<h3 class="tw-mb-0 tw-flex-1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message ($.Repository.ComposeMetas ctx)}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}}</h3>
|
||||
{{if not $.PageIsWiki}}
|
||||
<div>
|
||||
<div class="commit-header-buttons">
|
||||
<a class="ui primary tiny button" href="{{.SourcePath}}">
|
||||
{{ctx.Locale.Tr "repo.diff.browse_source"}}
|
||||
</a>
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
{{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.IsArchived) $.IsShowingAllCommits}}
|
||||
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} tw-mt-0" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if or ($file.ShouldBeHidden) (not $isExpandable)}}data-folded="true"{{end}}>
|
||||
<h4 class="diff-file-header sticky-2nd-row ui top attached header tw-font-normal tw-flex tw-items-center tw-justify-between tw-flex-wrap">
|
||||
<div class="diff-file-name tw-flex tw-items-center gt-gap-2 tw-flex-wrap">
|
||||
<div class="diff-file-name tw-flex tw-flex-1 tw-items-center tw-gap-1 tw-flex-wrap">
|
||||
<button class="fold-file btn interact-bg tw-p-1{{if not $isExpandable}} tw-invisible{{end}}">
|
||||
{{if $file.ShouldBeHidden}}
|
||||
{{svg "octicon-chevron-right" 18}}
|
||||
|
@ -128,7 +128,8 @@
|
|||
{{template "repo/diff/stats" dict "file" . "root" $}}
|
||||
{{end}}
|
||||
</div>
|
||||
<span class="file tw-font-mono"><a class="muted file-link" title="{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}" href="#diff-{{$file.NameHash}}">{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}</a>{{if .IsLFSFile}} ({{ctx.Locale.Tr "repo.stored_lfs"}}){{end}}</span>
|
||||
<span class="file tw-flex tw-items-center tw-font-mono tw-flex-1"><a class="muted file-link" title="{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}" href="#diff-{{$file.NameHash}}">{{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}</a>
|
||||
{{if .IsLFSFile}} ({{ctx.Locale.Tr "repo.stored_lfs"}}){{end}}
|
||||
<button class="btn interact-fg tw-p-2" data-clipboard-text="{{$file.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{if $file.IsGenerated}}
|
||||
<span class="ui label">{{ctx.Locale.Tr "repo.diff.generated"}}</span>
|
||||
|
@ -139,10 +140,11 @@
|
|||
{{if and $file.Mode $file.OldMode}}
|
||||
{{$old := ctx.Locale.Tr ($file.ModeTranslationKey $file.OldMode)}}
|
||||
{{$new := ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}
|
||||
<span class="tw-ml-4 tw-font-mono">{{ctx.Locale.Tr "git.filemode.changed_filemode" $old $new}}</span>
|
||||
<span class="tw-mx-2 tw-font-mono tw-whitespace-nowrap">{{ctx.Locale.Tr "git.filemode.changed_filemode" $old $new}}</span>
|
||||
{{else if $file.Mode}}
|
||||
<span class="tw-ml-4 tw-font-mono">{{ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}</span>
|
||||
<span class="tw-mx-2 tw-font-mono tw-whitespace-nowrap">{{ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}</span>
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="diff-file-header-actions tw-flex tw-items-center tw-gap-1 tw-flex-wrap">
|
||||
{{if $showFileViewToggle}}
|
||||
|
|
|
@ -59,8 +59,11 @@
|
|||
</div>
|
||||
{{end}}
|
||||
{{template "repo/sub_menu" .}}
|
||||
{{$n := len .TreeNames}}
|
||||
{{$l := Eval $n "-" 1}}
|
||||
{{$isHomepage := (eq $n 0)}}
|
||||
<div class="repo-button-row">
|
||||
<div class="tw-flex tw-items-center tw-flex-wrap tw-gap-y-2">
|
||||
<div class="tw-flex tw-items-center tw-gap-y-2">
|
||||
{{template "repo/branch_dropdown" dict "root" . "ContainerClasses" "tw-mr-1"}}
|
||||
{{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}}
|
||||
{{$cmpBranch := ""}}
|
||||
|
@ -75,9 +78,7 @@
|
|||
</a>
|
||||
{{end}}
|
||||
<!-- Show go to file and breadcrumbs if not on home page -->
|
||||
{{$n := len .TreeNames}}
|
||||
{{$l := Eval $n "-" 1}}
|
||||
{{if eq $n 0}}
|
||||
{{if $isHomepage}}
|
||||
<a href="{{.Repository.Link}}/find/{{.BranchNameSubURL}}" class="ui compact basic button">{{ctx.Locale.Tr "repo.find_file.go_to_file"}}</a>
|
||||
{{end}}
|
||||
|
||||
|
@ -101,20 +102,20 @@
|
|||
</button>
|
||||
{{end}}
|
||||
|
||||
{{if and (eq $n 0) (.Repository.IsTemplate)}}
|
||||
{{if and $isHomepage (.Repository.IsTemplate)}}
|
||||
<a role="button" class="ui primary compact button" href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}">
|
||||
{{ctx.Locale.Tr "repo.use_template"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if ne $n 0}}
|
||||
{{if (not $isHomepage)}}
|
||||
<span class="breadcrumb repo-path tw-ml-1">
|
||||
<a class="section" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}" title="{{.Repository.Name}}">{{StringUtils.EllipsisString .Repository.Name 30}}</a>
|
||||
{{- range $i, $v := .TreeNames -}}
|
||||
<span class="breadcrumb-divider">/</span>
|
||||
{{- if eq $i $l -}}
|
||||
<span class="active section" title="{{$v}}">{{StringUtils.EllipsisString $v 30}}</span>
|
||||
<span class="active section" title="{{$v}}">{{$v}}</span>
|
||||
{{- else -}}
|
||||
{{$p := index $.Paths $i}}<span class="section"><a href="{{$.BranchLink}}/{{PathEscapeSegments $p}}" title="{{$v}}">{{StringUtils.EllipsisString $v 30}}</a></span>
|
||||
{{$p := index $.Paths $i}}<span class="section"><a href="{{$.BranchLink}}/{{PathEscapeSegments $p}}" title="{{$v}}">{{$v}}</a></span>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
</span>
|
||||
|
@ -122,7 +123,7 @@
|
|||
</div>
|
||||
<div class="tw-flex tw-items-center">
|
||||
<!-- Only show clone panel in repository home page -->
|
||||
{{if eq $n 0}}
|
||||
{{if $isHomepage}}
|
||||
<div class="clone-panel ui action tiny input">
|
||||
{{template "repo/clone_buttons" .}}
|
||||
<button class="ui small jump dropdown icon button" data-tooltip-content="{{ctx.Locale.Tr "repo.more_operations"}}">
|
||||
|
@ -145,7 +146,7 @@
|
|||
</div>
|
||||
{{template "repo/cite/cite_modal" .}}
|
||||
{{end}}
|
||||
{{if and (ne $n 0) (not .IsViewFile) (not .IsBlame)}}
|
||||
{{if and (not $isHomepage) (not .IsViewFile) (not .IsBlame)}}
|
||||
<a class="ui button" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}">
|
||||
{{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}}
|
||||
</a>
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
<label for="interval">{{ctx.Locale.Tr "repo.mirror_interval" .MinimumMirrorInterval}}</label>
|
||||
<input id="interval" name="interval" value="{{.PullMirror.Interval}}">
|
||||
</div>
|
||||
{{$address := MirrorRemoteAddress $.Context .Repository .PullMirror.GetRemoteName false}}
|
||||
{{$address := MirrorRemoteAddress $.Context .Repository .PullMirror.GetRemoteName}}
|
||||
<div class="field {{if .Err_MirrorAddress}}error{{end}}">
|
||||
<label for="mirror_address">{{ctx.Locale.Tr "repo.mirror_address"}}</label>
|
||||
<input id="mirror_address" name="mirror_address" value="{{$address.Address}}" required>
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
{{end}}
|
||||
|
||||
{{if not .ReadmeInList}}
|
||||
<div id="repo-file-commit-box" class="ui top attached header list-header tw-mb-4">
|
||||
<div>
|
||||
<div id="repo-file-commit-box" class="ui top attached header list-header tw-mb-4 tw-flex tw-justify-between">
|
||||
<div class="latest-commit">
|
||||
{{template "repo/latest_commit" .}}
|
||||
</div>
|
||||
{{if .LatestCommit}}
|
||||
{{if .LatestCommit.Committer}}
|
||||
<div class="ui text grey right age">
|
||||
<div class="text grey age">
|
||||
{{TimeSince .LatestCommit.Committer.When ctx.Locale}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<table id="repo-files-table" class="ui single line table tw-mt-0" {{if .HasFilesWithoutLatestCommit}}hx-indicator="tr.notready td.message span" hx-trigger="load" hx-swap="morph" hx-post="{{.LastCommitLoaderURL}}"{{end}}>
|
||||
<thead>
|
||||
<tr class="commit-list">
|
||||
<th colspan="2">
|
||||
<th class="tw-overflow-hidden" colspan="2">
|
||||
<div class="tw-flex">
|
||||
<div class="latest-commit">
|
||||
{{template "repo/latest_commit" .}}
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When ctx.Locale}}{{end}}{{end}}</th>
|
||||
</tr>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div role="main" aria-label="{{.Title}}" class="page-content user notification" id="notification_div" data-sequence-number="{{.SequenceNumber}}">
|
||||
<div class="ui container">
|
||||
{{$notificationUnreadCount := call .NotificationUnreadCount}}
|
||||
<div class="tw-flex tw-items-center tw-justify-between tw-mb-4">
|
||||
<div class="tw-flex tw-items-center tw-justify-between tw-mb-[--page-spacing]">
|
||||
<div class="small-menu-items ui compact tiny menu">
|
||||
<a class="{{if eq .Status 1}}active {{end}}item" href="{{AppSubUrl}}/notifications?q=unread">
|
||||
{{ctx.Locale.Tr "notification.unread"}}
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
<div class="ui four wide column">
|
||||
{{template "shared/user/profile_big_avatar" .}}
|
||||
</div>
|
||||
<div class="ui twelve wide column">
|
||||
<div class="tw-mb-4">
|
||||
<div class="ui twelve wide column tw-mb-4">
|
||||
{{template "user/overview/header" .}}
|
||||
</div>
|
||||
{{template "package/shared/versionlist" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
<div class="ui four wide column">
|
||||
{{template "shared/user/profile_big_avatar" .}}
|
||||
</div>
|
||||
<div class="ui twelve wide column">
|
||||
<div class="tw-mb-4">
|
||||
<div class="ui twelve wide column tw-mb-4">
|
||||
{{template "user/overview/header" .}}
|
||||
</div>
|
||||
{{template "package/shared/list" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
<div class="ui four wide column">
|
||||
{{template "shared/user/profile_big_avatar" .}}
|
||||
</div>
|
||||
<div class="ui twelve wide column">
|
||||
<div class="tw-mb-4">
|
||||
<div class="ui twelve wide column tw-mb-4">
|
||||
{{template "user/overview/header" .}}
|
||||
</div>
|
||||
|
||||
{{if eq .TabName "activity"}}
|
||||
{{if .ContextUser.KeepActivityPrivate}}
|
||||
<div class="ui info message">
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
}
|
||||
|
||||
.run-list-item-right {
|
||||
flex: 0 0 15%;
|
||||
flex: 0 0 min(20%, 130px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
|
|
|
@ -24,7 +24,21 @@
|
|||
--repo-header-issue-min-height: 41px;
|
||||
--min-height-textarea: 132px; /* padding + 6 lines + border = calc(1.57142em + 6lh + 2px), but lh is not fully supported */
|
||||
--tab-size: 4;
|
||||
--checkbox-size: 16px; /* height and width of checkbox and radio inputs */
|
||||
--checkbox-size: 15px; /* height and width of checkbox and radio inputs */
|
||||
--page-spacing: 16px; /* space between page elements */
|
||||
--page-margin-x: 32px; /* minimum space on left and right side of page */
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 1200px) {
|
||||
:root {
|
||||
--page-margin-x: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
:root {
|
||||
--page-margin-x: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
:root * {
|
||||
|
@ -668,11 +682,14 @@ img.ui.avatar,
|
|||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
/* add padding to all content when there is no .secondary.nav. this uses padding instead of
|
||||
margin because with the negative margin on .ui.grid we would have to set margin-top: 0,
|
||||
but that does not work universally for all pages */
|
||||
/* add margin to all pages when there is no .secondary.nav */
|
||||
.page-content > :first-child:not(.secondary-nav) {
|
||||
padding-top: 14px;
|
||||
margin-top: var(--page-spacing);
|
||||
}
|
||||
/* if .ui.grid is the first child the first grid-column has 'padding-top: 1rem' which we need
|
||||
to compensate here */
|
||||
.page-content > :first-child.ui.grid {
|
||||
margin-top: calc(var(--page-spacing) - 1rem);
|
||||
}
|
||||
|
||||
.ui.pagination.menu .active.item {
|
||||
|
@ -1330,6 +1347,7 @@ overflow-menu .ui.label {
|
|||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
line-height: inherit; /* needed for inline code preview in markup */
|
||||
}
|
||||
|
||||
.blame .code-inner {
|
||||
|
|
|
@ -249,21 +249,6 @@ textarea:focus,
|
|||
.user.signup form .optional .title {
|
||||
margin-left: 250px !important;
|
||||
}
|
||||
.user.activate form .inline.field > input,
|
||||
.user.forgot.password form .inline.field > input,
|
||||
.user.reset.password form .inline.field > input,
|
||||
.user.link-account form .inline.field > input,
|
||||
.user.signin form .inline.field > input,
|
||||
.user.signup form .inline.field > input,
|
||||
.user.activate form .inline.field > textarea,
|
||||
.user.forgot.password form .inline.field > textarea,
|
||||
.user.reset.password form .inline.field > textarea,
|
||||
.user.link-account form .inline.field > textarea,
|
||||
.user.signin form .inline.field > textarea,
|
||||
.user.signup form .inline.field > textarea,
|
||||
.oauth-login-link {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
|
@ -310,14 +295,7 @@ textarea:focus,
|
|||
.user.reset.password form .inline.field > label,
|
||||
.user.link-account form .inline.field > label,
|
||||
.user.signin form .inline.field > label,
|
||||
.user.signup form .inline.field > label,
|
||||
.user.activate form input,
|
||||
.user.forgot.password form input,
|
||||
.user.reset.password form input,
|
||||
.user.link-account form input,
|
||||
.user.signin form input,
|
||||
.user.signup form input,
|
||||
.oauth-login-link {
|
||||
.user.signup form .inline.field > label {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
@ -435,9 +413,9 @@ textarea:focus,
|
|||
.repository.new.repo form label,
|
||||
.repository.new.migrate form label,
|
||||
.repository.new.fork form label,
|
||||
.repository.new.repo form input,
|
||||
.repository.new.migrate form input,
|
||||
.repository.new.fork form input,
|
||||
.repository.new.repo form .inline.field > input,
|
||||
.repository.new.migrate form .inline.field > input,
|
||||
.repository.new.fork form .inline.field > input,
|
||||
.repository.new.fork form .field a,
|
||||
.repository.new.repo form .selection.dropdown,
|
||||
.repository.new.migrate form .selection.dropdown,
|
||||
|
|
|
@ -20,7 +20,7 @@ input[type="radio"] {
|
|||
.ui.checkbox input[type="checkbox"],
|
||||
.ui.checkbox input[type="radio"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: 1px;
|
||||
left: 0;
|
||||
width: var(--checkbox-size);
|
||||
height: var(--checkbox-size);
|
||||
|
|
|
@ -49,30 +49,11 @@
|
|||
/* overwrite width of containers inside the main page content div (div with class "page-content") */
|
||||
.page-content .ui.ui.ui.container:not(.fluid) {
|
||||
width: 1280px;
|
||||
max-width: calc(100% - 64px);
|
||||
max-width: calc(100% - calc(2 * var(--page-margin-x)));
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.ui.container.fluid.padded {
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
/* enable fluid page widths for medium size viewports */
|
||||
@media (min-width: 768px) and (max-width: 1200px) {
|
||||
.page-content .ui.ui.ui.container:not(.fluid) {
|
||||
max-width: calc(100% - 32px);
|
||||
}
|
||||
.ui.container.fluid.padded {
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.page-content .ui.ui.ui.container:not(.fluid) {
|
||||
max-width: calc(100% - 16px);
|
||||
}
|
||||
.ui.container.fluid.padded {
|
||||
padding: 0 8px;
|
||||
}
|
||||
padding: 0 var(--page-margin-x);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
.flex-container {
|
||||
display: flex !important;
|
||||
gap: 16px;
|
||||
gap: var(--page-spacing);
|
||||
margin-top: var(--page-spacing);
|
||||
}
|
||||
|
||||
.flex-container-nav {
|
||||
|
|
|
@ -177,12 +177,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
.repository.file.list .repo-path {
|
||||
word-break: break-word;
|
||||
.commit-summary {
|
||||
flex: 1;
|
||||
overflow-wrap: anywhere;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.repository.file.list #repo-files-table {
|
||||
table-layout: fixed;
|
||||
.commit-header .commit-summary,
|
||||
td .commit-summary {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.latest-commit {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.latest-commit .sha {
|
||||
display: none;
|
||||
}
|
||||
.latest-commit .commit-summary {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.repo-path {
|
||||
display: flex;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
/* this is what limits the commit table width to a value that works on all viewport sizes */
|
||||
#repo-files-table th:first-of-type {
|
||||
max-width: calc(calc(min(100vw, 1280px)) - 145px - calc(2 * var(--page-margin-x)));
|
||||
}
|
||||
|
||||
.repository.file.list #repo-files-table thead th {
|
||||
|
@ -262,7 +294,6 @@
|
|||
}
|
||||
|
||||
.repository.file.list #repo-files-table td.age {
|
||||
width: 120px;
|
||||
color: var(--color-text-light-1);
|
||||
}
|
||||
|
||||
|
@ -1223,10 +1254,6 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.repository #commits-table td.message {
|
||||
text-overflow: unset;
|
||||
}
|
||||
|
||||
.repository #commits-table.ui.basic.striped.table tbody tr:nth-child(2n) {
|
||||
background-color: var(--color-light) !important;
|
||||
}
|
||||
|
@ -2153,6 +2180,20 @@
|
|||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.commit-header-buttons {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: flex-start;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.commit-header-buttons {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
.settings.webhooks .list > .item:not(:first-child),
|
||||
.settings.githooks .list > .item:not(:first-child),
|
||||
.settings.actions .list > .item:not(:first-child) {
|
||||
|
@ -2469,7 +2510,7 @@ tbody.commit-list {
|
|||
.author-wrapper {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: calc(100% - 50px);
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -2494,10 +2535,6 @@ tbody.commit-list {
|
|||
tr.commit-list {
|
||||
width: 100%;
|
||||
}
|
||||
th .message-wrapper {
|
||||
display: block;
|
||||
max-width: calc(100vw - 70px);
|
||||
}
|
||||
.author-wrapper {
|
||||
max-width: 80px;
|
||||
}
|
||||
|
@ -2507,27 +2544,18 @@ tbody.commit-list {
|
|||
tr.commit-list {
|
||||
width: 723px;
|
||||
}
|
||||
th .message-wrapper {
|
||||
max-width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) and (max-width: 1200px) {
|
||||
tr.commit-list {
|
||||
width: 933px;
|
||||
}
|
||||
th .message-wrapper {
|
||||
max-width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1201px) {
|
||||
tr.commit-list {
|
||||
width: 1127px;
|
||||
}
|
||||
th .message-wrapper {
|
||||
max-width: 525px;
|
||||
}
|
||||
}
|
||||
|
||||
.commit-list .commit-status-link {
|
||||
|
@ -2854,7 +2882,7 @@ tbody.commit-list {
|
|||
.repository.file.list #repo-files-table .entry td.message,
|
||||
.repository.file.list #repo-files-table .commit-list td.message,
|
||||
.repository.file.list #repo-files-table .entry span.commit-summary,
|
||||
.repository.file.list #repo-files-table .commit-list span.commit-summary {
|
||||
.repository.file.list #repo-files-table .commit-list tr span.commit-summary {
|
||||
display: none !important;
|
||||
}
|
||||
.repository.view.issue .comment-list .timeline,
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
--color-console-fg-subtle: #bec4c8;
|
||||
--color-console-bg: #171b1e;
|
||||
--color-console-border: #2e353b;
|
||||
--color-console-hover-bg: #e8e8ff16;
|
||||
--color-console-hover-bg: #292d31;
|
||||
--color-console-active-bg: #2e353b;
|
||||
--color-console-menu-bg: #252b30;
|
||||
--color-console-menu-border: #424b51;
|
||||
|
|
|
@ -63,12 +63,12 @@
|
|||
/* console colors - used for actions console and console files */
|
||||
--color-console-fg: #f8f8f9;
|
||||
--color-console-fg-subtle: #bec4c8;
|
||||
--color-console-bg: #181b1d;
|
||||
--color-console-border: #313538;
|
||||
--color-console-hover-bg: #ffffff16;
|
||||
--color-console-active-bg: #313538;
|
||||
--color-console-menu-bg: #272b2e;
|
||||
--color-console-menu-border: #464a4d;
|
||||
--color-console-bg: #171b1e;
|
||||
--color-console-border: #2e353b;
|
||||
--color-console-hover-bg: #292d31;
|
||||
--color-console-active-bg: #2e353b;
|
||||
--color-console-menu-bg: #252b30;
|
||||
--color-console-menu-border: #424b51;
|
||||
/* named colors */
|
||||
--color-red: #db2828;
|
||||
--color-orange: #f2711c;
|
||||
|
|
|
@ -526,8 +526,16 @@ export function initRepositoryActionView() {
|
|||
|
||||
.action-summary {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
margin: 0 0 0 28px;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.action-commit-summary {
|
||||
margin-left: 0;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================ */
|
||||
|
@ -540,6 +548,14 @@ export function initRepositoryActionView() {
|
|||
top: 12px;
|
||||
max-height: 100vh;
|
||||
overflow-y: auto;
|
||||
background: var(--color-body);
|
||||
z-index: 2; /* above .job-info-header */
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.action-view-left {
|
||||
position: static; /* can not sticky because multiple jobs would overlap into right view */
|
||||
}
|
||||
}
|
||||
|
||||
.job-artifacts-title {
|
||||
|
@ -701,7 +717,9 @@ export function initRepositoryActionView() {
|
|||
position: sticky;
|
||||
top: 0;
|
||||
height: 60px;
|
||||
z-index: 1;
|
||||
z-index: 1; /* above .job-step-container */
|
||||
background: var(--color-console-bg);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.job-info-header:has(+ .job-step-container) {
|
||||
|
@ -739,7 +757,7 @@ export function initRepositoryActionView() {
|
|||
|
||||
.job-step-container .job-step-summary.step-expandable:hover {
|
||||
color: var(--color-console-fg);
|
||||
background-color: var(--color-console-hover-bg);
|
||||
background: var(--color-console-hover-bg);
|
||||
}
|
||||
|
||||
.job-step-container .job-step-summary .step-summary-msg {
|
||||
|
@ -757,17 +775,15 @@ export function initRepositoryActionView() {
|
|||
top: 60px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width: 767.98px) {
|
||||
.action-view-body {
|
||||
flex-direction: column;
|
||||
}
|
||||
.action-view-left, .action-view-right {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action-view-left {
|
||||
max-width: none;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -207,13 +207,13 @@ export function initAdminCommon() {
|
|||
|
||||
// Notice
|
||||
if (document.querySelector('.admin.notice')) {
|
||||
const $detailModal = document.getElementById('detail-modal');
|
||||
const detailModal = document.getElementById('detail-modal');
|
||||
|
||||
// Attach view detail modals
|
||||
$('.view-detail').on('click', function () {
|
||||
$detailModal.find('.content pre').text($(this).parents('tr').find('.notice-description').text());
|
||||
$detailModal.find('.sub.header').text(this.closest('tr')?.querySelector('relative-time')?.getAttribute('title'));
|
||||
$detailModal.modal('show');
|
||||
const description = this.closest('tr').querySelector('.notice-description').textContent;
|
||||
detailModal.querySelector('.content pre').textContent = description;
|
||||
$(detailModal).modal('show');
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
|
@ -435,12 +435,10 @@ export function initRepoPullRequestReview() {
|
|||
offset += $('.diff-detail-box').outerHeight() + $(diffHeader).outerHeight();
|
||||
}
|
||||
|
||||
document.getElementById(`show-outdated-${id}`).classList.add('tw-hidden');
|
||||
document.getElementById(`code-comments-${id}`).classList.remove('tw-hidden');
|
||||
document.getElementById(`code-preview-${id}`).classList.remove('tw-hidden');
|
||||
document.getElementById(`hide-outdated-${id}`).classList.remove('tw-hidden');
|
||||
hideElem(`#show-outdated-${id}`);
|
||||
showElem(`#code-comments-${id}, #code-preview-${id}, #hide-outdated-${id}`);
|
||||
// if the comment box is folded, expand it
|
||||
if (ancestorDiffBox.getAttribute('data-folded') === 'true') {
|
||||
if (ancestorDiffBox?.getAttribute('data-folded') === 'true') {
|
||||
setFileFolding(ancestorDiffBox, ancestorDiffBox.querySelector('.fold-file'), false);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue