Skip to content

Commit d5d0d22

Browse files
authored
Merge branch 'main' into bugfix/svg_side_by_side_comparison
2 parents 8973e90 + 053b2f4 commit d5d0d22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+267
-195
lines changed

integrations/branches_test.go

+1-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"net/url"
1010
"testing"
1111

12-
"github.com/PuerkitoBio/goquery"
1312
"github.com/stretchr/testify/assert"
1413
"github.com/unknwon/i18n"
1514
)
@@ -62,7 +61,7 @@ func branchAction(t *testing.T, button string) (*HTMLDoc, string) {
6261
}
6362

6463
req = NewRequestWithValues(t, "POST", link, map[string]string{
65-
"_csrf": getCsrf(t, htmlDoc.doc),
64+
"_csrf": htmlDoc.GetCSRF(),
6665
})
6766
session.MakeRequest(t, req, http.StatusOK)
6867

@@ -73,9 +72,3 @@ func branchAction(t *testing.T, button string) (*HTMLDoc, string) {
7372

7473
return NewHTMLParser(t, resp.Body), url.Query().Get("name")
7574
}
76-
77-
func getCsrf(t *testing.T, doc *goquery.Document) string {
78-
csrf, exists := doc.Find("meta[name=\"_csrf\"]").Attr("content")
79-
assert.True(t, exists)
80-
return csrf
81-
}

integrations/html_helper.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (doc *HTMLDoc) Find(selector string) *goquery.Selection {
4444
return doc.doc.Find(selector)
4545
}
4646

47-
// GetCSRF for get CSRC token value from input
47+
// GetCSRF for getting CSRF token value from input
4848
func (doc *HTMLDoc) GetCSRF() string {
4949
return doc.GetInputValueByName("_csrf")
5050
}

