Merge remote-tracking branch 'upstream/main'
This commit is contained in:
		
						commit
						42b1bac7a6
					
				
					 59 changed files with 2425 additions and 2138 deletions
				
			
		
							
								
								
									
										36
									
								
								.drone.yml
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								.drone.yml
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -39,6 +39,16 @@ steps:
 | 
			
		|||
      - make lint-frontend
 | 
			
		||||
    depends_on: [deps-frontend]
 | 
			
		||||
 | 
			
		||||
  - name: security-check
 | 
			
		||||
    image: golang:1.19
 | 
			
		||||
    pull: always
 | 
			
		||||
    commands:
 | 
			
		||||
      - make security-check
 | 
			
		||||
    depends_on: [deps-backend]
 | 
			
		||||
    volumes:
 | 
			
		||||
      - name: deps
 | 
			
		||||
        path: /go
 | 
			
		||||
 | 
			
		||||
  - name: lint-backend
 | 
			
		||||
    image: gitea/test_env:linux-amd64  # https://gitea.com/gitea/test-env
 | 
			
		||||
    pull: always
 | 
			
		||||
| 
						 | 
				
			
			@ -90,10 +100,7 @@ steps:
 | 
			
		|||
  - name: checks-backend
 | 
			
		||||
    image: golang:1.19
 | 
			
		||||
    commands:
 | 
			
		||||
      - curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get -qqy install nodejs
 | 
			
		||||
      - make checks-backend
 | 
			
		||||
    environment:
 | 
			
		||||
      DEBIAN_FRONTEND: noninteractive
 | 
			
		||||
    depends_on: [deps-backend]
 | 
			
		||||
    volumes:
 | 
			
		||||
      - name: deps
 | 
			
		||||
| 
						 | 
				
			
			@ -105,11 +112,16 @@ steps:
 | 
			
		|||
      - make test-frontend
 | 
			
		||||
    depends_on: [lint-frontend]
 | 
			
		||||
 | 
			
		||||
  - name: generate-frontend
 | 
			
		||||
    image: golang:1.19
 | 
			
		||||
    commands:
 | 
			
		||||
      - make generate-frontend
 | 
			
		||||
 | 
			
		||||
  - name: build-frontend
 | 
			
		||||
    image: node:18
 | 
			
		||||
    commands:
 | 
			
		||||
      - make frontend
 | 
			
		||||
    depends_on: [test-frontend]
 | 
			
		||||
    depends_on: [deps-frontend, generate-frontend]
 | 
			
		||||
 | 
			
		||||
  - name: build-backend-no-gcc
 | 
			
		||||
    image: golang:1.18 # this step is kept as the lowest version of golang that we support
 | 
			
		||||
| 
						 | 
				
			
			@ -532,16 +544,21 @@ services:
 | 
			
		|||
 | 
			
		||||
steps:
 | 
			
		||||
  - name: deps-frontend
 | 
			
		||||
    image: node:16
 | 
			
		||||
    image: node:18
 | 
			
		||||
    pull: always
 | 
			
		||||
    commands:
 | 
			
		||||
      - make deps-frontend
 | 
			
		||||
 | 
			
		||||
  - name: generate-frontend
 | 
			
		||||
    image: golang:1.18
 | 
			
		||||
    commands:
 | 
			
		||||
      - make generate-frontend
 | 
			
		||||
 | 
			
		||||
  - name: build-frontend
 | 
			
		||||
    image: node:16
 | 
			
		||||
    image: node:18
 | 
			
		||||
    commands:
 | 
			
		||||
      - make frontend
 | 
			
		||||
    depends_on: [deps-frontend]
 | 
			
		||||
    depends_on: [deps-frontend, generate-frontend]
 | 
			
		||||
 | 
			
		||||
  - name: deps-backend
 | 
			
		||||
    image: golang:1.18
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +571,7 @@ steps:
 | 
			
		|||
 | 
			
		||||
  # TODO: We should probably build all dependencies into a test image
 | 
			
		||||
  - name: test-e2e
 | 
			
		||||
    image: mcr.microsoft.com/playwright:v1.23.1-focal
 | 
			
		||||
    image: mcr.microsoft.com/playwright:v1.24.0-focal
 | 
			
		||||
    commands:
 | 
			
		||||
      - curl -sLO https://go.dev/dl/go1.18.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz
 | 
			
		||||
      - groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea
 | 
			
		||||
| 
						 | 
				
			
			@ -569,6 +586,9 @@ steps:
 | 
			
		|||
      TEST_PGSQL_DBNAME: 'testgitea-e2e'
 | 
			
		||||
      DEBIAN_FRONTEND: noninteractive
 | 
			
		||||
    depends_on: [build-frontend, deps-backend]
 | 
			
		||||
    volumes:
 | 
			
		||||
      - name: deps
 | 
			
		||||
        path: /go
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
kind: pipeline
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ rules:
 | 
			
		|||
  accessor-pairs: [2]
 | 
			
		||||
  array-bracket-newline: [0]
 | 
			
		||||
  array-bracket-spacing: [2, never]
 | 
			
		||||
  array-callback-return: [0]
 | 
			
		||||
  array-callback-return: [2, {checkForEach: true}]
 | 
			
		||||
  array-element-newline: [0]
 | 
			
		||||
  arrow-body-style: [0]
 | 
			
		||||
  arrow-parens: [2, always]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -35,6 +35,7 @@ MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4
 | 
			
		|||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.0
 | 
			
		||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
 | 
			
		||||
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.3.0
 | 
			
		||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@latest
 | 
			
		||||
 | 
			
		||||
DOCKER_IMAGE ?= gitea/gitea
 | 
			
		||||
DOCKER_TAG ?= latest
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +211,7 @@ help:
 | 
			
		|||
	@echo " - golangci-lint                    run golangci-lint linter"
 | 
			
		||||
	@echo " - go-licenses                      regenerate go licenses"
 | 
			
		||||
	@echo " - vet                              examines Go source code and reports suspicious constructs"
 | 
			
		||||
	@echo " - tidy                             run go mod tidy and regenerate go licenses"
 | 
			
		||||
	@echo " - tidy                             run go mod tidy"
 | 
			
		||||
	@echo " - test[\#TestSpecificName]    	    run unit test"
 | 
			
		||||
	@echo " - test-sqlite[\#TestSpecificName]  run integration test for sqlite"
 | 
			
		||||
	@echo " - pr#<index>                       build and start gitea from a PR with integration test data loaded"
 | 
			
		||||
