Compare commits

..

1 Commits

Author SHA1 Message Date
Grzegorz Alibożek
4563148a61 Upgrade Alpine from 3.13 to 3.15 (#18050)
* Upgrade alpine to 3.15

* Add executability test to entrypoint for too old dockers

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Update docker/rootless/usr/local/bin/docker-entrypoint.sh

Co-authored-by: zeripath <art27@cantab.net>
2022-01-19 16:55:17 -05:00
75 changed files with 596 additions and 1278 deletions

View File

@@ -567,7 +567,7 @@ steps:
settings:
acl: public-read
bucket: gitea-artifacts
endpoint: https://ams3.digitaloceanspaces.com
endpoint: https://storage.gitea.io
path_style: true
source: "dist/release/*"
strip_prefix: dist/release/
@@ -588,7 +588,7 @@ steps:
settings:
acl: public-read
bucket: gitea-artifacts
endpoint: https://ams3.digitaloceanspaces.com
endpoint: https://storage.gitea.io
path_style: true
source: "dist/release/*"
strip_prefix: dist/release/
@@ -663,7 +663,7 @@ steps:
settings:
acl: public-read
bucket: gitea-artifacts
endpoint: https://ams3.digitaloceanspaces.com
endpoint: https://storage.gitea.io
path_style: true
source: "dist/release/*"
strip_prefix: dist/release/
@@ -850,67 +850,6 @@ steps:
exclude:
- pull_request
---
kind: pipeline
name: docker-linux-amd64-release-branch
platform:
os: linux
arch: amd64
depends_on:
- testing-amd64
- testing-arm64
trigger:
ref:
- "refs/heads/release/v*"
event:
exclude:
- cron
steps:
- name: fetch-tags
image: docker:git
commands:
- git fetch --tags --force
- name: publish
pull: always
image: techknowlogick/drone-docker:latest
settings:
auto_tag: false
tags: ${DRONE_BRANCH##release/v}-dev-linux-amd64
repo: gitea/gitea
build_args:
- GOPROXY=https://goproxy.cn
password:
from_secret: docker_password
username:
from_secret: docker_username
when:
event:
exclude:
- pull_request
- name: publish-rootless
image: techknowlogick/drone-docker:latest
settings:
dockerfile: Dockerfile.rootless
auto_tag: false
tags: ${DRONE_BRANCH##release/v}-dev-linux-amd64-rootless
repo: gitea/gitea
build_args:
- GOPROXY=https://goproxy.cn
password:
from_secret: docker_password
username:
from_secret: docker_username
when:
event:
exclude:
- pull_request
---
kind: pipeline
type: docker
@@ -1067,68 +1006,6 @@ steps:
event:
exclude:
- pull_request
---
kind: pipeline
name: docker-linux-arm64-release-branch
platform:
os: linux
arch: arm64
depends_on:
- testing-amd64
- testing-arm64
trigger:
ref:
- "refs/heads/release/v*"
event:
exclude:
- cron
steps:
- name: fetch-tags
image: docker:git
commands:
- git fetch --tags --force
- name: publish
pull: always
image: techknowlogick/drone-docker:latest
settings:
auto_tag: false
tags: ${DRONE_BRANCH##release/v}-dev-linux-arm64
repo: gitea/gitea
build_args:
- GOPROXY=https://goproxy.cn
password:
from_secret: docker_password
username:
from_secret: docker_username
when:
event:
exclude:
- pull_request
- name: publish-rootless
image: techknowlogick/drone-docker:latest
settings:
dockerfile: Dockerfile.rootless
auto_tag: false
tags: ${DRONE_BRANCH##release/v}-dev-linux-arm64-rootless
repo: gitea/gitea
build_args:
- GOPROXY=https://goproxy.cn
password:
from_secret: docker_password
username:
from_secret: docker_username
when:
event:
exclude:
- pull_request
---
kind: pipeline
type: docker
@@ -1209,7 +1086,6 @@ steps:
trigger:
ref:
- refs/heads/main
- "refs/heads/release/v*"
event:
exclude:
- cron
@@ -1217,8 +1093,6 @@ trigger:
depends_on:
- docker-linux-amd64-release
- docker-linux-arm64-release
- docker-linux-amd64-release-branch
- docker-linux-arm64-release-branch
---
kind: pipeline
@@ -1252,8 +1126,6 @@ depends_on:
- docker-linux-arm64-release
- docker-linux-amd64-release-version
- docker-linux-arm64-release-version
- docker-linux-amd64-release-branch
- docker-linux-arm64-release-branch
- docker-manifest
- docker-manifest-version
- docs

View File

@@ -4,45 +4,13 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.16.1](https://github.com/go-gitea/gitea/releases/tag/v1.16.1) - 2022-02-06
* SECURITY
* Update JS dependencies, fix lint (#18389) (#18540)
* ENHANCEMENTS
* Add dropdown icon to label set template dropdown (#18564) (#18571)
* BUGFIXES
* Comments on migrated issues/prs must link to the comment ID (#18630) (#18637)
* Stop logging an error when notes are not found (#18626) (#18635)
* Ensure that blob-excerpt links work for wiki (#18587) (#18624)
* Only attempt to flush queue if the underlying worker pool is not finished (#18593) (#18620)
* Ensure commit-statuses box is sized correctly in headers (#18538) (#18606)
* Prevent merge messages from being sorted to the top of email chains (#18566) (#18588)
* Prevent panic on prohibited user login with oauth2 (#18562) (#18563)
* Collaborator trust model should trust collaborators (#18539) (#18557)
* Detect conflicts with 3way merge (#18536) (#18537)
* In docker rootless use $GITEA_APP_INI if provided (#18524) (#18535)
* Add `GetUserTeams` (#18499) (#18531)
* Fix review excerpt (#18502) (#18530)
* Fix for AvatarURL database type (#18487) (#18529)
* Use `ImagedProvider` for gplus oauth2 provider (#18504) (#18505)
* Fix OAuth Source Edit Page (#18495) (#18503)
* Use "read" value for General Access (#18496) (#18500)
* Prevent NPE on partial match of compare URL and allow short SHA1 compare URLs (#18472) (#18473)
* BUILD
* Make docker gitea/gitea:v1.16-dev etc refer to the latest build on that branch (#18551) (#18569)
* DOCS
* Update 1.16.0 changelog to set #17846 as breaking (#18533) (#18534)
## [1.16.0](https://github.com/go-gitea/gitea/releases/tag/v1.16.0) - 2022-01-30
## [1.16.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.16.0-rc1) - 2022-01-19
* BREAKING
* Remove golang vendored directory (#18277)
* Paginate releases page & set default page size to 10 (#16857)
* Use shadowing script for docker (#17846)
* Only allow webhook to send requests to allowed hosts (#17482)
* SECURITY
* Disable content sniffing on `PlainTextBytes` (#18359) (#18365)
* Only view milestones from current repo (#18414) (#18417)
* Sanitize user-input on file name (#17666)
* Use `hostmatcher` to replace `matchlist` to improve blocking of bad hosts in Webhooks (#17605)
* FEATURES
@@ -260,16 +228,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Add left padding for chunk header of split diff view (#13397)
* Allow U2F 2FA without TOTP (#11573)
* BUGFIXES
* GitLab reviews may not have the updated_at field set (#18450) (#18461)
* Fix detection of no commits when the default branch is not master (#18422) (#18423)
* Fix broken oauth2 authentication source edit page (#18412) (#18419)
* Place inline diff comment dialogs on split diff in 4th and 8th columns (#18403) (#18404)
* Fix restore without topic failure (#18387) (#18400)
* Fix commit's time (#18375) (#18392)
* Fix partial cloning a repo (#18373) (#18377)
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
* Prevent showing webauthn error for every time visiting `/user/settings/security` (#18386)
* Fix mime-type detection for HTTP server (#18370) (#18371)
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
* Restore propagation of ErrDependenciesLeft (#18325)
* Fix PR comments UI (#18323)
@@ -337,22 +295,10 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* BUILD
* Add lockfile-check (#18285)
* Don't store assets modified time into generated files (#18193)
* Use shadowing script for docker (#17846)
* MISC
* Update JS dependencies (#17611)
## [1.15.11](https://github.com/go-gitea/gitea/releases/tag/v1.15.11) - 2022-01-29
* SECURITY
* Only view milestones from current repo (#18414) (#18418)
* BUGFIXES
* Fix broken when no commits and default branch is not master (#18422) (#18424)
* Fix commit's time (#18375) (#18409)
* Fix restore without topic failure (#18387) (#18401)
* Fix mermaid import in 1.15 (it uses ESModule now) (#18382)
* Update to go/text 0.3.7 (#18336)
* MISC
* Upgrade EasyMDE to 2.16.1 (#18278) (#18279)
## [1.15.10](https://github.com/go-gitea/gitea/releases/tag/v1.15.10) - 2022-01-14
* BUGFIXES

View File

@@ -1,7 +1,5 @@
###################################
#Build stage - temporarily using techknowlogick image until we upgrade to latest official alpine/go image
FROM techknowlogick/go:1.17-alpine3.13 AS build-env
#Build stage
FROM golang:1.17-alpine3.15 AS build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
@@ -25,7 +23,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
FROM alpine:3.13
FROM alpine:3.15
LABEL maintainer="maintainers@gitea.io"
EXPOSE 22 3000

View File

@@ -1,7 +1,5 @@
###################################
#Build stage - temporarily using techknowlogick image until we upgrade to latest official alpine/go image
FROM techknowlogick/go:1.17-alpine3.13 AS build-env
#Build stage
FROM golang:1.17-alpine3.15 AS build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
@@ -25,7 +23,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
FROM alpine:3.13
FROM alpine:3.15
LABEL maintainer="maintainers@gitea.io"
EXPOSE 2222 3000

View File

@@ -1,4 +1,4 @@
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-rootless
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-rootless
{{#if build.tags}}
tags:
{{#each build.tags}}
@@ -8,12 +8,12 @@ tags:
{{/if}}
manifests:
-
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64-rootless
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-amd64-rootless
platform:
architecture: amd64
os: linux
-
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64-rootless
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-arm64-rootless
platform:
architecture: arm64
os: linux

View File

@@ -1,4 +1,4 @@
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
@@ -8,13 +8,13 @@ tags:
{{/if}}
manifests:
-
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-amd64
platform:
architecture: amd64
os: linux
-
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-arm64
platform:
architecture: arm64
os: linux
variant: v8
variant: v8

View File

@@ -1,5 +1,11 @@
#!/bin/sh
# Protect against buggy runc in docker <20.10.6 causing problems in with Alpine >= 3.14
if [ ! -x /bin/sh ]; then
echo "Executable test for /bin/sh failed. Your Docker version is too old to run Alpine 3.14+ and Gitea. You must upgrade Docker.";
exit 1;
fi
if [ "${USER}" != "git" ]; then
# rename user
sed -i -e "s/^git\:/${USER}\:/g" /etc/passwd

View File

@@ -1,5 +1,11 @@
#!/bin/sh
# Protect against buggy runc in docker <20.10.6 causing problems in with Alpine >= 3.14
if [ ! -x /bin/sh ]; then
echo "Executable test for /bin/sh failed. Your Docker version is too old to run Alpine 3.14+ and Gitea. You must upgrade Docker.";
exit 1;
fi
if [ -x /usr/local/bin/docker-setup.sh ]; then
/usr/local/bin/docker-setup.sh || { echo 'docker setup failed' ; exit 1; }
fi

View File

@@ -32,7 +32,7 @@ for i in "$@"; do
done
if [ -z "$APP_INI_SET" ]; then
CONF_ARG="-c \"${GITEA_APP_INI:-$APP_INI}\""
CONF_ARG="-c \"$APP_INI\""
fi

View File

@@ -18,7 +18,7 @@ params:
description: Git with a cup of tea
author: The Gitea Authors
website: https://docs.gitea.io
version: 1.16.0
version: 1.15.10
minGoVersion: 1.16
goVersion: 1.17
minNodeVersion: 12.17

View File

@@ -32,7 +32,7 @@ image as a service. Since there is no database available, one can be initialized
Create a directory for `data` and `config` then paste the following content into a file named `docker-compose.yml`.
Note that the volume should be owned by the user/group with the UID/GID specified in the config file. By default Gitea in docker will use uid:1000 gid:1000. If needed you can set ownership on those folders with the command: `sudo chown 1000:1000 config/ data/`
If you don't give the volume correct permissions, the container may not start.
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:{{< version >}}-rootless`, but if you'd like to use the latest development version then `:dev-rootless` would be an appropriate tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-dev-rootless` tag, where x is the minor version of Gitea. (e.g. `:1.16-dev-rootless`)
For a stable release you could use `:latest-rootless`, `:1-rootless` or specify a certain release like `:{{< version >}}-rootless`, but if you'd like to use the latest development version then `:dev-rootless` would be an appropriate tag.
```yaml
version: "2"

View File

@@ -34,7 +34,7 @@ image as a service. Since there is no database available, one can be initialized
Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`.
Note that the volume should be owned by the user/group with the UID/GID specified in the config file.
If you don't give the volume correct permissions, the container may not start.
For a stable release you can use `:latest`, `:1` or specify a certain release like `:{{< version >}}`, but if you'd like to use the latest development version of Gitea then you could use the `:dev` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-dev` tag, where x is the minor version of Gitea. (e.g. `:1.16-dev`)
For a stable release you can use `:latest`, `:1` or specify a certain release like `:{{< version >}}`, but if you'd like to use the latest development version of Gitea then you could use the `:dev` tag.
```yaml
version: "3"

6
go.mod
View File

@@ -30,7 +30,7 @@ require (
github.com/denisenkom/go-mssqldb v0.10.0
github.com/djherbis/buffer v1.2.0
github.com/djherbis/nio/v3 v3.0.1
github.com/duo-labs/webauthn v0.0.0-20220122034320-81aea484c951
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
github.com/dustin/go-humanize v1.0.0
github.com/editorconfig/editorconfig-core-go/v2 v2.4.2
github.com/emirpasic/gods v1.12.0
@@ -54,7 +54,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.2.0
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-github/v39 v39.2.0
github.com/google/uuid v1.3.0
github.com/google/uuid v1.2.0
github.com/gorilla/feeds v1.1.1
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/sessions v1.2.1
@@ -145,6 +145,8 @@ replace github.com/markbates/goth v1.68.0 => github.com/zeripath/goth v1.68.1-0.
replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0
replace github.com/duo-labs/webauthn => github.com/authelia/webauthn v0.0.0-20211225121951-80d1f2a572e4
replace github.com/satori/go.uuid v1.2.0 => github.com/gofrs/uuid v4.2.0+incompatible
exclude github.com/gofrs/uuid v3.2.0+incompatible

9
go.sum
View File

@@ -131,6 +131,8 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:o
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/authelia/webauthn v0.0.0-20211225121951-80d1f2a572e4 h1:u3eFvgr4A8IjlAokbFt6XY6VdurX7DEYnQMQ4K2yobc=
github.com/authelia/webauthn v0.0.0-20211225121951-80d1f2a572e4/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
@@ -274,8 +276,6 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/duo-labs/webauthn v0.0.0-20220122034320-81aea484c951 h1:17esZ09oW+29rklBtCVphIguql2u3NxYH2OasFPPZoo=
github.com/duo-labs/webauthn v0.0.0-20220122034320-81aea484c951/go.mod h1:nHy3JdztZWcsjenDeBuE8gn171OAwg12LBN027UP5AE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
@@ -491,6 +491,7 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/goccy/go-json v0.7.4 h1:B44qRUFwz/vxPKPISQ1KhvzRi9kZ28RAf6YtjriBZ5k=
github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -584,8 +585,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=

View File

@@ -8,7 +8,6 @@ import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"
@@ -263,26 +262,23 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64)
return func(t *testing.T) {
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s",
owner, repo, index, ctx.Token)
req := NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{
MergeMessageField: "doAPIMergePullRequest Merge",
Do: string(repo_model.MergeStyleMerge),
})
var req *http.Request
var resp *httptest.ResponseRecorder
resp := ctx.Session.MakeRequest(t, req, NoExpectedStatus)
for i := 0; i < 6; i++ {
req = NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{
MergeMessageField: "doAPIMergePullRequest Merge",
Do: string(repo_model.MergeStyleMerge),
})
resp = ctx.Session.MakeRequest(t, req, NoExpectedStatus)
if resp.Code != http.StatusMethodNotAllowed {
break
}
if resp.Code == http.StatusMethodNotAllowed {
err := api.APIError{}
DecodeJSON(t, resp, &err)
assert.EqualValues(t, "Please try again later", err.Message)
queue.GetManager().FlushAll(context.Background(), 5*time.Second)
<-time.After(1 * time.Second)
req = NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{
MergeMessageField: "doAPIMergePullRequest Merge",
Do: string(repo_model.MergeStyleMerge),
})
resp = ctx.Session.MakeRequest(t, req, NoExpectedStatus)
}
expected := ctx.ExpectedCode

View File

@@ -123,17 +123,6 @@ func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
}
}
func doPartialGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
return func(t *testing.T) {
assert.NoError(t, git.CloneWithArgs(context.Background(), u.String(), dstLocalPath, allowLFSFilters(), git.CloneRepoOptions{
Filter: "blob:none",
}))
exist, err := util.IsExist(filepath.Join(dstLocalPath, "README.md"))
assert.NoError(t, err)
assert.True(t, exist)
}
}
func doGitCloneFail(u *url.URL) func(*testing.T) {
return func(t *testing.T) {
tmpDir, err := os.MkdirTemp("", "doGitCloneFail")

View File

@@ -69,12 +69,6 @@ func testGit(t *testing.T, u *url.URL) {
t.Run("Clone", doGitClone(dstPath, u))
dstPath2, err := os.MkdirTemp("", httpContext.Reponame)
assert.NoError(t, err)
defer util.RemoveAll(dstPath2)
t.Run("Partial Clone", doPartialGitClone(dstPath2, u))
little, big := standardCommitAndPushTest(t, dstPath)
littleLFS, bigLFS := lfsCommitAndPushTest(t, dstPath)
rawTest(t, &httpContext, little, big, littleLFS, bigLFS)

View File

@@ -71,7 +71,7 @@ const (
)
// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error)) []*SignCommit {
func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error)) []*SignCommit {
newCommits := make([]*SignCommit, 0, len(oldCommits))
keyMap := map[string]bool{}
@@ -81,7 +81,7 @@ func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustMod
Verification: ParseCommitWithSignature(c.Commit),
}
_ = CalculateTrustStatus(signCommit.Verification, repoTrustModel, isOwnerMemberCollaborator, &keyMap)
_ = CalculateTrustStatus(signCommit.Verification, repoTrustModel, isCodeReader, &keyMap)
newCommits = append(newCommits, signCommit)
}
@@ -455,7 +455,7 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use
// CalculateTrustStatus will calculate the TrustStatus for a commit verification within a repository
// There are several trust models in Gitea
func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error), keyMap *map[string]bool) (err error) {
func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error), keyMap *map[string]bool) (err error) {
if !verification.Verified {
return
}
@@ -500,11 +500,11 @@ func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_
var has bool
isMember, has = (*keyMap)[verification.SigningKey.KeyID]
if !has {
isMember, err = isOwnerMemberCollaborator(verification.SigningUser)
isMember, err = isCodeReader(verification.SigningUser)
(*keyMap)[verification.SigningKey.KeyID] = isMember
}
} else {
isMember, err = isOwnerMemberCollaborator(verification.SigningUser)
isMember, err = isCodeReader(verification.SigningUser)
}
if !isMember {

View File

@@ -18,7 +18,7 @@ func ConvertFromGitCommit(commits []*git.Commit, repo *repo_model.Repository) []
user_model.ValidateCommitsWithEmails(commits),
repo.GetTrustModel(),
func(user *user_model.User) (bool, error) {
return IsOwnerMemberCollaborator(repo, user.ID)
return IsUserRepoAdmin(repo, user)
},
),
repo,

View File

@@ -134,6 +134,22 @@ func GetMilestoneByRepoIDANDName(repoID int64, name string) (*Milestone, error)
return &mile, nil
}
// GetMilestoneByID returns the milestone via id .
func GetMilestoneByID(id int64) (*Milestone, error) {
return getMilestoneByID(db.GetEngine(db.DefaultContext), id)
}
func getMilestoneByID(e db.Engine, id int64) (*Milestone, error) {
var m Milestone
has, err := e.ID(id).Get(&m)
if err != nil {
return nil, err
} else if !has {
return nil, ErrMilestoneNotExist{ID: id, RepoID: 0}
}
return &m, nil
}
// UpdateMilestone updates information of given milestone.
func UpdateMilestone(m *Milestone, oldIsClosed bool) error {
ctx, committer, err := db.TxContext()

View File

@@ -49,67 +49,22 @@ func init() {
db.RegisterModel(new(TeamUnit))
}
// SearchOrgTeamOptions holds the search options
type SearchOrgTeamOptions struct {
// SearchTeamOptions holds the search options
type SearchTeamOptions struct {
db.ListOptions
UserID int64
Keyword string
OrgID int64
IncludeDesc bool
}
// GetUserTeamOptions holds the search options.
type GetUserTeamOptions struct {
db.ListOptions
UserID int64
}
// SearchMembersOptions holds the search options
type SearchMembersOptions struct {
db.ListOptions
}
// GetUserTeams search for org teams. Caller is responsible to check permissions.
func GetUserTeams(opts *GetUserTeamOptions) ([]*Team, int64, error) {
if opts.Page <= 0 {
opts.Page = 1
}
if opts.PageSize == 0 {
// Default limit
opts.PageSize = 10
}
sess := db.GetEngine(db.DefaultContext)
sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id").
And("team_user.uid=?", opts.UserID)
count, err := sess.
Count(new(Team))
if err != nil {
return nil, 0, err
}
if opts.PageSize == -1 {
opts.PageSize = int(count)
} else {
sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
}
sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id").
And("team_user.uid=?", opts.UserID)
teams := make([]*Team, 0, opts.PageSize)
if err = sess.
OrderBy("lower_name").
Find(&teams); err != nil {
return nil, 0, err
}
return teams, count, nil
}
// SearchOrgTeams search for org teams. Caller is responsible to check permissions.
func SearchOrgTeams(opts *SearchOrgTeamOptions) ([]*Team, int64, error) {
// SearchTeam search for teams. Caller is responsible to check permissions.
func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) {
if opts.Page <= 0 {
opts.Page = 1
}
@@ -241,7 +196,7 @@ func (t *Team) getRepositories(e db.Engine) error {
}
// GetRepositories returns paginated repositories in team of organization.
func (t *Team) GetRepositories(opts *SearchOrgTeamOptions) error {
func (t *Team) GetRepositories(opts *SearchTeamOptions) error {
if opts.Page == 0 {
return t.getRepositories(db.GetEngine(db.DefaultContext))
}
@@ -761,7 +716,7 @@ func UpdateTeam(t *Team, authChanged, includeAllChanged bool) (err error) {
// DeleteTeam deletes given team.
// It's caller's responsibility to assign organization ID.
func DeleteTeam(t *Team) error {
if err := t.GetRepositories(&SearchOrgTeamOptions{}); err != nil {
if err := t.GetRepositories(&SearchTeamOptions{}); err != nil {
return err
}
@@ -903,7 +858,7 @@ func AddTeamMember(team *Team, userID int64) error {
}
// Get team and its repositories.
if err := team.GetRepositories(&SearchOrgTeamOptions{}); err != nil {
if err := team.GetRepositories(&SearchTeamOptions{}); err != nil {
return err
}

View File

@@ -46,7 +46,7 @@ func TestTeam_GetRepositories(t *testing.T) {
test := func(teamID int64) {
team := unittest.AssertExistsAndLoadBean(t, &Team{ID: teamID}).(*Team)
assert.NoError(t, team.GetRepositories(&SearchOrgTeamOptions{}))
assert.NoError(t, team.GetRepositories(&SearchTeamOptions{}))
assert.Len(t, team.Repos, team.NumRepos)
for _, repo := range team.Repos {
unittest.AssertExistsAndLoadBean(t, &TeamRepo{TeamID: teamID, RepoID: repo.ID})
@@ -292,7 +292,7 @@ func TestGetTeamMembers(t *testing.T) {
func TestGetUserTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(userID int64) {
teams, _, err := GetUserTeams(&GetUserTeamOptions{UserID: userID})
teams, _, err := SearchTeam(&SearchTeamOptions{UserID: userID})
assert.NoError(t, err)
for _, team := range teams {
unittest.AssertExistsAndLoadBean(t, &TeamUser{TeamID: team.ID, UID: userID})

View File

@@ -60,7 +60,7 @@ type ExternalLoginUser struct {
LastName string
NickName string
Description string
AvatarURL string `xorm:"TEXT"`
AvatarURL string
Location string
AccessToken string `xorm:"TEXT"`
AccessTokenSecret string `xorm:"TEXT"`

View File

@@ -291,7 +291,6 @@ func (ctx *Context) PlainTextBytes(status int, bs []byte) {
}
ctx.Resp.WriteHeader(status)
ctx.Resp.Header().Set("Content-Type", "text/plain;charset=utf-8")
ctx.Resp.Header().Set("X-Content-Type-Options", "nosniff")
if _, err := ctx.Resp.Write(bs); err != nil {
log.Error("Write bytes failed: %v", err)
}

View File

@@ -59,28 +59,27 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff
ctx, _, finished := process.GetManager().AddContext(repo.Ctx, fmt.Sprintf("GetRawDiffForFile: [repo_path: %s]", repo.Path))
defer finished()
cmd := exec.CommandContext(ctx, GitExecutable, GlobalCommandArgs...)
var cmd *exec.Cmd
switch diffType {
case RawDiffNormal:
if len(startCommit) != 0 {
cmd.Args = append(cmd.Args, append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...)
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...)
} else if commit.ParentCount() == 0 {
cmd.Args = append(cmd.Args, append([]string{"show", endCommit}, fileArgs...)...)
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"show", endCommit}, fileArgs...)...)
} else {
c, _ := commit.Parent(0)
cmd.Args = append(cmd.Args, append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...)
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...)
}
case RawDiffPatch:
if len(startCommit) != 0 {
query := fmt.Sprintf("%s...%s", endCommit, startCommit)
cmd.Args = append(cmd.Args, append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...)
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...)
} else if commit.ParentCount() == 0 {
cmd.Args = append(cmd.Args, append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...)
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...)
} else {
c, _ := commit.Parent(0)
query := fmt.Sprintf("%s...%s", endCommit, c.ID.String())
cmd.Args = append(cmd.Args, append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
cmd = exec.CommandContext(ctx, GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
}
default:
return fmt.Errorf("invalid diffType: %s", diffType)

View File

@@ -22,9 +22,6 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
notes, err := repo.GetCommit(NotesRef)
if err != nil {
if IsErrNotExist(err) {
return err
}
log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
return err
}

View File

@@ -21,9 +21,6 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
notes, err := repo.GetCommit(NotesRef)
if err != nil {
if IsErrNotExist(err) {
return err
}
log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
return err
}

View File

@@ -79,21 +79,16 @@ func InitRepository(repoPath string, bare bool) error {
// IsEmpty Check if repository is empty.
func (repo *Repository) IsEmpty() (bool, error) {
var errbuf, output strings.Builder
if err := NewCommandContext(repo.Ctx, "rev-list", "--all", "--count", "--max-count=1").RunWithContext(&RunContext{
Timeout: -1,
Dir: repo.Path,
Stdout: &output,
Stderr: &errbuf,
}); err != nil {
var errbuf strings.Builder
if err := NewCommand("log", "-1").RunInDirPipeline(repo.Path, nil, &errbuf); err != nil {
if strings.Contains(errbuf.String(), "fatal: bad default revision 'HEAD'") ||
strings.Contains(errbuf.String(), "fatal: your current branch 'master' does not have any commits yet") {
return true, nil
}
return true, fmt.Errorf("check empty: %v - %s", err, errbuf.String())
}
c, err := strconv.Atoi(strings.TrimSpace(output.String()))
if err != nil {
return true, fmt.Errorf("check empty: convert %s to count failed: %v", output.String(), err)
}
return c == 0, nil
return false, nil
}
// CloneRepoOptions options when clone a repository
@@ -106,7 +101,6 @@ type CloneRepoOptions struct {
Shared bool
NoCheckout bool
Depth int
Filter string
}
// Clone clones original repository to target path.
@@ -147,9 +141,7 @@ func CloneWithArgs(ctx context.Context, from, to string, args []string, opts Clo
if opts.Depth > 0 {
cmd.AddArguments("--depth", strconv.Itoa(opts.Depth))
}
if opts.Filter != "" {
cmd.AddArguments("--filter", opts.Filter)
}
if len(opts.Branch) > 0 {
cmd.AddArguments("-b", opts.Branch)
}

View File

@@ -117,7 +117,7 @@ func (graph *Graph) LoadAndProcessCommits(repository *repo_model.Repository, git
c.Verification = asymkey_model.ParseCommitWithSignature(c.Commit)
_ = asymkey_model.CalculateTrustStatus(c.Verification, repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
return models.IsOwnerMemberCollaborator(repository, user.ID)
return models.IsUserRepoAdmin(repository, user)
}, &keyMap)
statuses, _, err := models.GetLatestCommitStatus(repository.ID, c.Commit.ID.String(), db.ListOptions{})

View File

@@ -55,7 +55,7 @@ var (
anySHA1Pattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40})(/[-+~_%.a-zA-Z0-9/]+)?(#[-+~_%.a-zA-Z0-9]+)?`)
// comparePattern matches "http://domain/org/repo/compare/COMMIT1...COMMIT2#hash"
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{7,40})(\.\.\.?)([0-9a-f]{7,40})?(#[-+~_%.a-zA-Z0-9]+)?`)
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40})(\.\.\.?)([0-9a-f]{40})?(#[-+~_%.a-zA-Z0-9]+)?`)
validLinksPattern = regexp.MustCompile(`^[a-z][\w-]+://`)
@@ -944,13 +944,6 @@ func comparePatternProcessor(ctx *RenderContext, node *html.Node) {
return
}
// Ensure that every group (m[0]...m[7]) has a match
for i := 0; i < 8; i++ {
if m[i] == -1 {
return
}
}
urlFull := node.Data[m[0]:m[1]]
text1 := base.ShortSha(node.Data[m[2]:m[3]])
textDots := base.ShortSha(node.Data[m[4]:m[5]])

View File

@@ -546,16 +546,3 @@ func TestFuzz(t *testing.T) {
assert.NoError(t, err)
}
func TestIssue18471(t *testing.T) {
data := `http://domain/org/repo/compare/783b039...da951ce`
var res strings.Builder
err := PostProcess(&RenderContext{
URLPrefix: "https://example.com",
Metas: localMetas,
}, strings.NewReader(data), &res)
assert.NoError(t, err)
assert.Equal(t, res.String(), "<a href=\"http://domain/org/repo/compare/783b039...da951ce\" class=\"compare\"><code class=\"nohighlight\">783b039...da951ce</code></a>")
}

View File

@@ -1,41 +0,0 @@
// 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.
package public
import "strings"
// wellKnownMimeTypesLower comes from Golang's builtin mime package: `builtinTypesLower`, see the comment of detectWellKnownMimeType
var wellKnownMimeTypesLower = map[string]string{
".avif": "image/avif",
".css": "text/css; charset=utf-8",
".gif": "image/gif",
".htm": "text/html; charset=utf-8",
".html": "text/html; charset=utf-8",
".jpeg": "image/jpeg",
".jpg": "image/jpeg",
".js": "text/javascript; charset=utf-8",
".json": "application/json",
".mjs": "text/javascript; charset=utf-8",
".pdf": "application/pdf",
".png": "image/png",
".svg": "image/svg+xml",
".wasm": "application/wasm",
".webp": "image/webp",
".xml": "text/xml; charset=utf-8",
// well, there are some types missing from the builtin list
".txt": "text/plain; charset=utf-8",
}
// detectWellKnownMimeType will return the mime-type for a well-known file ext name
// The purpose of this function is to bypass the unstable behavior of Golang's mime.TypeByExtension
// mime.TypeByExtension would use OS's mime-type config to overwrite the well-known types (see its document).
// If the user's OS has incorrect mime-type config, it would make Gitea can not respond a correct Content-Type to browsers.
// For example, if Gitea returns `text/plain` for a `.js` file, the browser couldn't run the JS due to security reasons.
// detectWellKnownMimeType makes the Content-Type for well-known files stable.
func detectWellKnownMimeType(ext string) string {
ext = strings.ToLower(ext)
return wellKnownMimeTypesLower[ext]
}

View File

@@ -95,15 +95,6 @@ func parseAcceptEncoding(val string) map[string]bool {
return types
}
// setWellKnownContentType will set the Content-Type if the file is a well-known type.
// See the comments of detectWellKnownMimeType
func setWellKnownContentType(w http.ResponseWriter, file string) {
mimeType := detectWellKnownMimeType(filepath.Ext(file))
if mimeType != "" {
w.Header().Set("Content-Type", mimeType)
}
}
func (opts *Options) handle(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) bool {
// use clean to keep the file is a valid path with no . or ..
f, err := fs.Open(path.Clean(file))
@@ -134,8 +125,6 @@ func (opts *Options) handle(w http.ResponseWriter, req *http.Request, fs http.Fi
return true
}
setWellKnownContentType(w, file)
serveContent(w, req, fi, fi.ModTime(), f)
return true
}

View File

@@ -9,12 +9,15 @@ package public
import (
"bytes"
"compress/gzip"
"io"
"mime"
"net/http"
"os"
"path/filepath"
"time"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
)
@@ -63,16 +66,24 @@ func serveContent(w http.ResponseWriter, req *http.Request, fi os.FileInfo, modt
encodings := parseAcceptEncoding(req.Header.Get("Accept-Encoding"))
if encodings["gzip"] {
if cf, ok := fi.(*vfsgen۰CompressedFileInfo); ok {
rdGzip := bytes.NewReader(cf.GzipBytes())
// all static files are managed by Gitea, so we can make sure every file has the correct ext name
// then we can get the correct Content-Type, we do not need to do http.DetectContentType on the decompressed data
mimeType := detectWellKnownMimeType(filepath.Ext(fi.Name()))
if mimeType == "" {
mimeType = "application/octet-stream"
}
w.Header().Set("Content-Type", mimeType)
rd := bytes.NewReader(cf.GzipBytes())
w.Header().Set("Content-Encoding", "gzip")
http.ServeContent(w, req, fi.Name(), modtime, rdGzip)
ctype := mime.TypeByExtension(filepath.Ext(fi.Name()))
if ctype == "" {
// read a chunk to decide between utf-8 text and binary
var buf [512]byte
grd, _ := gzip.NewReader(rd)
n, _ := io.ReadFull(grd, buf[:])
ctype = http.DetectContentType(buf[:n])
_, err := rd.Seek(0, io.SeekStart) // rewind to output whole file
if err != nil {
log.Error("rd.Seek error: %v", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
}
w.Header().Set("Content-Type", ctype)
http.ServeContent(w, req, fi.Name(), modtime, rd)
return
}
}

View File

@@ -72,8 +72,6 @@ type ManagedPool interface {
BoostWorkers() int
// SetPoolSettings sets the user updatable settings for the pool
SetPoolSettings(maxNumberOfWorkers, boostWorkers int, timeout time.Duration)
// Done returns a channel that will be closed when the Pool's baseCtx is closed
Done() <-chan struct{}
}
// ManagedQueueList implements the sort.Interface
@@ -143,6 +141,7 @@ func (m *Manager) Remove(qid int64) {
delete(m.Queues, qid)
m.mutex.Unlock()
log.Trace("Queue Manager removed: QID: %d", qid)
}
// GetManagedQueue by qid
@@ -194,17 +193,6 @@ func (m *Manager) FlushAll(baseCtx context.Context, timeout time.Duration) error
wg.Done()
continue
}
if pool, ok := mq.Managed.(ManagedPool); ok {
// No point into flushing pools when their base's ctx is already done.
select {
case <-pool.Done():
wg.Done()
continue
default:
}
}
allEmpty = false
if flushable, ok := mq.Managed.(Flushable); ok {
log.Debug("Flushing (flushable) queue: %s", mq.Name)
@@ -237,6 +225,7 @@ func (m *Manager) FlushAll(baseCtx context.Context, timeout time.Duration) error
wg.Wait()
}
return nil
}
// ManagedQueues returns the managed queues

View File

@@ -173,6 +173,7 @@ func (q *PersistableChannelQueue) Run(atShutdown, atTerminate func(func())) {
q.internal.(*LevelQueue).Shutdown()
GetManager().Remove(q.internal.(*LevelQueue).qid)
}
}
// Flush flushes the queue and blocks till the queue is empty
@@ -251,13 +252,14 @@ func (q *PersistableChannelQueue) Shutdown() {
q.channelQueue.Wait()
q.internal.(*LevelQueue).Wait()
// Redirect all remaining data in the chan to the internal channel
close(q.channelQueue.dataChan)
log.Trace("PersistableChannelQueue: %s Redirecting remaining data", q.delayedStarter.name)
for data := range q.channelQueue.dataChan {
_ = q.internal.Push(data)
atomic.AddInt64(&q.channelQueue.numInQueue, -1)
}
log.Trace("PersistableChannelQueue: %s Done Redirecting remaining data", q.delayedStarter.name)
go func() {
log.Trace("PersistableChannelQueue: %s Redirecting remaining data", q.delayedStarter.name)
for data := range q.channelQueue.dataChan {
_ = q.internal.Push(data)
atomic.AddInt64(&q.channelQueue.numInQueue, -1)
}
log.Trace("PersistableChannelQueue: %s Done Redirecting remaining data", q.delayedStarter.name)
}()
log.Debug("PersistableChannelQueue: %s Shutdown", q.delayedStarter.name)
}

View File

@@ -65,11 +65,6 @@ func NewWorkerPool(handle HandlerFunc, config WorkerPoolConfiguration) *WorkerPo
return pool
}
// Done returns when this worker pool's base context has been cancelled
func (p *WorkerPool) Done() <-chan struct{} {
return p.baseCtx.Done()
}
// Push pushes the data to the internal channel
func (p *WorkerPool) Push(data Data) {
atomic.AddInt64(&p.numInQueue, 1)
@@ -95,7 +90,7 @@ func (p *WorkerPool) zeroBoost() {
boost = p.maxNumberOfWorkers - p.numberOfWorkers
}
if mq != nil {
log.Debug("WorkerPool: %d (for %s) has zero workers - adding %d temporary workers for %s", p.qid, mq.Name, boost, p.boostTimeout)
log.Warn("WorkerPool: %d (for %s) has zero workers - adding %d temporary workers for %s", p.qid, mq.Name, boost, p.boostTimeout)
start := time.Now()
pid := mq.RegisterWorkers(boost, start, true, start.Add(p.boostTimeout), cancel, false)
@@ -103,7 +98,7 @@ func (p *WorkerPool) zeroBoost() {
mq.RemoveWorkers(pid)
}
} else {
log.Debug("WorkerPool: %d has zero workers - adding %d temporary workers for %s", p.qid, p.boostWorkers, p.boostTimeout)
log.Warn("WorkerPool: %d has zero workers - adding %d temporary workers for %s", p.qid, p.boostWorkers, p.boostTimeout)
}
p.lock.Unlock()
p.addWorkers(ctx, cancel, boost)
@@ -331,10 +326,7 @@ func (p *WorkerPool) FlushWithContext(ctx context.Context) error {
log.Trace("WorkerPool: %d Flush", p.qid)
for {
select {
case data, ok := <-p.dataChan:
if !ok {
return nil
}
case data := <-p.dataChan:
p.handle(data)
atomic.AddInt64(&p.numInQueue, -1)
case <-p.baseCtx.Done():
@@ -349,7 +341,7 @@ func (p *WorkerPool) FlushWithContext(ctx context.Context) error {
func (p *WorkerPool) doWork(ctx context.Context) {
delay := time.Millisecond * 300
data := make([]Data, 0, p.batchLength)
var data = make([]Data, 0, p.batchLength)
for {
select {
case <-ctx.Done():

View File

@@ -23,7 +23,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
testTeamRepositories := func(teamID int64, repoIds []int64) {
team := unittest.AssertExistsAndLoadBean(t, &models.Team{ID: teamID}).(*models.Team)
assert.NoError(t, team.GetRepositories(&models.SearchOrgTeamOptions{}), "%s: GetRepositories", team.Name)
assert.NoError(t, team.GetRepositories(&models.SearchTeamOptions{}), "%s: GetRepositories", team.Name)
assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name)
assert.Len(t, team.Repos, len(repoIds), "%s: repo count", team.Name)
for i, rid := range repoIds {

732
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
"@claviska/jquery-minicolors": "2.3.6",
"@primer/octicons": "16.2.0",
"add-asset-webpack-plugin": "2.0.1",
"codemirror": "5.65.1",
"codemirror": "5.65.0",
"css-loader": "6.5.1",
"dropzone": "6.0.0-beta.2",
"easymde": "2.16.1",
@@ -23,13 +23,13 @@
"less": "4.1.2",
"less-loader": "10.2.0",
"license-checker-webpack-plugin": "0.2.1",
"mermaid": "8.13.10",
"mermaid": "8.13.9",
"mini-css-extract-plugin": "2.5.2",
"monaco-editor": "0.31.1",
"monaco-editor-webpack-plugin": "7.0.1",
"pretty-ms": "7.0.1",
"sortablejs": "1.14.0",
"swagger-ui-dist": "4.2.1",
"swagger-ui-dist": "4.1.3",
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
"vue": "2.6.14",
@@ -37,8 +37,8 @@
"vue-calendar-heatmap": "0.8.4",
"vue-loader": "15.9.8",
"vue-template-compiler": "2.6.14",
"webpack": "5.67.0",
"webpack-cli": "4.9.2",
"webpack": "5.66.0",
"webpack-cli": "4.9.1",
"workbox-routing": "6.4.2",
"workbox-strategies": "6.4.2",
"worker-loader": "3.0.8",
@@ -55,7 +55,7 @@
"jest-extended": "1.2.0",
"jest-raw-loader": "1.0.1",
"postcss-less": "6.0.0",
"stylelint": "14.3.0",
"stylelint": "14.2.0",
"stylelint-config-standard": "24.0.0",
"svgo": "2.8.0",
"updates": "13.0.0"

View File

@@ -47,7 +47,7 @@ func ListTeams(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/TeamList"
teams, count, err := models.SearchOrgTeams(&models.SearchOrgTeamOptions{
teams, count, err := models.SearchTeam(&models.SearchTeamOptions{
ListOptions: utils.GetListOptions(ctx),
OrgID: ctx.Org.Organization.ID,
})
@@ -90,7 +90,7 @@ func ListUserTeams(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/TeamList"
teams, count, err := models.GetUserTeams(&models.GetUserTeamOptions{
teams, count, err := models.SearchTeam(&models.SearchTeamOptions{
ListOptions: utils.GetListOptions(ctx),
UserID: ctx.User.ID,
})
@@ -533,7 +533,7 @@ func GetTeamRepos(ctx *context.APIContext) {
// "$ref": "#/responses/RepositoryList"
team := ctx.Org.Team
if err := team.GetRepositories(&models.SearchOrgTeamOptions{
if err := team.GetRepositories(&models.SearchTeamOptions{
ListOptions: utils.GetListOptions(ctx),
}); err != nil {
ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
@@ -707,14 +707,15 @@ func SearchTeam(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx)
opts := &models.SearchOrgTeamOptions{
opts := &models.SearchTeamOptions{
UserID: ctx.User.ID,
Keyword: ctx.FormTrim("q"),
OrgID: ctx.Org.Organization.ID,
IncludeDesc: ctx.FormString("include_desc") == "" || ctx.FormBool("include_desc"),
ListOptions: listOptions,
}
teams, maxResults, err := models.SearchOrgTeams(opts)
teams, maxResults, err := models.SearchTeam(opts)
if err != nil {
log.Error("SearchTeam failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{

View File

@@ -192,9 +192,6 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
RequiredClaimName: form.Oauth2RequiredClaimName,
RequiredClaimValue: form.Oauth2RequiredClaimValue,
SkipLocalTwoFA: form.SkipLocalTwoFA,
GroupClaimName: form.Oauth2GroupClaimName,
RestrictedGroup: form.Oauth2RestrictedGroup,
AdminGroup: form.Oauth2AdminGroup,
}
}

View File

@@ -826,7 +826,7 @@ func SignInOAuthCallback(ctx *context.Context) {
u, gothUser, err := oAuth2UserLoginCallback(authSource, ctx.Req, ctx.Resp)
if err != nil {
if user_model.IsErrUserProhibitLogin(err) {
uplerr := err.(user_model.ErrUserProhibitLogin)
uplerr := err.(*user_model.ErrUserProhibitLogin)
log.Info("Failed authentication attempt for %s from %s: %v", uplerr.Name, ctx.RemoteAddr(), err)
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
@@ -904,10 +904,6 @@ func claimValueToStringSlice(claimValue interface{}) []string {
switch rawGroup := claimValue.(type) {
case []string:
groups = rawGroup
case []interface{}:
for _, group := range rawGroup {
groups = append(groups, fmt.Sprintf("%s", group))
}
default:
str := fmt.Sprintf("%s", rawGroup)
groups = strings.Split(str, ",")

View File

@@ -319,7 +319,7 @@ func TeamRepositories(ctx *context.Context) {
ctx.Data["Title"] = ctx.Org.Team.Name
ctx.Data["PageIsOrgTeams"] = true
ctx.Data["PageIsOrgTeamRepos"] = true
if err := ctx.Org.Team.GetRepositories(&models.SearchOrgTeamOptions{}); err != nil {
if err := ctx.Org.Team.GetRepositories(&models.SearchTeamOptions{}); err != nil {
ctx.ServerError("GetRepositories", err)
return
}

View File

@@ -351,7 +351,7 @@ func Diff(ctx *context.Context) {
ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
return models.IsOwnerMemberCollaborator(ctx.Repo.Repository, user.ID)
return models.IsUserRepoAdmin(ctx.Repo.Repository, user)
}, nil); err != nil {
ctx.ServerError("CalculateTrustStatus", err)
return

View File

@@ -786,15 +786,6 @@ func ExcerptBlob(ctx *context.Context) {
direction := ctx.FormString("direction")
filePath := ctx.FormString("path")
gitRepo := ctx.Repo.GitRepo
if ctx.FormBool("wiki") {
var err error
gitRepo, err = git.OpenRepositoryCtx(ctx, ctx.Repo.Repository.WikiPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return
}
defer gitRepo.Close()
}
chunkSize := gitdiff.BlobExcerptChunkSize
commit, err := gitRepo.GetCommit(commitID)
if err != nil {

View File

@@ -491,10 +491,7 @@ func serviceRPC(h serviceHandler, service string) {
defer finished()
var stderr bytes.Buffer
args := make([]string, len(git.GlobalCommandArgs))
copy(args, git.GlobalCommandArgs)
args = append(args, []string{service, "--stateless-rpc", h.dir}...)
cmd := exec.CommandContext(ctx, git.GitExecutable, args...)
cmd := exec.CommandContext(ctx, git.GitExecutable, service, "--stateless-rpc", h.dir)
cmd.Dir = h.dir
cmd.Env = append(os.Environ(), h.environ...)
cmd.Stdout = h.w

View File

@@ -802,7 +802,7 @@ func NewIssue(ctx *context.Context) {
milestoneID := ctx.FormInt64("milestone")
if milestoneID > 0 {
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, milestoneID)
milestone, err := models.GetMilestoneByID(milestoneID)
if err != nil {
log.Error("GetMilestoneByID: %d: %v", milestoneID, err)
} else {
@@ -889,7 +889,7 @@ func ValidateRepoMetas(ctx *context.Context, form forms.CreateIssueForm, isPull
// Check milestone.
milestoneID := form.MilestoneID
if milestoneID > 0 {
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, milestoneID)
milestone, err := models.GetMilestoneByID(milestoneID)
if err != nil {
ctx.ServerError("GetMilestoneByID", err)
return nil, nil, 0, 0

View File

@@ -264,7 +264,7 @@ func DeleteMilestone(ctx *context.Context) {
// MilestoneIssuesAndPulls lists all the issues and pull requests of the milestone
func MilestoneIssuesAndPulls(ctx *context.Context) {
milestoneID := ctx.ParamsInt64(":id")
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, milestoneID)
milestone, err := models.GetMilestoneByID(milestoneID)
if err != nil {
if models.IsErrMilestoneNotExist(err) {
ctx.NotFound("GetMilestoneByID", err)

View File

@@ -800,7 +800,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
verification := asymkey_model.ParseCommitWithSignature(latestCommit)
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
return models.IsOwnerMemberCollaborator(ctx.Repo.Repository, user.ID)
return models.IsUserRepoAdmin(ctx.Repo.Repository, user)
}, nil); err != nil {
ctx.ServerError("CalculateTrustStatus", err)
return nil

View File

@@ -5,7 +5,6 @@
package web
import (
gocontext "context"
"net/http"
"os"
"path"
@@ -953,25 +952,7 @@ func RegisterRoutes(m *web.Route) {
m.Group("/blob_excerpt", func() {
m.Get("/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob)
}, func(ctx *context.Context) (cancel gocontext.CancelFunc) {
if ctx.FormBool("wiki") {
ctx.Data["PageIsWiki"] = true
repo.MustEnableWiki(ctx)
return
}
reqRepoCodeReader(ctx)
if ctx.Written() {
return
}
cancel = context.RepoRef()(ctx)
if ctx.Written() {
return
}
repo.MustBeNotEmpty(ctx)
return
})
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
m.Group("/pulls/{index}", func() {
m.Get(".diff", repo.DownloadPullDiff)

View File

@@ -70,13 +70,13 @@ func init() {
}))
// named gplus due to legacy gplus -> google migration (Google killed Google+). This ensures old connections still work
RegisterGothProvider(NewImagedProvider("/assets/img/auth/google.png", NewSimpleProvider("gplus", "Google", []string{"email"},
RegisterGothProvider(NewSimpleProvider("gplus", "Google", []string{"email"},
func(clientKey, secret, callbackURL string, scopes ...string) goth.Provider {
if setting.OAuth2Client.UpdateAvatar || setting.OAuth2Client.EnableAutoRegistration {
scopes = append(scopes, "profile")
}
return google.New(clientKey, secret, callbackURL, scopes...)
})))
}))
RegisterGothProvider(NewSimpleProvider("twitter", "Twitter", nil,
func(clientKey, secret, callbackURL string, scopes ...string) goth.Provider {
@@ -107,4 +107,5 @@ func init() {
return microsoftonline.New(clientID, secret, callbackURL, scopes...)
},
))
}

View File

@@ -14,7 +14,6 @@ import (
"strconv"
"strings"
texttmpl "text/template"
"time"
"code.gitea.io/gitea/models"
repo_model "code.gitea.io/gitea/models/repo"
@@ -298,15 +297,13 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
}
// Make sure to compose independent messages to avoid leaking user emails
msgID := createReference(ctx.Issue, ctx.Comment, ctx.ActionType)
reference := createReference(ctx.Issue, nil, models.ActionType(0))
msgs := make([]*Message, 0, len(recipients))
for _, recipient := range recipients {
msg := NewMessageFrom([]string{recipient.Email}, ctx.Doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String())
msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
msg.SetHeader("Message-ID", "<"+msgID+">")
msg.SetHeader("Message-ID", "<"+createReference(ctx.Issue, ctx.Comment)+">")
reference := createReference(ctx.Issue, nil)
msg.SetHeader("In-Reply-To", "<"+reference+">")
msg.SetHeader("References", "<"+reference+">")
@@ -320,7 +317,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
return msgs, nil
}
func createReference(issue *models.Issue, comment *models.Comment, actionType models.ActionType) string {
func createReference(issue *models.Issue, comment *models.Comment) string {
var path string
if issue.IsPull {
path = "pulls"
@@ -331,17 +328,6 @@ func createReference(issue *models.Issue, comment *models.Comment, actionType mo
var extra string
if comment != nil {
extra = fmt.Sprintf("/comment/%d", comment.ID)
} else {
switch actionType {
case models.ActionCloseIssue, models.ActionClosePullRequest:
extra = fmt.Sprintf("/close/%d", time.Now().UnixNano()/1e6)
case models.ActionReopenIssue, models.ActionReopenPullRequest:
extra = fmt.Sprintf("/reopen/%d", time.Now().UnixNano()/1e6)
case models.ActionMergePullRequest:
extra = fmt.Sprintf("/merge/%d", time.Now().UnixNano()/1e6)
case models.ActionPullRequestReadyForReview:
extra = fmt.Sprintf("/ready/%d", time.Now().UnixNano()/1e6)
}
}
return fmt.Sprintf("%s/%s/%d%s@%s", issue.Repo.FullName(), path, issue.Index, extra, setting.Domain)

View File

@@ -6,9 +6,7 @@ package mailer
import (
"bytes"
"fmt"
"html/template"
"strings"
"testing"
texttmpl "text/template"
@@ -17,6 +15,7 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
@@ -237,115 +236,3 @@ func TestGenerateAdditionalHeaders(t *testing.T) {
}
}
}
func Test_createReference(t *testing.T) {
_, _, issue, comment := prepareMailerTest(t)
_, _, pullIssue, _ := prepareMailerTest(t)
pullIssue.IsPull = true
type args struct {
issue *models.Issue
comment *models.Comment
actionType models.ActionType
}
tests := []struct {
name string
args args
prefix string
suffix string
}{
{
name: "Open Issue",
args: args{
issue: issue,
actionType: models.ActionCreateIssue,
},
prefix: fmt.Sprintf("%s/issues/%d@%s", issue.Repo.FullName(), issue.Index, setting.Domain),
},
{
name: "Open Pull",
args: args{
issue: pullIssue,
actionType: models.ActionCreatePullRequest,
},
prefix: fmt.Sprintf("%s/pulls/%d@%s", issue.Repo.FullName(), issue.Index, setting.Domain),
},
{
name: "Comment Issue",
args: args{
issue: issue,
comment: comment,
actionType: models.ActionCommentIssue,
},
prefix: fmt.Sprintf("%s/issues/%d/comment/%d@%s", issue.Repo.FullName(), issue.Index, comment.ID, setting.Domain),
},
{
name: "Comment Pull",
args: args{
issue: pullIssue,
comment: comment,
actionType: models.ActionCommentPull,
},
prefix: fmt.Sprintf("%s/pulls/%d/comment/%d@%s", issue.Repo.FullName(), issue.Index, comment.ID, setting.Domain),
},
{
name: "Close Issue",
args: args{
issue: issue,
actionType: models.ActionCloseIssue,
},
prefix: fmt.Sprintf("%s/issues/%d/close/", issue.Repo.FullName(), issue.Index),
},
{
name: "Close Pull",
args: args{
issue: pullIssue,
actionType: models.ActionClosePullRequest,
},
prefix: fmt.Sprintf("%s/pulls/%d/close/", issue.Repo.FullName(), issue.Index),
},
{
name: "Reopen Issue",
args: args{
issue: issue,
actionType: models.ActionReopenIssue,
},
prefix: fmt.Sprintf("%s/issues/%d/reopen/", issue.Repo.FullName(), issue.Index),
},
{
name: "Reopen Pull",
args: args{
issue: pullIssue,
actionType: models.ActionReopenPullRequest,
},
prefix: fmt.Sprintf("%s/pulls/%d/reopen/", issue.Repo.FullName(), issue.Index),
},
{
name: "Merge Pull",
args: args{
issue: pullIssue,
actionType: models.ActionMergePullRequest,
},
prefix: fmt.Sprintf("%s/pulls/%d/merge/", issue.Repo.FullName(), issue.Index),
},
{
name: "Ready Pull",
args: args{
issue: pullIssue,
actionType: models.ActionPullRequestReadyForReview,
},
prefix: fmt.Sprintf("%s/pulls/%d/ready/", issue.Repo.FullName(), issue.Index),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := createReference(tt.args.issue, tt.args.comment, tt.args.actionType)
if !strings.HasPrefix(got, tt.prefix) {
t.Errorf("createReference() = %v, want %v", got, tt.prefix)
}
if !strings.HasSuffix(got, tt.suffix) {
t.Errorf("createReference() = %v, want %v", got, tt.prefix)
}
})
}
}

View File

@@ -32,7 +32,8 @@ func init() {
}
// GitlabDownloaderFactory defines a gitlab downloader factory
type GitlabDownloaderFactory struct{}
type GitlabDownloaderFactory struct {
}
// New returns a Downloader related to this factory according MigrateOptions
func (f *GitlabDownloaderFactory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) {
@@ -183,17 +184,16 @@ func (g *GitlabDownloader) GetTopics() ([]string, error) {
// GetMilestones returns milestones
func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) {
perPage := g.maxPerPage
state := "all"
milestones := make([]*base.Milestone, 0, perPage)
var perPage = g.maxPerPage
var state = "all"
var milestones = make([]*base.Milestone, 0, perPage)
for i := 1; ; i++ {
ms, _, err := g.client.Milestones.ListMilestones(g.repoID, &gitlab.ListMilestonesOptions{
State: &state,
ListOptions: gitlab.ListOptions{
Page: i,
PerPage: perPage,
},
}, nil, gitlab.WithContext(g.ctx))
}}, nil, gitlab.WithContext(g.ctx))
if err != nil {
return nil, err
}
@@ -203,7 +203,7 @@ func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) {
if m.Description != "" {
desc = m.Description
}
state := "open"
var state = "open"
var closedAt *time.Time
if m.State != "" {
state = m.State
@@ -255,8 +255,8 @@ func (g *GitlabDownloader) normalizeColor(val string) string {
// GetLabels returns labels
func (g *GitlabDownloader) GetLabels() ([]*base.Label, error) {
perPage := g.maxPerPage
labels := make([]*base.Label, 0, perPage)
var perPage = g.maxPerPage
var labels = make([]*base.Label, 0, perPage)
for i := 1; ; i++ {
ls, _, err := g.client.Labels.ListLabels(g.repoID, &gitlab.ListLabelsOptions{ListOptions: gitlab.ListOptions{
Page: i,
@@ -327,8 +327,8 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea
// GetReleases returns releases
func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) {
perPage := g.maxPerPage
releases := make([]*base.Release, 0, perPage)
var perPage = g.maxPerPage
var releases = make([]*base.Release, 0, perPage)
for i := 1; ; i++ {
ls, _, err := g.client.Releases.ListReleases(g.repoID, &gitlab.ListReleasesOptions{
Page: i,
@@ -381,7 +381,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
},
}
allIssues := make([]*base.Issue, 0, perPage)
var allIssues = make([]*base.Issue, 0, perPage)
issues, _, err := g.client.Issues.ListProjectIssues(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
if err != nil {
@@ -389,7 +389,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
}
for _, issue := range issues {
labels := make([]*base.Label, 0, len(issue.Labels))
var labels = make([]*base.Label, 0, len(issue.Labels))
for _, l := range issue.Labels {
labels = append(labels, &base.Label{
Name: l,
@@ -402,7 +402,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
}
var reactions []*base.Reaction
awardPage := 1
var awardPage = 1
for {
awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx))
if err != nil {
@@ -456,9 +456,9 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
return nil, false, fmt.Errorf("unexpected context: %+v", opts.Context)
}
allComments := make([]*base.Comment, 0, g.maxPerPage)
var allComments = make([]*base.Comment, 0, g.maxPerPage)
page := 1
var page = 1
for {
var comments []*gitlab.Discussion
@@ -503,6 +503,7 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
Created: *c.CreatedAt,
})
}
}
if resp.NextPage == 0 {
break
@@ -525,7 +526,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
},
}
allPRs := make([]*base.PullRequest, 0, perPage)
var allPRs = make([]*base.PullRequest, 0, perPage)
prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
if err != nil {
@@ -533,7 +534,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
}
for _, pr := range prs {
labels := make([]*base.Label, 0, len(pr.Labels))
var labels = make([]*base.Label, 0, len(pr.Labels))
for _, l := range pr.Labels {
labels = append(labels, &base.Label{
Name: l,
@@ -546,12 +547,12 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
pr.State = "closed"
}
mergeTime := pr.MergedAt
var mergeTime = pr.MergedAt
if merged && pr.MergedAt == nil {
mergeTime = pr.UpdatedAt
}
closeTime := pr.ClosedAt
var closeTime = pr.ClosedAt
if merged && pr.ClosedAt == nil {
closeTime = pr.UpdatedAt
}
@@ -567,7 +568,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
}
var reactions []*base.Reaction
awardPage := 1
var awardPage = 1
for {
awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx))
if err != nil {
@@ -640,22 +641,13 @@ func (g *GitlabDownloader) GetReviews(context base.IssueContext) ([]*base.Review
return nil, err
}
var createdAt time.Time
if approvals.CreatedAt != nil {
createdAt = *approvals.CreatedAt
} else if approvals.UpdatedAt != nil {
createdAt = *approvals.UpdatedAt
} else {
createdAt = time.Now()
}
reviews := make([]*base.Review, 0, len(approvals.ApprovedBy))
var reviews = make([]*base.Review, 0, len(approvals.ApprovedBy))
for _, user := range approvals.ApprovedBy {
reviews = append(reviews, &base.Review{
IssueIndex: context.LocalID(),
ReviewerID: int64(user.User.ID),
ReviewerName: user.User.Username,
CreatedAt: createdAt,
CreatedAt: *approvals.UpdatedAt,
// All we get are approvals
State: base.ReviewStateApproved,
})

View File

@@ -8,16 +8,13 @@ import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"os"
"strconv"
"testing"
"time"
base "code.gitea.io/gitea/modules/migration"
"github.com/stretchr/testify/assert"
"github.com/xanzy/go-gitlab"
)
func TestGitlabDownloadRepo(t *testing.T) {
@@ -313,14 +310,12 @@ func TestGitlabDownloadRepo(t *testing.T) {
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
IssueIndex: 1,
ReviewerID: 4102996,
ReviewerName: "zeripath",
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
State: "APPROVED",
},
{
IssueIndex: 1,
ReviewerID: 527793,
ReviewerName: "axifive",
CreatedAt: time.Date(2019, 11, 28, 16, 2, 8, 377000000, time.UTC),
@@ -332,7 +327,6 @@ func TestGitlabDownloadRepo(t *testing.T) {
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
IssueIndex: 2,
ReviewerID: 4575606,
ReviewerName: "real6543",
CreatedAt: time.Date(2020, 4, 19, 19, 24, 21, 108000000, time.UTC),
@@ -340,137 +334,3 @@ func TestGitlabDownloadRepo(t *testing.T) {
},
}, rvs)
}
func gitlabClientMockSetup(t *testing.T) (*http.ServeMux, *httptest.Server, *gitlab.Client) {
// mux is the HTTP request multiplexer used with the test server.
mux := http.NewServeMux()
// server is a test HTTP server used to provide mock API responses.
server := httptest.NewServer(mux)
// client is the Gitlab client being tested.
client, err := gitlab.NewClient("", gitlab.WithBaseURL(server.URL))
if err != nil {
server.Close()
t.Fatalf("Failed to create client: %v", err)
}
return mux, server, client
}
func gitlabClientMockTeardown(server *httptest.Server) {
server.Close()
}
type reviewTestCase struct {
repoID, prID, reviewerID int
reviewerName string
createdAt, updatedAt *time.Time
expectedCreatedAt time.Time
}
func convertTestCase(t reviewTestCase) (func(w http.ResponseWriter, r *http.Request), base.Review) {
var updatedAtField string
if t.updatedAt == nil {
updatedAtField = ""
} else {
updatedAtField = `"updated_at": "` + t.updatedAt.Format(time.RFC3339) + `",`
}
var createdAtField string
if t.createdAt == nil {
createdAtField = ""
} else {
createdAtField = `"created_at": "` + t.createdAt.Format(time.RFC3339) + `",`
}
handler := func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, `
{
"id": 5,
"iid": `+strconv.Itoa(t.prID)+`,
"project_id": `+strconv.Itoa(t.repoID)+`,
"title": "Approvals API",
"description": "Test",
"state": "opened",
`+createdAtField+`
`+updatedAtField+`
"merge_status": "cannot_be_merged",
"approvals_required": 2,
"approvals_left": 1,
"approved_by": [
{
"user": {
"name": "Administrator",
"username": "`+t.reviewerName+`",
"id": `+strconv.Itoa(t.reviewerID)+`,
"state": "active",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",
"web_url": "http://localhost:3000/root"
}
}
]
}`)
}
review := base.Review{
IssueIndex: int64(t.prID),
ReviewerID: int64(t.reviewerID),
ReviewerName: t.reviewerName,
CreatedAt: t.expectedCreatedAt,
State: "APPROVED",
}
return handler, review
}
func TestGitlabGetReviews(t *testing.T) {
mux, server, client := gitlabClientMockSetup(t)
defer gitlabClientMockTeardown(server)
repoID := 1324
downloader := &GitlabDownloader{
ctx: context.Background(),
client: client,
repoID: repoID,
}
createdAt := time.Date(2020, 4, 19, 19, 24, 21, 0, time.UTC)
for _, testCase := range []reviewTestCase{
{
repoID: repoID,
prID: 1,
reviewerID: 801,
reviewerName: "someone1",
createdAt: nil,
updatedAt: &createdAt,
expectedCreatedAt: createdAt,
},
{
repoID: repoID,
prID: 2,
reviewerID: 802,
reviewerName: "someone2",
createdAt: &createdAt,
updatedAt: nil,
expectedCreatedAt: createdAt,
},
{
repoID: repoID,
prID: 3,
reviewerID: 803,
reviewerName: "someone3",
createdAt: nil,
updatedAt: nil,
expectedCreatedAt: time.Now(),
},
} {
mock, review := convertTestCase(testCase)
mux.HandleFunc(fmt.Sprintf("/api/v4/projects/%d/merge_requests/%d/approvals", testCase.repoID, testCase.prID), mock)
rvs, err := downloader.GetReviews(base.BasicIssueContext(testCase.prID))
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{&review}, rvs)
}
}

View File

@@ -223,15 +223,15 @@ func assertRepositoryEqual(t *testing.T, expected, actual *base.Repository) {
}
func assertReviewEqual(t *testing.T, expected, actual *base.Review) {
assert.Equal(t, expected.ID, actual.ID, "ID")
assert.Equal(t, expected.IssueIndex, actual.IssueIndex, "IsssueIndex")
assert.Equal(t, expected.ReviewerID, actual.ReviewerID, "ReviewerID")
assert.Equal(t, expected.ReviewerName, actual.ReviewerName, "ReviewerName")
assert.Equal(t, expected.Official, actual.Official, "Official")
assert.Equal(t, expected.CommitID, actual.CommitID, "CommitID")
assert.Equal(t, expected.Content, actual.Content, "Content")
assert.WithinDuration(t, expected.CreatedAt, actual.CreatedAt, 10*time.Second)
assert.Equal(t, expected.State, actual.State, "State")
assert.Equal(t, expected.ID, actual.ID)
assert.Equal(t, expected.IssueIndex, actual.IssueIndex)
assert.Equal(t, expected.ReviewerID, actual.ReviewerID)
assert.Equal(t, expected.ReviewerName, actual.ReviewerName)
assert.Equal(t, expected.Official, actual.Official)
assert.Equal(t, expected.CommitID, actual.CommitID)
assert.Equal(t, expected.Content, actual.Content)
assertTimeEqual(t, expected.CreatedAt, actual.CreatedAt)
assert.Equal(t, expected.State, actual.State)
assertReviewCommentsEqual(t, expected.Comments, actual.Comments)
}

View File

@@ -97,9 +97,6 @@ func (r *RepositoryRestorer) GetTopics() ([]string, error) {
bs, err := os.ReadFile(p)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}

View File

@@ -339,10 +339,8 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
if prConfig.IgnoreWhitespaceConflicts {
args = append(args, "--ignore-whitespace")
}
is3way := false
if git.CheckGitVersionAtLeast("2.32.0") == nil {
args = append(args, "--3way")
is3way = true
}
args = append(args, patchPath)
pr.ConflictedFiles = make([]string, 0, 5)
@@ -381,9 +379,6 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
const prefix = "error: patch failed:"
const errorPrefix = "error: "
const threewayFailed = "Failed to perform three-way merge..."
const appliedPatchPrefix = "Applied patch to '"
const withConflicts = "' with conflicts."
conflictMap := map[string]bool{}
@@ -395,8 +390,6 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
conflict = true
filepath := strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0])
conflictMap[filepath] = true
} else if is3way && line == threewayFailed {
conflict = true
} else if strings.HasPrefix(line, errorPrefix) {
conflict = true
for _, suffix := range patchErrorSuffices {
@@ -408,12 +401,6 @@ func checkConflicts(pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath
break
}
}
} else if is3way && strings.HasPrefix(line, appliedPatchPrefix) && strings.HasSuffix(line, withConflicts) {
conflict = true
filepath := strings.TrimPrefix(strings.TrimSuffix(line, withConflicts), appliedPatchPrefix)
if filepath != "" {
conflictMap[filepath] = true
}
}
// only list 10 conflicted files
if len(conflictMap) >= 10 {

View File

@@ -286,10 +286,6 @@
<input id="skip_local_two_fa" name="skip_local_two_fa" type="checkbox" {{if $cfg.SkipLocalTwoFA}}checked{{end}}>
<p class="help">{{.i18n.Tr "admin.auths.skip_local_two_fa_helper"}}</p>
</div>
</div>
<div class="oauth2_use_custom_url inline field">
<div class="ui checkbox">
<label><strong>{{.i18n.Tr "admin.auths.oauth2_use_custom_url"}}</strong></label>
<input id="oauth2_use_custom_url" name="oauth2_use_custom_url" type="checkbox" {{if $cfg.CustomURLMapping}}checked{{end}}>
</div>
</div>

View File

@@ -56,7 +56,7 @@
<br>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="permission" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}>
<input type="radio" name="permission" value="{{if .PageIsOrgTeamsNew}}read{{else}}{{.Team.AccessMode}}{{end}}" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}>
<label>{{.i18n.Tr "org.teams.general_access"}}</label>
<span class="help">{{.i18n.Tr "org.teams.general_access_helper"}}</span>
</div>

View File

@@ -75,11 +75,7 @@
<pre class="commit-body" style="display: none;">{{RenderCommitBody .Message $commitRepoLink $.Repository.ComposeMetas}}</pre>
{{end}}
</td>
{{if .Committer}}
<td class="text right aligned">{{TimeSince .Committer.When $.Lang}}</td>
{{else}}
<td class="text right aligned">{{TimeSince .Author.When $.Lang}}</td>
{{end}}
<td class="text right aligned">{{TimeSince .Author.When $.Lang}}</td>
</tr>
{{end}}
</tbody>

View File

@@ -4,35 +4,40 @@
{{if eq .GetType 4}}
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down" data-anchor="{{$.Anchor}}">
{{svg "octicon-fold-down"}}
</a>
{{end}}
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up" data-anchor="{{$.Anchor}}">
{{svg "octicon-fold-up"}}
</a>
{{end}}
{{if eq $line.GetExpandDirection 2}}
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=" data-anchor="{{$.Anchor}}">
{{svg "octicon-fold"}}
</a>
{{end}}
</td>
<td colspan="5" class="lines-code lines-code-old ">{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
{{else}}
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $.fileName}}L{{$line.LeftIdx}}{{end}}"></span></td>
<td class="blob-excerpt lines-escape lines-escape-old">{{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}<a href="" class="toggle-escape-button" title="{{$.i18n.Tr "repo.line_unicode"}}"></a>{{end}}</td>
<td class="blob-excerpt lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker=""></span>{{end}}</td>
<td class="blob-excerpt lines-code lines-code-old halfwidth">{{/*
*/}}<code {{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{if $line.LeftIdx}}{{$inlineDiff.Content}}{{end}}</code>{{/*
*/}}</td>
*/}}{{if $line.LeftIdx}}{{/*
*/}}{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code>{{/*
*/}}{{else}}{{/*
*/}}<code class="code-inner"></code>{{/*
*/}}{{end}}{{/*
*/}}</td>
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $.fileName}}R{{$line.RightIdx}}{{end}}"></span></td>
<td class="blob-excerpt lines-escape lines-escape-new">{{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}<a href="" class="toggle-escape-button" title="{{$.i18n.Tr "repo.line_unicode"}}"></a>{{end}}</td>
<td class="blob-excerpt lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="mono" data-type-marker=""></span>{{end}}</td>
<td class="blob-excerpt lines-code lines-code-new halfwidth">{{/*
*/}}<code {{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{if $line.RightIdx}}{{$inlineDiff.Content}}{{end}}</code>{{/*
*/}}{{if $line.RightIdx}}{{/*
*/}}{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code>{{/*
*/}}{{else}}{{/*
*/}}<code class="code-inner"></code>{{/*
*/}}{{end}}{{/*
*/}}</td>
{{end}}
</tr>
@@ -43,17 +48,17 @@
{{if eq .GetType 4}}
<td colspan="2" class="lines-num">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down" data-anchor="{{$.Anchor}}">
{{svg "octicon-fold-down"}}
</a>
{{end}}
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up" data-anchor="{{$.Anchor}}">
{{svg "octicon-fold-up"}}
</a>
{{end}}
{{if eq $line.GetExpandDirection 2}}
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.PageIsWiki}}" data-anchor="{{$.Anchor}}">
<a role="button" class="blob-excerpt" data-url="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=" data-anchor="{{$.Anchor}}">
{{svg "octicon-fold"}}
</a>
{{end}}
@@ -62,10 +67,8 @@
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $.fileName}}L{{$line.LeftIdx}}{{end}}"></span></td>
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $.fileName}}R{{$line.RightIdx}}{{end}}"></span></td>
{{end}}
{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}
<td class="blob-excerpt lines-escape">{{if $inlineDiff.EscapeStatus.Escaped}}<a href="" class="toggle-escape-button" title="{{$.i18n.Tr "repo.line_unicode"}}"></a>{{end}}</td>
<td class="blob-excerpt lines-type-marker"><span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
<td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
<td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}">{{$inlineDiff := $.section.GetComputedInlineDiffFor $line}}<code {{if $inlineDiff.EscapeStatus.Escaped}}class="code-inner has-escaped" title="{{$.i18n.Tr "repo.line_unicode"}}"{{else}}class="code-inner"{{end}}>{{$inlineDiff.Content}}</code></td>
</tr>
{{end}}
{{end}}

View File

@@ -7,17 +7,17 @@
{{if eq .GetType 4}}
<td class="lines-num lines-num-old">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
{{svg "octicon-fold-down"}}
</a>
{{end}}
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
{{svg "octicon-fold-up"}}
</a>
{{end}}
{{if eq $line.GetExpandDirection 2}}
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
{{svg "octicon-fold"}}
</a>
{{end}}

View File

@@ -6,17 +6,17 @@
{{if eq .GetType 4}}
<td colspan="2" class="lines-num">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
{{svg "octicon-fold-down"}}
</a>
{{end}}
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
{{svg "octicon-fold-up"}}
</a>
{{end}}
{{if eq $line.GetExpandDirection 2}}
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.root.PageIsWiki}}" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
<a role="button" class="blob-excerpt" data-url="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}">
{{svg "octicon-fold"}}
</a>
{{end}}

View File

@@ -1,6 +1,12 @@
<div class="ui centered grid">
<div class="twelve wide computer column">
<div class="ui attached left aligned segment">
<!-- <h4 class="ui header">
{{.i18n.Tr "repo.issues.label_templates.title"}}
<a target="_blank" rel="noopener noreferrer" href="https://discuss.gogs.io/t/how-to-use-predefined-label-templates/599">
<span class="octicon octicon-question"></span>
</a>
</h4> -->
<p>{{.i18n.Tr "repo.issues.label_templates.info"}}</p>
<br/>
<form class="ui form center" action="{{.Link}}/initialize" method="post">
@@ -14,7 +20,6 @@
<div class="item" data-value="{{$template}}">{{$template}}<br/><i>({{$labels}})</i></div>
{{end}}
</div>
{{svg "octicon-triangle-down" 18 "dropdown icon"}}
</div>
</div>
<button type="submit" class="ui blue button">{{.i18n.Tr "repo.issues.label_templates.use"}}</button>

View File

@@ -28,7 +28,7 @@
{{ .OriginalAuthor }}
</span>
<span class="text grey">
{{$.i18n.Tr "repo.issues.commented_at" (.HashTag|Escape) $createdStr | Safe}} {{if $.Repository.OriginalURL}}
{{$.i18n.Tr "repo.issues.commented_at" (.Issue.HashTag|Escape) $createdStr | Safe}} {{if $.Repository.OriginalURL}}
</span>
<span class="text migrate">
({{$.i18n.Tr "repo.migrated_from" ($.Repository.OriginalURL|Escape) ($.Repository.GetOriginalURLHostname|Escape) | Safe }}){{end}}

View File

@@ -34,7 +34,7 @@
</span>
{{end}}
</th>
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When $.Lang}}{{end}}{{end}}</th>
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Author}}{{TimeSince .LatestCommit.Author.When $.Lang}}{{end}}{{end}}</th>
</tr>
</thead>
<tbody>

View File

@@ -496,17 +496,13 @@ export function initRepoPullRequestReview() {
<tr class="add-comment" data-line-type="${lineType}">
${isSplit ? `
<td class="lines-num"></td>
<td class="lines-escape"></td>
<td class="lines-type-marker"></td>
<td class="add-comment-left"></td>
<td class="lines-num"></td>
<td class="lines-escape"></td>
<td class="lines-type-marker"></td>
<td class="add-comment-right"></td>
` : `
<td class="lines-num"></td>
<td class="lines-num"></td>
<td class="lines-escape"></td>
<td colspan="3" class="lines-num"></td>
<td class="add-comment-left add-comment-right" colspan="2"></td>
`}
</tr>`);

View File

@@ -150,12 +150,13 @@ export function initUserAuthWebAuthnRegister() {
return;
}
if (!detectWebAuthnSupport()) {
return;
}
$('#webauthn-error').modal({allowMultiple: false});
$('#register-webauthn').on('click', (e) => {
e.preventDefault();
if (!detectWebAuthnSupport()) {
return;
}
webAuthnRegisterRequest();
});
}

View File

@@ -4,13 +4,6 @@
// otherwise some part of the popup will be hidden by viewport boundary
max-height: 45vh;
max-width: 60vw;
&.ui.right {
// Override `.ui.attached.header .right:not(.dropdown) height: 30px;` which would otherwise lead to
// the status popup box having its height fixed at 30px. See https://github.com/go-gitea/gitea/issues/18498
height: auto;
}
overflow: auto;
padding: 0;
@@ -3046,7 +3039,7 @@ td.blob-excerpt {
}
.file-info-entry + .file-info-entry {
border-left: 1px solid currentcolor;
border-left: 1px solid currentColor;
margin-left: 8px;
padding-left: 8px;
}
@@ -3193,7 +3186,7 @@ td.blob-excerpt {
background: var(--color-diff-inactive);
}
.code-diff-split tbody tr td:nth-child(5) {
.code-diff-split tbody tr td:nth-child(4) {
border-left: 1px solid var(--color-secondary);
}

View File

@@ -1,7 +1,7 @@
.svg {
display: inline-block;
vertical-align: text-top;
fill: currentcolor;
fill: currentColor;
.middle & {
vertical-align: middle;

View File

@@ -17,7 +17,7 @@
}
text {
fill: currentcolor !important;
fill: currentColor !important;
}
.total-contributions {

View File

@@ -26,6 +26,6 @@ body {
.swagger-back-link svg {
color: inherit;
fill: currentcolor;
fill: currentColor;
margin-right: .5rem;
}