integrations/pull_create_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func testUIDeleteBranch(t *testing.T, session *TestSession, ownerName, repoName,
114114
htmlDoc := NewHTMLParser(t, resp.Body)
115115

116116
req = NewRequestWithValues(t, "POST", relURL+"/delete", map[string]string{
117-
"_csrf": getCsrf(t, htmlDoc.doc),
117+
"_csrf": htmlDoc.GetCSRF(),
118118
"name": branchName,
119119
})
120120
session.MakeRequest(t, req, http.StatusOK)
@@ -127,7 +127,7 @@ func testDeleteRepository(t *testing.T, session *TestSession, ownerName, repoNam
127127
htmlDoc := NewHTMLParser(t, resp.Body)
128128

129129
req = NewRequestWithValues(t, "POST", relURL+"?action=delete", map[string]string{
130-
"_csrf": getCsrf(t, htmlDoc.doc),
130+
"_csrf": htmlDoc.GetCSRF(),
131131
"repo_name": repoName,
132132
})
133133
session.MakeRequest(t, req, http.StatusFound)

modules/context/context.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ func Contexter() func(next http.Handler) http.Handler {
645645
"CurrentURL": setting.AppSubURL + req.URL.RequestURI(),
646646
"PageStartTime": startTime,
647647
"Link": link,
648-
"IsProd": setting.IsProd,
648+
"RunModeIsProd": setting.IsProd,
649649
},
650650
}
651651
// PageData is passed by reference, and it will be rendered to `window.config.pageData` in `head.tmpl` for JavaScript modules

routers/web/repo/projects.go

-4
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ func DeleteProject(ctx *context.Context) {
205205
// EditProject allows a project to be edited
206206
func EditProject(ctx *context.Context) {
207207
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
208-
ctx.Data["PageIsProjects"] = true
209208
ctx.Data["PageIsEditProjects"] = true
210209
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
211210

@@ -233,7 +232,6 @@ func EditProject(ctx *context.Context) {
233232
func EditProjectPost(ctx *context.Context) {
234233
form := web.GetForm(ctx).(*forms.CreateProjectForm)
235234
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
236-
ctx.Data["PageIsProjects"] = true
237235
ctx.Data["PageIsEditProjects"] = true
238236
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
239237

@@ -335,8 +333,6 @@ func ViewProject(ctx *context.Context) {
335333
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(models.UnitTypeProjects)
336334
ctx.Data["Project"] = project
337335
ctx.Data["Boards"] = boards
338-
ctx.Data["PageIsProjects"] = true
339-
ctx.Data["RequiresDraggable"] = true
340336

341337
ctx.HTML(http.StatusOK, tplProjectsView)
342338
}

services/mirror/mirror_pull.go

+105-13
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,43 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult {
141141
return results
142142
}
143143

144+
func pruneBrokenReferences(ctx context.Context,
145+
m *models.Mirror,
146+
repoPath string,
147+
timeout time.Duration,
148+
stdoutBuilder, stderrBuilder *strings.Builder,
149+
sanitizer *strings.Replacer,
150+
isWiki bool) error {
151+
152+
wiki := ""
153+
if isWiki {
154+
wiki = "Wiki "
155+
}
156+
157+
stderrBuilder.Reset()
158+
stdoutBuilder.Reset()
159+
pruneErr := git.NewCommandContext(ctx, "remote", "prune", m.GetRemoteName()).
160+
SetDescription(fmt.Sprintf("Mirror.runSync %ssPrune references: %s ", wiki, m.Repo.FullName())).
161+
RunInDirTimeoutPipeline(timeout, repoPath, stdoutBuilder, stderrBuilder)
162+
if pruneErr != nil {
163+
stdout := stdoutBuilder.String()
164+
stderr := stderrBuilder.String()
165+
166+
// sanitize the output, since it may contain the remote address, which may
167+
// contain a password
168+
stderrMessage := sanitizer.Replace(stderr)
169+
stdoutMessage := sanitizer.Replace(stdout)
170+
171+
log.Error("Failed to prune mirror repository %s%-v references:\nStdout: %s\nStderr: %s\nErr: %v", wiki, m.Repo, stdoutMessage, stderrMessage, pruneErr)
172+
desc := fmt.Sprintf("Failed to prune mirror repository %s'%s' references: %s", wiki, repoPath, stderrMessage)
173+
if err := models.CreateRepositoryNotice(desc); err != nil {
174+
log.Error("CreateRepositoryNotice: %v", err)
175+
}
176+
// this if will only be reached on a successful prune so try to get the mirror again
177+
}
178+
return pruneErr
179+
}
180+
144181
// runSync returns true if sync finished without error.
145182
func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool) {
146183
repoPath := m.Repo.RepoPath()
@@ -161,25 +198,52 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool)
161198

162199
stdoutBuilder := strings.Builder{}
163200
stderrBuilder := strings.Builder{}
164-
if err := git.NewCommand(gitArgs...).
201+
if err := git.NewCommandContext(ctx, gitArgs...).
165202
SetDescription(fmt.Sprintf("Mirror.runSync: %s", m.Repo.FullName())).
166203
RunInDirTimeoutPipeline(timeout, repoPath, &stdoutBuilder, &stderrBuilder); err != nil {
167204
stdout := stdoutBuilder.String()
168205
stderr := stderrBuilder.String()
169206

170207
// sanitize the output, since it may contain the remote address, which may
171208
// contain a password
172-
173209
sanitizer := util.NewURLSanitizer(remoteAddr, true)
174210
stderrMessage := sanitizer.Replace(stderr)
175211
stdoutMessage := sanitizer.Replace(stdout)
176212

177-
log.Error("Failed to update mirror repository %v:\nStdout: %s\nStderr: %s\nErr: %v", m.Repo, stdoutMessage, stderrMessage, err)
178-
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, stderrMessage)
179-
if err = models.CreateRepositoryNotice(desc); err != nil {
180-
log.Error("CreateRepositoryNotice: %v", err)
213+
// Now check if the error is a resolve reference due to broken reference
214+
if strings.Contains(stderr, "unable to resolve reference") && strings.Contains(stderr, "reference broken") {
215+
log.Warn("Failed to update mirror repository %-v due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
216+
err = nil
217+
218+
// Attempt prune
219+
pruneErr := pruneBrokenReferences(ctx, m, repoPath, timeout, &stdoutBuilder, &stderrBuilder, sanitizer, false)
220+
if pruneErr == nil {
221+
// Successful prune - reattempt mirror
222+
stderrBuilder.Reset()
223+
stdoutBuilder.Reset()
224+
if err = git.NewCommandContext(ctx, gitArgs...).
225+
SetDescription(fmt.Sprintf("Mirror.runSync: %s", m.Repo.FullName())).
226+
RunInDirTimeoutPipeline(timeout, repoPath, &stdoutBuilder, &stderrBuilder); err != nil {
227+
stdout := stdoutBuilder.String()
228+
stderr := stderrBuilder.String()
229+
230+
// sanitize the output, since it may contain the remote address, which may
231+
// contain a password
232+
stderrMessage = sanitizer.Replace(stderr)
233+
stdoutMessage = sanitizer.Replace(stdout)
234+
}
235+
}
236+
}
237+
238+
// If there is still an error (or there always was an error)
239+
if err != nil {
240+
log.Error("Failed to update mirror repository %-v:\nStdout: %s\nStderr: %s\nErr: %v", m.Repo, stdoutMessage, stderrMessage, err)
241+
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, stderrMessage)
242+
if err = models.CreateRepositoryNotice(desc); err != nil {
243+
log.Error("CreateRepositoryNotice: %v", err)
244+
}
245+
return nil, false
181246
}
182-
return nil, false
183247
}
184248
output := stderrBuilder.String()
185249

@@ -212,7 +276,7 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool)
212276
log.Trace("SyncMirrors [repo: %-v Wiki]: running git remote update...", m.Repo)
213277
stderrBuilder.Reset()
214278
stdoutBuilder.Reset()
215-
if err := git.NewCommand("remote", "update", "--prune", m.GetRemoteName()).
279+
if err := git.NewCommandContext(ctx, "remote", "update", "--prune", m.GetRemoteName()).
216280
SetDescription(fmt.Sprintf("Mirror.runSync Wiki: %s ", m.Repo.FullName())).
217281
RunInDirTimeoutPipeline(timeout, wikiPath, &stdoutBuilder, &stderrBuilder); err != nil {
218282
stdout := stdoutBuilder.String()
@@ -226,16 +290,44 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool)
226290
log.Error("GetRemoteAddress Error %v", remoteErr)
227291
}
228292

293+
// sanitize the output, since it may contain the remote address, which may
294+
// contain a password
229295
sanitizer := util.NewURLSanitizer(remoteAddr, true)
230296
stderrMessage := sanitizer.Replace(stderr)
231297
stdoutMessage := sanitizer.Replace(stdout)
232298

233-
log.Error("Failed to update mirror repository wiki %v:\nStdout: %s\nStderr: %s\nErr: %v", m.Repo, stdoutMessage, stderrMessage, err)
234-
desc := fmt.Sprintf("Failed to update mirror repository wiki '%s': %s", wikiPath, stderrMessage)
235-
if err = models.CreateRepositoryNotice(desc); err != nil {
236-
log.Error("CreateRepositoryNotice: %v", err)
299+
// Now check if the error is a resolve reference due to broken reference
300+
if strings.Contains(stderrMessage, "unable to resolve reference") && strings.Contains(stderrMessage, "reference broken") {
301+
log.Warn("Failed to update mirror wiki repository %-v due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
302+
err = nil
303+
304+
// Attempt prune
305+
pruneErr := pruneBrokenReferences(ctx, m, repoPath, timeout, &stdoutBuilder, &stderrBuilder, sanitizer, true)
306+
if pruneErr == nil {
307+
// Successful prune - reattempt mirror
308+
stderrBuilder.Reset()
309+
stdoutBuilder.Reset()
310+
311+
if err = git.NewCommandContext(ctx, "remote", "update", "--prune", m.GetRemoteName()).
312+
SetDescription(fmt.Sprintf("Mirror.runSync Wiki: %s ", m.Repo.FullName())).
313+
RunInDirTimeoutPipeline(timeout, wikiPath, &stdoutBuilder, &stderrBuilder); err != nil {
314+
stdout := stdoutBuilder.String()
315+
stderr := stderrBuilder.String()
316+
stderrMessage = sanitizer.Replace(stderr)
317+
stdoutMessage = sanitizer.Replace(stdout)
318+
}
319+
}
320+
}
321+
322+
// If there is still an error (or there always was an error)
323+
if err != nil {
324+
log.Error("Failed to update mirror repository wiki %-v:\nStdout: %s\nStderr: %s\nErr: %v", m.Repo, stdoutMessage, stderrMessage, err)
325+
desc := fmt.Sprintf("Failed to update mirror repository wiki '%s': %s", wikiPath, stderrMessage)
326+
if err = models.CreateRepositoryNotice(desc); err != nil {
327+
log.Error("CreateRepositoryNotice: %v", err)
328+
}
329+
return nil, false
237330
}
238-
return nil, false
239331
}
240332
log.Trace("SyncMirrors [repo: %-v Wiki]: git remote update complete", m.Repo)
241333
}

templates/base/head.tmpl

+13-22
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,32 @@
33
<head>
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1">
6-
<title>{{if .Title}}{{.Title | RenderEmojiPlain}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}} </title>
6+
<title>{{if .Title}}{{.Title | RenderEmojiPlain}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
77
<link rel="manifest" href="data:{{.ManifestData}}"/>
88
<meta name="theme-color" content="{{ThemeColorMetaTag}}">
99
<meta name="default-theme" content="{{DefaultTheme}}" />
1010
<meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}" />
1111
<meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}" />
1212
<meta name="keywords" content="{{MetaKeywords}}">
1313
<meta name="referrer" content="no-referrer" />
14-
<meta name="_csrf" content="{{.CsrfToken}}" />
1514
{{if .GoGetImport}}
1615
<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">
1716
<meta name="go-source" content="{{.GoGetImport}} _ {{.GoDocDirectory}} {{.GoDocFile}}">
1817
{{end}}
1918
<script>
2019
<!-- /* eslint-disable */ -->
2120
window.config = {
22-
AppVer: '{{AppVer}}',
23-
AppSubUrl: '{{AppSubUrl}}',
24-
AssetUrlPrefix: '{{AssetUrlPrefix}}',
25-
IsProd: {{.IsProd}},
26-
CustomEmojis: {{CustomEmojis}},
27-
UseServiceWorker: {{UseServiceWorker}},
28-
csrf: '{{.CsrfToken}}',
29-
pageData: {{ .PageData }},
30-
HighlightJS: {{if .RequireHighlightJS}}true{{else}}false{{end}},
31-
SimpleMDE: {{if .RequireSimpleMDE}}true{{else}}false{{end}},
32-
Tribute: {{if .RequireTribute}}true{{else}}false{{end}},
33-
NotificationSettings: {
34-
MinTimeout: {{NotificationSettings.MinTimeout}},
35-
TimeoutStep: {{NotificationSettings.TimeoutStep}},
36-
MaxTimeout: {{NotificationSettings.MaxTimeout}},
37-
EventSourceUpdateTime: {{NotificationSettings.EventSourceUpdateTime}},
38-
},
39-
EnableTimetracking: {{if EnableTimetracking}}true{{else}}false{{end}},
40-
PageIsProjects: {{if .PageIsProjects }}true{{else}}false{{end}},
21+
appVer: '{{AppVer}}',
22+
appSubUrl: '{{AppSubUrl}}',
23+
assetUrlPrefix: '{{AssetUrlPrefix}}',
24+
runModeIsProd: {{.RunModeIsProd}},
25+
customEmojis: {{CustomEmojis}},
26+
useServiceWorker: {{UseServiceWorker}},
27+
csrfToken: '{{.CsrfToken}}',
28+
pageData: {{.PageData}},
29+
requireTribute: {{.RequireTribute}},
30+
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}
31+
enableTimeTracking: {{EnableTimetracking}},
4132
{{if .RequireTribute}}
4233
tributeValues: Array.from(new Map([
4334
{{ range .Participants }}
@@ -54,7 +45,7 @@
5445
{{ end }}
5546
]).values()),
5647
{{end}}
57-
MermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}},
48+
mermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}},
5849
};
5950
</script>
6051
<link rel="icon" href="{{AssetUrlPrefix}}/img/logo.svg" type="image/svg+xml">