| 
						 | 
				
			
			@ -406,9 +407,9 @@ tidy:
 | 
			
		|||
	$(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
 | 
			
		||||
	$(GO) mod tidy -compat=$(MIN_GO_VERSION)
 | 
			
		||||
 | 
			
		||||
.PHONY: vendor
 | 
			
		||||
vendor: tidy
 | 
			
		||||
vendor: go.mod go.sum
 | 
			
		||||
	$(GO) mod vendor
 | 
			
		||||
	@touch vendor
 | 
			
		||||
 | 
			
		||||
.PHONY: tidy-check
 | 
			
		||||
tidy-check: tidy
 | 
			
		||||
| 
						 | 
				
			
			@ -420,12 +421,12 @@ tidy-check: tidy
 | 
			
		|||
	fi
 | 
			
		||||
 | 
			
		||||
.PHONY: go-licenses
 | 
			
		||||
go-licenses: assets/go-licenses.json
 | 
			
		||||
go-licenses: $(GO_LICENSE_FILE)
 | 
			
		||||
 | 
			
		||||
assets/go-licenses.json: go.mod go.sum build/generate-go-licenses.js
 | 
			
		||||
	-$(GO) run $(GO_LICENSES_PACKAGE) save . --force --save_path="$(GO_LICENSE_TMP_DIR)" 2>/dev/null
 | 
			
		||||
	node build/generate-go-licenses.js "$(GO_LICENSE_TMP_DIR)" "$(GO_LICENSE_FILE)"
 | 
			
		||||
	@rm -rf "$(GO_LICENSE_TMP_DIR)"
 | 
			
		||||
$(GO_LICENSE_FILE): go.mod go.sum
 | 
			
		||||
	-$(GO) run $(GO_LICENSES_PACKAGE) save . --force --save_path=$(GO_LICENSE_TMP_DIR) 2>/dev/null
 | 
			
		||||
	$(GO) run build/generate-go-licenses.go $(GO_LICENSE_TMP_DIR) $(GO_LICENSE_FILE)
 | 
			
		||||
	@rm -rf $(GO_LICENSE_TMP_DIR)
 | 
			
		||||
 | 
			
		||||
generate-ini-sqlite:
 | 
			
		||||
	sed -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
 | 
			
		||||
| 
						 | 
				
			
			@ -717,15 +718,20 @@ backend: go-check generate-backend $(EXECUTABLE)
 | 
			
		|||
.PHONY: generate
 | 
			
		||||
generate: generate-backend generate-frontend
 | 
			
		||||
 | 
			
		||||
.PHONY: generate-frontend
 | 
			
		||||
generate-frontend: $(GO_LICENSE_FILE)
 | 
			
		||||
 | 
			
		||||
.PHONY: generate-backend
 | 
			
		||||
generate-backend: $(TAGS_PREREQ) generate-go
 | 
			
		||||
 | 
			
		||||
.PHONY: generate-go
 | 
			
		||||
generate-go: $(TAGS_PREREQ)
 | 
			
		||||
	@echo "Running go generate..."
 | 
			
		||||
	@CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' $(GO_PACKAGES)
 | 
			
		||||
 | 
			
		||||
.PHONY: generate-frontend
 | 
			
		||||
generate-frontend: $(TAGS_PREREQ) go-licenses
 | 
			
		||||
.PHONY: security-check
 | 
			
		||||
security-check:
 | 
			
		||||
	govulncheck -v ./...
 | 
			
		||||
 | 
			
		||||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
 | 
			
		||||
	CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
 | 
			
		||||
| 
						 | 
				
			
			@ -812,6 +818,7 @@ deps-backend:
 | 
			
		|||
	$(GO) install $(SWAGGER_PACKAGE)
 | 
			
		||||
	$(GO) install $(XGO_PACKAGE)
 | 
			
		||||
	$(GO) install $(GO_LICENSES_PACKAGE)
 | 
			
		||||
	$(GO) install $(GOVULNCHECK_PACKAGE)
 | 
			
		||||
 | 
			
		||||
node_modules: package-lock.json
 | 
			
		||||
	npm install --no-save
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										82
									
								
								build/generate-go-licenses.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								build/generate-go-licenses.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
// Copyright 2022 The Gitea Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build ignore
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// regexp is based on go-license, excluding README and NOTICE
 | 
			
		||||
// https://github.com/google/go-licenses/blob/master/licenses/find.go
 | 
			
		||||
var licenseRe = regexp.MustCompile(`^(?i)((UN)?LICEN(S|C)E|COPYING).*$`)
 | 
			
		||||
 | 
			
		||||
type LicenseEntry struct {
 | 
			
		||||
	Name        string `json:"name"`
 | 
			
		||||
	Path        string `json:"path"`
 | 
			
		||||
	LicenseText string `json:"licenseText"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	base, out := os.Args[1], os.Args[2]
 | 
			
		||||
 | 
			
		||||
	paths := []string{}
 | 
			
		||||
	err := filepath.WalkDir(base, func(path string, entry fs.DirEntry, err error) error {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if entry.IsDir() || !licenseRe.MatchString(entry.Name()) {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		paths = append(paths, path)
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sort.Strings(paths)
 | 
			
		||||
 | 
			
		||||
	entries := []LicenseEntry{}
 | 
			
		||||
	for _, path := range paths {
 | 
			
		||||
		licenseText, err := os.ReadFile(path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		path := strings.Replace(path, base+string(os.PathSeparator), "", 1)
 | 
			
		||||
		name := filepath.Dir(path)
 | 
			
		||||
 | 
			
		||||
		// There might be a bug somewhere in go-licenses that sometimes interprets the
 | 
			
		||||
		// root package as "." and sometimes as "code.gitea.io/gitea". Workaround by
 | 
			
		||||
		// removing both of them for the sake of stable output.
 | 
			
		||||
		if name == "." || name == "code.gitea.io/gitea" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		entries = append(entries, LicenseEntry{
 | 
			
		||||
			Name: name,
 | 
			
		||||
			Path: path,
 | 
			
		||||
			LicenseText: string(licenseText),
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	jsonBytes, err := json.MarshalIndent(entries, "", "  ")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = os.WriteFile(out, jsonBytes, 0o644)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,30 +0,0 @@
 | 
			
		|||
#!/usr/bin/env node
 | 
			
		||||
import fastGlob from 'fast-glob';
 | 
			
		||||
import {fileURLToPath} from 'url';
 | 
			
		||||
import {readFileSync, writeFileSync} from 'fs';
 | 
			
		||||
import wrapAnsi from 'wrap-ansi';
 | 
			
		||||
import {join, dirname} from 'path';
 | 
			
		||||
 | 
			
		||||
const base = process.argv[2];
 | 
			
		||||
const out = process.argv[3];
 | 
			
		||||
 | 
			
		||||
function exit(err) {
 | 
			
		||||
  if (err) console.error(err);
 | 
			
		||||
  process.exit(err ? 1 : 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function main() {
 | 
			
		||||
  const data = fastGlob.sync('**/*', {
 | 
			
		||||
    cwd: fileURLToPath(new URL(`../${base}`, import.meta.url)),
 | 
			
		||||
  }).filter((path) => {
 | 
			
		||||
    return /\/((UN)?LICEN(S|C)E|COPYING|NOTICE)/i.test(path);
 | 
			
		||||
  }).sort().map((path) => {
 | 
			
		||||
    return {
 | 
			
		||||
      name: dirname(path),
 | 
			
		||||
      body: wrapAnsi(readFileSync(join(base, path), 'utf8') || '', 80)
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
  writeFileSync(out, JSON.stringify(data, null, 2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main().then(exit).catch(exit);
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ Apart from `extra_links.tmpl` and `extra_tabs.tmpl`, there are other useful temp
 | 
			
		|||
- `body_inner_pre.tmpl`, before the top navigation bar, but already inside the main container `<div class="full height">`.
 | 
			
		||||
- `body_inner_post.tmpl`, before the end of the main container.
 | 
			
		||||
- `body_outer_post.tmpl`, before the bottom `<footer>` element.
 | 
			
		||||
- `footer.tmpl`, right before the end of the `<body>` tag, a good place for additional Javascript.
 | 
			
		||||
- `footer.tmpl`, right before the end of the `<body>` tag, a good place for additional JavaScript.
 | 
			
		||||
 | 
			
		||||
#### Example: PlantUML
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +129,7 @@ You can add [PlantUML](https://plantuml.com/) support to Gitea's markdown by usi
 | 
			
		|||
The data is encoded and sent to the PlantUML server which generates the picture. There is an online
 | 
			
		||||
demo server at http://www.plantuml.com/plantuml, but if you (or your users) have sensitive data you
 | 
			
		||||
can set up your own [PlantUML server](https://plantuml.com/server) instead. To set up PlantUML rendering,
 | 
			
		||||
copy javascript files from https://gitea.com/davidsvantesson/plantuml-code-highlight and put them in your
 | 
			
		||||
copy JavaScript files from https://gitea.com/davidsvantesson/plantuml-code-highlight and put them in your
 | 
			
		||||
`$GITEA_CUSTOM/public` folder. Then add the following to `custom/footer.tmpl`:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
| 
						 | 
				
			
			@ -137,9 +137,9 @@ copy javascript files from https://gitea.com/davidsvantesson/plantuml-code-highl
 | 
			
		|||
  $(async () => {
 | 
			
		||||
    if (!$('.language-plantuml').length) return;
 | 
			
		||||
    await Promise.all([
 | 
			
		||||
      $.getScript('https://your-server.com/deflate.js'), 
 | 
			
		||||
      $.getScript('https://your-server.com/encode.js'),
 | 
			
		||||
      $.getScript('https://your-server.com/plantuml_codeblock_parse.js'),
 | 
			
		||||
      $.getScript('https://your-gitea-server.com/assets/deflate.js'),
 | 
			
		||||
      $.getScript('https://your-gitea-server.com/assets/encode.js'),
 | 
			
		||||
      $.getScript('https://your-gitea-server.com/assets/plantuml_codeblock_parse.js'),
 | 
			
		||||
    ]);
 | 
			
		||||
    // Replace call with address to your plantuml server
 | 
			
		||||
    parsePlantumlCodeBlocks("https://www.plantuml.com/plantuml");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,12 +15,14 @@ menu:
 | 
			
		|||
 | 
			
		||||
# Logging Configuration
 | 
			
		||||
 | 
			
		||||
The logging framework has been revamped in Gitea 1.9.0.
 | 
			
		||||
 | 
			
		||||
**Table of Contents**
 | 
			
		||||
 | 
			
		||||
{{< toc >}}
 | 
			
		||||
 | 
			
		||||
## Collecting Logs for Help
 | 
			
		||||
 | 
			
		||||
To collect logs for help and issue report, see [Support Options]({{< relref "doc/help/seek-help.en-us.md" >}}).
 | 
			
		||||
 | 
			
		||||
## Log Groups
 | 
			
		||||
 | 
			
		||||
The fundamental thing to be aware of in Gitea is that there are several
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -392,7 +392,9 @@ Gitea requires the system or browser to have one of the supported Emoji fonts in
 | 
			
		|||
 | 
			
		||||
Stdout on systemd goes to the journal by default. Try using `journalctl`, `journalctl  -u gitea`, or `journalctl <path-to-gitea-binary>`.
 | 
			
		||||
 | 
			
		||||
Similarly stdout on docker can be viewed using `docker logs <container>`
 | 
			
		||||
Similarly, stdout on docker can be viewed using `docker logs <container>`.
 | 
			
		||||
 | 
			
		||||
To collect logs for help and issue report, see [Support Options]({{< relref "doc/help/seek-help.en-us.md" >}}).
 | 
			
		||||
 | 
			
		||||
## Initial logging
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -413,7 +415,7 @@ unchanged in the database schema. This may lead to warning such as:
 | 
			
		|||
2020/08/02 11:32:29 ...rm/session_schema.go:360:Sync2() [W] Table user Column keep_activity_private db default is , struct default is 0
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
These can safely be ignored but you may able to stop these warnings by getting Gitea to recreate these tables using:
 | 
			
		||||
These can safely be ignored, but you are able to stop these warnings by getting Gitea to recreate these tables using:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
gitea doctor recreate-table user
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,12 +22,14 @@ menu:
 | 
			
		|||
 | 
			
		||||
1. Your `app.ini` (with any sensitive data scrubbed as necessary).
 | 
			
		||||
2. The Gitea logs, and any other appropriate log files for the situation.
 | 
			
		||||
    - The logs are likely to be outputted to console. If you need to collect logs from files,
 | 
			
		||||
    - When using systemd, use `journalctl --lines 1000 --unit gitea` to collect logs.
 | 
			
		||||
    - When using docker, use `docker logs --tail 1000 <gitea-container>` to collect logs.
 | 
			
		||||
    - By default, the logs are outputted to console. If you need to collect logs from files,
 | 
			
		||||
      you could copy the following config into your `app.ini` (remove all other `[log]` sections),
 | 
			
		||||
      then you can find the `*.log` files in Gitea's log directory (default: `%(GITEA_WORK_DIR)/log`).
 | 
			
		||||
 | 
			
		||||
    ```ini
 | 
			
		||||
    ; To show all SQL logs, you can also set LOG_SQL=true in the [database] section 
 | 
			
		||||
    ; To show all SQL logs, you can also set LOG_SQL=true in the [database] section
 | 
			
		||||
    [log]
 | 
			
		||||
    LEVEL=debug
 | 
			
		||||
    MODE=console,file
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,9 +49,9 @@ Open "Windows Services", search for the service named "gitea", right-click it an
 | 
			
		|||
"Run". If everything is OK, Gitea will be reachable on `http://localhost:3000` (or the port
 | 
			
		||||
that was configured).
 | 
			
		||||
 | 
			
		||||
## Adding startup dependancies
 | 
			
		||||
## Adding startup dependencies
 | 
			
		||||
 | 
			
		||||
To add a startup dependancy to the Gitea Windows service (eg Mysql, Mariadb), as an Administrator, then run the following command:
 | 
			
		||||
To add a startup dependency to the Gitea Windows service (eg Mysql, Mariadb), as an Administrator, then run the following command:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sc.exe config gitea depend= mariadb
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ Possible file names for issue templates:
 | 
			
		|||
- `.gitea/ISSUE_TEMPLATE.yml`
 | 
			
		||||
- `.gitea/issue_template.md`
 | 
			
		||||
- `.gitea/issue_template.yaml`
 | 
			
		||||
- `.gitea/issue_template.md`
 | 
			
		||||
- `.gitea/issue_template.yml`
 | 
			
		||||
- `.github/ISSUE_TEMPLATE.md`
 | 
			
		||||
- `.github/ISSUE_TEMPLATE.yaml`
 | 
			
		||||
- `.github/ISSUE_TEMPLATE.yml`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,36 +1,296 @@
 | 
			
		|||
---
 | 
			
		||||
date: "2018-05-10T16:00:00+02:00"
 | 
			
		||||
title: "使用:Issue 和 Pull Request 模板"
 | 
			
		||||
date: "2022-09-07T16:00:00+08:00"
 | 
			
		||||
title: "使用:从模板创建工单与合并请求"
 | 
			
		||||
slug: "issue-pull-request-templates"
 | 
			
		||||
weight: 15
 | 
			
		||||
toc: false
 | 
			
		||||
toc: true
 | 
			
		||||
draft: false
 | 
			
		||||
menu:
 | 
			
		||||
  sidebar:
 | 
			
		||||
    parent: "usage"
 | 
			
		||||
    name: "Issue 和 Pull Request 模板"
 | 
			
		||||
    name: "从模板创建工单与合并请求"
 | 
			
		||||
    weight: 15
 | 
			
		||||
    identifier: "issue-pull-request-templates"
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# 使用 Issue 和 Pull Request 模板
 | 
			
		||||
# 从模板创建工单与合并请求
 | 
			
		||||
 | 
			
		||||
对于一些项目,在创建 issue 或 pull request 时有一个标准的询问列表需要提交者填写。Gitea 支持添加此类模板至 repository 的主分支,以便提交者在创建 issue 或 pull request 时可以自动生成一个需要完成的表单,这么做可以减少一些前期关于 issue 抑或 pull request 细节上的沟通成本。
 | 
			
		||||
开发者可以利用问题模板创建工单与合并请求,其目的在于规范参与者的语言表达。
 | 
			
		||||
 | 
			
		||||
以下罗列了一些可供参考的 issue 模板:
 | 
			
		||||
**目录**
 | 
			
		||||
 | 
			
		||||
* ISSUE_TEMPLATE.md
 | 
			
		||||
* issue_template.md
 | 
			
		||||
* .gitea/ISSUE_TEMPLATE.md
 | 
			
		||||
* .gitea/issue_template.md
 | 
			
		||||
* .github/ISSUE_TEMPLATE.md
 | 
			
		||||
* .github/issue_template.md
 | 
			
		||||
{{< toc >}}
 | 
			
		||||
 | 
			
		||||
以下罗列了一些可供参考的 PR 模板:
 | 
			
		||||
## 模板介绍
 | 
			
		||||
 | 
			
		||||
* PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
* pull_request_template.md
 | 
			
		||||
* .gitea/PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
* .gitea/pull_request_template.md
 | 
			
		||||
* .github/PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
* .github/pull_request_template.md
 | 
			
		||||
Gitea 支持两种格式的模板:Markdown 和 YAML。
 | 
			
		||||
 | 
			
		||||
### Markdown 模板
 | 
			
		||||
 | 
			
		||||
在 Gitea 中存在两种用途的 Markdown 模板:
 | 
			
		||||
 | 
			
		||||
- `ISSUE_TEMPLATE/bug-report.md` 用于规范工单的 Markdown 文本描述
 | 
			
		||||
- `PULL_REQUEST_TEMPLATE.md` 用于规范合并请求的 Markdown 文本描述
 | 
			
		||||
 | 
			
		||||
对于以上 Markdown 模板,我们推荐您将它们放置到项目目录 `.gitea` 进行收纳。
 | 
			
		||||
 | 
			
		||||
### YAML 模板
 | 
			
		||||
 | 
			
		||||
用 YAML 语法编写的模板相比 Markdown 可以实现更丰富的功能,利用表单实现诸如:问卷调查、字符校验。在 Gitea 中的 YAML 同样支持两种用途:
 | 
			
		||||
 | 
			
		||||
- `ISSUE_TEMPLATE/bug-report.yaml` 用于创建问卷调查形式的工单
 | 
			
		||||
- `PULL_REQUEST_TEMPLATE.yaml` 用于创建表单形式的合并请求
 | 
			
		||||
 | 
			
		||||
对于以上 YAML 模板,我们同样推荐您将它们放置到项目目录 `.gitea` 进行收纳。
 | 
			
		||||
 | 
			
		||||
##### 表单支持通过 URL 查询参数传值
 | 
			
		||||
 | 
			
		||||
当新建工单页面 URL 以 `?title=Issue+Title&body=Issue+Text` 为查询参数,表单将使用其中的参数(key-value)填充表单内容。
 | 
			
		||||
 | 
			
		||||
### Gitea 支持的模板文件路径
 | 
			
		||||
 | 
			
		||||
工单模板文件名:
 | 
			
		||||
 | 
			
		||||
- `ISSUE_TEMPLATE.md`
 | 
			
		||||
- `ISSUE_TEMPLATE.yaml`
 | 
			
		||||
- `ISSUE_TEMPLATE.yml`
 | 
			
		||||
- `issue_template.md`
 | 
			
		||||
- `issue_template.yaml`
 | 
			
		||||
- `issue_template.yml`
 | 
			
		||||
- `.gitea/ISSUE_TEMPLATE.md`
 | 
			
		||||
- `.gitea/ISSUE_TEMPLATE.yaml`
 | 
			
		||||
- `.gitea/ISSUE_TEMPLATE.yml`
 | 
			
		||||
- `.gitea/issue_template.md`
 | 
			
		||||
- `.gitea/issue_template.yaml`
 | 
			
		||||
- `.gitea/issue_template.yml`
 | 
			
		||||
- `.github/ISSUE_TEMPLATE.md`
 | 
			
		||||
- `.github/ISSUE_TEMPLATE.yaml`
 | 
			
		||||
- `.github/ISSUE_TEMPLATE.yml`
 | 
			
		||||
- `.github/issue_template.md`
 | 
			
		||||
- `.github/issue_template.yaml`
 | 
			
		||||
- `.github/issue_template.yml`
 | 
			
		||||
 | 
			
		||||
合并请求模板:
 | 
			
		||||
 | 
			
		||||
- `PULL_REQUEST_TEMPLATE.md`
 | 
			
		||||
- `PULL_REQUEST_TEMPLATE.yaml`
 | 
			
		||||
- `PULL_REQUEST_TEMPLATE.yml`
 | 
			
		||||
- `pull_request_template.md`
 | 
			
		||||
- `pull_request_template.yaml`
 | 
			
		||||
- `pull_request_template.yml`
 | 
			
		||||
- `.gitea/PULL_REQUEST_TEMPLATE.md`
 | 
			
		||||
- `.gitea/PULL_REQUEST_TEMPLATE.yaml`
 | 
			
		||||
- `.gitea/PULL_REQUEST_TEMPLATE.yml`
 | 
			
		||||
- `.gitea/pull_request_template.md`
 | 
			
		||||
- `.gitea/pull_request_template.yaml`
 | 
			
		||||
- `.gitea/pull_request_template.yml`
 | 
			
		||||
- `.github/PULL_REQUEST_TEMPLATE.md`
 | 
			
		||||
- `.github/PULL_REQUEST_TEMPLATE.yaml`
 | 
			
		||||
- `.github/PULL_REQUEST_TEMPLATE.yml`
 | 
			
		||||
- `.github/pull_request_template.md`
 | 
			
		||||
- `.github/pull_request_template.yaml`
 | 
			
		||||
- `.github/pull_request_template.yml`
 | 
			
		||||
 | 
			
		||||
#### 工单模板目录
 | 
			
		||||
 | 
			
		||||
由于工单存在多种类型,Gitea 支持将工单模板统一收纳到 `ISSUE_TEMPLATE` 目录。以下是 Gitea 支持的工单模板目录:
 | 
			
		||||
 | 
			
		||||
- `ISSUE_TEMPLATE`
 | 
			
		||||
- `issue_template`
 | 
			
		||||
- `.gitea/ISSUE_TEMPLATE`
 | 
			
		||||
- `.gitea/issue_template`
 | 
			
		||||
- `.github/ISSUE_TEMPLATE`
 | 
			
		||||
- `.github/issue_template`
 | 
			
		||||
- `.gitlab/ISSUE_TEMPLATE`
 | 
			
		||||
- `.gitlab/issue_template`
 | 
			
		||||
 | 
			
		||||
目录支持混合存放 Markdown (`.md`) 或 YAML (`.yaml`/`.yml`) 格式的工单模板。另外,合并请求模板不支持目录存放。
 | 
			
		||||
 | 
			
		||||
## Markdown 模板语法
 | 
			
		||||
 | 
			
		||||
```md
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
name: "Template Name"
 | 
			
		||||
about: "This template is for testing!"
 | 
			
		||||
title: "[TEST] "
 | 
			
		||||
ref: "main"
 | 
			
		||||
labels:
 | 
			
		||||
 | 
			
		||||
- bug
 | 
			
		||||
- "help needed"
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
This is the template!
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
上面的示例表示用户从列表中选择一个工单模板时,列表会展示模板名称 `Template Name` 和模板描述 `This template is for testing!`。 同时,标题会预先填充为 `[TEST]`,而正文将预先填充 `This is the template!`。 最后,Issue 还会被分配两个标签,`bug` 和 `help needed`,并且将问题指向 `main` 分支。
 | 
			
		||||
 | 
			
		||||
## YAML 模板语法
 | 
			
		||||
 | 
			
		||||
YAML 模板格式如下,相比 Markdown 模板提供了更多实用性的功能。
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: 表单名称
 | 
			
		||||
about: 表单描述
 | 
			
		||||
title: 默认标题
 | 
			
		||||
body: 主体内容
 | 
			
		||||
  type: 定义表单元素类型
 | 
			
		||||
    id: 定义表单标号
 | 
			
		||||
    attributes: 扩展的属性
 | 
			
		||||
    validations: 内容校验
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
下例 YAML 配置文件完整定义了一个用于提交 bug 的问卷调查。
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: Bug Report
 | 
			
		||||
about: File a bug report
 | 
			
		||||
title: "[Bug]: "
 | 
			
		||||
body:
 | 
			
		||||
  - type: markdown
 | 
			
		||||
    attributes:
 | 
			
		||||
      value: |
 | 
			
		||||
        Thanks for taking the time to fill out this bug report!
 | 
			
		||||
  - type: input
 | 
			
		||||
    id: contact
 | 
			
		||||
    attributes:
 | 
			
		||||
      label: Contact Details
 | 
			
		||||
      description: How can we get in touch with you if we need more info?
 | 
			
		||||
      placeholder: ex. email@example.com
 | 
			
		||||
    validations:
 | 
			
		||||
      required: false
 | 
			
		||||
  - type: textarea
 | 
			
		||||
    id: what-happened
 | 
			
		||||
    attributes:
 | 
			
		||||
      label: What happened?
 | 
			
		||||
      description: Also tell us, what did you expect to happen?
 | 
			
		||||
      placeholder: Tell us what you see!
 | 
			
		||||
      value: "A bug happened!"
 | 
			
		||||
    validations:
 | 
			
		||||
      required: true
 | 
			
		||||
  - type: dropdown
 | 
			
		||||
    id: version
 | 
			
		||||
    attributes:
 | 
			
		||||
      label: Version
 | 
			
		||||
      description: What version of our software are you running?
 | 
			
		||||
      options:
 | 
			
		||||
        - 1.0.2 (Default)
 | 
			
		||||
        - 1.0.3 (Edge)
 | 
			
		||||
    validations:
 | 
			
		||||
      required: true
 | 
			
		||||
  - type: dropdown
 | 
			
		||||
    id: browsers
 | 
			
		||||
    attributes:
 | 
			
		||||
      label: What browsers are you seeing the problem on?
 | 
			
		||||
      multiple: true
 | 
			
		||||
      options:
 | 
			
		||||
        - Firefox
 | 
			
		||||
        - Chrome
 | 
			
		||||
        - Safari
 | 
			
		||||
        - Microsoft Edge
 | 
			
		||||
  - type: textarea
 | 
			
		||||
    id: logs
 | 
			
		||||
    attributes:
 | 
			
		||||
      label: Relevant log output
 | 
			
		||||
      description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
 | 
			
		||||
      render: shell
 | 
			
		||||
  - type: checkboxes
 | 
			
		||||
    id: terms
 | 
			
		||||
    attributes:
 | 
			
		||||
      label: Code of Conduct
 | 
			
		||||
      description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com)
 | 
			
		||||
      options:
 | 
			
		||||
        - label: I agree to follow this project's Code of Conduct
 | 
			
		||||
          required: true
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Markdown 段落
 | 
			
		||||
 | 
			
		||||
您可以在 YAML 模板中使用 `markdown` 元素为开发者提供额外的上下文支撑,这部分内容会作为创建工单的提示但不会作为工单内容提交。
 | 
			
		||||
 | 
			
		||||
`attributes` 子项提供了以下扩展能力:
 | 
			
		||||
 | 
			
		||||
| 键      | 描述                           | 必选 | 类型   | 默认值 | 有效值 |
 | 
			
		||||
| ------- | ------------------------------ | ---- | ------ | ------ | ------ |
 | 
			
		||||
| `value` | 渲染的文本。支持 Markdown 格式 | 必选 | 字符串 | -      | -      |
 | 
			
		||||
 | 
			
		||||
### Textarea 多行文本输入框
 | 
			
		||||
 | 
			
		||||
您可以使用 `textarea` 元素在表单中添加多行文本输入框。 除了输入文本,开发者还可以在 `textarea` 区域附加文件。
 | 
			
		||||
 | 
			
		||||
`attributes` 子项提供了以下扩展能力:
 | 
			
		||||
 | 
			
		||||
| 键            | 描述                                                                                                  | 必选 | 类型   | 默认值   | 有效值             |
 | 
			
		||||
| ------------- | ----------------------------------------------------------------------------------------------------- | ---- | ------ | -------- | ------------------ |
 | 
			
		||||
| `label`       | 预期用户输入的简短描述,也以表单形式显示。                                                            | 必选 | 字符串 | -        | -                  |
 | 
			
		||||
| `description` | 提供上下文或指导的文本区域的描述,以表单形式显示。                                                    | 可选 | 字符串 | 空字符串 | -                  |
 | 
			
		||||
| `placeholder` | 半透明的占位符,在文本区域空白时呈现                                                                  | 可选 | 字符串 | 空字符串 | -                  |
 | 
			
		||||
| `value`       | 在文本区域中预填充的文本。                                                                            | 可选 | 字符串 | -        | -                  |
 | 
			
		||||
| `render`      | 如果提供了值,提交的文本将格式化为代码块。 提供此键时,文本区域将不会扩展到文件附件或 Markdown 编辑。 | 可选 | 字符串 | -        | Gitea 支持的语言。 |
 | 
			
		||||
 | 
			
		||||
`validations` 子项提供以下文本校验参数:
 | 
			
		||||
 | 
			
		||||
| 键         | 描述                         | 必选 | 类型   | 默认值 | 有效值 |
 | 
			
		||||
| ---------- | ---------------------------- | ---- | ------ | ------ | ------ |
 | 
			
		||||
| `required` | 防止在元素完成之前提交表单。 | 可选 | 布尔型 | false  | -      |
 | 
			
		||||
 | 
			
		||||
### Input 单行输入框
 | 
			
		||||
 | 
			
		||||
您可以使用 `input` 元素添加单行文本字段到表单。
 | 
			
		||||
 | 
			
		||||
`attributes` 子项提供了以下扩展能力:
 | 
			
		||||
 | 
			
		||||
| 键            | 描述                                           | 必选 | 类型   | 默认值   | 有效值 |
 | 
			
		||||
| ------------- | ---------------------------------------------- | ---- | ------ | -------- | ------ |
 | 
			
		||||
| `label`       | 预期用户输入的简短描述,也以表单形式显示。     | 必选 | 字符串 | -        | -      |
 | 
			
		||||
| `description` | 提供上下文或指导的字段的描述,以表单形式显示。 | 可选 | 字符串 | 空字符串 | -      |
 | 
			
		||||
| `placeholder` | 半透明的占位符,在字段空白时呈现。             | 可选 | 字符串 | 空字符串 | -      |
 | 
			
		||||
| `value`       | 字段中预填的文本。                             | 可选 | 字符串 | -        | -      |
 | 
			
		||||
 | 
			
		||||
`validations` 子项提供以下文本校验参数:
 | 
			
		||||
 | 
			
		||||
| 键          | 描述                             | 必选 | 类型   | 默认值 | 有效值                                                         |
 | 
			
		||||
| ----------- | -------------------------------- | ---- | ------ | ------ | -------------------------------------------------------------- |
 | 
			
		||||
| `required`  | 防止在未填内容时提交表单。       | 可选 | 布尔型 | false  | -                                                              |
 | 
			
		||||
| `is_number` | 防止在未填数字时提交表单。       | 可选 | 布尔型 | false  | -                                                              |
 | 
			
		||||
| `regex`     | 直到满足了与正则表达式匹配的值。 | 可选 | 字符串 | -      | [正则表达式](https://en.wikipedia.org/wiki/Regular_expression) |
 | 
			
		||||
 | 
			
		||||
### Dropdown 下拉菜单
 | 
			
		||||
 | 
			
		||||
您可以使用 `dropdown` 元素在表单中添加下拉菜单。
 | 
			
		||||
 | 
			
		||||
`attributes` 子项提供了以下扩展能力:
 | 
			
		||||
 | 
			
		||||
| 键            | 描述                                                      | 必选 | 类型       | 默认值   | 有效值 |
 | 
			
		||||
| ------------- | --------------------------------------------------------- | ---- | ---------- | -------- | ------ |
 | 
			
		||||
| `label`       | 预期用户输入的简短描述,以表单形式显示。                  | 必选 | 字符串     | -        | -      |
 | 
			
		||||
| `description` | 提供上下文或指导的下拉列表的描述,以表单形式显示。        | 可选 | 字符串     | 空字符串 | -      |
 | 
			
		||||
| `multiple`    | 确定用户是否可以选择多个选项。                            | 可选 | 布尔型     | false    | -      |
 | 
			
		||||
| `options`     | 用户可以选择的选项列表。 不能为空,所有选择必须是不同的。 | 必选 | 字符串数组 | -        | -      |
 | 
			
		||||
 | 
			
		||||
`validations` 子项提供以下文本校验参数:
 | 
			
		||||
 | 
			
		||||
| 键         | 描述                         | 必选 | 类型   | 默认值 | 有效值 |
 | 
			
		||||
| ---------- | ---------------------------- | ---- | ------ | ------ | ------ |
 | 
			
		||||
| `required` | 防止在元素完成之前提交表单。 | 可选 | 布尔型 | false  | -      |
 | 
			
		||||
 | 
			
		||||
### Checkboxes 复选框
 | 
			
		||||
 | 
			
		||||
您可以使用 `checkboxes` 元素添加一组复选框到表单。
 | 
			
		||||
 | 
			
		||||
`attributes` 子项提供了以下扩展能力:
 | 
			
		||||
 | 
			
		||||
| 键            | 描述                                                  | 必选 | 类型   | 默认值   | 有效值 |
 | 
			
		||||
| ------------- | ----------------------------------------------------- | ---- | ------ | -------- | ------ |
 | 
			
		||||
| `label`       | 预期用户输入的简短描述,以表单形式显示。              | 必选 | 字符串 | -        | -      |
 | 
			
		||||
| `description` | 复选框集的描述,以表单形式显示。 支持 Markdown 格式。 | 可选 | 字符串 | 空字符串 | -      |
 | 
			
		||||
| `options`     | 用户可以选择的复选框列表。 有关语法,请参阅下文。     | 必选 | 数组   | -        | -      |
 | 
			
		||||
 | 
			
		||||
对于 `options`,您可以设置以下参数:
 | 
			
		||||
 | 
			
		||||
| 键         | 描述                                                                              | 必选 | 类型   | 默认值 | 有效值 |
 | 
			
		||||
| ---------- | --------------------------------------------------------------------------------- | ---- | ------ | ------ | ------ |
 | 
			
		||||
| `label`    | 选项的标识符,显示在表单中。 支持 Markdown 用于粗体或斜体文本格式化和超文本链接。 | 必选 | 字符串 | -      | -      |
 | 
			
		||||
| `required` | 防止在元素完成之前提交表单。                                                      | 可选 | 布尔型 | false  | -      |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ type ActivityAuthorData struct {
 | 
			
		|||
	Commits    int64  `json:"commits"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ActivityStats represets issue and pull request information.
 | 
			
		||||
// ActivityStats represents issue and pull request information.
 | 
			
		||||
type ActivityStats struct {
 | 
			
		||||
	OpenedPRs                   issues_model.PullRequestList
 | 
			
		||||
	OpenedPRAuthorCount         int64
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ func TestHasOwnerPackages(t *testing.T) {
 | 
			
		|||
	assert.NotNil(t, pv)
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	// A package with an internal package version gets automaticaly cleaned up and should return false
 | 
			
		||||
	// A package with an internal package version gets automatically cleaned up and should return false
 | 
			
		||||
	has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
 | 
			
		||||
	assert.False(t, has)
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ import (
 | 
			
		|||
	"xorm.io/builder"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo.
 | 
			
		||||
// ErrUserDoesNotHaveAccessToRepo represents an error where the user doesn't has access to a given repo.
 | 
			
		||||
type ErrUserDoesNotHaveAccessToRepo struct {
 | 
			
		||||
	UserID   int64
 | 
			
		||||
	RepoName string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ type Metadata struct {
 | 
			
		|||
	RepositoryURL string `json:"repository_url,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseMetadataFromBox parses the metdata of a box file
 | 
			
		||||
// ParseMetadataFromBox parses the metadata of a box file
 | 
			
		||||
func ParseMetadataFromBox(r io.Reader) (*Metadata, error) {
 | 
			
		||||
	gzr, err := gzip.NewReader(r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -376,15 +376,15 @@ func NewFuncMap() []template.FuncMap {
 | 
			
		|||
			// the table is NOT sorted with this header
 | 
			
		||||
			return ""
 | 
			
		||||
		},
 | 
			
		||||
		"RenderLabels": func(labels []*issues_model.Label) template.HTML {
 | 
			
		||||
		"RenderLabels": func(labels []*issues_model.Label, repoLink string) template.HTML {
 | 
			
		||||
			html := `<span class="labels-list">`
 | 
			
		||||
			for _, label := range labels {
 | 
			
		||||
				// Protect against nil value in labels - shouldn't happen but would cause a panic if so
 | 
			
		||||
				if label == nil {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				html += fmt.Sprintf("<div class='ui label' style='color: %s; background-color: %s'>%s</div> ",
 | 
			
		||||
					label.ForegroundColor(), label.Color, RenderEmoji(label.Name))
 | 
			
		||||
				html += fmt.Sprintf("<a href='%s/issues?labels=%d' class='ui label' style='color: %s !important; background-color: %s !important'>%s</a> ",
 | 
			
		||||
					repoLink, label.ID, label.ForegroundColor(), label.Color, RenderEmoji(label.Name))
 | 
			
		||||
			}
 | 
			
		||||
			html += "</span>"
 | 
			
		||||
			return template.HTML(html)
 | 
			
		||||
| 
						 | 
				
			
			@ -631,7 +631,7 @@ func SVG(icon string, others ...interface{}) template.HTML {
 | 
			
		|||
 | 
			
		||||
// Avatar renders user avatars. args: user, size (int), class (string)
 | 
			
		||||
func Avatar(item interface{}, others ...interface{}) template.HTML {
 | 
			
		||||
	size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image vm", others...)
 | 
			
		||||
	size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...)
 | 
			
		||||
 | 
			
		||||
	switch t := item.(type) {
 | 
			
		||||
	case *user_model.User:
 | 
			
		||||
| 
						 | 
				
			
			@ -662,7 +662,7 @@ func AvatarByAction(action *activities_model.Action, others ...interface{}) temp
 | 
			
		|||
 | 
			
		||||
// RepoAvatar renders repo avatars. args: repo, size(int), class (string)
 | 
			
		||||
func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTML {
 | 
			
		||||
	size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image", others...)
 | 
			
		||||
	size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...)
 | 
			
		||||
 | 
			
		||||
	src := repo.RelAvatarLink()
 | 
			
		||||
	if src != "" {
 | 
			
		||||
| 
						 | 
				
			
			@ -673,7 +673,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM
 | 
			
		|||
 | 
			
		||||
// AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string)
 | 
			
		||||
func AvatarByEmail(email, name string, others ...interface{}) template.HTML {
 | 
			
		||||
	size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image", others...)
 | 
			
		||||
	size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...)
 | 
			
		||||
	src := avatars.GenerateEmailAvatarFastLink(email, size*setting.Avatar.RenderedSizeFactor)
 | 
			
		||||
 | 
			
		||||
	if src != "" {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,6 +178,8 @@ log_root_path_helper=Τα αρχεία καταγραφής θα γράφοντ
 | 
			
		|||
 | 
			
		||||
optional_title=Προαιρετικές Ρυθμίσεις
 | 
			
		||||
email_title=Ρυθμίσεις Email
 | 
			
		||||
smtp_addr=Διακομιστής SMTP
 | 
			
		||||
smtp_port=Θύρα SMTP
 | 
			
		||||
smtp_from=Αποστολή Email Ως
 | 
			
		||||
smtp_from_helper=Η διεύθυνση email που θα χρησιμοποιεί το Gitea. Εισάγετε μια απλή διεύθυνση ηλεκτρονικού ταχυδρομείου ή χρησιμοποιήστε τη μορφή "Όνομα" <email@example.com>.
 | 
			
		||||
mailer_user=Όνομα Χρήστη SMTP
 | 
			
		||||
| 
						 | 
				
			
			@ -275,6 +277,8 @@ org_no_results=Δεν βρέθηκαν οργανισμοί που να ταιρ
 | 
			
		|||
code_no_results=Δεν βρέθηκε πηγαίος κώδικας που να ταιριάζει με τον όρο αναζήτησης.
 | 
			
		||||
code_search_results=Αποτελέσματα αναζήτησης για '%s'
 | 
			
		||||
code_last_indexed_at=Τελευταίο δημιουργία ευρετηρίου στις %s
 | 
			
		||||
relevant_repositories_tooltip=Τα αποθετήρια που είναι forks ή που δεν έχουν θέμα, εικονίδιο και περιγραφή είναι κρυμμένα.
 | 
			
		||||
relevant_repositories=Εμφανίζονται μόνο τα σχετικά αποθετήρια, <a href="%s">εμφάνιση χωρίς φίλτρο</a>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[auth]
 | 
			
		||||
| 
						 | 
				
			
			@ -798,6 +802,7 @@ email_notifications.enable=Ενεργοποίηση Ειδοποιήσεων Μ
 | 
			
		|||
email_notifications.onmention=Email Μόνο κατά την Αναφορά
 | 
			
		||||
email_notifications.disable=Απενεργοποίηση Ειδοποιήσεων μέσω Email
 | 
			
		||||
email_notifications.submit=Ορισμός Προτιμότερου Email
 | 
			
		||||
email_notifications.andyourown=Και Τις Δικές Σας Ειδοποιήσεις
 | 
			
		||||
 | 
			
		||||
visibility=Ορατότητα χρήστη
 | 
			
		||||
visibility.public=Δημόσια
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,6 +1038,13 @@ file_view_rendered=Προβολή Απόδοσης
 | 
			
		|||
file_view_raw=Προβολή Ακατέργαστου
 | 
			
		||||
file_permalink=Permalink
 | 
			
		||||
file_too_large=Το αρχείο είναι πολύ μεγάλο για να εμφανιστεί.
 | 
			
		||||
invisible_runes_header=`Αυτό το αρχείο περιέχει αόρατους χαρακτήρες Unicode!`
 | 
			
		||||
invisible_runes_description=`Αυτό το αρχείο περιέχει αόρατους χαρακτήρες Unicode που μπορεί να επεξεργάζονται διαφορετικά από ό, τι εμφανίζονται παρακάτω. Αν η περίπτωση χρήσης σας είναι σκόπιμη και νόμιμη, μπορείτε να αγνοήσετε με ασφάλεια αυτή την προειδοποίηση. Χρησιμοποιήστε το κουμπί Escape για να αποκαλύψετε κρυμμένους χαρακτήρες.`
 | 
			
		||||
ambiguous_runes_header=`Αυτό το αρχείο περιέχει ασαφείς χαρακτήρες Unicode!`
 | 
			
		||||
ambiguous_runes_description=`Αυτό το αρχείο περιέχει ασαφείς χαρακτήρες Unicode που μπορεί να συγχέονται με άλλους στην τοπική σας γλώσσα. Αν η περίπτωση χρήσης σας είναι σκόπιμη και νόμιμη, μπορείτε να αγνοήσετε με ασφάλεια αυτή την προειδοποίηση. Χρησιμοποιήστε το κουμπί Escape για να επισημάνετε αυτούς τους χαρακτήρες.`
 | 
			
		||||
invisible_runes_line=`Αυτή η γραμμή έχει αόρατους χαρακτήρες unicode `
 | 
			
		||||
ambiguous_runes_line=`Αυτή η γραμμή έχει ασαφείς χαρακτήρες unicode `
 | 
			
		||||
ambiguous_character=`ο %[1]c [U+%04[1]X] μπορεί να μπερδευτεί με τον %[2]c [U+%04[2]X]`
 | 
			
		||||
 | 
			
		||||
escape_control_characters=Escape
 | 
			
		||||
unescape_control_characters=Unescape
 | 
			
		||||
| 
						 | 
				
			
			@ -1053,6 +1065,7 @@ normal_view=Κανονική Προβολή
 | 
			
		|||
line=γραμμή
 | 
			
		||||
lines=γραμμές
 | 
			
		||||
 | 
			
		||||
editor.add_file=Προσθήκη Αρχείου
 | 
			
		||||
editor.new_file=Νέο Αρχείο
 | 
			
		||||
editor.upload_file=Ανέβασμα Αρχείου
 | 
			
		||||
editor.edit_file=Επεξεργασία Αρχείου
 | 
			
		||||
| 
						 | 
				
			
			@ -1218,6 +1231,8 @@ issues.new.add_reviewer_title=Αίτηση επανεξέτασης
 | 
			
		|||
issues.choose.get_started=Ας Αρχίσουμε
 | 
			
		||||
issues.choose.blank=Προεπιλογή
 | 
			
		||||
issues.choose.blank_about=Δημιουργήστε ένα ζήτημα από το προεπιλεγμένο πρότυπο.
 | 
			
		||||
issues.choose.ignore_invalid_templates=Μη έγκυρα πρότυπα έχουν αγνοηθεί
 | 
			
		||||
issues.choose.invalid_templates=%v βρέθηκε μη έγκυρο πρότυπο(α)
 | 
			
		||||
issues.no_ref=Δεν Έχει Οριστεί Κλάδος/Ετικέτα
 | 
			
		||||
issues.create=Δημιουργία Ζητήματος
 | 
			
		||||
issues.new_label=Νέο Σήμα
 | 
			
		||||
| 
						 | 
				
			
			@ -1258,6 +1273,8 @@ issues.filter_milestone=Ορόσημο
 | 
			
		|||
issues.filter_milestone_no_select=Όλα τα ορόσημα
 | 
			
		||||
issues.filter_assignee=Αποδέκτης
 | 
			
		||||
issues.filter_assginee_no_select=Όλοι οι αποδέκτες
 | 
			
		||||
issues.filter_poster=Συγγραφέας
 | 
			
		||||
issues.filter_poster_no_select=Όλοι οι συγγραφείς
 | 
			
		||||
issues.filter_type=Τύπος
 | 
			
		||||
issues.filter_type.all_issues=Όλα τα ζητήματα
 | 
			
		||||
issues.filter_type.assigned_to_you=Ανατέθηκαν σε εσάς
 | 
			
		||||
| 
						 | 
				
			
			@ -1939,6 +1956,8 @@ settings.event_delete=Διαγραφή
 | 
			
		|||
settings.event_delete_desc=Ο κλάδος ή η ετικέτα διαγράφηκε.
 | 
			
		||||
settings.event_fork=Fork
 | 
			
		||||
settings.event_fork_desc=Το αποθετήριο έγινε fork.
 | 
			
		||||
settings.event_wiki=Wiki
 | 
			
		||||
settings.event_wiki_desc=Η σελίδα Wiki δημιουργήθηκε, μετονομάστηκε, επεξεργάστηκε ή διαγράφηκε.
 | 
			
		||||
settings.event_release=Έκδοση
 | 
			
		||||
settings.event_release_desc=Η έκδοση δημοσιεύτηκε, ενημερώθηκε ή διαγράφηκε από ένα αποθετήριο.
 | 
			
		||||
settings.event_push=Push
 | 
			
		||||
| 
						 | 
				
			
			@ -2786,13 +2805,19 @@ config.queue_length=Μέγεθος Ουράς
 | 
			
		|||
config.deliver_timeout=Χρονικό Όριο Παράδοσης
 | 
			
		||||
config.skip_tls_verify=Παράλειψη Επαλήθευσης TLS
 | 
			
		||||
 | 
			
		||||
config.mailer_config=Ρυθμίσεις Αλληλογραφίας
 | 
			
		||||
config.mailer_enabled=Ενεργοποιημένο
 | 
			
		||||
config.mailer_enable_helo=Ενεργοποίηση HELO
 | 
			
		||||
config.mailer_name=Όνομα
 | 
			
		||||
config.mailer_protocol=Πρωτόκολλο
 | 
			
		||||
config.mailer_smtp_addr=Διευθ SMTP
 | 
			
		||||
config.mailer_smtp_port=Θύρα SMTP
 | 
			
		||||
config.mailer_user=Χρήστης
 | 
			
		||||
config.mailer_use_sendmail=Χρήση Sendmail
 | 
			
		||||
config.mailer_sendmail_path=Διαδρομή Sendmail
 | 
			
		||||
config.mailer_sendmail_args=Επιπλέον παράμετροι για το Sendmail
 | 
			
		||||
config.mailer_sendmail_timeout=Χρονικό Όριο Sendmail
 | 
			
		||||
config.mailer_use_dummy=Ψεύτικο
 | 
			
		||||
config.test_email_placeholder=Email (π.χ. test@example.com)
 | 
			
		||||
config.send_test_mail=Αποστολή Δοκιμαστικού Email
 | 
			
		||||
config.test_mail_failed=Αποτυχία αποστολής δοκιμαστικού email στο'%s': %v
 | 
			
		||||
| 
						 | 
				
			
			@ -2877,6 +2902,7 @@ monitor.queue.nopool.title=Χωρίς Δεξαμενή Εργατών
 | 
			
		|||
monitor.queue.nopool.desc=Αυτή η ουρά συμπεριλαμβάνει άλλες ουρές και δεν έχει η ίδια δεξαμενή εργατών.
 | 
			
		||||
monitor.queue.wrapped.desc=Μια ουρά συμπερίληψης, περιλαμβάνει μια ουρά αργής εκκίνησης, κρατώντας προσωρινά τις αιτήσεις πού βρίσκονται στην ουρά, μέσα σε ένα κανάλι. Δεν διαθέτει μια δεξαμενή εργατών.
 | 
			
		||||
monitor.queue.persistable-channel.desc=Ένα ανθεκτικό-κανάλι περιλαμβάνει δύο ουρές, μια ουρά καναλιών που έχει τη δική του δεξαμενή εργατών και μια ουρά επιπέδου για κρατημένα αιτήματα από προηγούμενες απενεργοποιήσεις. Δεν έχει το ίδιο δεξαμενή εργατών.
 | 
			
		||||
monitor.queue.flush=Εκκαθάριση εργάτη
 | 
			
		||||
monitor.queue.pool.timeout=Λήξη ορίου χρόνου
 | 
			
		||||
monitor.queue.pool.addworkers.title=Προσθήκη Εργατών
 | 
			
		||||
monitor.queue.pool.addworkers.submit=Προσθήκη Εργατών
 | 
			
		||||
| 
						 | 
				
			
			@ -3029,6 +3055,7 @@ title=Πακέτα
 | 
			
		|||
desc=Διαχείριση πακέτων μητρώου.
 | 
			
		||||
empty=Δεν υπάρχουν πακέτα ακόμα.
 | 
			
		||||
empty.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο πακέτων, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/overview">στην τεκμηρίωση</a>.
 | 
			
		||||
empty.repo=Μήπως ανεβάσατε ένα πακέτο, αλλά δεν εμφανίζεται εδώ; Πηγαίνετε στις <a href="%[1]s">ρυθμίσεις πακέτων</a> και συνδέστε το σε αυτό το αποθετήριο.
 | 
			
		||||
filter.type=Τύπος
 | 
			
		||||
filter.type.all=Όλα
 | 
			
		||||
filter.no_result=Το φίλτρο δεν παρήγαγε αποτελέσματα.
 | 
			
		||||
| 
						 | 
				
			
			@ -3094,6 +3121,10 @@ npm.dependencies.development=Εξαρτήσεις Ανάπτυξης
 | 
			
		|||
npm.dependencies.peer=Εξαρτήσεις Ομότιμου
 | 
			
		||||
npm.dependencies.optional=Προαιρετικές Εξαρτήσεις
 | 
			
		||||
npm.details.tag=Σήμανση
 | 
			
		||||
pub.install=Για να εγκαταστήσετε το πακέτο μέσω του Dart, εκτελέστε την ακόλουθη εντολή:
 | 
			
		||||
pub.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο Pub, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">στην τεκμηρίωση</a>.
 | 
			
		||||
pub.details.repository_site=Ιστοσελίδα Αποθετηρίου
 | 
			
		||||
pub.details.documentation_site=Ιστοσελίδα Τεκμηρίωσης
 | 
			
		||||
pypi.requires=Απαιτεί Python
 | 
			
		||||
pypi.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το pip, εκτελέστε την ακόλουθη εντολή:
 | 
			
		||||
pypi.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο PyPI, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">στην τεκμηρίωση</a>.
 | 
			
		||||
| 
						 | 
				
			
			@ -3104,6 +3135,8 @@ rubygems.dependencies.development=Εξαρτήσεις Ανάπτυξης
 | 
			
		|||
rubygems.required.ruby=Απαιτεί την έκδοση Ruby
 | 
			
		||||
rubygems.required.rubygems=Απαιτεί έκδοση RubyGem
 | 
			
		||||
rubygems.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο RubyGems, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/rubygems/">στην τεκμηρίωση</a>.
 | 
			
		||||
vagrant.install=Για προσθήκη ενός κυτίου Vagrant, εκτελέστε την ακόλουθη εντολή:
 | 
			
		||||
vagrant.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο του Vagrant, ανατρέξτε <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/vagrant/">στην τεκμηρίωση</a>.
 | 
			
		||||
settings.link=Σύνδεση αυτού του πακέτου με ένα αποθετήριο
 | 
			
		||||
settings.link.description=Εάν συνδέσετε ένα πακέτο με ένα αποθετήριο, το πακέτο περιλαμβάνεται στη λίστα πακέτων του αποθετηρίου.
 | 
			
		||||
settings.link.select=Επιλογή Αποθετηρίου
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1231,6 +1231,8 @@ issues.new.add_reviewer_title=レビュー依頼
 | 
			
		|||
issues.choose.get_started=始める
 | 
			
		||||
issues.choose.blank=デフォルト
 | 
			
		||||
issues.choose.blank_about=デフォルトのテンプレートからイシューを作成。
 | 
			
		||||
issues.choose.ignore_invalid_templates=無効なテンプレートが無視されました
 | 
			
		||||
issues.choose.invalid_templates=無効なテンプレートが%v 件見つかりました
 | 
			
		||||
issues.no_ref=ブランチ/タグ指定なし
 | 
			
		||||
issues.create=イシューを作成
 | 
			
		||||
issues.new_label=新しいラベル
 | 
			
		||||
| 
						 | 
				
			
			@ -1954,6 +1956,8 @@ settings.event_delete=削除
 | 
			
		|||
settings.event_delete_desc=ブランチやタグが削除されたとき。
 | 
			
		||||
settings.event_fork=フォーク
 | 
			
		||||
settings.event_fork_desc=リポジトリがフォークされたとき。
 | 
			
		||||
settings.event_wiki=Wiki
 | 
			
		||||
settings.event_wiki_desc=Wikiページが作成・名前変更・編集・削除されたとき。
 | 
			
		||||
settings.event_release=リリース
 | 
			
		||||
settings.event_release_desc=リポジトリでリリースが作成・更新・削除されたとき。
 | 
			
		||||
settings.event_push=プッシュ
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1956,6 +1956,8 @@ settings.event_delete=Eliminar
 | 
			
		|||
settings.event_delete_desc=Ramo ou etiqueta eliminados.
 | 
			
		||||
settings.event_fork=Derivar
 | 
			
		||||
settings.event_fork_desc=Feita a derivação do repositório.
 | 
			
		||||
settings.event_wiki=Wiki
 | 
			
		||||
settings.event_wiki_desc=Página do wiki criada, renomeada, editada ou eliminada.
 | 
			
		||||
settings.event_release=Lançamento
 | 
			
		||||
settings.event_release_desc=Lançamento publicado, modificado ou eliminado num repositório.
 | 
			
		||||
settings.event_push=Enviar
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1231,6 +1231,8 @@ issues.new.add_reviewer_title=İnceleme iste
 | 
			
		|||
issues.choose.get_started=Başla
 | 
			
		||||
issues.choose.blank=Varsayılan
 | 
			
		||||
issues.choose.blank_about=Varsayılan şablondan bir konu oluşturun.
 | 
			
		||||
issues.choose.ignore_invalid_templates=Geçersiz şablonlar göz ardı edildi
 | 
			
		||||
issues.choose.invalid_templates=%v geçersiz şablon bulundu
 | 
			
		||||
issues.no_ref=Bölüm/Etiket Belirtilmedi
 | 
			
		||||
issues.create=Konu Oluştur
 | 
			
		||||
issues.new_label=Yeni Etiket
 | 
			
		||||
| 
						 | 
				
			
			@ -1954,6 +1956,8 @@ settings.event_delete=Sil
 | 
			
		|||
settings.event_delete_desc=Dal veya etiket silindi.
 | 
			
		||||
settings.event_fork=Çatalla
 | 
			
		||||
settings.event_fork_desc=Depo çatallandı.
 | 
			
		||||
settings.event_wiki=Viki
 | 
			
		||||
settings.event_wiki_desc=Viki sayfası oluşturuldu, adı değiştirildi, düzenlendi veya silindi.
 | 
			
		||||
settings.event_release=Sürüm
 | 
			
		||||
settings.event_release_desc=Sürüm yayınlandığında, güncellendiğinde veya silindiğinde.
 | 
			
		||||
settings.event_push=Çek
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -866,7 +866,7 @@ mirror_prune_desc=删除过时的远程跟踪引用
 | 
			
		|||
mirror_interval=镜像间隔 (有效的时间单位是 'h', 'm', 's')。0 禁用自动定期同步 (最短间隔: %s)
 | 
			
		||||
mirror_interval_invalid=镜像间隔无效。
 | 
			
		||||
mirror_sync_on_commit=推送提交时同步
 | 
			
		||||
mirror_address=从URL克隆
 | 
			
		||||
mirror_address=从 URL 克隆
 | 
			
		||||
mirror_address_desc=在授权框中输入必要的凭据。
 | 
			
		||||
mirror_address_url_invalid=URL无效。请检查您所输入的URL是否正确。
 | 
			
		||||
mirror_address_protocol_invalid=提供的 url 无效。只能从 http(s):// 或 git:// 位置进行镜像。
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2844
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2844
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										20
									
								
								package.json
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								package.json
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,16 +9,16 @@
 | 
			
		|||
  "dependencies": {
 | 
			
		||||
    "@claviska/jquery-minicolors": "2.3.6",
 | 
			
		||||
    "@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
 | 
			
		||||
    "@primer/octicons": "17.4.1",
 | 
			
		||||
    "@primer/octicons": "17.5.0",
 | 
			
		||||
    "add-asset-webpack-plugin": "2.0.1",
 | 
			
		||||
    "css-loader": "6.7.1",
 | 
			
		||||
    "dropzone": "6.0.0-beta.2",
 | 
			
		||||
    "easymde": "2.17.0",
 | 
			
		||||
    "esbuild-loader": "2.19.0",
 | 
			
		||||
    "esbuild-loader": "2.20.0",
 | 
			
		||||
    "escape-goat": "4.0.0",
 | 
			
		||||
    "fast-glob": "3.2.11",
 | 
			
		||||
    "fast-glob": "3.2.12",
 | 
			
		||||
    "font-awesome": "4.7.0",
 | 
			
		||||
    "jquery": "3.6.0",
 | 
			
		||||
    "jquery": "3.6.1",
 | 
			
		||||
    "jquery.are-you-sure": "1.9.0",
 | 
			
		||||
    "less": "4.1.3",
 | 
			
		||||
    "less-loader": "11.0.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -46,23 +46,23 @@
 | 
			
		|||
    "wrap-ansi": "8.0.1"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@playwright/test": "1.25.1",
 | 
			
		||||
    "@playwright/test": "1.25.2",
 | 
			
		||||
    "@stoplight/spectral-cli": "6.5.1",
 | 
			
		||||
    "eslint": "8.22.0",
 | 
			
		||||
    "eslint": "8.23.0",
 | 
			
		||||
    "eslint-plugin-import": "2.26.0",
 | 
			
		||||
    "eslint-plugin-jquery": "1.5.1",
 | 
			
		||||
    "eslint-plugin-sonarjs": "0.15.0",
 | 
			
		||||
    "eslint-plugin-unicorn": "43.0.2",
 | 
			
		||||
    "eslint-plugin-vue": "9.4.0",
 | 
			
		||||
    "jest": "28.1.3",
 | 
			
		||||
    "jest-environment-jsdom": "28.1.3",
 | 
			
		||||
    "jest-extended": "3.0.2",
 | 
			
		||||
    "jest": "29.0.3",
 | 
			
		||||
    "jest-environment-jsdom": "29.0.3",
 | 
			
		||||
    "jest-extended": "3.1.0",
 | 
			
		||||
    "markdownlint-cli": "0.32.2",
 | 
			
		||||
    "postcss-less": "6.0.0",
 | 
			
		||||
    "stylelint": "14.11.0",
 | 
			
		||||
    "stylelint-config-standard": "28.0.0",
 | 
			
		||||
    "svgo": "2.8.0",
 | 
			
		||||
    "updates": "13.1.4"
 | 
			
		||||
    "updates": "13.1.5"
 | 
			
		||||
  },
 | 
			
		||||
  "browserslist": [
 | 
			
		||||
    "defaults",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								public/img/svg/octicon-accessibility-inset.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/img/svg/octicon-accessibility-inset.svg
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
<svg viewBox="0 0 16 16" class="svg octicon-accessibility-inset" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm2 4a2 2 0 0 1-1.05 1.76c.115.069.222.15.32.24h2.98a.75.75 0 0 1 0 1.5H9.888l.608 5.67a.75.75 0 1 1-1.492.16L8.754 11H7.246l-.25 2.33a.75.75 0 1 1-1.49-.16l.607-5.67H3.75a.75.75 0 0 1 0-1.5h2.98a1.87 1.87 0 0 1 .32-.24A2 2 0 1 1 10 4z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 413 B  | 
							
								
								
									
										1
									
								
								public/img/svg/octicon-shield-slash.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/img/svg/octicon-shield-slash.svg
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
<svg viewBox="0 0 16 16" class="svg octicon-shield-slash" width="16" height="16" aria-hidden="true"><path d="M8.533.133a1.75 1.75 0 0 0-1.066 0l-2.091.67a.75.75 0 0 0 .457 1.428l2.09-.67a.25.25 0 0 1 .153 0l5.25 1.68a.25.25 0 0 1 .174.239V7c0 .233-.008.464-.025.694a.75.75 0 1 0 1.495.112c.02-.27.03-.538.03-.806V3.48a1.75 1.75 0 0 0-1.217-1.667L8.533.133z"/><path fill-rule="evenodd" d="m1 2.857-.69-.5a.75.75 0 1 1 .88-1.214l14.5 10.5a.75.75 0 1 1-.88 1.214l-1.282-.928c-.995 1.397-2.553 2.624-4.864 3.608-.425.181-.905.18-1.329 0-2.447-1.042-4.049-2.356-5.032-3.855C1.32 10.182 1 8.566 1 7V2.857zm1.5 1.086V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297.05.02.106.02.153 0 2.127-.905 3.439-1.982 4.237-3.108L2.5 3.943z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 747 B  | 
| 
						 | 
				
			
			@ -23,7 +23,7 @@ import (
 | 
			
		|||
 | 
			
		||||
// https://www.python.org/dev/peps/pep-0503/#normalized-names
 | 
			
		||||
var normalizer = strings.NewReplacer(".", "-", "_", "-")
 | 
			
		||||
var nameMatcher = regexp.MustCompile(`\A[a-z0-9\.\-_]+\z`)
 | 
			
		||||
var nameMatcher = regexp.MustCompile(`\A[a-zA-Z0-9\.\-_]+\z`)
 | 
			
		||||
 | 
			
		||||
// https://www.python.org/dev/peps/pep-0440/#appendix-b-parsing-version-strings-with-regular-expressions
 | 
			
		||||
var versionMatcher = regexp.MustCompile(`^([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$`)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ func Commits(ctx *context.Context) {
 | 
			
		|||
	ctx.Data["CommitCount"] = commitsCount
 | 
			
		||||
	ctx.Data["RefName"] = ctx.Repo.RefName
 | 
			
		||||
 | 
			
		||||
	pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
 | 
			
		||||
	pager := context.NewPagination(int(commitsCount), pageSize, page, 5)
 | 
			
		||||
	pager.SetDefaultParams(ctx)
 | 
			
		||||
	ctx.Data["Page"] = pager
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ var IssueTemplateCandidates = []string{
 | 
			
		|||
	".gitea/ISSUE_TEMPLATE.yml",
 | 
			
		||||
	".gitea/issue_template.md",
 | 
			
		||||
	".gitea/issue_template.yaml",
 | 
			
		||||
	".gitea/issue_template.md",
 | 
			
		||||
	".gitea/issue_template.yml",
 | 
			
		||||
	".github/ISSUE_TEMPLATE.md",
 | 
			
		||||
	".github/ISSUE_TEMPLATE.yaml",
 | 
			
		||||
	".github/ISSUE_TEMPLATE.yml",
 | 
			
		||||
| 
						 | 
				
			
			@ -1336,11 +1336,16 @@ func ViewIssue(ctx *context.Context) {
 | 
			
		|||
 | 
			
		||||
	if issue.IsPull {
 | 
			
		||||
		canChooseReviewer := ctx.Repo.CanWrite(unit.TypePullRequests)
 | 
			
		||||
		if !canChooseReviewer && ctx.Doer != nil && ctx.IsSigned {
 | 
			
		||||
			canChooseReviewer, err = issues_model.IsOfficialReviewer(ctx, issue, ctx.Doer)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.ServerError("IsOfficialReviewer", err)
 | 
			
		||||
				return
 | 
			
		||||
		if ctx.Doer != nil && ctx.IsSigned {
 | 
			
		||||
			if !canChooseReviewer {
 | 
			
		||||
				canChooseReviewer = ctx.Doer.ID == issue.PosterID
 | 
			
		||||
			}
 | 
			
		||||
			if !canChooseReviewer {
 | 
			
		||||
				canChooseReviewer, err = issues_model.IsOfficialReviewer(ctx, issue, ctx.Doer)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					ctx.ServerError("IsOfficialReviewer", err)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// localizedExtensions prepends the provided language code with and without a
 | 
			
		||||
// regional identifier to the provided extenstion.
 | 
			
		||||
// regional identifier to the provided extension.
 | 
			
		||||
// Note: the language code will always be lower-cased, if a region is present it must be separated with a `-`
 | 
			
		||||
// Note: ext should be prefixed with a `.`
 | 
			
		||||
func localizedExtensions(ext, languageCode string) (localizedExts []string) {
 | 
			
		||||
| 
						 | 
				
			
			@ -374,6 +374,11 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
 | 
			
		|||
	ctx.Data["FileName"] = blob.Name()
 | 
			
		||||
	ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
 | 
			
		||||
 | 
			
		||||
	if ctx.Repo.TreePath == ".editorconfig" {
 | 
			
		||||
		_, editorconfigErr := ctx.Repo.GetEditorconfig()
 | 
			
		||||
		ctx.Data["FileError"] = editorconfigErr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buf := make([]byte, 1024)
 | 
			
		||||
	n, _ := util.ReadAtMost(dataRc, buf)
 | 
			
		||||
	buf = buf[:n]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,7 +131,10 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User,
 | 
			
		|||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pemResult = permDoer.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests)
 | 
			
		||||
		pemResult = doer.ID == issue.PosterID
 | 
			
		||||
		if !pemResult {
 | 
			
		||||
			pemResult = permDoer.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests)
 | 
			
		||||
		}
 | 
			
		||||
		if !pemResult {
 | 
			
		||||
			pemResult, err = issues_model.IsOfficialReviewer(ctx, issue, doer)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -201,7 +204,7 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team,
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		doerCanWrite := permission.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests)
 | 
			
		||||
		if !doerCanWrite {
 | 
			
		||||
		if !doerCanWrite && doer.ID != issue.PosterID {
 | 
			
		||||
			official, err := issues_model.IsOfficialReviewer(ctx, issue, doer)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Error("Unable to Check if IsOfficialReviewer for %-v in %-v#%d", doer, issue.Repo, issue.Index)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@
 | 
			
		|||
	{{end}}
 | 
			
		||||
	<div class="item brand" style="justify-content: space-between;">
 | 
			
		||||
		<a href="{{AppSubUrl}}/" aria-label="{{if .IsSigned}}{{.locale.Tr "dashboard"}}{{else}}{{.locale.Tr "home"}}{{end}}">
 | 
			
		||||
			<img class="ui mini image" width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{.locale.Tr "logo"}}" aria-hidden="true">
 | 
			
		||||
			<img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{.locale.Tr "logo"}}" aria-hidden="true">
 | 
			
		||||
		</a>
 | 
			
		||||
		{{if .IsSigned}}
 | 
			
		||||
		<a href="{{AppSubUrl}}/notifications" class="tooltip mobile-only" data-content='{{.locale.Tr "notifications"}}'>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
<script>
 | 
			
		||||
	// synchronously set clone button states and urls here to avoid flickering
 | 
			
		||||
	// on page load. initRepoCloneLink calls this when proto changes.
 | 
			
		||||
	// this applies the protocol-dependant clone url to all elements with the
 | 
			
		||||
	// `js-clone-url` and `js-clone-url-vsc` classes.
 | 
			
		||||
	// TODO: This localStorage setting should be moved to backend user config
 | 
			
		||||
	// so it's available during rendering, then this inline script can be removed.
 | 
			
		||||
	(window.updateCloneStates = function() {
 | 
			
		||||
| 
						 | 
				
			
			@ -19,5 +21,8 @@
 | 
			
		|||
		for (const el of document.getElementsByClassName('js-clone-url')) {
 | 
			
		||||
			el[el.nodeName === 'INPUT' ? 'value' : 'textContent'] = link;
 | 
			
		||||
		}
 | 
			
		||||
		for (const el of document.getElementsByClassName('js-clone-url-vsc')) {
 | 
			
		||||
			el['href'] = 'vscode://vscode.git/clone?url=' + encodeURIComponent(link);
 | 
			
		||||
		}
 | 
			
		||||
	})();
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
<a class="ui link commit-statuses-trigger vm">{{template "repo/commit_status" .Status}}</a>
 | 
			
		||||
<a class="ui link commit-statuses-trigger vm"{{if eq (len .Statuses) 1}}{{$status := index .Statuses 0}}{{if $status.TargetURL}} href="{{$status.TargetURL}}"{{end}}{{end}}>{{template "repo/commit_status" .Status}}</a>
 | 
			
		||||
<div class="ui commit-statuses-popup commit-statuses tippy-target">
 | 
			
		||||
	<div class="ui relaxed list divided">
 | 
			
		||||
		{{range .Statuses}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@
 | 
			
		|||
	</h2>
 | 
			
		||||
	{{if .Flash.WarningMsg}}
 | 
			
		||||
		{{/*
 | 
			
		||||
			There's alreay a importing of alert.tmpl in new_form.tmpl,
 | 
			
		||||
			There's already an importing of alert.tmpl in new_form.tmpl,
 | 
			
		||||
			but only the negative message will be displayed within forms for some reasons, see semantic.css:10659.
 | 
			
		||||
			To avoid repeated negative messages, the importing here if for .Flash.WarningMsg only.
 | 
			
		||||
		*/}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,32 +73,33 @@
 | 
			
		|||
						</a>
 | 
			
		||||
					{{end}}
 | 
			
		||||
					<a href="{{.Repository.Link}}/find/{{.BranchNameSubURL}}" class="ui compact basic button tooltip" data-content="{{.locale.Tr "repo.find_file.go_to_file"}}">{{svg "octicon-file-moved" 15}}</a>
 | 
			
		||||
					{{if or .CanAddFile .CanUploadFile}}
 | 
			
		||||
						<button class="ui basic small compact dropdown jump icon button mr-2">
 | 
			
		||||
							<span class="text">{{.locale.Tr "repo.editor.add_file"}}</span>
 | 
			
		||||
							<div class="menu">
 | 
			
		||||
								{{if .Repository.CanEnableEditor}}
 | 
			
		||||
									{{if .CanAddFile}}
 | 
			
		||||
										<a class="item" href="{{.RepoLink}}/_new/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
 | 
			
		||||
											{{.locale.Tr "repo.editor.new_file"}}
 | 
			
		||||
										</a>
 | 
			
		||||
									{{end}}
 | 
			
		||||
									{{if .CanUploadFile}}
 | 
			
		||||
										<a class="item" href="{{.RepoLink}}/_upload/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
 | 
			
		||||
											{{.locale.Tr "repo.editor.upload_file"}}
 | 
			
		||||
										</a>
 | 
			
		||||
									{{end}}
 | 
			
		||||
									{{if .CanAddFile}}
 | 
			
		||||
										<a class="item" href="{{.RepoLink}}/_diffpatch/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
 | 
			
		||||
											{{.locale.Tr "repo.editor.patch"}}
 | 
			
		||||
										</a>
 | 
			
		||||
									{{end}}
 | 
			
		||||
				{{end}}
 | 
			
		||||
				{{if or .CanAddFile .CanUploadFile}}
 | 
			
		||||
					<button class="ui basic small compact dropdown jump icon button mr-2">
 | 
			
		||||
						<span class="text">{{.locale.Tr "repo.editor.add_file"}}</span>
 | 
			
		||||
						<div class="menu">
 | 
			
		||||
							{{if .Repository.CanEnableEditor}}
 | 
			
		||||
								{{if .CanAddFile}}
 | 
			
		||||
									<a class="item" href="{{.RepoLink}}/_new/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
 | 
			
		||||
										{{.locale.Tr "repo.editor.new_file"}}
 | 
			
		||||
									</a>
 | 
			
		||||
								{{end}}
 | 
			
		||||
							</div>
 | 
			
		||||
							{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 | 
			
		||||
						</button>
 | 
			
		||||
					{{end}}
 | 
			
		||||
				{{else}}
 | 
			
		||||
								{{if .CanUploadFile}}
 | 
			
		||||
									<a class="item" href="{{.RepoLink}}/_upload/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
 | 
			
		||||
										{{.locale.Tr "repo.editor.upload_file"}}
 | 
			
		||||
									</a>
 | 
			
		||||
								{{end}}
 | 
			
		||||
								{{if .CanAddFile}}
 | 
			
		||||
									<a class="item" href="{{.RepoLink}}/_diffpatch/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
 | 
			
		||||
										{{.locale.Tr "repo.editor.patch"}}
 | 
			
		||||
									</a>
 | 
			
		||||
								{{end}}
 | 
			
		||||
							{{end}}
 | 
			
		||||
						</div>
 | 
			
		||||
						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 | 
			
		||||
					</button>
 | 
			
		||||
				{{end}}
 | 
			
		||||
				{{if ne $n 0}}
 | 
			
		||||
					<span class="ui breadcrumb repo-path"><a class="section" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}" title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span class="divider">/</span>{{if eq $i $l}}<span class="active section" title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{$p := index $.Paths $i}}<span class="section"><a href="{{$.BranchLink}}/{{PathEscapeSegments $p}}" title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +126,7 @@
 | 
			
		|||
									<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.tar.gz" rel="nofollow">{{svg "octicon-file-zip" 16 "mr-3"}}{{.locale.Tr "repo.download_tar"}}</a>
 | 
			
		||||
									<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.bundle" rel="nofollow">{{svg "octicon-package" 16 "mr-3"}}{{.locale.Tr "repo.download_bundle"}}</a>
 | 
			
		||||
								{{end}}
 | 
			
		||||
								<a class="item" href="vscode://vscode.git/clone?url={{$.RepoCloneLink.HTTPS}}">{{svg "gitea-vscode" 16 "mr-3"}}{{.locale.Tr "repo.clone_in_vsc"}}</a>
 | 
			
		||||
								<a class="item js-clone-url-vsc" href="vscode://vscode.git/clone?url={{.CloneButtonOriginLink.HTTPS}}">{{svg "gitea-vscode" 16 "mr-3"}}{{.locale.Tr "repo.clone_in_vsc"}}</a>
 | 
			
		||||
							</div>
 | 
			
		||||
						</button>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
		<div class="ui divider"></div>
 | 
			
		||||
		{{if .Flash.WarningMsg}}
 | 
			
		||||
			{{/*
 | 
			
		||||
			There's alreay a importing of alert.tmpl in new_form.tmpl,
 | 
			
		||||
			There's already an importing of alert.tmpl in new_form.tmpl,
 | 
			
		||||
			but only the negative message will be displayed within forms for some reasons, see semantic.css:10659.
 | 
			
		||||
			To avoid repeated negative messages, the importing here if for .Flash.WarningMsg only.
 | 
			
		||||
			 */}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,9 +11,9 @@
 | 
			
		|||
						{{if not (containGeneric $.Content .UUID)}}
 | 
			
		||||
							{{$hasThumbnails = true}}
 | 
			
		||||
						{{end}}
 | 
			
		||||
						<span class="ui image">{{svg "octicon-file"}}</span>
 | 
			
		||||
						{{svg "octicon-file"}}
 | 
			
		||||
					{{else}}
 | 
			
		||||
						<span class="ui image">{{svg "octicon-desktop-download"}}</span>
 | 
			
		||||
						{{svg "octicon-desktop-download"}}
 | 
			
		||||
					{{end}}
 | 
			
		||||
					<span><strong>{{.Name}}</strong></span>
 | 
			
		||||
				</a>
 | 
			
		||||
| 
						 | 
				
			
			@ -26,12 +26,12 @@
 | 
			
		|||
 | 
			
		||||
	{{if $hasThumbnails}}
 | 
			
		||||
		<div class="ui clearing divider"></div>
 | 
			
		||||
		<div class="ui small images thumbnails">
 | 
			
		||||
		<div class="ui small thumbnails">
 | 
			
		||||
			{{- range .Attachments -}}
 | 
			
		||||
				{{if FilenameIsImage .Name}}
 | 
			
		||||
					{{if not (containGeneric $.Content .UUID)}}
 | 
			
		||||
					<a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
 | 
			
		||||
						<img class="ui image" src="{{.DownloadURL}}" title='{{$.ctx.locale.Tr "repo.issues.attachment.open_tab" .Name}}'>
 | 
			
		||||
						<img src="{{.DownloadURL}}" title='{{$.ctx.locale.Tr "repo.issues.attachment.open_tab" .Name}}'>
 | 
			
		||||
					</a>
 | 
			
		||||
					{{end}}
 | 
			
		||||
				{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -182,11 +182,11 @@
 | 
			
		|||
					<span class="text grey">
 | 
			
		||||
						{{template "shared/user/authorlink" .Poster}}
 | 
			
		||||
						{{if and .AddedLabels (not .RemovedLabels)}}
 | 
			
		||||
							{{$.locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels .AddedLabels) $createdStr | Safe}}
 | 
			
		||||
							{{$.locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels .AddedLabels $.RepoLink) $createdStr | Safe}}
 | 
			
		||||
						{{else if and (not .AddedLabels) .RemovedLabels}}
 | 
			
		||||
							{{$.locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels .RemovedLabels) $createdStr | Safe}}
 | 
			
		||||
							{{$.locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels .RemovedLabels $.RepoLink) $createdStr | Safe}}
 | 
			
		||||
						{{else}}
 | 
			
		||||
							{{$.locale.Tr "repo.issues.add_remove_labels" (RenderLabels .AddedLabels) (RenderLabels .RemovedLabels) $createdStr | Safe}}
 | 
			
		||||
							{{$.locale.Tr "repo.issues.add_remove_labels" (RenderLabels .AddedLabels $.RepoLink) (RenderLabels .RemovedLabels $.RepoLink) $createdStr | Safe}}
 | 
			
		||||
						{{end}}
 | 
			
		||||
					</span>
 | 
			
		||||
				</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,7 +168,7 @@
 | 
			
		|||
													</span>
 | 
			
		||||
												</span>
 | 
			
		||||
												<a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
 | 
			
		||||
													<strong><span class="ui image" title='{{.Name}}'>{{svg "octicon-package" 16 "mr-2"}}</span>{{.Name}}</strong>
 | 
			
		||||
													<strong>{{svg "octicon-package" 16 "mr-2"}}{{.Name}}</strong>
 | 
			
		||||
												</a>
 | 
			
		||||
											</li>
 | 
			
		||||
										{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,14 +94,14 @@
 | 
			
		|||
												{{$userIDs := .AllowlistUserIDs}}
 | 
			
		||||
												{{range $.Users}}
 | 
			
		||||
													{{if contain $userIDs .ID}}
 | 
			
		||||
														<a class="ui basic image label" href="{{.HomeLink}}">{{avatar . 26}} {{.GetDisplayName}}</a>
 | 
			
		||||
														<a class="ui basic label" href="{{.HomeLink}}">{{avatar . 26}} {{.GetDisplayName}}</a>
 | 
			
		||||
													{{end}}
 | 
			
		||||
												{{end}}
 | 
			
		||||
												{{if $.Owner.IsOrganization}}
 | 
			
		||||
													{{$teamIDs := .AllowlistTeamIDs}}
 | 
			
		||||
													{{range $.Teams}}
 | 
			
		||||
														{{if contain $teamIDs .ID}}
 | 
			
		||||
															<a class="ui basic image label" href="{{$.Owner.OrganisationLink}}/teams/{{PathEscape .LowerName}}">{{.Name}}</a>
 | 
			
		||||
															<a class="ui basic label" href="{{$.Owner.OrganisationLink}}/teams/{{PathEscape .LowerName}}">{{.Name}}</a>
 | 
			
		||||
														{{end}}
 | 
			
		||||
													{{end}}
 | 
			
		||||
												{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,11 @@
 | 
			
		|||
<div class="{{TabSizeClass .Editorconfig .FileName}} non-diff-file-content">
 | 
			
		||||
	{{- if .FileError}}
 | 
			
		||||
		<div class="ui warning message">
 | 
			
		||||
			<div class="text left">
 | 
			
		||||
				<div>{{.FileError}}</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	{{end}}
 | 
			
		||||
	<h4 class="file-header ui top attached header df ac sb">
 | 
			
		||||
		<div class="file-header-left df ac pr-4">
 | 
			
		||||
			{{if .ReadmeInList}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
<div class="page-content ui container center full-screen-width {{if .IsRepo}}repository{{end}}">
 | 
			
		||||
	{{if .IsRepo}}{{template "repo/header" .}}{{end}}
 | 
			
		||||
	<div class="ui container center">
 | 
			
		||||
		<p style="margin-top: 100px"><img class="ui centered image" src="{{AssetUrlPrefix}}/img/404.png" alt="404"/></p>
 | 
			
		||||
		<p style="margin-top: 100px"><img src="{{AssetUrlPrefix}}/img/404.png" alt="404"/></p>
 | 
			
		||||
		<div class="ui divider"></div>
 | 
			
		||||
		<br>
 | 
			
		||||
		<p>{{.locale.Tr "error404" | Safe}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
{{template "base/head" .}}
 | 
			
		||||
<div class="page-content ui container full-screen-width center">
 | 
			
		||||
	<p style="margin-top: 100px"><img class="ui centered image" src="{{AssetUrlPrefix}}/img/500.png" alt="500"/></p>
 | 
			
		||||
	<p style="margin-top: 100px"><img src="{{AssetUrlPrefix}}/img/500.png" alt="500"/></p>
 | 
			
		||||
	<div class="ui divider"></div>
 | 
			
		||||
	<br>
 | 
			
		||||
	{{if .ErrorMsg}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
{{template "base/head" .}}
 | 
			
		||||
<div class="user signin webauthn-prompt">
 | 
			
		||||
	<div class="ui middle centered very relaxed page grid">
 | 
			
		||||
		<div class="column">
 | 
			
		||||
		<div class="column center aligned">
 | 
			
		||||
				<h3 class="ui top attached header">
 | 
			
		||||
				{{.locale.Tr "twofa"}}
 | 
			
		||||
				</h3>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ test('Test Register Form', async ({page}, workerInfo) => {
 | 
			
		|||
  await page.click('form button.ui.green.button:visible');
 | 
			
		||||
  // Make sure we routed to the home page. Else login failed.
 | 
			
		||||
  await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
 | 
			
		||||
  await expect(page.locator('.dashboard-navbar span>img.ui.avatar.image')).toBeVisible();
 | 
			
		||||
  await expect(page.locator('.dashboard-navbar span>img.ui.avatar')).toBeVisible();
 | 
			
		||||
  await expect(page.locator('.ui.positive.message.flash-success')).toHaveText('Account was successfully created.');
 | 
			
		||||
 | 
			
		||||
  save_visual(page);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,8 +52,8 @@ export async function save_visual(page) {
 | 
			
		|||
      fullPage: true,
 | 
			
		||||
      timeout: 20000,
 | 
			
		||||
      mask: [
 | 
			
		||||
        page.locator('.dashboard-navbar span>img.ui.avatar.image'),
 | 
			
		||||
        page.locator('.ui.dropdown.jump.item.tooltip span>img.ui.avatar.image'),
 | 
			
		||||
        page.locator('.dashboard-navbar span>img.ui.avatar'),
 | 
			
		||||
        page.locator('.ui.dropdown.jump.item.tooltip span>img.ui.avatar'),
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ func doAPICreateCommitStatus(ctx APITestContext, commitID string, status api.Com
 | 
			
		|||
 | 
			
		||||
func TestPullCreate_EmptyChangesWithDifferentCommits(t *testing.T) {
 | 
			
		||||
	// Merge must continue if commits SHA are different, even if content is same
 | 
			
		||||
	// Reason: gitflow and merging master back into develop, where is high possiblity, there are no changes
 | 
			
		||||
	// Reason: gitflow and merging master back into develop, where is high possibility, there are no changes
 | 
			
		||||
	// but just commit saying "Merge branch". And this meta commit can be also tagged,
 | 
			
		||||
	// so we need to have this meta commit also in develop branch.
 | 
			
		||||
	onGiteaRun(t, func(t *testing.T, u *url.URL) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										342
									
								
								web_src/fomantic/build/semantic.css
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										342
									
								
								web_src/fomantic/build/semantic.css
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -24344,348 +24344,6 @@ i.icon.youtube.play:before {
 | 
			
		|||
  font-family: 'brand-icons';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
         Site Overrides
 | 
			
		||||
*******************************/
 | 
			
		||||
/*!
 | 
			
		||||
 * # Fomantic-UI - Image
 | 
			
		||||
 * http://github.com/fomantic/Fomantic-UI/
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * Released under the MIT license
 | 
			
		||||
 * http://opensource.org/licenses/MIT
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
             Image
 | 
			
		||||
*******************************/
 | 
			
		||||
 | 
			
		||||
.ui.image {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  vertical-align: middle;
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  background-color: transparent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.ui.image {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.image svg,
 | 
			
		||||
.ui.image img {
 | 
			
		||||
  display: block;
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  height: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
            States
 | 
			
		||||
*******************************/
 | 
			
		||||
 | 
			
		||||
.ui.hidden.images,
 | 
			
		||||
.ui.ui.hidden.image {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.hidden.transition.images,
 | 
			
		||||
.ui.hidden.transition.image {
 | 
			
		||||
  display: block;
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.images > .hidden.transition {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.disabled.images,
 | 
			
		||||
.ui.disabled.image {
 | 
			
		||||
  cursor: default;
 | 
			
		||||
  opacity: var(--opacity-disabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
          Variations
 | 
			
		||||
*******************************/
 | 
			
		||||
 | 
			
		||||
/*--------------
 | 
			
		||||
       Inline
 | 
			
		||||
  ---------------*/
 | 
			
		||||
 | 
			
		||||
.ui.inline.image,
 | 
			
		||||
.ui.inline.image svg,
 | 
			
		||||
.ui.inline.image img {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*------------------
 | 
			
		||||
    Vertical Aligned
 | 
			
		||||
  -------------------*/
 | 
			
		||||
 | 
			
		||||
.ui.top.aligned.image,
 | 
			
		||||
.ui.top.aligned.image svg,
 | 
			
		||||
.ui.top.aligned.image img {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  vertical-align: top;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.middle.aligned.image,
 | 
			
		||||
.ui.middle.aligned.image svg,
 | 
			
		||||
.ui.middle.aligned.image img {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.bottom.aligned.image,
 | 
			
		||||
.ui.bottom.aligned.image svg,
 | 
			
		||||
.ui.bottom.aligned.image img {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  vertical-align: bottom;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.top.aligned.images .image,
 | 
			
		||||
.ui.images .ui.top.aligned.image {
 | 
			
		||||
  align-self: flex-start;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.middle.aligned.images .image,
 | 
			
		||||
.ui.images .ui.middle.aligned.image {
 | 
			
		||||
  align-self: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.bottom.aligned.images .image,
 | 
			
		||||
.ui.images .ui.bottom.aligned.image {
 | 
			
		||||
  align-self: flex-end;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------
 | 
			
		||||
       Rounded
 | 
			
		||||
  ---------------*/
 | 
			
		||||
 | 
			
		||||
.ui.rounded.images .image,
 | 
			
		||||
.ui.rounded.image,
 | 
			
		||||
.ui.rounded.images .image > *,
 | 
			
		||||
.ui.rounded.image > * {
 | 
			
		||||
  border-radius: 0.3125em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------
 | 
			
		||||
      Bordered
 | 
			
		||||
  ---------------*/
 | 
			
		||||
 | 
			
		||||
.ui.bordered.images .image,
 | 
			
		||||
.ui.bordered.images img,
 | 
			
		||||
.ui.bordered.images svg,
 | 
			
		||||
.ui.bordered.image img,
 | 
			
		||||
.ui.bordered.image svg,
 | 
			
		||||
img.ui.bordered.image {
 | 
			
		||||
  border: 1px solid rgba(0, 0, 0, 0.1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------
 | 
			
		||||
      Circular
 | 
			
		||||
  ---------------*/
 | 
			
		||||
 | 
			
		||||
.ui.circular.images,
 | 
			
		||||
.ui.circular.image {
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.circular.images .image,
 | 
			
		||||
.ui.circular.image,
 | 
			
		||||
.ui.circular.images .image > *,
 | 
			
		||||
.ui.circular.image > * {
 | 
			
		||||
  border-radius: 500rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------
 | 
			
		||||
       Fluid
 | 
			
		||||
  ---------------*/
 | 
			
		||||
 | 
			
		||||
.ui.fluid.images,
 | 
			
		||||
.ui.fluid.image,
 | 
			
		||||
.ui.fluid.images img,
 | 
			
		||||
.ui.fluid.images svg,
 | 
			
		||||
.ui.fluid.image svg,
 | 
			
		||||
.ui.fluid.image img {
 | 
			
		||||
  display: block;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------
 | 
			
		||||
       Avatar
 | 
			
		||||
  ---------------*/
 | 
			
		||||
 | 
			
		||||
.ui.avatar.images .image,
 | 
			
		||||
.ui.avatar.images img,
 | 
			
		||||
.ui.avatar.images svg,
 | 
			
		||||
.ui.avatar.image img,
 | 
			
		||||
.ui.avatar.image svg,
 | 
			
		||||
.ui.avatar.image {
 | 
			
		||||
  margin-right: 0.25em;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  width: 2em;
 | 
			
		||||
  height: 2em;
 | 
			
		||||
  border-radius: 500rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-------------------
 | 
			
		||||
         Spaced
 | 
			
		||||
  --------------------*/
 | 
			
		||||
 | 
			
		||||
.ui.spaced.image {
 | 
			
		||||
  display: inline-block !important;
 | 
			
		||||
  margin-left: 0.5em;
 | 
			
		||||
  margin-right: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui[class*="left spaced"].image {
 | 
			
		||||
  margin-left: 0.5em;
 | 
			
		||||
  margin-right: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui[class*="right spaced"].image {
 | 
			
		||||
  margin-left: 0;
 | 
			
		||||
  margin-right: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-------------------
 | 
			
		||||
         Floated
 | 
			
		||||
  --------------------*/
 | 
			
		||||
 | 
			
		||||
.ui.floated.image,
 | 
			
		||||
.ui.floated.images {
 | 
			
		||||
  float: left;
 | 
			
		||||
  margin-right: 1em;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.right.floated.images,
 | 
			
		||||
.ui.right.floated.image {
 | 
			
		||||
  float: right;
 | 
			
		||||
  margin-right: 0;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
  margin-left: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.floated.images:last-child,
 | 
			
		||||
.ui.floated.image:last-child {
 | 
			
		||||
  margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.centered.image {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin-left: auto;
 | 
			
		||||
  margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.centered.images {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  align-items: stretch;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------
 | 
			
		||||
     Sizes
 | 
			
		||||
---------------*/
 | 
			
		||||
 | 
			
		||||
.ui.medium.images .image,
 | 
			
		||||
.ui.medium.images img,
 | 
			
		||||
.ui.medium.images svg,
 | 
			
		||||
.ui.medium.image {
 | 
			
		||||
  width: 300px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.mini.images .image,
 | 
			
		||||
.ui.mini.images img,
 | 
			
		||||
.ui.mini.images svg,
 | 
			
		||||
.ui.mini.image {
 | 
			
		||||
  width: 35px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 0.78571429rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.tiny.images .image,
 | 
			
		||||
.ui.tiny.images img,
 | 
			
		||||
.ui.tiny.images svg,
 | 
			
		||||
.ui.tiny.image {
 | 
			
		||||
  width: 80px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 0.85714286rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.small.images .image,
 | 
			
		||||
.ui.small.images img,
 | 
			
		||||
.ui.small.images svg,
 | 
			
		||||
.ui.small.image {
 | 
			
		||||
  width: 150px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 0.92857143rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.large.images .image,
 | 
			
		||||
.ui.large.images img,
 | 
			
		||||
.ui.large.images svg,
 | 
			
		||||
.ui.large.image {
 | 
			
		||||
  width: 450px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 1.14285714rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.big.images .image,
 | 
			
		||||
.ui.big.images img,
 | 
			
		||||
.ui.big.images svg,
 | 
			
		||||
.ui.big.image {
 | 
			
		||||
  width: 600px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 1.28571429rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.huge.images .image,
 | 
			
		||||
.ui.huge.images img,
 | 
			
		||||
.ui.huge.images svg,
 | 
			
		||||
.ui.huge.image {
 | 
			
		||||
  width: 800px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 1.42857143rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.massive.images .image,
 | 
			
		||||
.ui.massive.images img,
 | 
			
		||||
.ui.massive.images svg,
 | 
			
		||||
.ui.massive.image {
 | 
			
		||||
  width: 960px;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  font-size: 1.71428571rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
                Groups
 | 
			
		||||
  *******************************/
 | 
			
		||||
 | 
			
		||||
.ui.images {
 | 
			
		||||
  font-size: 0;
 | 
			
		||||
  margin: 0 -0.25rem 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.images .image,
 | 
			
		||||
.ui.images > img,
 | 
			
		||||
.ui.images > svg {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  margin: 0 0.25rem 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
         Theme Overrides
 | 
			
		||||
*******************************/
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
         Site Overrides
 | 
			
		||||
*******************************/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,6 @@
 | 
			
		|||
    "grid",
 | 
			
		||||
    "header",
 | 
			
		||||
    "icon",
 | 
			
		||||
    "image",
 | 
			
		||||
    "input",
 | 
			
		||||
    "item",
 | 
			
		||||
    "label",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,7 +61,6 @@ export function initCommitStatuses() {
 | 
			
		|||
    const top = $('.repository.file.list').length > 0 || $('.repository.diff').length > 0;
 | 
			
		||||
 | 
			
		||||
    createTippy(this, {
 | 
			
		||||
      trigger: 'click',
 | 
			
		||||
      content: this.nextElementSibling,
 | 
			
		||||
      placement: top ? 'top-start' : 'bottom-start',
 | 
			
		||||
      interactive: true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,8 @@ export function createTippy(target, opts = {}) {
 | 
			
		|||
    placement: target.getAttribute('data-placement') || 'top-start',
 | 
			
		||||
    animation: false,
 | 
			
		||||
    allowHTML: false,
 | 
			
		||||
    interactiveBorder: 30,
 | 
			
		||||
    ignoreAttributes: true,
 | 
			
		||||
    maxWidth: 500, // increase over default 350px
 | 
			
		||||
    arrow: `<svg width="16" height="7"><path d="m0 7 8-7 8 7Z" class="tippy-svg-arrow-outer"/><path d="m0 8 8-7 8 7Z" class="tippy-svg-arrow-inner"/></svg>`,
 | 
			
		||||
    ...(opts?.role && {theme: opts.role}),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -692,12 +692,9 @@ a.ui.card:hover,
 | 
			
		|||
  border-color: var(--color-secondary);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.avatar.images .image,
 | 
			
		||||
.ui.avatar.images img,
 | 
			
		||||
.ui.avatar.images svg,
 | 
			
		||||
.ui.avatar.image img,
 | 
			
		||||
.ui.avatar.image svg,
 | 
			
		||||
.ui.avatar.image,
 | 
			
		||||
.ui.avatar img,
 | 
			
		||||
.ui.avatar svg,
 | 
			
		||||
.ui.avatar.img,
 | 
			
		||||
.ui.cards > .card img.avatar,
 | 
			
		||||
.ui.cards > .card .avatar img,
 | 
			
		||||
.ui.card img.avatar,
 | 
			
		||||
| 
						 | 
				
			
			@ -758,10 +755,6 @@ a.ui.card:hover,
 | 
			
		|||
    padding-left: 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .brand .ui.mini.image {
 | 
			
		||||
    width: 30px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .top.menu a.item:hover,
 | 
			
		||||
  .top.menu .dropdown.item:hover,
 | 
			
		||||
  .top.menu .dropdown.item.active {
 | 
			
		||||
| 
						 | 
				
			
			@ -1686,7 +1679,7 @@ a.ui.label:hover {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .ui.avatar.image {
 | 
			
		||||
  .ui.avatar {
 | 
			
		||||
    height: 18px;
 | 
			
		||||
    width: 18px;
 | 
			
		||||
    display: block;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,7 @@
 | 
			
		|||
      padding-top: 25px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .ui.avatar.image {
 | 
			
		||||
    img.ui.avatar {
 | 
			
		||||
      width: 40px;
 | 
			
		||||
      height: 40px;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -846,8 +846,8 @@
 | 
			
		|||
          display: none;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .avatar.image,
 | 
			
		||||
        .avatar.image img {
 | 
			
		||||
        img.avatar,
 | 
			
		||||
        .avatar img {
 | 
			
		||||
          width: 20px;
 | 
			
		||||
          height: 20px;
 | 
			
		||||
          margin: 0 .25rem;
 | 
			
		||||
| 
						 | 
				
			
			@ -908,8 +908,8 @@
 | 
			
		|||
            line-height: 34px; /* this must be same as .badge height, to avoid overflow */
 | 
			
		||||
            clear: both; // reset the "float right shabox", in the future, use flexbox instead
 | 
			
		||||
 | 
			
		||||
            > .avatar.image,
 | 
			
		||||
            > .avatar.image img {
 | 
			
		||||
            > img.avatar,
 | 
			
		||||
            > .avatar img {
 | 
			
		||||
              position: relative;
 | 
			
		||||
              top: -2px;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1125,7 +1125,7 @@
 | 
			
		|||
          margin-left: 36px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .avatar.image {
 | 
			
		||||
        img.avatar {
 | 
			
		||||
          width: 28px;
 | 
			
		||||
          height: 28px;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -2497,7 +2497,7 @@
 | 
			
		|||
#search-user-box {
 | 
			
		||||
  .results {
 | 
			
		||||
    .result {
 | 
			
		||||
      .image {
 | 
			
		||||
      img {
 | 
			
		||||
        float: left;
 | 
			
		||||
        margin-right: 8px;
 | 
			
		||||
        width: 2em;
 | 
			
		||||
| 
						 | 
				
			
			@ -2827,6 +2827,11 @@ tbody.commit-list {
 | 
			
		|||
  vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// in the commit list, messages can wrap so we can use inline
 | 
			
		||||
.commit-list .message-wrapper {
 | 
			
		||||
  display: inline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media @mediaSm {
 | 
			
		||||
  tr.commit-list {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
| 
						 | 
				
			
			@ -3300,7 +3305,7 @@ td.blob-excerpt {
 | 
			
		|||
        display: flex;
 | 
			
		||||
        margin-bottom: auto;
 | 
			
		||||
 | 
			
		||||
        img.avatar.image {
 | 
			
		||||
        img.avatar {
 | 
			
		||||
          height: 24px;
 | 
			
		||||
          width: 24px;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,10 +90,10 @@
 | 
			
		|||
        float: none;
 | 
			
		||||
        margin: 0 .5rem 0 0;
 | 
			
		||||
        flex-shrink: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
        &.image {
 | 
			
		||||
          margin: 0 !important;
 | 
			
		||||
        }
 | 
			
		||||
      img.avatar {
 | 
			
		||||
        margin: 0 !important;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .comment-content {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,7 +134,7 @@
 | 
			
		|||
      padding-bottom: 1px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .author .ui.avatar.image {
 | 
			
		||||
    .author img.ui.avatar {
 | 
			
		||||
      width: auto;
 | 
			
		||||
      height: 18px;
 | 
			
		||||
      max-width: none;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,8 @@ import {readFileSync} from 'fs';
 | 
			
		|||
const {VueLoaderPlugin} = VueLoader;
 | 
			
		||||
const {ESBuildMinifyPlugin} = EsBuildLoader;
 | 
			
		||||
const {SourceMapDevToolPlugin} = webpack;
 | 
			
		||||
const formatLicenseText = (licenseText) => wrapAnsi(licenseText || '', 80).trim();
 | 
			
		||||
 | 
			
		||||
const glob = (pattern) => fastGlob.sync(pattern, {
 | 
			
		||||
  cwd: dirname(fileURLToPath(new URL(import.meta.url))),
 | 
			
		||||
  absolute: true,
 | 
			
		||||
| 
						 | 
				
			
			@ -206,10 +208,12 @@ export default {
 | 
			
		|||
      outputFilename: 'js/licenses.txt',
 | 
			
		||||
      outputWriter: ({dependencies}) => {
 | 
			
		||||
        const line = '-'.repeat(80);
 | 
			
		||||
        const goModules = JSON.parse(readFileSync('assets/go-licenses.json', 'utf8'));
 | 
			
		||||
        const goJson = readFileSync('assets/go-licenses.json', 'utf8');
 | 
			
		||||
        const goModules = JSON.parse(goJson).map(({name, licenseText}) => {
 | 
			
		||||
          return {name, body: formatLicenseText(licenseText)};
 | 
			
		||||
        });
 | 
			
		||||
        const jsModules = dependencies.map(({name, version, licenseName, licenseText}) => {
 | 
			
		||||
          const body = wrapAnsi(licenseText || '', 80);
 | 
			
		||||
          return {name, version, licenseName, body};
 | 
			
		||||
          return {name, version, licenseName, body: formatLicenseText(licenseText)};
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        const modules = [...goModules, ...jsModules].sort((a, b) => a.name.localeCompare(b.name));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue