Feature: Archive repos (#5009)
This commit is contained in:
@@ -95,6 +95,12 @@ func HTTP(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't allow pushing if the repo is archived
|
||||
if repo.IsArchived && !isPull {
|
||||
ctx.HandleText(http.StatusForbidden, "This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.")
|
||||
return
|
||||
}
|
||||
|
||||
// Only public pull don't need auth.
|
||||
isPublicPull := !repo.IsPrivate && isPull
|
||||
var (
|
||||
|
||||
@@ -67,7 +67,7 @@ func Releases(ctx *context.Context) {
|
||||
}
|
||||
|
||||
writeAccess := ctx.Repo.CanWrite(models.UnitTypeReleases)
|
||||
ctx.Data["CanCreateRelease"] = writeAccess
|
||||
ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
|
||||
|
||||
opts := models.FindReleasesOptions{
|
||||
IncludeDrafts: writeAccess,
|
||||
|
||||
@@ -354,6 +354,47 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.wiki_deletion_success"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
case "archive":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Error(403)
|
||||
return
|
||||
}
|
||||
|
||||
if repo.IsMirror {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.archive.error_ismirror"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
return
|
||||
}
|
||||
|
||||
if err := repo.SetArchiveRepoState(true); err != nil {
|
||||
log.Error(4, "Tried to archive a repo: %s", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.archive.error"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.archive.success"))
|
||||
|
||||
log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
case "unarchive":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Error(403)
|
||||
return
|
||||
}
|
||||
|
||||
if err := repo.SetArchiveRepoState(false); err != nil {
|
||||
log.Error(4, "Tried to unarchive a repo: %s", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.unarchive.error"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.unarchive.success"))
|
||||
|
||||
log.Trace("Repository was un-archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
default:
|
||||
ctx.NotFound("", nil)
|
||||
}
|
||||
|
||||
@@ -151,8 +151,8 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
|
||||
// Check permission to add or upload new file.
|
||||
if ctx.Repo.CanWrite(models.UnitTypeCode) && ctx.Repo.IsViewBranch {
|
||||
ctx.Data["CanAddFile"] = true
|
||||
ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled
|
||||
ctx.Data["CanAddFile"] = !ctx.Repo.Repository.IsArchived
|
||||
ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled && !ctx.Repo.Repository.IsArchived
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ func renderWikiPage(ctx *context.Context, isViewPage bool) (*git.Repository, *gi
|
||||
// Wiki renders single wiki page
|
||||
func Wiki(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki)
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) && !ctx.Repo.Repository.IsArchived
|
||||
|
||||
if !ctx.Repo.Repository.HasWiki() {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.wiki")
|
||||
@@ -246,7 +246,7 @@ func WikiPages(ctx *context.Context) {
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("repo.wiki.pages")
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki)
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) && !ctx.Repo.Repository.IsArchived
|
||||
|
||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
if err != nil {
|
||||
|
||||
+17
-17
@@ -492,7 +492,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Group("/branches", func() {
|
||||
m.Combo("").Get(repo.ProtectedBranch).Post(repo.ProtectedBranchPost)
|
||||
m.Combo("/*").Get(repo.SettingsProtectedBranch).
|
||||
Post(bindIgnErr(auth.ProtectBranchForm{}), repo.SettingsProtectedBranchPost)
|
||||
Post(bindIgnErr(auth.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo.SettingsProtectedBranchPost)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
@@ -530,13 +530,13 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.UnitTypes(), context.RepoRef())
|
||||
|
||||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
|
||||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.RepoMustNotBeArchived(), repo.Action)
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("/issues", func() {
|
||||
m.Combo("/new").Get(context.RepoRef(), repo.NewIssue).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
|
||||
}, reqRepoIssueReader)
|
||||
}, context.RepoMustNotBeArchived(), reqRepoIssueReader)
|
||||
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest.
|
||||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/issues", func() {
|
||||
@@ -557,24 +557,24 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
})
|
||||
})
|
||||
m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeIssueReaction)
|
||||
})
|
||||
}, context.RepoMustNotBeArchived())
|
||||
|
||||
m.Post("/labels", reqRepoIssuesOrPullsWriter, repo.UpdateIssueLabel)
|
||||
m.Post("/milestone", reqRepoIssuesOrPullsWriter, repo.UpdateIssueMilestone)
|
||||
m.Post("/assignee", reqRepoIssuesOrPullsWriter, repo.UpdateIssueAssignee)
|
||||
m.Post("/status", reqRepoIssuesOrPullsWriter, repo.UpdateIssueStatus)
|
||||
})
|
||||
}, context.RepoMustNotBeArchived())
|
||||
m.Group("/comments/:id", func() {
|
||||
m.Post("", repo.UpdateCommentContent)
|
||||
m.Post("/delete", repo.DeleteComment)
|
||||
m.Post("/reactions/:action", bindIgnErr(auth.ReactionForm{}), repo.ChangeCommentReaction)
|
||||
})
|
||||
}, context.RepoMustNotBeArchived())
|
||||
m.Group("/labels", func() {
|
||||
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
|
||||
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
|
||||
m.Post("/delete", repo.DeleteLabel)
|
||||
m.Post("/initialize", bindIgnErr(auth.InitializeLabelsForm{}), repo.InitializeLabels)
|
||||
}, reqRepoIssuesOrPullsWriter, context.RepoRef())
|
||||
}, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef())
|
||||
m.Group("/milestones", func() {
|
||||
m.Combo("/new").Get(repo.NewMilestone).
|
||||
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
|
||||
@@ -582,7 +582,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
|
||||
m.Get("/:id/:action", repo.ChangeMilestonStatus)
|
||||
m.Post("/delete", repo.DeleteMilestone)
|
||||
}, reqRepoIssuesOrPullsWriter, context.RepoRef())
|
||||
}, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef())
|
||||
m.Group("/milestone", func() {
|
||||
m.Get("/:id", repo.MilestoneIssuesAndPulls)
|
||||
}, reqRepoIssuesOrPullsWriter, context.RepoRef())
|
||||
@@ -607,7 +607,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Post("/upload-file", repo.UploadFileToServer)
|
||||
m.Post("/upload-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
|
||||
}, context.RepoRef(), repo.MustBeEditable, repo.MustBeAbleToUpload)
|
||||
}, reqRepoCodeWriter, repo.MustBeNotEmpty)
|
||||
}, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/branches", func() {
|
||||
m.Group("/_new/", func() {
|
||||
@@ -617,7 +617,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
}, bindIgnErr(auth.NewBranchForm{}))
|
||||
m.Post("/delete", repo.DeleteBranchPost)
|
||||
m.Post("/restore", repo.RestoreBranchPost)
|
||||
}, reqRepoCodeWriter, repo.MustBeNotEmpty)
|
||||
}, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty)
|
||||
|
||||
}, reqSignIn, context.RepoAssignment(), context.UnitTypes())
|
||||
|
||||
@@ -630,11 +630,11 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Get("/new", repo.NewRelease)
|
||||
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
|
||||
m.Post("/delete", repo.DeleteRelease)
|
||||
}, reqSignIn, repo.MustBeNotEmpty, reqRepoReleaseWriter, context.RepoRef())
|
||||
}, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef())
|
||||
m.Group("/releases", func() {
|
||||
m.Get("/edit/*", repo.EditRelease)
|
||||
m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
|
||||
}, reqSignIn, repo.MustBeNotEmpty, reqRepoReleaseWriter, func(ctx *context.Context) {
|
||||
}, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, func(ctx *context.Context) {
|
||||
var err error
|
||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
|
||||
if err != nil {
|
||||
@@ -652,7 +652,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Post("/topics", repo.TopicsPost)
|
||||
}, context.RepoAssignment(), reqRepoAdmin)
|
||||
}, context.RepoMustNotBeArchived(), context.RepoAssignment(), reqRepoAdmin)
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("", func() {
|
||||
@@ -672,7 +672,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Combo("/:page/_edit").Get(repo.EditWiki).
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
|
||||
m.Post("/:page/delete", repo.DeleteWikiPagePost)
|
||||
}, reqSignIn, reqRepoWikiWriter)
|
||||
}, context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter)
|
||||
}, repo.MustEnableWiki, context.RepoRef())
|
||||
|
||||
m.Group("/wiki", func() {
|
||||
@@ -694,14 +694,14 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Get(".diff", repo.DownloadPullDiff)
|
||||
m.Get(".patch", repo.DownloadPullPatch)
|
||||
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
|
||||
m.Post("/merge", reqRepoPullsWriter, bindIgnErr(auth.MergePullRequestForm{}), repo.MergePullRequest)
|
||||
m.Post("/cleanup", context.RepoRef(), repo.CleanUpPullRequest)
|
||||
m.Post("/merge", context.RepoMustNotBeArchived(), reqRepoPullsWriter, bindIgnErr(auth.MergePullRequestForm{}), repo.MergePullRequest)
|
||||
m.Post("/cleanup", context.RepoMustNotBeArchived(), context.RepoRef(), repo.CleanUpPullRequest)
|
||||
m.Group("/files", func() {
|
||||
m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.ViewPullFiles)
|
||||
m.Group("/reviews", func() {
|
||||
m.Post("/comments", bindIgnErr(auth.CodeCommentForm{}), repo.CreateCodeComment)
|
||||
m.Post("/submit", bindIgnErr(auth.SubmitReviewForm{}), repo.SubmitReview)
|
||||
})
|
||||
}, context.RepoMustNotBeArchived())
|
||||
})
|
||||
}, repo.MustAllowPulls)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user