Merge branch 'main' into feature/bots

This commit is contained in:
Jason Song
2022-12-22 12:00:41 +08:00
58 changed files with 2368 additions and 1716 deletions

View File

@@ -344,7 +344,7 @@ func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNames
Content: content,
Properties: &FeedEntryProperties{
Version: pd.Version.Version,
NormalizedVersion: normalizeVersion(pd.SemVer),
NormalizedVersion: pd.Version.Version,
Authors: metadata.Authors,
Dependencies: buildDependencyString(metadata),
Description: metadata.Description,

View File

@@ -4,15 +4,11 @@
package nuget
import (
"bytes"
"fmt"
"sort"
"time"
packages_model "code.gitea.io/gitea/models/packages"
nuget_module "code.gitea.io/gitea/modules/packages/nuget"
"github.com/hashicorp/go-version"
)
// https://docs.microsoft.com/en-us/nuget/api/service-index#resources
@@ -95,8 +91,8 @@ func createRegistrationIndexResponse(l *linkBuilder, pds []*packages_model.Packa
{
RegistrationPageURL: l.GetRegistrationIndexURL(pds[0].Package.Name),
Count: len(pds),
Lower: normalizeVersion(pds[0].SemVer),
Upper: normalizeVersion(pds[len(pds)-1].SemVer),
Lower: pds[0].Version.Version,
Upper: pds[len(pds)-1].Version.Version,
Items: items,
},
},
@@ -173,7 +169,7 @@ type PackageVersionsResponse struct {
func createPackageVersionsResponse(pds []*packages_model.PackageDescriptor) *PackageVersionsResponse {
versions := make([]string, 0, len(pds))
for _, pd := range pds {
versions = append(versions, normalizeVersion(pd.SemVer))
versions = append(versions, pd.Version.Version)
}
return &PackageVersionsResponse{
@@ -248,15 +244,3 @@ func createSearchResult(l *linkBuilder, pds []*packages_model.PackageDescriptor)
RegistrationIndexURL: l.GetRegistrationIndexURL(latest.Package.Name),
}
}
// normalizeVersion removes the metadata
func normalizeVersion(v *version.Version) string {
var buf bytes.Buffer
segments := v.Segments64()
fmt.Fprintf(&buf, "%d.%d.%d", segments[0], segments[1], segments[2])
pre := v.Prerelease()
if pre != "" {
fmt.Fprintf(&buf, "-%s", pre)
}
return buf.String()
}

View File

@@ -490,6 +490,11 @@ func EditPullRequest(ctx *context.APIContext) {
issue := pr.Issue
issue.Repo = ctx.Repo.Repository
if err := issue.LoadAttributes(ctx); err != nil {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
if !issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWrite(unit.TypePullRequests) {
ctx.Status(http.StatusForbidden)
return

View File

@@ -12,6 +12,7 @@ import (
"strings"
activities_model "code.gitea.io/gitea/models/activities"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
@@ -268,3 +269,46 @@ func GetFeedType(name string, req *http.Request) (bool, string, string) {
return false, name, ""
}
// feedActionsToFeedItems convert gitea's Repo's Releases to feeds Item
func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, isReleasesOnly bool) (items []*feeds.Item, err error) {
for _, rel := range releases {
err := rel.LoadAttributes(ctx)
if err != nil {
return nil, err
}
var title, content string
if rel.IsTag {
title = rel.TagName
} else {
title = rel.Title
}
link := &feeds.Link{Href: rel.HTMLURL()}
content, err = markdown.RenderString(&markup.RenderContext{
Ctx: ctx,
URLPrefix: rel.Repo.Link(),
Metas: rel.Repo.ComposeMetas(),
}, rel.Note)
if err != nil {
return nil, err
}
items = append(items, &feeds.Item{
Title: title,
Link: link,
Created: rel.CreatedUnix.AsTime(),
Author: &feeds.Author{
Name: rel.Publisher.DisplayName(),
Email: rel.Publisher.GetEmail(),
},
Id: fmt.Sprintf("%v: %v", strconv.FormatInt(rel.ID, 10), link.Href),
Content: content,
})
}
return items, err
}

View File

@@ -0,0 +1,50 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package feed
import (
"time"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/context"
"github.com/gorilla/feeds"
)
// shows tags and/or releases on the repo as RSS / Atom feed
func ShowReleaseFeed(ctx *context.Context, repo *repo_model.Repository, isReleasesOnly bool, formatType string) {
releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{
IncludeTags: !isReleasesOnly,
})
if err != nil {
ctx.ServerError("GetReleasesByRepoID", err)
return
}
var title string
var link *feeds.Link
if isReleasesOnly {
title = ctx.Tr("repo.release.releases_for", repo.FullName())
link = &feeds.Link{Href: repo.HTMLURL() + "/release"}
} else {
title = ctx.Tr("repo.release.tags_for", repo.FullName())
link = &feeds.Link{Href: repo.HTMLURL() + "/tags"}
}
feed := &feeds.Feed{
Title: title,
Link: link,
Description: repo.Description,
Created: time.Now(),
}
feed.Items, err = releasesToFeedItems(ctx, releases, isReleasesOnly)
if err != nil {
ctx.ServerError("releasesToFeedItems", err)
return
}
writeFeed(ctx, feed, formatType)
}

View File

@@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
secret_model "code.gitea.io/gitea/models/secret"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/base"
@@ -25,7 +26,6 @@ import (
"code.gitea.io/gitea/services/org"
container_service "code.gitea.io/gitea/services/packages/container"
repo_service "code.gitea.io/gitea/services/repository"
secret_service "code.gitea.io/gitea/services/secrets"
user_service "code.gitea.io/gitea/services/user"
)
@@ -38,12 +38,12 @@ const (
tplSettingsHooks base.TplName = "org/settings/hooks"
// tplSettingsLabels template path for render labels settings
tplSettingsLabels base.TplName = "org/settings/labels"
// tplSettingsSecrets template path for render secrets settings
tplSettingsSecrets base.TplName = "org/settings/secrets"
// tplSettingsRunners template path for render runners settings
tplSettingsRunners base.TplName = "org/settings/runners"
// tplSettingsRunnersEdit template path for render runners edit settings
tplSettingsRunnersEdit base.TplName = "org/settings/runners_edit"
// tplSettingsSecrets template path for render secrets settings
tplSettingsSecrets base.TplName = "org/settings/secrets"
)
// Settings render the main settings page
@@ -259,11 +259,10 @@ func Secrets(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.secrets")
ctx.Data["PageIsOrgSettings"] = true
ctx.Data["PageIsOrgSettingsSecrets"] = true
ctx.Data["RequireTribute"] = true
secrets, err := secret_service.FindUserSecrets(ctx, ctx.Org.Organization.ID)
secrets, err := secret_model.FindSecrets(ctx, secret_model.FindSecretsOptions{OwnerID: ctx.Org.Organization.ID})
if err != nil {
ctx.ServerError("FindRepoSecrets", err)
ctx.ServerError("FindSecrets", err)
return
}
ctx.Data["Secrets"] = secrets
@@ -274,22 +273,28 @@ func Secrets(ctx *context.Context) {
// SecretsPost add secrets
func SecretsPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.AddSecretForm)
if err := secret_service.InsertOrgSecret(ctx, ctx.Org.Organization.ID, form.Title, form.Content, form.PullRequestRead); err != nil {
ctx.ServerError("InsertRepoSecret", err)
_, err := secret_model.InsertEncryptedSecret(ctx, ctx.Org.Organization.ID, 0, form.Title, form.Content)
if err != nil {
ctx.Flash.Error(ctx.Tr("secrets.creation.failed"))
log.Error("validate secret: %v", err)
ctx.Redirect(ctx.Org.OrgLink + "/settings/secrets")
return
}
log.Trace("Secret added: %d", ctx.Org.Organization.ID)
ctx.Flash.Success(ctx.Tr("repo.settings.add_secret_success", form.Title))
log.Trace("Org %d: secret added", ctx.Org.Organization.ID)
ctx.Flash.Success(ctx.Tr("secrets.creation.success", form.Title))
ctx.Redirect(ctx.Org.OrgLink + "/settings/secrets")
}
// SecretsDelete delete secrets
func SecretsDelete(ctx *context.Context) {
if err := secret_service.DeleteSecretByID(ctx, ctx.FormInt64("id")); err != nil {
ctx.Flash.Error("DeleteSecretByID: " + err.Error())
id := ctx.FormInt64("id")
if _, err := db.DeleteByBean(ctx, &secret_model.Secret{ID: id}); err != nil {
ctx.Flash.Error(ctx.Tr("secrets.deletion.failed"))
log.Error("delete secret %d: %v", id, err)
} else {
ctx.Flash.Success(ctx.Tr("repo.settings.secret_deletion_success"))
ctx.Flash.Success(ctx.Tr("secrets.deletion.success"))
}
ctx.JSON(http.StatusOK, map[string]interface{}{

View File

@@ -23,6 +23,7 @@ import (
"code.gitea.io/gitea/modules/upload"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/web/feed"
"code.gitea.io/gitea/services/forms"
releaseservice "code.gitea.io/gitea/services/release"
)
@@ -199,6 +200,30 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
ctx.HTML(http.StatusOK, tplReleases)
}
// ReleasesFeedRSS get feeds for releases in RSS format
func ReleasesFeedRSS(ctx *context.Context) {
releasesOrTagsFeed(ctx, true, "rss")
}
// TagsListFeedRSS get feeds for tags in RSS format
func TagsListFeedRSS(ctx *context.Context) {
releasesOrTagsFeed(ctx, false, "rss")
}
// ReleasesFeedAtom get feeds for releases in Atom format
func ReleasesFeedAtom(ctx *context.Context) {
releasesOrTagsFeed(ctx, true, "atom")
}
// TagsListFeedAtom get feeds for tags in RSS format
func TagsListFeedAtom(ctx *context.Context) {
releasesOrTagsFeed(ctx, false, "atom")
}
func releasesOrTagsFeed(ctx *context.Context, isReleasesOnly bool, formatType string) {
feed.ShowReleaseFeed(ctx, ctx.Repo.Repository, isReleasesOnly, formatType)
}
// SingleRelease renders a single release's page
func SingleRelease(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.release.releases")

View File

@@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
secret_model "code.gitea.io/gitea/models/secret"
unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
@@ -44,7 +45,6 @@ import (
mirror_service "code.gitea.io/gitea/services/mirror"
org_service "code.gitea.io/gitea/services/org"
repo_service "code.gitea.io/gitea/services/repository"
secret_service "code.gitea.io/gitea/services/secrets"
wiki_service "code.gitea.io/gitea/services/wiki"
)
@@ -1123,9 +1123,9 @@ func DeployKeys(ctx *context.Context) {
}
ctx.Data["Deploykeys"] = keys
secrets, err := secret_service.FindRepoSecrets(ctx, ctx.Repo.Repository.ID)
secrets, err := secret_model.FindSecrets(ctx, secret_model.FindSecretsOptions{RepoID: ctx.Repo.Repository.ID})
if err != nil {
ctx.ServerError("FindRepoSecrets", err)
ctx.ServerError("FindSecrets", err)
return
}
ctx.Data["Secrets"] = secrets
@@ -1135,26 +1135,24 @@ func DeployKeys(ctx *context.Context) {
// SecretsPost response for creating a new secret
func SecretsPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.AddKeyForm)
if err := secret_service.InsertRepoSecret(ctx, ctx.Repo.Repository.ID, form.Title, form.Content, form.PullRequestRead); err != nil {
ctx.ServerError("InsertRepoSecret", err)
form := web.GetForm(ctx).(*forms.AddSecretForm)
_, err := secret_model.InsertEncryptedSecret(ctx, 0, ctx.Repo.Repository.ID, form.Title, form.Content)
if err != nil {
ctx.Flash.Error(ctx.Tr("secrets.creation.failed"))
log.Error("validate secret: %v", err)
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
return
}
log.Trace("Secret added: %d", ctx.Repo.Repository.ID)
ctx.Flash.Success(ctx.Tr("repo.settings.add_secret_success", form.Title))
ctx.Flash.Success(ctx.Tr("secrets.creation.success", form.Title))
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
}
// DeployKeysPost response for adding a deploy key of a repository
func DeployKeysPost(ctx *context.Context) {
if ctx.FormString("act") == "secret" {
SecretsPost(ctx)
return
}
form := web.GetForm(ctx).(*forms.AddKeyForm)
ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys")
ctx.Data["PageIsSettingsKeys"] = true
ctx.Data["DisableSSH"] = setting.SSH.Disabled
@@ -1214,10 +1212,12 @@ func DeployKeysPost(ctx *context.Context) {
}
func DeleteSecret(ctx *context.Context) {
if err := secret_service.DeleteSecretByID(ctx, ctx.FormInt64("id")); err != nil {
ctx.Flash.Error("DeleteSecretByID: " + err.Error())
id := ctx.FormInt64("id")
if _, err := db.DeleteByBean(ctx, &secret_model.Secret{ID: id}); err != nil {
ctx.Flash.Error(ctx.Tr("secrets.deletion.failed"))
log.Error("delete secret %d: %v", id, err)
} else {
ctx.Flash.Success(ctx.Tr("repo.settings.secret_deletion_success"))
ctx.Flash.Success(ctx.Tr("secrets.deletion.success"))
}
ctx.JSON(http.StatusOK, map[string]interface{}{
@@ -1227,11 +1227,6 @@ func DeleteSecret(ctx *context.Context) {
// DeleteDeployKey response for deleting a deploy key
func DeleteDeployKey(ctx *context.Context) {
if ctx.FormString("act") == "secret" {
DeleteSecret(ctx)
return
}
if err := asymkey_service.DeleteDeployKey(ctx.Doer, ctx.FormInt64("id")); err != nil {
ctx.Flash.Error("DeleteDeployKey: " + err.Error())
} else {

View File

@@ -272,7 +272,7 @@ func getFileReader(repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileIn
}
meta, err := git_model.GetLFSMetaObjectByOid(repoID, pointer.Oid)
if err != git_model.ErrLFSObjectNotExist { // fallback to plain file
if err != nil && err != git_model.ErrLFSObjectNotExist { // fallback to plain file
return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
}

View File

@@ -935,6 +935,10 @@ func RegisterRoutes(m *web.Route) {
m.Combo("").Get(repo.DeployKeys).
Post(web.Bind(forms.AddKeyForm{}), repo.DeployKeysPost)
m.Post("/delete", repo.DeleteDeployKey)
m.Group("/secrets", func() {
m.Post("", web.Bind(forms.AddSecretForm{}), repo.SecretsPost)
m.Post("/delete", repo.DeleteSecret)
})
})
m.Group("/lfs", func() {
@@ -1108,12 +1112,21 @@ func RegisterRoutes(m *web.Route) {
// Releases
m.Group("/{username}/{reponame}", func() {
m.Get("/tags", repo.TagsList, repo.MustBeNotEmpty,
reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag))
m.Group("/tags", func() {
m.Get("", repo.TagsList)
m.Get(".rss", feedEnabled, repo.TagsListFeedRSS)
m.Get(".atom", feedEnabled, repo.TagsListFeedAtom)
}, func(ctx *context.Context) {
ctx.Data["EnableFeed"] = setting.EnableFeed
}, repo.MustBeNotEmpty, reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag, true))
m.Group("/releases", func() {
m.Get("/", repo.Releases)
m.Get("/tag/*", repo.SingleRelease)
m.Get("/latest", repo.LatestRelease)
m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS)
m.Get(".atom", feedEnabled, repo.ReleasesFeedAtom)
}, func(ctx *context.Context) {
ctx.Data["EnableFeed"] = setting.EnableFeed
}, repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag, true))
m.Get("/releases/attachments/{uuid}", repo.GetAttachment, repo.MustBeNotEmpty, reqRepoReleaseReader)
m.Group("/releases", func() {