templates/repo/projects/list.tmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{{template "base/head" .}}
2-
<div class="page-content repository milestones">
2+
<div class="page-content repository projects milestones">
33
{{template "repo/header" .}}
44
<div class="ui container">
55
<div class="navbar">

templates/repo/projects/new.tmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{{template "base/head" .}}
2-
<div class="page-content repository new milestone">
2+
<div class="page-content repository projects edit-project new milestone">
33
{{template "repo/header" .}}
44
<div class="ui container">
55
<div class="navbar">

templates/repo/projects/view.tmpl

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{{template "base/head" .}}
2-
<div class="page-content repository">
2+
<div class="page-content repository projects view-project">
33
{{template "repo/header" .}}
44
<div class="ui container">
55
<div class="ui two column stackable grid">
66
<div class="column">
77
{{template "repo/issue/navbar" .}}
88
</div>
99
<div class="column right aligned">
10-
{{if and .CanWriteProjects (not .Repository.IsArchived) .PageIsProjects}}
10+
{{if and .CanWriteProjects (not .Repository.IsArchived)}}
1111
<a class="ui green button show-modal item" href="{{$.RepoLink}}/issues/new?project={{$.Project.ID}}">{{.i18n.Tr "repo.issues.new"}}</a>
1212
<a class="ui green button show-modal item" data-modal="#new-board-item">{{.i18n.Tr "new_project_board"}}</a>
1313
{{end}}
@@ -80,10 +80,10 @@
8080
<div class="board">
8181
{{ range $board := .Boards }}
8282

