Skip to content

Commit 0b51072

Browse files
kolaentetechknowlogick
authored andcommitted
Feature: Archive repos (#5009)
1 parent 6ad834e commit 0b51072

30 files changed

+436
-243
lines changed

models/repo.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,9 @@ type Repository struct {
186186
NumOpenMilestones int `xorm:"-"`
187187
NumReleases int `xorm:"-"`
188188

189-
IsPrivate bool `xorm:"INDEX"`
190-
IsEmpty bool `xorm:"INDEX"`
189+
IsPrivate bool `xorm:"INDEX"`
190+
IsEmpty bool `xorm:"INDEX"`
191+
IsArchived bool `xorm:"INDEX"`
191192

192193
IsMirror bool `xorm:"INDEX"`
193194
*Mirror `xorm:"-"`
@@ -292,6 +293,7 @@ func (repo *Repository) innerAPIFormat(e Engine, mode AccessMode, isParent bool)
292293
Description: repo.Description,
293294
Private: repo.IsPrivate,
294295
Empty: repo.IsEmpty,
296+
Archived: repo.IsArchived,
295297
Size: int(repo.Size / 1024),
296298
Fork: repo.IsFork,
297299
Parent: parent,
@@ -2341,6 +2343,13 @@ func CheckRepoStats() {
23412343
// ***** END: Repository.NumForks *****
23422344
}
23432345

2346+
// SetArchiveRepoState sets if a repo is archived
2347+
func (repo *Repository) SetArchiveRepoState(isArchived bool) (err error) {
2348+
repo.IsArchived = isArchived
2349+
_, err = x.Where("id = ?", repo.ID).Cols("is_archived").Update(repo)
2350+
return
2351+
}
2352+
23442353
// ___________ __
23452354
// \_ _____/__________| | __
23462355
// | __)/ _ \_ __ \ |/ /

modules/auth/repo_form.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ type RepoSettingForm struct {
117117
EnableTimetracker bool
118118
AllowOnlyContributorsToTrackTime bool
119119
EnableIssueDependencies bool
120+
IsArchived bool
120121

121122
// Admin settings
122123
EnableHealthCheck bool

modules/context/repo.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,23 @@ type Repository struct {
5656

5757
// CanEnableEditor returns true if repository is editable and user has proper access level.
5858
func (r *Repository) CanEnableEditor() bool {
59-
return r.Permission.CanWrite(models.UnitTypeCode) && r.Repository.CanEnableEditor() && r.IsViewBranch
59+
return r.Permission.CanWrite(models.UnitTypeCode) && r.Repository.CanEnableEditor() && r.IsViewBranch && !r.Repository.IsArchived
6060
}
6161

6262
// CanCreateBranch returns true if repository is editable and user has proper access level.
6363
func (r *Repository) CanCreateBranch() bool {
6464
return r.Permission.CanWrite(models.UnitTypeCode) && r.Repository.CanCreateBranch()
6565
}
6666

67+
// RepoMustNotBeArchived checks if a repo is archived
68+
func RepoMustNotBeArchived() macaron.Handler {
69+
return func(ctx *Context) {
70+
if ctx.Repo.Repository.IsArchived {
71+
ctx.NotFound("IsArchived", fmt.Errorf(ctx.Tr("repo.archive.title")))
72+
}
73+
}
74+
}
75+
6776
// CanCommitToBranch returns true if repository is editable and user has proper access level
6877
// and branch is not protected for push
6978
func (r *Repository) CanCommitToBranch(doer *models.User) (bool, error) {

options/locale/locale_en-US.ini

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,10 @@ forks = Forks
542542
pick_reaction = Pick your reaction
543543
reactions_more = and %d more
544544
545+
archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
546+
archive.issue.nocomment = This repo is archived. You cannot comment on issues.
547+
archive.pull.nocomment = This repo is archived. You cannot comment on pull requests.
548+
545549
form.reach_limit_of_creation = You have already reached your limit of %d repositories.
546550
form.name_reserved = The repository name '%s' is reserved.
547551
form.name_pattern_not_allowed = The pattern '%s' is not allowed in a repository name.
@@ -1176,6 +1180,18 @@ settings.choose_branch = Choose a branch…
11761180
settings.no_protected_branch = There are no protected branches.
11771181
settings.edit_protected_branch = Edit
11781182
settings.protected_branch_required_approvals_min = Required approvals cannot be negative.
1183+
settings.archive.button = Archive Repo
1184+
settings.archive.header = Archive This Repo
1185+
settings.archive.text = Archiving the repo will make it entirely read-only. It is hidden from the dashboard, cannot be committed to and no issues or pull-requests can be created.
1186+
settings.archive.success = The repo was successfully archived.
1187+
settings.archive.error = An error occured while trying to archive the repo. See the log for more details.
1188+
settings.archive.error_ismirror = You cannot archive a mirrored repo.
1189+
settings.archive.branchsettings_unavailable = Branch settings are not available if the repo is archived.
1190+
settings.unarchive.button = Un-Archive Repo
1191+
settings.unarchive.header = Un-Archive This Repo
1192+
settings.unarchive.text = Un-Archiving the repo will restore its ability to recieve commits and pushes, as well as new issues and pull-requests.
1193+
settings.unarchive.success = The repo was successfully un-archived.
1194+
settings.unarchive.error = An error occured while trying to un-archive the repo. See the log for more details.
11791195
11801196
diff.browse_source = Browse Source
11811197
diff.parent = parent

public/css/index.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/less/_base.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,3 +629,11 @@ footer {
629629
.heatmap-color-5 {
630630
background-color: #2f6b1b;
631631
}
632+
633+
.archived-icon{
634+
color: lighten(#000, 70%) !important;
635+
}
636+
637+
.archived-icon{
638+
color: lighten(#000, 70%) !important;
639+
}

routers/repo/http.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ func HTTP(ctx *context.Context) {
9595
return
9696
}
9797

98+
// Don't allow pushing if the repo is archived
99+
if repo.IsArchived && !isPull {
100+
ctx.HandleText(http.StatusForbidden, "This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.")
101+
return
102+
}
103+
98104
// Only public pull don't need auth.
99105
isPublicPull := !repo.IsPrivate && isPull
100106
var (

routers/repo/release.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func Releases(ctx *context.Context) {
6767
}
6868

6969
writeAccess := ctx.Repo.CanWrite(models.UnitTypeReleases)
70-
ctx.Data["CanCreateRelease"] = writeAccess
70+
ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
7171

7272
opts := models.FindReleasesOptions{
7373
IncludeDrafts: writeAccess,

routers/repo/setting.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,47 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
354354
ctx.Flash.Success(ctx.Tr("repo.settings.wiki_deletion_success"))
355355
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
356356

357+
case "archive":
358+
if !ctx.Repo.IsOwner() {
359+
ctx.Error(403)
360+
return
361+
}
362+
363+
if repo.IsMirror {
364+
ctx.Flash.Error(ctx.Tr("repo.settings.archive.error_ismirror"))
365+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
366+
return
367+
}
368+
369+
if err := repo.SetArchiveRepoState(true); err != nil {
370+
log.Error(4, "Tried to archive a repo: %s", err)
371+
ctx.Flash.Error(ctx.Tr("repo.settings.archive.error"))
372+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
373+
return
374+
}
375+
376+
ctx.Flash.Success(ctx.Tr("repo.settings.archive.success"))
377+
378+
log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
379+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
380+
case "unarchive":
381+
if !ctx.Repo.IsOwner() {
382+
ctx.Error(403)
383+
return
384+
}
385+
386+
if err := repo.SetArchiveRepoState(false); err != nil {
387+
log.Error(4, "Tried to unarchive a repo: %s", err)
388+
ctx.Flash.Error(ctx.Tr("repo.settings.unarchive.error"))
389+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
390+
return
391+
}
392+
393+
ctx.Flash.Success(ctx.Tr("repo.settings.unarchive.success"))
394+
395+
log.Trace("Repository was un-archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
396+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
397+
357398
default:
358399
ctx.NotFound("", nil)
359400
}

routers/repo/view.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ func renderDirectory(ctx *context.Context, treeLink string) {
151151

152152
// Check permission to add or upload new file.
153153
if ctx.Repo.CanWrite(models.UnitTypeCode) && ctx.Repo.IsViewBranch {
154-
ctx.Data["CanAddFile"] = true
155-
ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled
154+
ctx.Data["CanAddFile"] = !ctx.Repo.Repository.IsArchived
155+
ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled && !ctx.Repo.Repository.IsArchived
156156
}
157157
}
158158

0 commit comments

Comments
 (0)