Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added dependencies for issues (#2196) #2531

Merged
merged 380 commits into from
Jul 17, 2018
Merged

Conversation

kolaente
Copy link
Member

@kolaente kolaente commented Sep 17, 2017

Introduction

This PR implements dependencies for issues, as described in #2196.

It lets you define anonther issue as a dependency for an issue. You the cannot close the issue if it has any dependent issues which aren't closed. If you try to autoclose an issue via commit message which still has dependencies left, autoclose will simply not close the issue, but the commit will not fail.

You can disable dependencies in the repo settings.

Example: You set #2, #3 and #4 as a dependency of #1. Now you need to close all #2, #3 and #4, before you can close #1.

Screenshots

Overview of Issue Dependencies (sidebar):
Overview of Issue Dependencies (sidebar):

Comments after adding a new dependency:
Comments after adding a new dependency

Questions

Currently, i would describe this as "working, but not finished", as there are some questions i have:

  1. For now, you need the issue ID (not the index) to create a dependency. This is not very user-friendly, I'd like to have some kind of search bar where you search for the issue title/index select it, and it'll do the rest. Problem: There is no API-Endpoint to search for issues like that (Or just returns a list of all issues as JSON). I think this should be implemented first.
    If such thing already exists, please point me to it, I haven't found any.
  2. It is currently possible to create dependencies with issues from other repositories. Is this okay? Or should one not be able to do this, as it could create a massive overhead with all permission-checking etc.
  3. There is some work to be done with migrations etc, currently i simply put the xorm-call at the beginning of the function, which probably shouldn't be there. Where is the appropriate place to put this?

This is my first time I've done something like this in Go, before i've only played around with Go but never really did anything bigger. So, there are probably some things I didn't got right as a novice. Looking forward to hear your improvents to be made! Also thanks to @JonasFranzDEV who has helped me a lot.

Copy link
Member

@jonasfranz jonasfranz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase to master.

sess := x.NewSession()

// TODO: Move this to the appropriate place
err = x.Sync(new(IssueDependency))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to a migration.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As i stated above:

There is some work to be done with migrations etc, currently i simply put the xorm-call at the beginning of the function, which probably shouldn't be there. Where is the appropriate place to put this?

Where?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migrations are found in models/migrations. Create a new one and call from migrations.go.

sess := x.NewSession()

// TODO: Same as above
err = x.Sync(new(IssueDependency))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to a migration.

models/repo.go Outdated
@@ -666,6 +668,41 @@ func (repo *Repository) CanEnableEditor() bool {
return !repo.IsMirror
}

// Find all Dependencies an issue is blocked by
func (repo *Repository) BlockedByDependencies(issueID int64) (_ []*Issue, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace _ []*Issue with issueDepsFull []*Issue and remove var issueDepsFull = make([]*Issue, 0).

@lafriks lafriks added the type/feature Completely new functionality. Can only be merged if feature freeze is not active. label Sep 17, 2017
@lafriks lafriks added this to the 1.x.x milestone Sep 17, 2017
}

// RemoveIssueDependency removes a dependency from an issue
func RemoveIssueDependency(user *User, issue *Issue, dep *Issue, depType int64) (err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create custom type for depType and constant for each type. Maybe type issueDependencyType int. Also why int64 when you are using only 1 or 2? Even byte would be sufficient.

// If it exists, remove it, otherwise show an error message
if exists {

if depType == 1 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use custom type and define constants instead of hardcoded values.

}
}

if depType == 2 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use custom type and define constants instead of hardcoded values.

return
}

if depType != 1 && depType != 2 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use custom type and define constants instead of hardcoded values.

}

// Dependency Type
// Types: 1 = blockedBy, 2 = blocking
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create constants for known options.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now you don't need these comments if you have custom types (or you define map as suggested in aother comment)