83-
<div class="ui segment board-column" style="background: {{.Color}}!important;" data-id="{{.ID}}" data-sorting="{{.Sorting}}" data-url="{{$.RepoLink}}/projects/{{$.Project.ID}}/{{.ID}}">
83+
<div class="ui segment board-column" style="background: {{.Color}} !important;" data-id="{{.ID}}" data-sorting="{{.Sorting}}" data-url="{{$.RepoLink}}/projects/{{$.Project.ID}}/{{.ID}}">
8484
<div class="board-column-header df ac sb">
8585
<div class="ui large label board-label py-2">{{.Title}}</div>
86-
{{if and $.CanWriteProjects (not $.Repository.IsArchived) $.PageIsProjects (ne .ID 0)}}
86+
{{if and $.CanWriteProjects (not $.Repository.IsArchived) (ne .ID 0)}}
8787
<div class="ui dropdown jump item poping up" data-variation="tiny inverted">
8888
<div class="not-mobile px-3" tabindex="-1">
8989
{{svg "octicon-kebab-horizontal"}}
@@ -232,7 +232,7 @@
232232
{{if .Labels}}
233233
<div class="extra content labels-list p-0 pt-2">
234234
{{ range .Labels }}
235-
<a class="ui label" href="{{$.RepoLink}}/issues?labels={{.ID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}" title="{{.Description | RenderEmojiPlain}}">{{.Name | RenderEmoji}}</a>
235+
<a class="ui label" href="{{$.RepoLink}}/issues?labels={{.ID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}};" title="{{.Description | RenderEmojiPlain}}">{{.Name | RenderEmoji}}</a>
236236
{{ end }}
237237
</div>
238238
{{end}}

web_src/js/components/ContextPopup.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<script>
2323
import {SvgIcon} from '../svg.js';
2424
25-
const {AppSubUrl} = window.config;
25+
const {appSubUrl} = window.config;
2626
2727
// NOTE: see models/issue_label.go for similar implementation
2828
const srgbToLinear = (color) => {
@@ -112,7 +112,7 @@ export default {
112112
methods: {
113113
load(data, callback) {
114114
this.loading = true;
115-
$.get(`${AppSubUrl}/api/v1/repos/${data.owner}/${data.repo}/issues/${data.index}`, (issue) => {
115+
$.get(`${appSubUrl}/api/v1/repos/${data.owner}/${data.repo}/issues/${data.index}`, (issue) => {
116116
this.issue = issue;
117117
this.loading = false;
118118
this.$nextTick(() => {

0 commit comments

Comments
 (0)