func IssueNoDependenciesLeft(issue *Issue) bool {

var issueDeps []IssueDependency
err := x.Where("issue_id = ?", issue.ID).Find(&issueDeps)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create just one, complex query (join IssueDependecy and Issue table).

models/repo.go Outdated
// BlockedByDependencies finds all Dependencies an issue is blocked by
func (repo *Repository) BlockedByDependencies(issueID int64) (_ []*Issue, err error) {

issueDeps, err := repo.getBlockedByDependencies(x, issueID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create one complex query to find all issues.

models/repo.go Outdated
// BlockingDependencies returns all blocking dependencies
func (repo *Repository) BlockingDependencies(issueID int64) (_ []*Issue, err error) {

issueDeps, err := repo.getBlockingDependencies(x, issueID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create one complex query to find all issues.


canbeClosed := models.IssueNoDependenciesLeft(issue)

if !canbeClosed {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if !models.IssueNoDependenciesLeft(issue)

@@ -428,6 +428,14 @@ func MergePullRequest(ctx *context.Context) {

pr.Issue = issue
pr.Issue.Repo = ctx.Repo.Repository
canbeClosed := models.IssueNoDependenciesLeft(issue)

if !canbeClosed {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if !models.IssueNoDependenciesLeft(issue)

@lunny lunny added the pr/wip This PR is not ready for review label Sep 18, 2017
@kolaente
Copy link
Member Author

@Morlinest @JonasFranzDEV Done.

@tboerger tboerger added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Sep 24, 2017
@lunny
Copy link
Member

lunny commented Sep 24, 2017

@kolaente conflicting files.

@kolaente
Copy link
Member Author

@lunny Done.

@@ -15,43 +15,21 @@ type IssueDependency struct {
IssueID int64 `xorm:"UNIQUE(watch) NOT NULL"`
DependencyID int64 `xorm:"UNIQUE(watch) NOT NULL"`
Created time.Time `xorm:"-"`
CreatedUnix int64 `xorm:"NOT NULL"`
CreatedUnix int64 `xorm:"INDEX created"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INDEX is optional, don't know if you need it or just used code from previous review.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've just used it, think it works.

// Define Dependency Type Constants
const (
DependencyTypeBlockedBy int64 = 1
DependencyTypeBlocking int64 = 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type DependencyType int

const (
	DependencyTypeBlockedBy DependencyType = iota
	DependencyTypeBlocking
)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how do i check for the given type by the user in routers/repo/issue_dependency_remove.go:33?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please read all comments first. I think I've already answered it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the compiler complains because i cannot compare an int with a custom type DepenencyType (although they both are ints).
Or did I overlooked something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't have place where you compare int with custom type. What error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error was something like "You cannot compare a variable of type int with a variable of type DependencyType". But it's ok i guess, i've solved it differently.

}

// RemoveIssueDependency removes a dependency from an issue
func RemoveIssueDependency(user *User, issue *Issue, dep *Issue, depType int64) (err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RemoveIssueDependency(user *User, issue *Issue, dep *Issue, depType DependencyType)


// Dependency Type
// Types: 1 = blockedBy, 2 = blocking
depType, err := strconv.ParseInt(c.Req.PostForm.Get("dependencyType"), 10, 64)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use map. Eg:

depTypes := map[int]DependencyType{1: DependencyTypeBlockedBy, 2: DependencyTypeBlocking}

and check:

depType, ok := depTypes[c.QueryInt("dependencyType")]
if !ok {
	c.Handle(http.StatusBadRequest, "GetDependecyType", nil)
	return
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like the idea, but wouldn't this mean i had to define the dependency types two times? (which i'd rather want to avoid)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think no. This is mapping. Actualy I think you can change it from int to string and use strings in post calls (as it would be more descriptive). Something like:

map[int]DependencyType{"blockedby": DependencyTypeBlockedBy, "blocking": DependencyTypeBlocking}

You know that DependencyTypeXYZ is also int, but in reality it is custom type that can be anything. If you use constnants you don't care about real type (it can be type DependencyType string for example). Also it's not same number:

const (
	DependencyTypeBlockedBy DependencyType = iota    // = 0
	DependencyTypeBlocking                           // = 1
)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solved it without a map.

}
}

if depType == DependencyTypeBlocking {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use else if or switch. What if depType has other values? You shoould check that too. Also you can store IssueDependency in variable and then call x.Delete(). Eg:

var issueDepToDelete IssueDependency

switch depType {
case DependencyTypeBlockedBy:
	issueDepToDelete = IssueDependency{IssueID: issue.ID, DependencyID: dep.ID}
case DependencyTypeBlocking:
	issueDepToDelete = IssueDependency{IssueID: dep.ID, DependencyID: issue.ID}
default:
	// return error
}

_, err := x.Delete(&issueDepToDelete)
if err != nil {
	return err
}

sess := x.NewSession()

// Check if it exists
exists, err := issueDepExists(x, issue.ID, dep.ID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do check where you switch issue for dep, but later you are deleting in given order. What it should do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It checks if the dependency already exists as you send it to the backend, but it also checks the other way around to prevent to issues blocking each other. This would result in none of them could be closed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

}

// Check if the dependency already exists
func issueDepExists(e Engine, issueID int64, depID int64) (exists bool, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like names issueID and depID because you are switching their meaning inside function.

Copy link
Member Author

@kolaente kolaente Sep 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First issueID means issueID and second time issueID means depID. I think both arguments are equivalent because you are trying to find dependency between them not matter which way. Variable names should reflect this fact (eg. issue1ID, issue2ID int64).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I try to find all dependencies, no matter of direction.
But: issueID is the issue we're currently on, depID is the other issue we want to look for. I think it would be more confunsing to rename the variables to issue1ID etc. I would prefer keeping it the way it is.

To be more clear, an example:
When I'm on issue #1 and want to add a new dependency of #2 i send a request to the backend saying something like "Hi, I'm issue #1 and want to add #2 as my dependent issue.". The dependend issue (#2) becomes depID, the issue we're on becomes isuueID.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with that as long as issueDepExists stays unexported and is used only for your mentioned scenario.

I was thinking about it in more general way. Like using this function for checking (from any place of code) any dependency between two issues.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, cool.

I think to be more general, it would need to return a struct with both issues, but i dont see a usecase for this (yet).

}
}

if err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move err check before range.

}

// Dependency Type
// Types: 1 = blockedBy, 2 = blocking
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now you don't need these comments if you have custom types (or you define map as suggested in aother comment)

// Check for open dependencies
if form.Status == "close" {

if models.IssueNoDependenciesLeft(issue) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if form.Status == "close" && models.IssueNoDependenciesLeft(issue)

@@ -1,7 +1,7 @@
{{range .Issue.Comments}}
{{ $createdStr:= TimeSince .Created $.Lang }}

<!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF, 5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 12 = START_TRACKING, 13 = STOP_TRACKING, 14 = ADD_TIME_MANUAL -->
<!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF, 5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 12 = START_TRACKING, 13 = STOP_TRACKING, 14 = ADD_TIME_MANUAL, 15 = CANCEL_TIME_TRACKING, 16 = ADDED_DEPENDENCY, 17 = REMOVED_DEPENDENCY -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

16 = ADD_DEPENDENCY, 17 = REMOVE_DEPENDENCY

@Morlinest
Copy link
Member

Can you add some screenshots pls?

@kolaente
Copy link
Member Author

@Morlinest of course, please see my updated first comment.

@kolaente
Copy link
Member Author

And we really need a better way to search for other issues (see my first question)

@Morlinest
Copy link
Member

@kolaente Thx for screenshots. And yes, we need better search. Adding issue search api would be great.

@kolaente
Copy link
Member Author

Adding issue search api would be great.
@Morlinest wouldn't this be a seperate pr?

@Morlinest
Copy link
Member

Yes, as another PR. Maybe I can do something with it.

@kolaente
Copy link
Member Author

I've created a seperate issue for the api endpoint so we dont forget it: #2597
@Morlinest

@kolaente
Copy link
Member Author

However, am i right when i say this pr is blocked until we have an apiendpoint to search for issues?

@Morlinest
Copy link
Member

@kolaente No. Searching can be added later. Also I am working on issue search api right now, There is api endpoint for issues, but doesn't contains search by part of ID. You can wait for it or use it as it is now, without partialy ID matching.

@kolaente
Copy link
Member Author

Ok, cool. But i should change it so you only need the issue index, not its id (as it is right now).

Also, a more general question: should we allow dependencies across repositories? It doesn't check currently which repository the id belongs to you give it.
If so, this probably could create some problems with different access rights of a repository... (If I set a dependency to another repository, to which user B doesn't have access and he looks at the issue, should he see the dependent issue (from the other repository) or not, what if he tries to close it and so on... This could be solved, but it surely is worth thinking about.

(For now, I think I'll just implement it with the issue index, later, when we have the search we could probably think about dependencies across repositories)

@Morlinest
Copy link
Member

It should be possible to add dependency only on same repository. One of reasons (for me) is security and access rights.

@Morlinest
Copy link
Member

@kolaente I've finished (at least first version, but working very nice) index search for issues api. Will send PR tomorrow.

@kolaente
Copy link
Member Author

Ok, then i'll wait until this is merged to master (or shouldn't I?)

@Morlinest
Copy link
Member

Don't wait. Maybe changes to current api is not needed for this feature (read #2606 - you can use existing api and load latests issues for making suggestions).

@kolaente
Copy link
Member Author

kolaente commented Sep 26, 2017

you can use existing api and load latests issues for making suggestions.

The problem is, there is no apiendpoint to get a list of issues (not even one issue). Or did i overlooked something?

@Morlinest
Copy link
Member

Yes, overlooked :) /api/v1/:username/:reponame/issues

@kolaente
Copy link
Member Author

kolaente commented Jul 6, 2018

@JonasFranzDEV fixed.

@kolaente
Copy link
Member Author

kolaente commented Jul 6, 2018

@Morlinest @lafriks please approve.

@kolaente
Copy link
Member Author

@Morlinest @lafriks please approve.

@kolaente
Copy link
Member Author

Thanks @Morlinest !

@kolaente
Copy link
Member Author

@lafriks please approve.

# Conflicts:
#	options/locale/locale_en-US.ini
#	templates/repo/issue/view_content/sidebar.tmpl
@lafriks
Copy link
Member

lafriks commented Jul 17, 2018

Sry for taking so long to approve, nice work 👍

@techknowlogick techknowlogick added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Jul 17, 2018
@bkcsoft bkcsoft added the lgtm/need 1 This PR needs approval from one additional maintainer to be merged. label Jul 17, 2018
@kolaente
Copy link
Member Author

@lafriks Thank you!

@techknowlogick
Copy link
Member

LGTM

@bkcsoft bkcsoft removed the lgtm/need 1 This PR needs approval from one additional maintainer to be merged. label Jul 17, 2018
@techknowlogick techknowlogick merged commit 1bff02d into go-gitea:master Jul 17, 2018
@Aragur
Copy link

Aragur commented Jul 19, 2018

In the dependencies list it only lists the last 10 issues relative to that one.
For example issue 23 can only see to 12. Issue 20 can only see issues 19 - 9.
Also manual mention (for example of #13) doesn't work.
@kolaente Is this an intended behavior or a bug?

Edit:
Added an example: https://try.gitea.io/Aragur/Issue-Dependency_Issue/issues
Try to select #1 on issue #12
Try to select #1 on issue #12

@Morlinest
Copy link
Member

@AragurDEV Fast search: issues search api (/api/v1/repos/:username/:reponame/issues) uses SearchIssuesByKeyword to find issues by given keyword and right now it search in:

newMatchPhraseQuery(keyword, "Title", issueIndexerAnalyzer),
newMatchPhraseQuery(keyword, "Content", issueIndexerAnalyzer),
newMatchPhraseQuery(keyword, "Comments", issueIndexerAnalyzer),

I tested it, you can search only with full words, in your example it would be "test", "issue". But I can confirm, this feature is little buggy right now and UI does not fully work as expected in my tests.

@Aragur
Copy link

Aragur commented Jul 19, 2018

@Morlinest thanks a lot!
I think it should be possible to directly reference a issue id. No matter if the search api succeeds

@Morlinest
Copy link
Member

@AragurDEV Please create an issue so we can discuss there. This feature needs little tweaks.

@Aragur Aragur mentioned this pull request Jul 20, 2018
2 tasks
aswild added a commit to aswild/gitea that referenced this pull request Oct 24, 2018
Prepare for wild/v1.6 branch

* BREAKING
  * Respect email privacy option in user search via API (go-gitea#4512)
  * Simply remove tidb and deps (go-gitea#3993)
  * Swagger.v1.json template (go-gitea#3572)
* FEATURE
  * Pull request review/approval and comment on code (go-gitea#3748)
  * Added dependencies for issues (go-gitea#2196) (go-gitea#2531)
  * Add the ability to have built in themes in Gitea and provide dark theme arc-green (go-gitea#4198)
  * Add sudo functionality to the API (go-gitea#4809)
  * Add oauth providers via cli (go-gitea#4591)
  * Disable merging a WIP Pull request (go-gitea#4529)
  * Force user to change password (go-gitea#4489)
  * Add letsencrypt to Gitea (go-gitea#4189)
  * Add push webhook support for mirrored repositories (go-gitea#4127)
  * Add csv file render support defaultly (go-gitea#4105)
  * Add Recaptcha functionality to Gitea (go-gitea#4044)
* BUGFIXES
  * Fix release creation via API (go-gitea#5076)
  * Remove links from topics in edit mode  (go-gitea#5026)
  * Fix missing AppSubUrl in few more templates (fixup) (go-gitea#5021)
  * Fix missing AppSubUrl in some templates (go-gitea#5020)
  * Hide outdated comments in file view (go-gitea#5017)
  * Upgrade gopkg.in/testfixtures.v2 (go-gitea#4999)
  * Disable debug routes unless PPROF is enabled in configuration (go-gitea#4995)
  * Fix user menu item styling (go-gitea#4985)
  * Fix layout of the topics editing form (go-gitea#4971)
  * Fix null pointer dereference in ParseCommitWithSignature (go-gitea#4962)
  * Fix url in discord webhook (go-gitea#4953)
  * Detect charset and convert non UTF-8 files for display (go-gitea#4950)
  * Make sure to catch the right error so it is displayed on the UI (go-gitea#4945)
  * Fix(topics): don't redirect to explore page. (go-gitea#4938)
  * Fix bug forget to remove Stopwatch when remove repository (go-gitea#4928)
  * Fix bug when repo remained bare if multiple branches pushed in single push (go-gitea#4923)
  * Fix: Let's Encrypt configuration settings (go-gitea#4911)
  * Fix: Crippled diff (go-gitea#4726) (go-gitea#4900)
  * Fix trimming of markup section names (go-gitea#4863)
  * Issues api allow pulls and fix go-gitea#4832 (go-gitea#4852)
  * Do not autocreate directory for new users/orgs (go-gitea#4828) (go-gitea#4849)
  * Fix redirect with non-ascii branch names (go-gitea#4764) (go-gitea#4810)
  * Fix missing release title in webhook (go-gitea#4783) (go-gitea#4796)
  * User shouldn't be able to approve or reject his/her own PR (go-gitea#4729)
  * Make sure to reset commit count in the cache on mirror syncing (go-gitea#4720)
  * Fixed bug where team with admin privelege type doesn't get any unit  (go-gitea#4719)
  * Fix incorrect caption of webhook setting (go-gitea#4701) (go-gitea#4717)
  * Allow WIP marker to contains < or > (go-gitea#4709)
  * Hide org/create menu item in Dashboard if user has no rights (go-gitea#4678) (go-gitea#4680)
  * Site admin could create repos even MAX_CREATION_LIMIT=0 (go-gitea#4645)
  * Fix custom templates being ignored (go-gitea#4638)
  * Fix starring icon after semantic ui update (go-gitea#4628)
  * Fix Split-View line adjustment (go-gitea#4622)
  * Fix integer constant overflows in tests (go-gitea#4616)
  * Push whitelist now doesn't apply to branch deletion (go-gitea#4601) (go-gitea#4607)
  * Fix bugs when too many IN variables (go-gitea#4594)
  * Fix failure on creating pull request with assignees (go-gitea#4419) (go-gitea#4583)
  * Fix panic issue on update avatar email (go-gitea#4580) (go-gitea#4581)
  * Fix status code label for a successful webhook (go-gitea#4540)
  * An inactive user shouldn't be able to be added as a collaborator (go-gitea#4535)
  * Don't fail silently if trying to add a collaborator twice (go-gitea#4533)
  * Fix incorrect MergeWhitelistTeamIDs check in CanUserMerge function (go-gitea#4519) (go-gitea#4525)
  * Fix out-of-transaction query in removeOrgUser (go-gitea#4521) (go-gitea#4522)
  * Fix migration from older releases (go-gitea#4495)
  * Accept 'Data:' in commit graph (go-gitea#4487)
  * Update xorm to latest version and fix correct `user` table referencing in sql (go-gitea#4473)
  * Relative URLs for LibreJS page (go-gitea#4460)
  * Redirect to correct page after using scratch token (go-gitea#4458)
  * Fix column droping for MSSQL that need new transaction for that (go-gitea#4440)
  * Replace src with raw to fix image paths (go-gitea#4377)
  * Add default merge options when creating new repository (go-gitea#4369)
  * Fix docker build (go-gitea#4358)
  * Fixes repo membership check in API (go-gitea#4341)
  * Dep upgrade mysql lib (go-gitea#4161)
  * Fix some issues with special chars in branch names (go-gitea#3767)
  * Responsive design fixes (go-gitea#4508)
* ENHANCEMENT
  * Fix milestones sorted wrongly (go-gitea#4987)
  * Allow api to create tags for releases if they don't exist (go-gitea#4890)
  * Fix go-gitea#4877 to follow the OpenID Connect Audiences spec (go-gitea#4878)
  * Enforce token on api routes [fixed critical security issue go-gitea#4357] (go-gitea#4840)
  * Update legacy branch and tag URLs in dashboard to new format (go-gitea#4812)
  * Slack webhook channel name cannot be empty or just contain an hashtag (go-gitea#4786)
  * Add whitespace handling to PR-comparsion (go-gitea#4683)
  * Make reverse proxy auth optional (go-gitea#4643)
  * MySQL TLS (go-gitea#4642)
  * Make sure to set PR split view when creating/previewing a pull request  (go-gitea#4617)
  * Log user in after a successful sign up (go-gitea#4615)
  * Fix typo IsPullReuqestBroken -> IsPullRequestBroken (go-gitea#4578)
  * Allow admin toggle forcing a password change for newly created users (go-gitea#4563)
  * Update jQuery to v1.12.4 (go-gitea#4551)
  * Env var GITEA_PUSHER_EMAIL (go-gitea#4516)
  * Feat(repo): support search repository by topic name (go-gitea#4505)
  * Small improvements to dependency UI (go-gitea#4503)
  * Make max commits in graph configurable (go-gitea#4498)
  * Add valid for lfs oid (go-gitea#4461)
  * Add shortcut to save wiki page (go-gitea#4452)
  * Allow administrator to create repository for any organization (go-gitea#4368)
  * Fix repository last updated time update when delete a user who watched the repo (go-gitea#4363)
  * Switch plaintext scratch tokens to use hash instead (go-gitea#4331)
  * Increase default TOTP secret size to 320 bits (go-gitea#4287)
  * Keep preseeded database password (go-gitea#4284)
  * Implemented hover text showing user FullName (go-gitea#4261)
  * Add ability to delete a token (go-gitea#4235)
  * Fix typos in i18n variable names. (go-gitea#4080)
  * Api: repos/search: add parameters to control the sort order (go-gitea#3964)
  * Add missing path in the Docker app.ini template (go-gitea#2181)
  * Add file name and branch to page title (go-gitea#4902)
  * Offline use of google fonts (go-gitea#4872)
  * Add missing History link to directory listings v2 (go-gitea#4829)
  * Locale for Edit and Remove due date issue (go-gitea#4802)
  * Disable 'May Import Local Repository' when is disabled by setting (Is… (go-gitea#4780)
  * API /admin/users/{username} missing parameter (go-gitea#4775)
  * Display error when adding a user to a team twice (go-gitea#4746)
  * Remove UsePrivilegeSeparation from the Docker sshd_config, see go-gitea#2876 (go-gitea#4722)
  * Focus title input when clicking helper link (go-gitea#4696)
  * Add vendor to user reserved words and format words list according alphabet (go-gitea#4685)
  * Add gitea/issues link to 500 page (go-gitea#4654)
  * Hide home button when landing page is not set to home (go-gitea#4651)
  * Remove link to GitHub issues in 404 template (go-gitea#4639)
  * Cmd/serve: pprof cpu and memory profile dumps to disk (go-gitea#4560)
  * Add flash message after an account has been successfully activated (go-gitea#4510)
  * Prevent html entity escaping on delete branch (go-gitea#4471)
  * Locale for button Edit on protected branch (go-gitea#4442)
  * Update notification icon (go-gitea#4343)
  * Added front-end topics validation (go-gitea#4316)
  * Don't display buttons if there are no system notifications (go-gitea#4280)
  * Issue due date api (go-gitea#3890)
* SECURITY
  * Improve URL validation for external wiki  and external issues (go-gitea#4710)
  * Make cookies HttpOnly and obey COOKIE_SECURE flag (go-gitea#4706)
  * Don't disclose emails of all users when sending out emails (go-gitea#4664)
  * Check that repositories can only be migrated to own user or organizations (go-gitea#4366)
* TRANSLATION
  * Fix punctuation in English translation (go-gitea#4958)
  * Fix translation (go-gitea#4355)
@lafriks lafriks added the type/changelog Adds the changelog for a new Gitea version label Nov 10, 2018
@go-gitea go-gitea locked and limited conversation to collaborators Nov 24, 2020
@delvh delvh removed the type/changelog Adds the changelog for a new Gitea version label Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. type/feature Completely new functionality. Can only be merged if feature freeze is not active.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet