mirror of
https://github.com/go-gitea/gitea.git
synced 2025-04-08 17:05:45 +02:00
Merge branch 'main' into feature/bots
This commit is contained in:
commit
d183b32aa8
@ -551,7 +551,7 @@ steps:
|
||||
|
||||
# TODO: We should probably build all dependencies into a test image
|
||||
- name: test-e2e
|
||||
image: mcr.microsoft.com/playwright:v1.28.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
commands:
|
||||
- curl -sLO https://go.dev/dl/go1.19.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
|
||||
- groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea
|
||||
@ -928,10 +928,8 @@ trigger:
|
||||
|
||||
steps:
|
||||
- name: build-docs
|
||||
image: plugins/hugo:latest
|
||||
pull: always
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- apk add --no-cache make bash curl
|
||||
- cd docs
|
||||
- make trans-copy clean build
|
||||
|
||||
|
@ -255,7 +255,7 @@ rules:
|
||||
no-irregular-whitespace: [2]
|
||||
no-iterator: [2]
|
||||
no-label-var: [2]
|
||||
no-labels: [0]
|
||||
no-labels: [0] # handled by no-restricted-syntax
|
||||
no-lone-blocks: [2]
|
||||
no-lonely-if: [0]
|
||||
no-loop-func: [0]
|
||||
@ -335,7 +335,7 @@ rules:
|
||||
no-void: [2]
|
||||
no-warning-comments: [0]
|
||||
no-whitespace-before-property: [2]
|
||||
no-with: [0]
|
||||
no-with: [0] # handled by no-restricted-syntax
|
||||
nonblock-statement-body-position: [2]
|
||||
object-curly-newline: [0]
|
||||
object-curly-spacing: [2, never]
|
||||
@ -495,7 +495,7 @@ rules:
|
||||
unicorn/prefer-native-coercion-functions: [2]
|
||||
unicorn/prefer-negative-index: [2]
|
||||
unicorn/prefer-node-append: [0]
|
||||
unicorn/prefer-node-protocol: [0]
|
||||
unicorn/prefer-node-protocol: [2]
|
||||
unicorn/prefer-node-remove: [0]
|
||||
unicorn/prefer-number-properties: [0]
|
||||
unicorn/prefer-object-from-entries: [2]
|
||||
|
@ -2,7 +2,7 @@
|
||||
import imageminZopfli from 'imagemin-zopfli';
|
||||
import {optimize} from 'svgo';
|
||||
import {fabric} from 'fabric';
|
||||
import {readFile, writeFile} from 'fs/promises';
|
||||
import {readFile, writeFile} from 'node:fs/promises';
|
||||
|
||||
function exit(err) {
|
||||
if (err) console.error(err);
|
||||
|
@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
import fastGlob from 'fast-glob';
|
||||
import {optimize} from 'svgo';
|
||||
import {parse} from 'path';
|
||||
import {readFile, writeFile, mkdir} from 'fs/promises';
|
||||
import {fileURLToPath} from 'url';
|
||||
import {parse} from 'node:path';
|
||||
import {readFile, writeFile, mkdir} from 'node:fs/promises';
|
||||
import {fileURLToPath} from 'node:url';
|
||||
|
||||
const glob = (pattern) => fastGlob.sync(pattern, {
|
||||
cwd: fileURLToPath(new URL('..', import.meta.url)),
|
||||
|
@ -1036,6 +1036,9 @@ ROUTER = console
|
||||
;;
|
||||
;; Add co-authored-by and co-committed-by trailers if committer does not match author
|
||||
;ADD_CO_COMMITTER_TRAILERS = true
|
||||
;;
|
||||
;; In addition to testing patches using the three-way merge method, re-test conflicting patches with git apply
|
||||
;TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -2,6 +2,8 @@ THEME := themes/gitea
|
||||
PUBLIC := public
|
||||
ARCHIVE := https://dl.gitea.io/theme/master.tar.gz
|
||||
|
||||
HUGO_PACKAGE := github.com/gohugoio/hugo@v0.81.0
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
@ -11,19 +13,19 @@ clean:
|
||||
|
||||
.PHONY: trans-copy
|
||||
trans-copy:
|
||||
@bash scripts/trans-copy
|
||||
bash scripts/trans-copy.sh
|
||||
|
||||
.PHONY: server
|
||||
server: $(THEME)
|
||||
hugo server
|
||||
go run $(HUGO_PACKAGE) server
|
||||
|
||||
.PHONY: build
|
||||
build: $(THEME)
|
||||
hugo --cleanDestinationDir
|
||||
go run $(HUGO_PACKAGE) --cleanDestinationDir
|
||||
|
||||
.PHONY: build-offline
|
||||
build-offline: $(THEME)
|
||||
hugo --baseURL="/" --cleanDestinationDir
|
||||
go run $(HUGO_PACKAGE) --baseURL="/" --cleanDestinationDir
|
||||
|
||||
.PHONY: update
|
||||
update: $(THEME)
|
||||
|
@ -134,6 +134,7 @@ In addition there is _`StaticRootPath`_ which can be set as a built-in at build
|
||||
- `DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY`: **true**: In default merge messages only include approvers who are officially allowed to review.
|
||||
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request.
|
||||
- `ADD_CO_COMMITTER_TRAILERS`: **true**: Add co-authored-by and co-committed-by trailers to merge commit messages if committer does not match author.
|
||||
- `TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY`: **false**: PR patches are tested using a three-way merge method to discover if there are conflicts. If this setting is set to **true**, conflicting patches will be retested using `git apply` - This was the previous behaviour in 1.18 (and earlier) but is somewhat inefficient. Please report if you find that this setting is required.
|
||||
|
||||
### Repository - Issue (`repository.issue`)
|
||||
|
||||
|
@ -82,7 +82,7 @@ services:
|
||||
restart: always
|
||||
volumes:
|
||||
- ./data:/var/lib/gitea
|
||||
- ./config:/etc/gitea
|
||||
- ./config:/etc/gitea
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
@ -112,7 +112,7 @@ services:
|
||||
restart: always
|
||||
volumes:
|
||||
- ./data:/var/lib/gitea
|
||||
- ./config:/etc/gitea
|
||||
- ./config:/etc/gitea
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
@ -153,7 +153,7 @@ services:
|
||||
restart: always
|
||||
volumes:
|
||||
- ./data:/var/lib/gitea
|
||||
- ./config:/etc/gitea
|
||||
- ./config:/etc/gitea
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
@ -293,13 +293,13 @@ These environment variables can be passed to the docker container in `docker-com
|
||||
services:
|
||||
server:
|
||||
environment:
|
||||
- GITEA__mailer__ENABLED=true
|
||||
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
||||
- GITEA__mailer__MAILER_TYPE=smtp
|
||||
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
||||
- GITEA__mailer__IS_TLS_ENABLED=true
|
||||
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
||||
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
||||
- GITEA__mailer__ENABLED=true
|
||||
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
||||
- GITEA__mailer__MAILER_TYPE=smtp
|
||||
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
||||
- GITEA__mailer__IS_TLS_ENABLED=true
|
||||
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
||||
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
||||
```
|
||||
|
||||
To set required TOKEN and SECRET values, consider using Gitea's built-in [generate utility functions](https://docs.gitea.io/en-us/command-line/#generate).
|
||||
|
@ -117,11 +117,11 @@ services:
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
+ - GITEA__database__DB_TYPE=mysql
|
||||
+ - GITEA__database__HOST=db:3306
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
+ - GITEA__database__DB_TYPE=mysql
|
||||
+ - GITEA__database__HOST=db:3306
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
restart: always
|
||||
networks:
|
||||
- gitea
|
||||
@ -168,11 +168,11 @@ services:
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
+ - GITEA__database__DB_TYPE=postgres
|
||||
+ - GITEA__database__HOST=db:5432
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
+ - GITEA__database__DB_TYPE=postgres
|
||||
+ - GITEA__database__HOST=db:5432
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
restart: always
|
||||
networks:
|
||||
- gitea
|
||||
@ -225,8 +225,8 @@ services:
|
||||
networks:
|
||||
- gitea
|
||||
volumes:
|
||||
- - ./gitea:/data
|
||||
+ - gitea:/data
|
||||
- - ./gitea:/data
|
||||
+ - gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
@ -294,13 +294,13 @@ These environment variables can be passed to the docker container in `docker-com
|
||||
services:
|
||||
server:
|
||||
environment:
|
||||
- GITEA__mailer__ENABLED=true
|
||||
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
||||
- GITEA__mailer__MAILER_TYPE=smtp
|
||||
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
||||
- GITEA__mailer__IS_TLS_ENABLED=true
|
||||
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
||||
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
||||
- GITEA__mailer__ENABLED=true
|
||||
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
||||
- GITEA__mailer__MAILER_TYPE=smtp
|
||||
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
||||
- GITEA__mailer__IS_TLS_ENABLED=true
|
||||
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
||||
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
||||
```
|
||||
|
||||
Gitea will generate new secrets/tokens for every new installation automatically and write them into the app.ini. If you want to set the secrets/tokens manually, you can use the following docker commands to use of Gitea's built-in [generate utility functions](https://docs.gitea.io/en-us/command-line/#generate). Do not lose/change your SECRET_KEY after the installation, otherwise the encrypted data can not be decrypted anymore.
|
||||
|
@ -103,11 +103,11 @@ services:
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
+ - GITEA__database__DB_TYPE=mysql
|
||||
+ - GITEA__database__HOST=db:3306
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
+ - GITEA__database__DB_TYPE=mysql
|
||||
+ - GITEA__database__HOST=db:3306
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
restart: always
|
||||
networks:
|
||||
- gitea
|
||||
@ -153,11 +153,11 @@ services:
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
+ - GITEA__database__DB_TYPE=postgres
|
||||
+ - GITEA__database__HOST=db:5432
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
+ - GITEA__database__DB_TYPE=postgres
|
||||
+ - GITEA__database__HOST=db:5432
|
||||
+ - GITEA__database__NAME=gitea
|
||||
+ - GITEA__database__USER=gitea
|
||||
+ - GITEA__database__PASSWD=gitea
|
||||
restart: always
|
||||
networks:
|
||||
- gitea
|
||||
@ -207,8 +207,8 @@ services:
|
||||
networks:
|
||||
- gitea
|
||||
volumes:
|
||||
- - ./gitea:/data
|
||||
+ - gitea:/data
|
||||
- - ./gitea:/data
|
||||
+ - gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
@ -285,13 +285,13 @@ docker-compose up -d
|
||||
services:
|
||||
server:
|
||||
environment:
|
||||
- GITEA__mailer__ENABLED=true
|
||||
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
||||
- GITEA__mailer__MAILER_TYPE=smtp
|
||||
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
||||
- GITEA__mailer__IS_TLS_ENABLED=true
|
||||
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
||||
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
||||
- GITEA__mailer__ENABLED=true
|
||||
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
||||
- GITEA__mailer__MAILER_TYPE=smtp
|
||||
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
||||
- GITEA__mailer__IS_TLS_ENABLED=true
|
||||
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
||||
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
||||
```
|
||||
|
||||
Gitea 将为每次新安装自动生成新的 `SECRET_KEY` 并将它们写入 `app.ini`。 如果您想手动设置 `SECRET_KEY`,您可以使用以下 docker 命令来使用 Gitea 内置的[方法](https://docs.gitea.io/en-us/command-line/#generate)生成 `SECRET_KEY`。 安装后请妥善保管您的 `SECRET_KEY`,如若丢失则无法解密已加密的数据。
|
||||
|
36
docs/content/doc/secrets/overview.en-us.md
Normal file
36
docs/content/doc/secrets/overview.en-us.md
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
date: "2022-12-19T21:26:00+08:00"
|
||||
title: "Encrypted secrets"
|
||||
slug: "secrets/overview"
|
||||
draft: false
|
||||
toc: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "secrets"
|
||||
name: "Overview"
|
||||
weight: 1
|
||||
identifier: "overview"
|
||||
---
|
||||
|
||||
# Encrypted secrets
|
||||
|
||||
Encrypted secrets allow you to store sensitive information in your organization or repository.
|
||||
Secrets are available on Gitea 1.19+.
|
||||
|
||||
# Naming your secrets
|
||||
|
||||
The following rules apply to secret names:
|
||||
|
||||
Secret names can only contain alphanumeric characters (`[a-z]`, `[A-Z]`, `[0-9]`) or underscores (`_`). Spaces are not allowed.
|
||||
|
||||
Secret names must not start with the `GITHUB_` and `GITEA_` prefix.
|
||||
|
||||
Secret names must not start with a number.
|
||||
|
||||
Secret names are not case-sensitive.
|
||||
|
||||
Secret names must be unique at the level they are created at.
|
||||
|
||||
For example, a secret created at the repository level must have a unique name in that repository, and a secret created at the organization level must have a unique name at that level.
|
||||
|
||||
If a secret with the same name exists at multiple levels, the secret at the lowest level takes precedence. For example, if an organization-level secret has the same name as a repository-level secret, then the repository-level secret takes precedence.
|
@ -26,7 +26,6 @@ for SOURCE in $(find ${ROOT}/content -type f -iname *.en-us.md); do
|
||||
DEST="${SOURCE%.en-us.md}.${LOCALE}.md"
|
||||
|
||||
if [[ ! -f ${DEST} ]]; then
|
||||
echo "Creating fallback for ${DEST#${ROOT}/content/}"
|
||||
cp ${SOURCE} ${DEST}
|
||||
sed -i.bak "s/en\-us/${LOCALE}/g" ${DEST}
|
||||
rm ${DEST}.bak
|
22
go.mod
22
go.mod
@ -17,8 +17,8 @@ require (
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/PuerkitoBio/goquery v1.8.0
|
||||
github.com/alecthomas/chroma/v2 v2.4.0
|
||||
github.com/blevesearch/bleve/v2 v2.3.4
|
||||
github.com/bufbuild/connect-go v1.3.1
|
||||
github.com/blevesearch/bleve/v2 v2.3.5
|
||||
github.com/buildkite/terminal-to-html/v3 v3.7.0
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/chi-middleware/proxy v1.1.1
|
||||
@ -135,21 +135,21 @@ require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.3.3 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.0.3 // indirect
|
||||
github.com/blevesearch/geo v0.1.14 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.0.4 // indirect
|
||||
github.com/blevesearch/geo v0.1.15 // indirect
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||
github.com/blevesearch/gtreap v0.1.1 // indirect
|
||||
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.2 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.3 // indirect
|
||||
github.com/blevesearch/segment v0.9.0 // indirect
|
||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
|
||||
github.com/blevesearch/vellum v1.0.8 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.3.5 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.3.5 // indirect
|
||||
github.com/blevesearch/vellum v1.0.9 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.3.6 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.3.6 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.3.6 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.3.6 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.3.6 // indirect
|
||||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||
@ -315,6 +315,8 @@ replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142
|
||||
|
||||
replace github.com/satori/go.uuid v1.2.0 => github.com/gofrs/uuid v4.2.0+incompatible
|
||||
|
||||
replace github.com/blevesearch/zapx/v15 v15.3.6 => github.com/zeripath/zapx/v15 v15.3.6-alignment-fix
|
||||
|
||||
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||
|
||||
exclude github.com/gofrs/uuid v4.0.0+incompatible
|
||||
|
45
go.sum
45
go.sum
@ -153,7 +153,6 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
|
||||
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||
github.com/RoaringBitmap/roaring v1.2.1 h1:58/LJlg/81wfEHd5L9qsHduznOIhyv4qb1yWcSvVq9A=
|
||||
github.com/RoaringBitmap/roaring v1.2.1/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
@ -230,52 +229,47 @@ github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
|
||||
github.com/blevesearch/bleve/v2 v2.3.4 h1:SSb7/cwGzo85LWX1jchIsXM8ZiNNMX3shT5lROM63ew=
|
||||
github.com/blevesearch/bleve/v2 v2.3.4/go.mod h1:Ot0zYum8XQRfPcwhae8bZmNyYubynsoMjVvl1jPqL30=
|
||||
github.com/blevesearch/bleve/v2 v2.3.5 h1:1wuR7eB8Fk9UaCaBUfnQt5V7zIpi4VDok9ExN7Rl+/8=
|
||||
github.com/blevesearch/bleve/v2 v2.3.5/go.mod h1:FneKGHMRrCLrp4X9+iy3wlBqgM2ALucg7bp8jUuAi/s=
|
||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/bleve_index_api v1.0.3 h1:DDSWaPXOZZJ2BB73ZTWjKxydAugjwywcqU+91AAqcAg=
|
||||
github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/geo v0.1.13/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
|
||||
github.com/blevesearch/geo v0.1.14 h1:TTDpJN6l9ck/cUYbXSn4aCElNls0Whe44rcQKsB7EfU=
|
||||
github.com/blevesearch/geo v0.1.14/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
|
||||
github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A=
|
||||
github.com/blevesearch/bleve_index_api v1.0.4 h1:mtlzsyJjMIlDngqqB1mq8kPryUMIuEVVbRbJHOWEexU=
|
||||
github.com/blevesearch/bleve_index_api v1.0.4/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms=
|
||||
github.com/blevesearch/geo v0.1.15 h1:0NybEduqE5fduFRYiUKF0uqybAIFKXYjkBdXKYn7oA4=
|
||||
github.com/blevesearch/geo v0.1.15/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||
github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ=
|
||||
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
||||
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
||||
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
|
||||
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.2 h1:TAte9VZLWda5WAVlZTTZ+GCzEHqGJb4iB2aiZSA6Iv8=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.2/go.mod h1:rvoQXZGq8drq7vXbNeyiRzdEOwZkjkiYGf1822i6CRA=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.3 h1:2UzpR2dR5DvSZk8tVJkcQ7D5xhoK/UBelYw8ttBHrRQ=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.3/go.mod h1:eZrfp1y+lUh+DzFjUcTBUSnKGuunyFIpBIvqYVzJfvc=
|
||||
github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac=
|
||||
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
||||
github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg=
|
||||
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
|
||||
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.1 h1:1SYRwyoFLwG3sj0ed89RLtM15amfX2pXlYbFOnF8zNU=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
|
||||
github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo=
|
||||
github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRvNBlNMrEVgY=
|
||||
github.com/blevesearch/vellum v1.0.8 h1:iMGh4lfxza4BnWO/UJTMPlI3HsK9YawjPv+TteVa9ck=
|
||||
github.com/blevesearch/vellum v1.0.8/go.mod h1:+cpRi/tqq49xUYSQN2P7A5zNSNrS+MscLeeaZ3J46UA=
|
||||
github.com/blevesearch/vellum v1.0.9 h1:PL+NWVk3dDGPCV0hoDu9XLLJgqU4E5s/dOeEJByQ2uQ=
|
||||
github.com/blevesearch/vellum v1.0.9/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k=
|
||||
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
||||
github.com/blevesearch/zapx/v11 v11.3.5 h1:eBQWQ7huA+mzm0sAGnZDwgGGli7S45EO+N+ObFWssbI=
|
||||
github.com/blevesearch/zapx/v11 v11.3.5/go.mod h1:5UdIa/HRMdeRCiLQOyFESsnqBGiip7vQmYReA9toevU=
|
||||
github.com/blevesearch/zapx/v11 v11.3.6 h1:50jET4HUJ6eCqGxdhUt+mjybMvEX2MWyqLGtCx3yUgc=
|
||||
github.com/blevesearch/zapx/v11 v11.3.6/go.mod h1:B0CzJRj/pS7hJIroflRtFsa9mRHpMSucSgre0FVINns=
|
||||
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
||||
github.com/blevesearch/zapx/v12 v12.3.5 h1:5pX2hU+R1aZihT7ac1dNWh1n4wqkIM9pZzWp0ANED9s=
|
||||
github.com/blevesearch/zapx/v12 v12.3.5/go.mod h1:ANcthYRZQycpbRut/6ArF5gP5HxQyJqiFcuJCBju/ss=
|
||||
github.com/blevesearch/zapx/v12 v12.3.6 h1:G304NHBLgQeZ+IHK/XRCM0nhHqAts8MEvHI6LhoDNM4=
|
||||
github.com/blevesearch/zapx/v12 v12.3.6/go.mod h1:iYi7tIKpauwU5os5wTxJITixr5Km21Hl365otMwdaP0=
|
||||
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
||||
github.com/blevesearch/zapx/v13 v13.3.5 h1:eJ3gbD+Nu8p36/O6lhfdvWQ4pxsGYSuTOBrLLPVWJ74=
|
||||
github.com/blevesearch/zapx/v13 v13.3.5/go.mod h1:FV+dRnScFgKnRDIp08RQL4JhVXt1x2HE3AOzqYa6fjo=
|
||||
github.com/blevesearch/zapx/v13 v13.3.6 h1:vavltQHNdjQezhLZs5nIakf+w/uOa1oqZxB58Jy/3Ig=
|
||||
github.com/blevesearch/zapx/v13 v13.3.6/go.mod h1:X+FsTwCU8qOHtK0d/ArvbOH7qiIgViSQ1GQvcR6LSkI=
|
||||
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
||||
github.com/blevesearch/zapx/v14 v14.3.5 h1:hEvVjZaagFCvOUJrlFQ6/Z6Jjy0opM3g7TMEo58TwP4=
|
||||
github.com/blevesearch/zapx/v14 v14.3.5/go.mod h1:954A/eKFb+pg/ncIYWLWCKY+mIjReM9FGTGIO2Wu1cU=
|
||||
github.com/blevesearch/zapx/v14 v14.3.6 h1:b9lub7TvcwUyJxK/cQtnN79abngKxsI7zMZnICU0WhE=
|
||||
github.com/blevesearch/zapx/v14 v14.3.6/go.mod h1:9X8W3XoikagU0rwcTqwZho7p9cC7m7zhPZO94S4wUvM=
|
||||
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
||||
github.com/blevesearch/zapx/v15 v15.3.5 h1:NVD0qq8vRk66ImJn1KloXT5ckqPDUZT7VbVJs9jKlac=
|
||||
github.com/blevesearch/zapx/v15 v15.3.5/go.mod h1:QMUh2hXCaYIWFKPYGavq/Iga2zbHWZ9DZAa9uFbWyvg=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
@ -368,7 +362,6 @@ github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFl
|
||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 h1:4KDlx3vjalrHD/EfsjCpV91HNX3JPaIqRtt83zZ7x+Y=
|
||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
|
||||
github.com/couchbase/moss v0.2.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
@ -1514,6 +1507,8 @@ github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87/go.m
|
||||
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
|
||||
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
github.com/zeripath/zapx/v15 v15.3.6-alignment-fix h1:fKZ9OxEDoJKgM0KBXRbSb5IgKUEXis6C3zEIiMtzzQ0=
|
||||
github.com/zeripath/zapx/v15 v15.3.6-alignment-fix/go.mod h1:5DbhhDTGtuQSns1tS2aJxJLPc91boXCvjOMeCLD1saM=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
|
||||
github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is=
|
||||
|
@ -443,6 +443,8 @@ var migrations = []Migration{
|
||||
// v235 -> v236
|
||||
NewMigration("Add index for access_token", v1_19.AddIndexForAccessToken),
|
||||
// v236 -> v237
|
||||
NewMigration("Create secrets table", v1_19.CreateSecretsTable),
|
||||
// v237 -> v238
|
||||
NewMigration("Add actions tables", v1_19.AddActionsTables),
|
||||
}
|
||||
|
||||
|
@ -4,173 +4,20 @@
|
||||
package v1_19 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddActionsTables(x *xorm.Engine) error {
|
||||
type ActionRunner struct {
|
||||
func CreateSecretsTable(x *xorm.Engine) error {
|
||||
type Secret struct {
|
||||
ID int64
|
||||
UUID string `xorm:"CHAR(36) UNIQUE"`
|
||||
Name string `xorm:"VARCHAR(32)"`
|
||||
OwnerID int64 `xorm:"index"` // org level runner, 0 means system
|
||||
RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global
|
||||
Description string `xorm:"TEXT"`
|
||||
Base int // 0 native 1 docker 2 virtual machine
|
||||
RepoRange string // glob match which repositories could use this runner
|
||||
|
||||
Token string `xorm:"-"`
|
||||
TokenHash string `xorm:"UNIQUE"` // sha256 of token
|
||||
TokenSalt string
|
||||
// TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token
|
||||
|
||||
LastOnline timeutil.TimeStamp `xorm:"index"`
|
||||
LastActive timeutil.TimeStamp `xorm:"index"`
|
||||
|
||||
// Store OS and Artch.
|
||||
AgentLabels []string
|
||||
// Store custom labes use defined.
|
||||
CustomLabels []string
|
||||
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
Deleted timeutil.TimeStamp `xorm:"deleted"`
|
||||
OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL"`
|
||||
RepoID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL DEFAULT 0"`
|
||||
Name string `xorm:"UNIQUE(owner_repo_name) NOT NULL"`
|
||||
Data string `xorm:"LONGTEXT"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
|
||||
}
|
||||
|
||||
type ActionRunnerToken struct {
|
||||
ID int64
|
||||
Token string `xorm:"UNIQUE"`
|
||||
OwnerID int64 `xorm:"index"` // org level runner, 0 means system
|
||||
RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global
|
||||
IsActive bool
|
||||
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
Deleted timeutil.TimeStamp `xorm:"deleted"`
|
||||
}
|
||||
|
||||
type ActionRun struct {
|
||||
ID int64
|
||||
Title string
|
||||
RepoID int64 `xorm:"index unique(repo_index)"`
|
||||
OwnerID int64 `xorm:"index"`
|
||||
WorkflowID string `xorm:"index"` // the name of workflow file
|
||||
Index int64 `xorm:"index unique(repo_index)"` // a unique number for each run of a repository
|
||||
TriggerUserID int64
|
||||
Ref string
|
||||
CommitSHA string
|
||||
Event string
|
||||
IsForkPullRequest bool
|
||||
EventPayload string `xorm:"LONGTEXT"`
|
||||
Status int `xorm:"index"`
|
||||
Started timeutil.TimeStamp
|
||||
Stopped timeutil.TimeStamp
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
type ActionRunJob struct {
|
||||
ID int64
|
||||
RunID int64 `xorm:"index"`
|
||||
RepoID int64 `xorm:"index"`
|
||||
OwnerID int64 `xorm:"index"`
|
||||
CommitSHA string `xorm:"index"`
|
||||
IsForkPullRequest bool
|
||||
Name string
|
||||
Attempt int64
|
||||
WorkflowPayload []byte
|
||||
JobID string // job id in workflow, not job's id
|
||||
Needs []string `xorm:"JSON TEXT"`
|
||||
RunsOn []string `xorm:"JSON TEXT"`
|
||||
TaskID int64 // the latest task of the job
|
||||
Status int `xorm:"index"`
|
||||
Started timeutil.TimeStamp
|
||||
Stopped timeutil.TimeStamp
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated index"`
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
NumRuns int `xorm:"NOT NULL DEFAULT 0"`
|
||||
NumClosedRuns int `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
type ActionRunIndex db.ResourceIndex
|
||||
|
||||
type ActionTask struct {
|
||||
ID int64
|
||||
JobID int64
|
||||
Attempt int64
|
||||
RunnerID int64 `xorm:"index"`
|
||||
Status int `xorm:"index"`
|
||||
Started timeutil.TimeStamp `xorm:"index"`
|
||||
Stopped timeutil.TimeStamp
|
||||
|
||||
RepoID int64 `xorm:"index"`
|
||||
OwnerID int64 `xorm:"index"`
|
||||
CommitSHA string `xorm:"index"`
|
||||
IsForkPullRequest bool
|
||||
|
||||
TokenHash string `xorm:"UNIQUE"` // sha256 of token
|
||||
TokenSalt string
|
||||
TokenLastEight string `xorm:"index token_last_eight"`
|
||||
|
||||
LogFilename string // file name of log
|
||||
LogInStorage bool // read log from database or from storage
|
||||
LogLength int64 // lines count
|
||||
LogSize int64 // blob size
|
||||
LogIndexes *[]int64 `xorm:"LONGBLOB"` // line number to offset
|
||||
LogExpired bool // files that are too old will be deleted
|
||||
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated index"`
|
||||
}
|
||||
|
||||
type ActionTaskStep struct {
|
||||
ID int64
|
||||
Name string
|
||||
TaskID int64 `xorm:"index unique(task_number)"`
|
||||
Number int64 `xorm:"index unique(task_number)"`
|
||||
RepoID int64 `xorm:"index"`
|
||||
Status int `xorm:"index"`
|
||||
LogIndex int64
|
||||
LogLength int64
|
||||
Started timeutil.TimeStamp
|
||||
Stopped timeutil.TimeStamp
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
type dbfsMeta struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
FullPath string `xorm:"VARCHAR(500) UNIQUE NOT NULL"`
|
||||
BlockSize int64 `xorm:"BIGINT NOT NULL"`
|
||||
FileSize int64 `xorm:"BIGINT NOT NULL"`
|
||||
CreateTimestamp int64 `xorm:"BIGINT NOT NULL"`
|
||||
ModifyTimestamp int64 `xorm:"BIGINT NOT NULL"`
|
||||
}
|
||||
|
||||
type dbfsData struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Revision int64 `xorm:"BIGINT NOT NULL"`
|
||||
MetaID int64 `xorm:"BIGINT index(meta_offset) NOT NULL"`
|
||||
BlobOffset int64 `xorm:"BIGINT index(meta_offset) NOT NULL"`
|
||||
BlobSize int64 `xorm:"BIGINT NOT NULL"`
|
||||
BlobData []byte `xorm:"BLOB NOT NULL"`
|
||||
}
|
||||
|
||||
return x.Sync(
|
||||
new(ActionRunner),
|
||||
new(ActionRunnerToken),
|
||||
new(ActionRun),
|
||||
new(ActionRunJob),
|
||||
new(Repository),
|
||||
new(ActionRunIndex),
|
||||
new(ActionTask),
|
||||
new(ActionTaskStep),
|
||||
new(dbfsMeta),
|
||||
new(dbfsData),
|
||||
)
|
||||
return x.Sync(new(Secret))
|
||||
}
|
||||
|
177
models/migrations/v1_19/v237.go
Normal file
177
models/migrations/v1_19/v237.go
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_19 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddActionsTables(x *xorm.Engine) error {
|
||||
type ActionRunner struct {
|
||||
ID int64
|
||||
UUID string `xorm:"CHAR(36) UNIQUE"`
|
||||
Name string `xorm:"VARCHAR(32)"`
|
||||
OwnerID int64 `xorm:"index"` // org level runner, 0 means system
|
||||
RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global
|
||||
Description string `xorm:"TEXT"`
|
||||
Base int // 0 native 1 docker 2 virtual machine
|
||||
RepoRange string // glob match which repositories could use this runner
|
||||
|
||||
Token string `xorm:"-"`
|
||||
TokenHash string `xorm:"UNIQUE"` // sha256 of token
|
||||
TokenSalt string
|
||||
// TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token
|
||||
|
||||
LastOnline timeutil.TimeStamp `xorm:"index"`
|
||||
LastActive timeutil.TimeStamp `xorm:"index"`
|
||||
|
||||
// Store OS and Artch.
|
||||
AgentLabels []string
|
||||
// Store custom labes use defined.
|
||||
CustomLabels []string
|
||||
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
Deleted timeutil.TimeStamp `xorm:"deleted"`
|
||||
}
|
||||
|
||||
type ActionRunnerToken struct {
|
||||
ID int64
|
||||
Token string `xorm:"UNIQUE"`
|
||||
OwnerID int64 `xorm:"index"` // org level runner, 0 means system
|
||||
RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global
|
||||
IsActive bool
|
||||
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
Deleted timeutil.TimeStamp `xorm:"deleted"`
|
||||
}
|
||||
|
||||
type ActionRun struct {
|
||||
ID int64
|
||||
Title string
|
||||
RepoID int64 `xorm:"index unique(repo_index)"`
|
||||
OwnerID int64 `xorm:"index"`
|
||||
WorkflowID string `xorm:"index"` // the name of workflow file
|
||||
Index int64 `xorm:"index unique(repo_index)"` // a unique number for each run of a repository
|
||||
TriggerUserID int64
|
||||
Ref string
|
||||
CommitSHA string
|
||||
Event string
|
||||
IsForkPullRequest bool
|
||||
EventPayload string `xorm:"LONGTEXT"`
|
||||
Status int `xorm:"index"`
|
||||
Started timeutil.TimeStamp
|
||||
Stopped timeutil.TimeStamp
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
type ActionRunJob struct {
|
||||
ID int64
|
||||
RunID int64 `xorm:"index"`
|
||||
RepoID int64 `xorm:"index"`
|
||||
OwnerID int64 `xorm:"index"`
|
||||
CommitSHA string `xorm:"index"`
|
||||
IsForkPullRequest bool
|
||||
Name string
|
||||
Attempt int64
|
||||
WorkflowPayload []byte
|
||||
JobID string // job id in workflow, not job's id
|
||||
Needs []string `xorm:"JSON TEXT"`
|
||||
RunsOn []string `xorm:"JSON TEXT"`
|
||||
TaskID int64 // the latest task of the job
|
||||
Status int `xorm:"index"`
|
||||
Started timeutil.TimeStamp
|
||||
Stopped timeutil.TimeStamp
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated index"`
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
NumRuns int `xorm:"NOT NULL DEFAULT 0"`
|
||||
NumClosedRuns int `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
type ActionRunIndex db.ResourceIndex
|
||||
|
||||
type ActionTask struct {
|
||||
ID int64
|
||||
JobID int64
|
||||
Attempt int64
|
||||
RunnerID int64 `xorm:"index"`
|
||||
Status int `xorm:"index"`
|
||||
Started timeutil.TimeStamp `xorm:"index"`
|
||||
Stopped timeutil.TimeStamp
|
||||
|
||||
RepoID int64 `xorm:"index"`
|
||||
OwnerID int64 `xorm:"index"`
|
||||
CommitSHA string `xorm:"index"`
|
||||
IsForkPullRequest bool
|
||||
|
||||
TokenHash string `xorm:"UNIQUE"` // sha256 of token
|
||||
TokenSalt string
|
||||
TokenLastEight string `xorm:"index token_last_eight"`
|
||||
|
||||
LogFilename string // file name of log
|
||||
LogInStorage bool // read log from database or from storage
|
||||
LogLength int64 // lines count
|
||||
LogSize int64 // blob size
|
||||
LogIndexes *[]int64 `xorm:"LONGBLOB"` // line number to offset
|
||||
LogExpired bool // files that are too old will be deleted
|
||||
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated index"`
|
||||
}
|
||||
|
||||
type ActionTaskStep struct {
|
||||
ID int64
|
||||
Name string
|
||||
TaskID int64 `xorm:"index unique(task_number)"`
|
||||
Number int64 `xorm:"index unique(task_number)"`
|
||||
RepoID int64 `xorm:"index"`
|
||||
Status int `xorm:"index"`
|
||||
LogIndex int64
|
||||
LogLength int64
|
||||
Started timeutil.TimeStamp
|
||||
Stopped timeutil.TimeStamp
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
type dbfsMeta struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
FullPath string `xorm:"VARCHAR(500) UNIQUE NOT NULL"`
|
||||
BlockSize int64 `xorm:"BIGINT NOT NULL"`
|
||||
FileSize int64 `xorm:"BIGINT NOT NULL"`
|
||||
CreateTimestamp int64 `xorm:"BIGINT NOT NULL"`
|
||||
ModifyTimestamp int64 `xorm:"BIGINT NOT NULL"`
|
||||
}
|
||||
|
||||
type dbfsData struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Revision int64 `xorm:"BIGINT NOT NULL"`
|
||||
MetaID int64 `xorm:"BIGINT index(meta_offset) NOT NULL"`
|
||||
BlobOffset int64 `xorm:"BIGINT index(meta_offset) NOT NULL"`
|
||||
BlobSize int64 `xorm:"BIGINT NOT NULL"`
|
||||
BlobData []byte `xorm:"BLOB NOT NULL"`
|
||||
}
|
||||
|
||||
return x.Sync(
|
||||
new(ActionRunner),
|
||||
new(ActionRunnerToken),
|
||||
new(ActionRun),
|
||||
new(ActionRunJob),
|
||||
new(Repository),
|
||||
new(ActionRunIndex),
|
||||
new(ActionTask),
|
||||
new(ActionTaskStep),
|
||||
new(dbfsMeta),
|
||||
new(dbfsData),
|
||||
)
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@ -370,6 +371,7 @@ func DeleteOrganization(ctx context.Context, org *Organization) error {
|
||||
&TeamUser{OrgID: org.ID},
|
||||
&TeamUnit{OrgID: org.ID},
|
||||
&TeamInvite{OrgID: org.ID},
|
||||
&secret_model.Secret{OwnerID: org.ID},
|
||||
); err != nil {
|
||||
return fmt.Errorf("DeleteBeans: %w", err)
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
@ -150,6 +151,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
||||
&admin_model.Task{RepoID: repoID},
|
||||
&repo_model.Watch{RepoID: repoID},
|
||||
&webhook.Webhook{RepoID: repoID},
|
||||
&secret_model.Secret{RepoID: repoID},
|
||||
); err != nil {
|
||||
return fmt.Errorf("deleteBeans: %w", err)
|
||||
}
|
||||
|
124
models/secret/secret.go
Normal file
124
models/secret/secret.go
Normal file
@ -0,0 +1,124 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package secret
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
secret_module "code.gitea.io/gitea/modules/secret"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
type ErrSecretInvalidValue struct {
|
||||
Name *string
|
||||
Data *string
|
||||
}
|
||||
|
||||
func (err ErrSecretInvalidValue) Error() string {
|
||||
if err.Name != nil {
|
||||
return fmt.Sprintf("secret name %q is invalid", *err.Name)
|
||||
}
|
||||
if err.Data != nil {
|
||||
return fmt.Sprintf("secret data %q is invalid", *err.Data)
|
||||
}
|
||||
return util.ErrInvalidArgument.Error()
|
||||
}
|
||||
|
||||
func (err ErrSecretInvalidValue) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// Secret represents a secret
|
||||
type Secret struct {
|
||||
ID int64
|
||||
OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL"`
|
||||
RepoID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL DEFAULT 0"`
|
||||
Name string `xorm:"UNIQUE(owner_repo_name) NOT NULL"`
|
||||
Data string `xorm:"LONGTEXT"` // encrypted data
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
|
||||
}
|
||||
|
||||
// newSecret Creates a new already encrypted secret
|
||||
func newSecret(ownerID, repoID int64, name, data string) *Secret {
|
||||
return &Secret{
|
||||
OwnerID: ownerID,
|
||||
RepoID: repoID,
|
||||
Name: strings.ToUpper(name),
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// InsertEncryptedSecret Creates, encrypts, and validates a new secret with yet unencrypted data and insert into database
|
||||
func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*Secret, error) {
|
||||
encrypted, err := secret_module.EncryptSecret(setting.SecretKey, strings.TrimSpace(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secret := newSecret(ownerID, repoID, name, encrypted)
|
||||
if err := secret.Validate(); err != nil {
|
||||
return secret, err
|
||||
}
|
||||
return secret, db.Insert(ctx, secret)
|
||||
}
|
||||
|
||||
func init() {
|
||||
db.RegisterModel(new(Secret))
|
||||
}
|
||||
|
||||
var (
|
||||
secretNameReg = regexp.MustCompile("^[A-Z_][A-Z0-9_]*$")
|
||||
forbiddenSecretPrefixReg = regexp.MustCompile("^GIT(EA|HUB)_")
|
||||
)
|
||||
|
||||
// Validate validates the required fields and formats.
|
||||
func (s *Secret) Validate() error {
|
||||
switch {
|
||||
case len(s.Name) == 0 || len(s.Name) > 50:
|
||||
return ErrSecretInvalidValue{Name: &s.Name}
|
||||
case len(s.Data) == 0:
|
||||
return ErrSecretInvalidValue{Data: &s.Data}
|
||||
case !secretNameReg.MatchString(s.Name) ||
|
||||
forbiddenSecretPrefixReg.MatchString(s.Name):
|
||||
return ErrSecretInvalidValue{Name: &s.Name}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type FindSecretsOptions struct {
|
||||
db.ListOptions
|
||||
OwnerID int64
|
||||
RepoID int64
|
||||
}
|
||||
|
||||
func (opts *FindSecretsOptions) toConds() builder.Cond {
|
||||
cond := builder.NewCond()
|
||||
if opts.OwnerID > 0 {
|
||||
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
|
||||
}
|
||||
if opts.RepoID > 0 {
|
||||
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
|
||||
}
|
||||
|
||||
return cond
|
||||
}
|
||||
|
||||
func FindSecrets(ctx context.Context, opts FindSecretsOptions) ([]*Secret, error) {
|
||||
var secrets []*Secret
|
||||
sess := db.GetEngine(ctx)
|
||||
if opts.PageSize != 0 {
|
||||
sess = db.SetSessionPagination(sess, &opts.ListOptions)
|
||||
}
|
||||
return secrets, sess.
|
||||
Where(opts.toConds()).
|
||||
Find(&secrets)
|
||||
}
|
@ -5,8 +5,10 @@ package nuget
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@ -182,7 +184,23 @@ func ParseNuspecMetaData(r io.Reader) (*Package, error) {
|
||||
return &Package{
|
||||
PackageType: packageType,
|
||||
ID: p.Metadata.ID,
|
||||
Version: v.String(),
|
||||
Version: toNormalizedVersion(v),
|
||||
Metadata: m,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#normalized-version-numbers
|
||||
// https://github.com/NuGet/NuGet.Client/blob/dccbd304b11103e08b97abf4cf4bcc1499d9235a/src/NuGet.Core/NuGet.Versioning/VersionFormatter.cs#L121
|
||||
func toNormalizedVersion(v *version.Version) string {
|
||||
var buf bytes.Buffer
|
||||
segments := v.Segments64()
|
||||
fmt.Fprintf(&buf, "%d.%d.%d", segments[0], segments[1], segments[2])
|
||||
if len(segments) > 3 && segments[3] > 0 {
|
||||
fmt.Fprintf(&buf, ".%d", segments[3])
|
||||
}
|
||||
pre := v.Prerelease()
|
||||
if pre != "" {
|
||||
fmt.Fprint(&buf, "-", pre)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -146,6 +146,19 @@ func TestParseNuspecMetaData(t *testing.T) {
|
||||
assert.Len(t, deps, 1)
|
||||
assert.Equal(t, dependencyID, deps[0].ID)
|
||||
assert.Equal(t, dependencyVersion, deps[0].Version)
|
||||
|
||||
t.Run("NormalizedVersion", func(t *testing.T) {
|
||||
np, err := ParseNuspecMetaData(strings.NewReader(`<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>test</id>
|
||||
<version>1.04.5.2.5-rc.1+metadata</version>
|
||||
</metadata>
|
||||
</package>`))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, np)
|
||||
assert.Equal(t, "1.4.5.2-rc.1", np.Version)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Symbols Package", func(t *testing.T) {
|
||||
|
@ -82,6 +82,7 @@ var (
|
||||
DefaultMergeMessageOfficialApproversOnly bool
|
||||
PopulateSquashCommentWithCommitMessages bool
|
||||
AddCoCommitterTrailers bool
|
||||
TestConflictingPatchesWithGitApply bool
|
||||
} `ini:"repository.pull-request"`
|
||||
|
||||
// Issue Setting
|
||||
@ -204,6 +205,7 @@ var (
|
||||
DefaultMergeMessageOfficialApproversOnly bool
|
||||
PopulateSquashCommentWithCommitMessages bool
|
||||
AddCoCommitterTrailers bool
|
||||
TestConflictingPatchesWithGitApply bool
|
||||
}{
|
||||
WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
|
||||
// Same as GitHub. See
|
||||
|
@ -12,8 +12,13 @@ import (
|
||||
// TimeStamp defines a timestamp
|
||||
type TimeStamp int64
|
||||
|
||||
// mock is NOT concurrency-safe!!
|
||||
var mock time.Time
|
||||
var (
|
||||
// mock is NOT concurrency-safe!!
|
||||
mock time.Time
|
||||
|
||||
// Used for IsZero, to check if timestamp is the zero time instant.
|
||||
timeZeroUnix = time.Time{}.Unix()
|
||||
)
|
||||
|
||||
// Set sets the time to a mocked time.Time
|
||||
func Set(now time.Time) {
|
||||
@ -102,5 +107,5 @@ func (ts TimeStamp) FormatDate() string {
|
||||
|
||||
// IsZero is zero time
|
||||
func (ts TimeStamp) IsZero() bool {
|
||||
return int64(ts) == 0
|
||||
return int64(ts) == 0 || int64(ts) == timeZeroUnix
|
||||
}
|
||||
|
@ -2300,6 +2300,8 @@ release.downloads = Downloads
|
||||
release.download_count = Downloads: %s
|
||||
release.add_tag_msg = Use the title and content of release as tag message.
|
||||
release.add_tag = Create Tag Only
|
||||
release.releases_for = Releases for %s
|
||||
release.tags_for = Tags for %s
|
||||
|
||||
branch.name = Branch Name
|
||||
branch.search = Search branches
|
||||
@ -3263,3 +3265,19 @@ owner.settings.cleanuprules.remove.days = Remove versions older than
|
||||
owner.settings.cleanuprules.remove.pattern = Remove versions matching
|
||||
owner.settings.cleanuprules.success.update = Cleanup rule has been updated.
|
||||
owner.settings.cleanuprules.success.delete = Cleanup rule has been deleted.
|
||||
|
||||
[secrets]
|
||||
secrets = Secrets
|
||||
description = Secrets will be passed to certain actions and cannot be read otherwise.
|
||||
none = There are no secrets yet.
|
||||
value = Value
|
||||
name = Name
|
||||
creation = Add Secret
|
||||
creation.name_placeholder = case-insensitive, alphanumeric characters or underscores only, cannot start with GITEA_ or GITHUB_
|
||||
creation.value_placeholder = Input any content. Whitespace at the start and end will be omitted.
|
||||
creation.success = The secret '%s' has been added.
|
||||
creation.failed = Failed to add secret.
|
||||
deletion = Remove secret
|
||||
deletion.description = Removing a secret will revoke its access to repositories. Continue?
|
||||
deletion.success = The secret has been removed.
|
||||
deletion.failed = Failed to remove secret.
|
||||
|
2734
package-lock.json
generated
2734
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@ -13,25 +13,25 @@
|
||||
"@citation-js/plugin-software-formats": "0.6.0",
|
||||
"@claviska/jquery-minicolors": "2.3.6",
|
||||
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
|
||||
"@primer/octicons": "17.9.0",
|
||||
"@primer/octicons": "17.10.0",
|
||||
"@vue/compiler-sfc": "3.2.45",
|
||||
"add-asset-webpack-plugin": "2.0.1",
|
||||
"ansi-to-html": "0.7.2",
|
||||
"css-loader": "6.7.2",
|
||||
"css-loader": "6.7.3",
|
||||
"dropzone": "6.0.0-beta.2",
|
||||
"easymde": "2.18.0",
|
||||
"esbuild-loader": "2.20.0",
|
||||
"escape-goat": "4.0.0",
|
||||
"fast-glob": "3.2.12",
|
||||
"font-awesome": "4.7.0",
|
||||
"jquery": "3.6.1",
|
||||
"jquery": "3.6.2",
|
||||
"jquery.are-you-sure": "1.9.0",
|
||||
"katex": "0.16.3",
|
||||
"katex": "0.16.4",
|
||||
"less": "4.1.3",
|
||||
"less-loader": "11.1.0",
|
||||
"license-checker-webpack-plugin": "0.2.1",
|
||||
"mermaid": "9.2.2",
|
||||
"mini-css-extract-plugin": "2.7.0",
|
||||
"mermaid": "9.3.0",
|
||||
"mini-css-extract-plugin": "2.7.2",
|
||||
"monaco-editor": "0.34.1",
|
||||
"monaco-editor-webpack-plugin": "7.0.1",
|
||||
"pretty-ms": "8.0.0",
|
||||
@ -45,31 +45,31 @@
|
||||
"vue-loader": "17.0.1",
|
||||
"vue3-calendar-heatmap": "2.0.0",
|
||||
"webpack": "5.75.0",
|
||||
"webpack-cli": "5.0.0",
|
||||
"webpack-cli": "5.0.1",
|
||||
"workbox-routing": "6.5.4",
|
||||
"workbox-strategies": "6.5.4",
|
||||
"worker-loader": "3.0.8",
|
||||
"wrap-ansi": "8.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.28.0",
|
||||
"@playwright/test": "1.29.0",
|
||||
"@rollup/pluginutils": "5.0.2",
|
||||
"@stoplight/spectral-cli": "6.6.0",
|
||||
"eslint": "8.28.0",
|
||||
"eslint": "8.30.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-sonarjs": "0.16.0",
|
||||
"eslint-plugin-unicorn": "45.0.0",
|
||||
"eslint-plugin-vue": "9.7.0",
|
||||
"eslint-plugin-sonarjs": "0.17.0",
|
||||
"eslint-plugin-unicorn": "45.0.2",
|
||||
"eslint-plugin-vue": "9.8.0",
|
||||
"jsdom": "20.0.3",
|
||||
"markdownlint-cli": "0.32.2",
|
||||
"postcss-less": "6.0.0",
|
||||
"stylelint": "14.15.0",
|
||||
"stylelint": "14.16.0",
|
||||
"stylelint-config-standard": "29.0.0",
|
||||
"stylelint-declaration-strict-value": "1.9.1",
|
||||
"svgo": "3.0.2",
|
||||
"updates": "13.2.1",
|
||||
"vitest": "0.25.2"
|
||||
"updates": "13.2.4",
|
||||
"vitest": "0.26.1"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults",
|
||||
|
1
public/img/svg/octicon-goal.svg
Normal file
1
public/img/svg/octicon-goal.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-goal" width="16" height="16" aria-hidden="true"><g fill-rule="evenodd"><path d="M13.637 2.363 13.302.687a.25.25 0 0 0-.422-.128l-1.374 1.374a.875.875 0 0 0-.256.619v1.137L8.389 6.551A1.502 1.502 0 0 0 6.5 8a1.5 1.5 0 1 0 2.95-.389l2.86-2.861h1.138a.875.875 0 0 0 .619-.256L15.44 3.12a.25.25 0 0 0-.128-.422l-1.676-.335z"/><path d="M2 8a6 6 0 0 1 7.656-5.769.75.75 0 0 0 .413-1.442 7.5 7.5 0 1 0 5.142 5.142.75.75 0 1 0-1.442.413A6 6 0 1 1 2 8z"/><path d="M5 8a3 3 0 0 1 3.346-2.98.75.75 0 1 0 .17-1.49 4.5 4.5 0 1 0 3.953 3.947.75.75 0 1 0-1.49.172A3 3 0 1 1 5 8z"/></g></svg>
|
After Width: | Height: | Size: 620 B |
1
public/img/svg/octicon-read.svg
Normal file
1
public/img/svg/octicon-read.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-read" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.115.65a1.75 1.75 0 0 1 1.77 0l6.25 3.663c.536.314.865.889.865 1.51v6.427A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25V5.823c0-.621.33-1.196.865-1.51L7.115.65zm1.011 1.293a.25.25 0 0 0-.252 0l-5.72 3.353L6.468 7.76a2.75 2.75 0 0 1 3.066 0l4.312-2.464-5.719-3.353zM14.5 6.65l-3.687 2.106 3.687 2.897V6.65zM5.187 8.756 1.5 6.65v5.003l3.687-2.897zM13.15 12.5H2.85l4.378-3.44a1.25 1.25 0 0 1 1.544 0l4.378 3.44z"/></svg>
|
After Width: | Height: | Size: 548 B |
1
public/img/svg/octicon-rel-file-path.svg
Normal file
1
public/img/svg/octicon-rel-file-path.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-rel-file-path" width="16" height="16" aria-hidden="true"><path d="M13.94 3.045a.75.75 0 0 0-1.38-.59l-4.5 10.5a.75.75 0 1 0 1.38.59l4.5-10.5zM5 11.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/></svg>
|
After Width: | Height: | Size: 238 B |
1
public/img/svg/octicon-sponsor-tiers.svg
Normal file
1
public/img/svg/octicon-sponsor-tiers.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-sponsor-tiers" width="16" height="16" aria-hidden="true"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105zM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75z"/></svg>
|
After Width: | Height: | Size: 974 B |
1
public/img/svg/octicon-unlink.svg
Normal file
1
public/img/svg/octicon-unlink.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-unlink" width="16" height="16" aria-hidden="true"><path d="M12.914 5.914a2 2 0 0 0-2.828-2.828l-.837.837a.75.75 0 1 1-1.06-1.061l.836-.837a3.5 3.5 0 1 1 4.95 4.95l-.195.194a.75.75 0 0 1-1.06-1.06l.194-.195zm-1.87 3.482a.759.759 0 0 1-.07.079c-.63.63-1.468 1.108-2.343 1.263-.89.159-1.86-.017-2.606-.763a.75.75 0 1 1 1.06-1.06c.329.327.767.438 1.284.347.493-.088 1.018-.36 1.445-.752l-1.247-.897a.709.709 0 0 1-.01-.008l-.295-.212c-.94-.597-1.984-.499-2.676.193l-2.5 2.5a2 2 0 1 0 2.828 2.828l.837-.836a.75.75 0 0 1 1.06 1.06l-.836.837a3.5 3.5 0 0 1-4.95-4.95l2.5-2.5a3.472 3.472 0 0 1 1.354-.848L2.312 3.109a.75.75 0 0 1 .876-1.218l5.93 4.27c.115.074.226.155.335.24l6.235 4.49a.75.75 0 0 1-.876 1.218l-3.768-2.713z"/></svg>
|
After Width: | Height: | Size: 767 B |
1
public/img/svg/octicon-unread.svg
Normal file
1
public/img/svg/octicon-unread.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-unread" width="16" height="16" aria-hidden="true"><path d="M10.5 3.5H1.75a.25.25 0 0 0-.25.25v.32L8 7.88l3.02-1.77a.75.75 0 0 1 .758 1.295L8.379 9.397a.75.75 0 0 1-.758 0L1.5 5.809v6.441c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4.5a.75.75 0 0 1 1.5 0v4.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25V4.513a.75.75 0 0 1 0-.027V3.75C0 2.784.784 2 1.75 2h8.75a.75.75 0 0 1 0 1.5z"/><path d="M14 6a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></svg>
|
After Width: | Height: | Size: 490 B |
@ -344,7 +344,7 @@ func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNames
|
||||
Content: content,
|
||||
Properties: &FeedEntryProperties{
|
||||
Version: pd.Version.Version,
|
||||
NormalizedVersion: normalizeVersion(pd.SemVer),
|
||||
NormalizedVersion: pd.Version.Version,
|
||||
Authors: metadata.Authors,
|
||||
Dependencies: buildDependencyString(metadata),
|
||||
Description: metadata.Description,
|
||||
|
@ -4,15 +4,11 @@
|
||||
package nuget
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
nuget_module "code.gitea.io/gitea/modules/packages/nuget"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
// https://docs.microsoft.com/en-us/nuget/api/service-index#resources
|
||||
@ -95,8 +91,8 @@ func createRegistrationIndexResponse(l *linkBuilder, pds []*packages_model.Packa
|
||||
{
|
||||
RegistrationPageURL: l.GetRegistrationIndexURL(pds[0].Package.Name),
|
||||
Count: len(pds),
|
||||
Lower: normalizeVersion(pds[0].SemVer),
|
||||
Upper: normalizeVersion(pds[len(pds)-1].SemVer),
|
||||
Lower: pds[0].Version.Version,
|
||||
Upper: pds[len(pds)-1].Version.Version,
|
||||
Items: items,
|
||||
},
|
||||
},
|
||||
@ -173,7 +169,7 @@ type PackageVersionsResponse struct {
|
||||
func createPackageVersionsResponse(pds []*packages_model.PackageDescriptor) *PackageVersionsResponse {
|
||||
versions := make([]string, 0, len(pds))
|
||||
for _, pd := range pds {
|
||||
versions = append(versions, normalizeVersion(pd.SemVer))
|
||||
versions = append(versions, pd.Version.Version)
|
||||
}
|
||||
|
||||
return &PackageVersionsResponse{
|
||||
@ -248,15 +244,3 @@ func createSearchResult(l *linkBuilder, pds []*packages_model.PackageDescriptor)
|
||||
RegistrationIndexURL: l.GetRegistrationIndexURL(latest.Package.Name),
|
||||
}
|
||||
}
|
||||
|
||||
// normalizeVersion removes the metadata
|
||||
func normalizeVersion(v *version.Version) string {
|
||||
var buf bytes.Buffer
|
||||
segments := v.Segments64()
|
||||
fmt.Fprintf(&buf, "%d.%d.%d", segments[0], segments[1], segments[2])
|
||||
pre := v.Prerelease()
|
||||
if pre != "" {
|
||||
fmt.Fprintf(&buf, "-%s", pre)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -490,6 +490,11 @@ func EditPullRequest(ctx *context.APIContext) {
|
||||
issue := pr.Issue
|
||||
issue.Repo = ctx.Repo.Repository
|
||||
|
||||
if err := issue.LoadAttributes(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWrite(unit.TypePullRequests) {
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
|
||||
activities_model "code.gitea.io/gitea/models/activities"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
@ -268,3 +269,46 @@ func GetFeedType(name string, req *http.Request) (bool, string, string) {
|
||||
|
||||
return false, name, ""
|
||||
}
|
||||
|
||||
// feedActionsToFeedItems convert gitea's Repo's Releases to feeds Item
|
||||
func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, isReleasesOnly bool) (items []*feeds.Item, err error) {
|
||||
for _, rel := range releases {
|
||||
err := rel.LoadAttributes(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var title, content string
|
||||
|
||||
if rel.IsTag {
|
||||
title = rel.TagName
|
||||
} else {
|
||||
title = rel.Title
|
||||
}
|
||||
|
||||
link := &feeds.Link{Href: rel.HTMLURL()}
|
||||
content, err = markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: rel.Repo.Link(),
|
||||
Metas: rel.Repo.ComposeMetas(),
|
||||
}, rel.Note)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items = append(items, &feeds.Item{
|
||||
Title: title,
|
||||
Link: link,
|
||||
Created: rel.CreatedUnix.AsTime(),
|
||||
Author: &feeds.Author{
|
||||
Name: rel.Publisher.DisplayName(),
|
||||
Email: rel.Publisher.GetEmail(),
|
||||
},
|
||||
Id: fmt.Sprintf("%v: %v", strconv.FormatInt(rel.ID, 10), link.Href),
|
||||
Content: content,
|
||||
})
|
||||
}
|
||||
|
||||
return items, err
|
||||
}
|
||||
|
50
routers/web/feed/release.go
Normal file
50
routers/web/feed/release.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package feed
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
"github.com/gorilla/feeds"
|
||||
)
|
||||
|
||||
// shows tags and/or releases on the repo as RSS / Atom feed
|
||||
func ShowReleaseFeed(ctx *context.Context, repo *repo_model.Repository, isReleasesOnly bool, formatType string) {
|
||||
releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{
|
||||
IncludeTags: !isReleasesOnly,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetReleasesByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
var title string
|
||||
var link *feeds.Link
|
||||
|
||||
if isReleasesOnly {
|
||||
title = ctx.Tr("repo.release.releases_for", repo.FullName())
|
||||
link = &feeds.Link{Href: repo.HTMLURL() + "/release"}
|
||||
} else {
|
||||
title = ctx.Tr("repo.release.tags_for", repo.FullName())
|
||||
link = &feeds.Link{Href: repo.HTMLURL() + "/tags"}
|
||||
}
|
||||
|
||||
feed := &feeds.Feed{
|
||||
Title: title,
|
||||
Link: link,
|
||||
Description: repo.Description,
|
||||
Created: time.Now(),
|
||||
}
|
||||
|
||||
feed.Items, err = releasesToFeedItems(ctx, releases, isReleasesOnly)
|
||||
if err != nil {
|
||||
ctx.ServerError("releasesToFeedItems", err)
|
||||
return
|
||||
}
|
||||
|
||||
writeFeed(ctx, feed, formatType)
|
||||
}
|
@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/models/webhook"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
@ -25,7 +26,6 @@ import (
|
||||
"code.gitea.io/gitea/services/org"
|
||||
container_service "code.gitea.io/gitea/services/packages/container"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
secret_service "code.gitea.io/gitea/services/secrets"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
)
|
||||
|
||||
@ -38,12 +38,12 @@ const (
|
||||
tplSettingsHooks base.TplName = "org/settings/hooks"
|
||||
// tplSettingsLabels template path for render labels settings
|
||||
tplSettingsLabels base.TplName = "org/settings/labels"
|
||||
// tplSettingsSecrets template path for render secrets settings
|
||||
tplSettingsSecrets base.TplName = "org/settings/secrets"
|
||||
// tplSettingsRunners template path for render runners settings
|
||||
tplSettingsRunners base.TplName = "org/settings/runners"
|
||||
// tplSettingsRunnersEdit template path for render runners edit settings
|
||||
tplSettingsRunnersEdit base.TplName = "org/settings/runners_edit"
|
||||
// tplSettingsSecrets template path for render secrets settings
|
||||
tplSettingsSecrets base.TplName = "org/settings/secrets"
|
||||
)
|
||||
|
||||
// Settings render the main settings page
|
||||
@ -259,11 +259,10 @@ func Secrets(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.secrets")
|
||||
ctx.Data["PageIsOrgSettings"] = true
|
||||
ctx.Data["PageIsOrgSettingsSecrets"] = true
|
||||
ctx.Data["RequireTribute"] = true
|
||||
|
||||
secrets, err := secret_service.FindUserSecrets(ctx, ctx.Org.Organization.ID)
|
||||
secrets, err := secret_model.FindSecrets(ctx, secret_model.FindSecretsOptions{OwnerID: ctx.Org.Organization.ID})
|
||||
if err != nil {
|
||||
ctx.ServerError("FindRepoSecrets", err)
|
||||
ctx.ServerError("FindSecrets", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Secrets"] = secrets
|
||||
@ -274,22 +273,28 @@ func Secrets(ctx *context.Context) {
|
||||
// SecretsPost add secrets
|
||||
func SecretsPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.AddSecretForm)
|
||||
if err := secret_service.InsertOrgSecret(ctx, ctx.Org.Organization.ID, form.Title, form.Content, form.PullRequestRead); err != nil {
|
||||
ctx.ServerError("InsertRepoSecret", err)
|
||||
|
||||
_, err := secret_model.InsertEncryptedSecret(ctx, ctx.Org.Organization.ID, 0, form.Title, form.Content)
|
||||
if err != nil {
|
||||
ctx.Flash.Error(ctx.Tr("secrets.creation.failed"))
|
||||
log.Error("validate secret: %v", err)
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings/secrets")
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Secret added: %d", ctx.Org.Organization.ID)
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.add_secret_success", form.Title))
|
||||
log.Trace("Org %d: secret added", ctx.Org.Organization.ID)
|
||||
ctx.Flash.Success(ctx.Tr("secrets.creation.success", form.Title))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings/secrets")
|
||||
}
|
||||
|
||||
// SecretsDelete delete secrets
|
||||
func SecretsDelete(ctx *context.Context) {
|
||||
if err := secret_service.DeleteSecretByID(ctx, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteSecretByID: " + err.Error())
|
||||
id := ctx.FormInt64("id")
|
||||
if _, err := db.DeleteByBean(ctx, &secret_model.Secret{ID: id}); err != nil {
|
||||
ctx.Flash.Error(ctx.Tr("secrets.deletion.failed"))
|
||||
log.Error("delete secret %d: %v", id, err)
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.secret_deletion_success"))
|
||||
ctx.Flash.Success(ctx.Tr("secrets.deletion.success"))
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/upload"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/web/feed"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
releaseservice "code.gitea.io/gitea/services/release"
|
||||
)
|
||||
@ -199,6 +200,30 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
|
||||
ctx.HTML(http.StatusOK, tplReleases)
|
||||
}
|
||||
|
||||
// ReleasesFeedRSS get feeds for releases in RSS format
|
||||
func ReleasesFeedRSS(ctx *context.Context) {
|
||||
releasesOrTagsFeed(ctx, true, "rss")
|
||||
}
|
||||
|
||||
// TagsListFeedRSS get feeds for tags in RSS format
|
||||
func TagsListFeedRSS(ctx *context.Context) {
|
||||
releasesOrTagsFeed(ctx, false, "rss")
|
||||
}
|
||||
|
||||
// ReleasesFeedAtom get feeds for releases in Atom format
|
||||
func ReleasesFeedAtom(ctx *context.Context) {
|
||||
releasesOrTagsFeed(ctx, true, "atom")
|
||||
}
|
||||
|
||||
// TagsListFeedAtom get feeds for tags in RSS format
|
||||
func TagsListFeedAtom(ctx *context.Context) {
|
||||
releasesOrTagsFeed(ctx, false, "atom")
|
||||
}
|
||||
|
||||
func releasesOrTagsFeed(ctx *context.Context, isReleasesOnly bool, formatType string) {
|
||||
feed.ShowReleaseFeed(ctx, ctx.Repo.Repository, isReleasesOnly, formatType)
|
||||
}
|
||||
|
||||
// SingleRelease renders a single release's page
|
||||
func SingleRelease(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.releases")
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
unit_model "code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
@ -44,7 +45,6 @@ import (
|
||||
mirror_service "code.gitea.io/gitea/services/mirror"
|
||||
org_service "code.gitea.io/gitea/services/org"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
secret_service "code.gitea.io/gitea/services/secrets"
|
||||
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||
)
|
||||
|
||||
@ -1123,9 +1123,9 @@ func DeployKeys(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["Deploykeys"] = keys
|
||||
|
||||
secrets, err := secret_service.FindRepoSecrets(ctx, ctx.Repo.Repository.ID)
|
||||
secrets, err := secret_model.FindSecrets(ctx, secret_model.FindSecretsOptions{RepoID: ctx.Repo.Repository.ID})
|
||||
if err != nil {
|
||||
ctx.ServerError("FindRepoSecrets", err)
|
||||
ctx.ServerError("FindSecrets", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Secrets"] = secrets
|
||||
@ -1135,26 +1135,24 @@ func DeployKeys(ctx *context.Context) {
|
||||
|
||||
// SecretsPost response for creating a new secret
|
||||
func SecretsPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.AddKeyForm)
|
||||
if err := secret_service.InsertRepoSecret(ctx, ctx.Repo.Repository.ID, form.Title, form.Content, form.PullRequestRead); err != nil {
|
||||
ctx.ServerError("InsertRepoSecret", err)
|
||||
form := web.GetForm(ctx).(*forms.AddSecretForm)
|
||||
|
||||
_, err := secret_model.InsertEncryptedSecret(ctx, 0, ctx.Repo.Repository.ID, form.Title, form.Content)
|
||||
if err != nil {
|
||||
ctx.Flash.Error(ctx.Tr("secrets.creation.failed"))
|
||||
log.Error("validate secret: %v", err)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Secret added: %d", ctx.Repo.Repository.ID)
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.add_secret_success", form.Title))
|
||||
ctx.Flash.Success(ctx.Tr("secrets.creation.success", form.Title))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
|
||||
}
|
||||
|
||||
// DeployKeysPost response for adding a deploy key of a repository
|
||||
func DeployKeysPost(ctx *context.Context) {
|
||||
if ctx.FormString("act") == "secret" {
|
||||
SecretsPost(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
form := web.GetForm(ctx).(*forms.AddKeyForm)
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys")
|
||||
ctx.Data["PageIsSettingsKeys"] = true
|
||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||
@ -1214,10 +1212,12 @@ func DeployKeysPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func DeleteSecret(ctx *context.Context) {
|
||||
if err := secret_service.DeleteSecretByID(ctx, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteSecretByID: " + err.Error())
|
||||
id := ctx.FormInt64("id")
|
||||
if _, err := db.DeleteByBean(ctx, &secret_model.Secret{ID: id}); err != nil {
|
||||
ctx.Flash.Error(ctx.Tr("secrets.deletion.failed"))
|
||||
log.Error("delete secret %d: %v", id, err)
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.secret_deletion_success"))
|
||||
ctx.Flash.Success(ctx.Tr("secrets.deletion.success"))
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
@ -1227,11 +1227,6 @@ func DeleteSecret(ctx *context.Context) {
|
||||
|
||||
// DeleteDeployKey response for deleting a deploy key
|
||||
func DeleteDeployKey(ctx *context.Context) {
|
||||
if ctx.FormString("act") == "secret" {
|
||||
DeleteSecret(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
if err := asymkey_service.DeleteDeployKey(ctx.Doer, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteDeployKey: " + err.Error())
|
||||
} else {
|
||||
|
@ -272,7 +272,7 @@ func getFileReader(repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileIn
|
||||
}
|
||||
|
||||
meta, err := git_model.GetLFSMetaObjectByOid(repoID, pointer.Oid)
|
||||
if err != git_model.ErrLFSObjectNotExist { // fallback to plain file
|
||||
if err != nil && err != git_model.ErrLFSObjectNotExist { // fallback to plain file
|
||||
return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
|
||||
}
|
||||
|
||||
|
@ -935,6 +935,10 @@ func RegisterRoutes(m *web.Route) {
|
||||
m.Combo("").Get(repo.DeployKeys).
|
||||
Post(web.Bind(forms.AddKeyForm{}), repo.DeployKeysPost)
|
||||
m.Post("/delete", repo.DeleteDeployKey)
|
||||
m.Group("/secrets", func() {
|
||||
m.Post("", web.Bind(forms.AddSecretForm{}), repo.SecretsPost)
|
||||
m.Post("/delete", repo.DeleteSecret)
|
||||
})
|
||||
})
|
||||
|
||||
m.Group("/lfs", func() {
|
||||
@ -1108,12 +1112,21 @@ func RegisterRoutes(m *web.Route) {
|
||||
|
||||
// Releases
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Get("/tags", repo.TagsList, repo.MustBeNotEmpty,
|
||||
reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag))
|
||||
m.Group("/tags", func() {
|
||||
m.Get("", repo.TagsList)
|
||||
m.Get(".rss", feedEnabled, repo.TagsListFeedRSS)
|
||||
m.Get(".atom", feedEnabled, repo.TagsListFeedAtom)
|
||||
}, func(ctx *context.Context) {
|
||||
ctx.Data["EnableFeed"] = setting.EnableFeed
|
||||
}, repo.MustBeNotEmpty, reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag, true))
|
||||
m.Group("/releases", func() {
|
||||
m.Get("/", repo.Releases)
|
||||
m.Get("/tag/*", repo.SingleRelease)
|
||||
m.Get("/latest", repo.LatestRelease)
|
||||
m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS)
|
||||
m.Get(".atom", feedEnabled, repo.ReleasesFeedAtom)
|
||||
}, func(ctx *context.Context) {
|
||||
ctx.Data["EnableFeed"] = setting.EnableFeed
|
||||
}, repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag, true))
|
||||
m.Get("/releases/attachments/{uuid}", repo.GetAttachment, repo.MustBeNotEmpty, reqRepoReleaseReader)
|
||||
m.Group("/releases", func() {
|
||||
|
@ -348,14 +348,13 @@ func (f *AddOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding
|
||||
|
||||
// AddKeyForm form for adding SSH/GPG key
|
||||
type AddKeyForm struct {
|
||||
Type string `binding:"OmitEmpty"`
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string `binding:"Required"`
|
||||
Signature string `binding:"OmitEmpty"`
|
||||
KeyID string `binding:"OmitEmpty"`
|
||||
Fingerprint string `binding:"OmitEmpty"`
|
||||
IsWritable bool
|
||||
PullRequestRead bool
|
||||
Type string `binding:"OmitEmpty"`
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string `binding:"Required"`
|
||||
Signature string `binding:"OmitEmpty"`
|
||||
KeyID string `binding:"OmitEmpty"`
|
||||
Fingerprint string `binding:"OmitEmpty"`
|
||||
IsWritable bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
@ -366,9 +365,8 @@ func (f *AddKeyForm) Validate(req *http.Request, errs binding.Errors) binding.Er
|
||||
|
||||
// AddSecretForm for adding secrets
|
||||
type AddSecretForm struct {
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string `binding:"Required"`
|
||||
PullRequestRead bool
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
@ -289,13 +290,15 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
||||
|
||||
// 2. AttemptThreeWayMerge first - this is much quicker than plain patch to base
|
||||
description := fmt.Sprintf("PR[%d] %s/%s#%d", pr.ID, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Index)
|
||||
conflict, _, err := AttemptThreeWayMerge(ctx,
|
||||
conflict, conflictFiles, err := AttemptThreeWayMerge(ctx,
|
||||
tmpBasePath, gitRepo, pr.MergeBase, "base", "tracking", description)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !conflict {
|
||||
// No conflicts detected so we need to check if the patch is empty...
|
||||
// a. Write the newly merged tree and check the new tree-hash
|
||||
var treeHash string
|
||||
treeHash, _, err = git.NewCommand(ctx, "write-tree").RunStdString(&git.RunOpts{Dir: tmpBasePath})
|
||||
if err != nil {
|
||||
@ -307,6 +310,8 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// b. compare the new tree-hash with the base tree hash
|
||||
if treeHash == baseTree.ID.String() {
|
||||
log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID)
|
||||
pr.Status = issues_model.PullRequestStatusEmpty
|
||||
@ -315,9 +320,17 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// 3. OK read-tree has failed so we need to try a different thing - this might actually succeed where the above fails due to whitespace handling.
|
||||
// 3. OK the three-way merge method has detected conflicts
|
||||
// 3a. Are still testing with GitApply? If not set the conflict status and move on
|
||||
if !setting.Repository.PullRequest.TestConflictingPatchesWithGitApply {
|
||||
pr.Status = issues_model.PullRequestStatusConflict
|
||||
pr.ConflictedFiles = conflictFiles
|
||||
|
||||
// 3a. Create a plain patch from head to base
|
||||
log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// 3b. Create a plain patch from head to base
|
||||
tmpPatchFile, err := os.CreateTemp("", "patch")
|
||||
if err != nil {
|
||||
log.Error("Unable to create temporary patch file! Error: %v", err)
|
||||
@ -340,7 +353,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
||||
patchPath := tmpPatchFile.Name()
|
||||
tmpPatchFile.Close()
|
||||
|
||||
// 3b. if the size of that patch is 0 - there can be no conflicts!
|
||||
// 3c. if the size of that patch is 0 - there can be no conflicts!
|
||||
if stat.Size() == 0 {
|
||||
log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID)
|
||||
pr.Status = issues_model.PullRequestStatusEmpty
|
||||
|
@ -12,6 +12,9 @@
|
||||
<a class="{{if .PageIsOrgSettingsLabels}}active {{end}}item" href="{{.OrgLink}}/settings/labels">
|
||||
{{.locale.Tr "repo.labels"}}
|
||||
</a>
|
||||
<a class="{{if .PageIsOrgSettingsSecrets}}active {{end}}item" href="{{.OrgLink}}/settings/secrets">
|
||||
{{.locale.Tr "secrets.secrets"}}
|
||||
</a>
|
||||
{{if .EnableOAuth2}}
|
||||
<a class="{{if .PageIsSettingsApplications}}active {{end}}item" href="{{.OrgLink}}/settings/applications">
|
||||
{{.locale.Tr "settings.applications"}}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{{template "base/head" .}}
|
||||
<div class="page-content organization settings secrets">
|
||||
<div class="page-content organization settings webhooks">
|
||||
{{template "org/header" .}}
|
||||
<div class="ui container">
|
||||
<div class="ui grid">
|
||||
@ -7,37 +7,28 @@
|
||||
<div class="ui twelve wide column content">
|
||||
{{template "base/alert" .}}
|
||||
<h4 class="ui top attached header">
|
||||
{{.locale.Tr "repo.settings.secrets"}}
|
||||
{{.locale.Tr "secrets.secrets"}}
|
||||
<div class="ui right">
|
||||
<div class="ui primary tiny show-panel button" data-panel="#add-secret-panel">{{.locale.Tr "repo.settings.add_secret"}}</div>
|
||||
<div class="ui primary tiny show-panel button" data-panel="#add-secret-panel">{{.locale.Tr "secrets.creation"}}</div>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<div class="{{if not .HasError}}hide{{end}} mb-4" id="add-secret-panel">
|
||||
<form class="ui form" action="{{.Link}}?act=secret" method="post">
|
||||
<div class="{{if not .HasError}}hide {{end}}mb-4" id="add-secret-panel">
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field">
|
||||
{{.locale.Tr "repo.settings.secret_desc"}}
|
||||
{{.locale.Tr "secrets.description"}}
|
||||
</div>
|
||||
<div class="field {{if .Err_Title}}error{{end}}">
|
||||
<label for="title">{{.locale.Tr "repo.settings.secret_key"}}</label>
|
||||
<input id="key-title" name="title" value="{{.title}}" autofocus required>
|
||||
<div class="field{{if .Err_Title}} error{{end}}">
|
||||
<label for="secret-title">{{.locale.Tr "secrets.name"}}</label>
|
||||
<input id="secret-title" name="title" value="{{.title}}" autofocus required pattern="^[a-zA-Z_][a-zA-Z0-9_]*$" placeholder="{{.locale.Tr "secrets.creation.name_placeholder"}}">
|
||||
</div>
|
||||
<div class="field {{if .Err_Content}}error{{end}}">
|
||||
<label for="content">{{.locale.Tr "repo.settings.secret_content"}}</label>
|
||||
<textarea id="key-content" name="content" placeholder="{{.locale.Tr "repo.settings.secret_value_content_placeholder"}}" required>{{.content}}</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox {{if .Err_PullRequestRead}}error{{end}}">
|
||||
<input id="pull_request_read" name="pull_request_read" class="hidden" type="checkbox" value="1">
|
||||
<label for="is_writable">
|
||||
{{.locale.Tr "repo.settings.pull_request_read"}}
|
||||
</label>
|
||||
<small style="padding-left: 26px;">{{$.locale.Tr "repo.settings.pull_request_read_info" | Str2html}}</small>
|
||||
</div>
|
||||
<div class="field{{if .Err_Content}} error{{end}}">
|
||||
<label for="secret-content">{{.locale.Tr "secrets.value"}}</label>
|
||||
<textarea id="secret-content" name="content" required placeholder="{{.locale.Tr "secrets.creation.value_placeholder"}}">{{.content}}</textarea>
|
||||
</div>
|
||||
<button class="ui green button">
|
||||
{{.locale.Tr "repo.settings.add_secret"}}
|
||||
{{.locale.Tr "secrets.creation"}}
|
||||
</button>
|
||||
<button class="ui hide-panel button" data-panel="#add-secret-panel">
|
||||
{{.locale.Tr "cancel"}}
|
||||
@ -54,19 +45,15 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="left floated content">
|
||||
<i class="tooltip">{{svg "octicon-key" 32}}</i>
|
||||
<i>{{svg "octicon-key" 32}}</i>
|
||||
</div>
|
||||
<div class="content">
|
||||
<strong>{{.Name}}</strong>
|
||||
<div class="print meta">
|
||||
{{Shadow .Data}}
|
||||
</div>
|
||||
<div class="print meta">******</div>
|
||||
<div class="activity meta">
|
||||
<i>
|
||||
{{$.locale.Tr "settings.add_on"}}
|
||||
<span>{{.CreatedUnix.FormatShort}}</span>
|
||||
{{if .PullRequest}} — {{svg "octicon-info"}} -
|
||||
<span>{{$.locale.Tr "repo.settings.pull_request_read_hint"}}</span> {{end}}
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
@ -74,7 +61,7 @@
|
||||
{{end}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{.locale.Tr "repo.settings.no_secret"}}
|
||||
{{.locale.Tr "secrets.none"}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
@ -85,10 +72,10 @@
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui header">
|
||||
{{svg "octicon-trash" 16 "mr-2"}}
|
||||
{{.locale.Tr "repo.settings.secret_deletion"}}
|
||||
{{.locale.Tr "secrets.deletion"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "repo.settings.secret_deletion_desc"}}</p>
|
||||
<p>{{.locale.Tr "secrets.deletion.description"}}</p>
|
||||
</div>
|
||||
{{template "base/delete_modal_actions" .}}
|
||||
</div>
|
||||
|
@ -11,6 +11,9 @@
|
||||
<a class="{{if .PageIsTagList}}active {{end}}item" href="{{.RepoLink}}/tags">{{.locale.Tr "repo.release.tags"}}</a>
|
||||
{{end}}
|
||||
</h2>
|
||||
{{if .EnableFeed}}
|
||||
<a href="{{.RepoLink}}/{{if .PageIsTagList}}tags{{else}}releases{{end}}.rss"><i class="ui grey icon tooltip ml-3" data-content="{{.locale.Tr "rss_feed"}}" data-position="top center">{{svg "octicon-rss" 18}}</i></a>
|
||||
{{end}}
|
||||
{{if (and .CanCreateRelease (not .PageIsTagList))}}
|
||||
<a class="ui right small green button" href="{{$.RepoLink}}/releases/new">
|
||||
{{.locale.Tr "repo.release.new_release"}}
|
||||
|
@ -51,7 +51,7 @@
|
||||
{{range .Deploykeys}}
|
||||
<div class="item">
|
||||
<div class="right floated content">
|
||||
<button class="ui red tiny button delete-button" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
|
||||
<button class="ui red tiny button delete-button" data-modal-id="delete-deploy_keys-modal" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
|
||||
{{$.locale.Tr "settings.delete_key"}}
|
||||
</button>
|
||||
</div>
|
||||
@ -79,7 +79,7 @@
|
||||
{{template "repo/settings/secrets" .}}
|
||||
</div>
|
||||
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui small basic delete modal" id="delete-deploy_keys-modal">
|
||||
<div class="ui icon header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "repo.settings.deploy_key_deletion"}}
|
||||
|
@ -12,7 +12,7 @@
|
||||
{{if or .SignedUser.AllowGitHook .SignedUser.IsAdmin}}
|
||||
<li {{if .PageIsSettingsGitHooks}}class="current"{{end}}><a href="{{.RepoLink}}/settings/hooks/git">{{.locale.Tr "repo.settings.githooks"}}</a></li>
|
||||
{{end}}
|
||||
<li {{if .PageIsSettingsKeys}}class="current"{{end}}><a href="{{.RepoLink}}/settings/keys">{{.locale.Tr "repo.settings.secrets"}}</a></li>
|
||||
<li {{if .PageIsSettingsKeys}}class="current"{{end}}><a href="{{.RepoLink}}/settings/keys">{{.locale.Tr "secrets.secrets"}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,7 +25,7 @@
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="{{if .PageIsSettingsKeys}}active {{end}}item" href="{{.RepoLink}}/settings/keys">
|
||||
{{.locale.Tr "repo.settings.deploy_keys"}}
|
||||
{{.locale.Tr "secrets.secrets"}}
|
||||
</a>
|
||||
{{if .LFSStartServer}}
|
||||
<a class="{{if .PageIsSettingsLFS}}active {{end}}item" href="{{.RepoLink}}/settings/lfs">
|
||||
|
@ -1,69 +1,80 @@
|
||||
<div class="ui container">
|
||||
<h4 class="ui top attached header">
|
||||
{{.locale.Tr "repo.settings.secrets"}}
|
||||
<div class="ui right">
|
||||
<div class="ui primary tiny show-panel button" data-panel="#add-secret-panel">{{.locale.Tr "repo.settings.add_secret"}}</div>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<div class="{{if not .HasError}}hide{{end}} mb-4" id="add-secret-panel">
|
||||
<form class="ui form" action="{{.Link}}?act=secret" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field">
|
||||
{{.locale.Tr "repo.settings.secret_desc"}}
|
||||
</div>
|
||||
<div class="field {{if .Err_Title}}error{{end}}">
|
||||
<label for="title">{{.locale.Tr "repo.settings.secret_key"}}</label>
|
||||
<input id="ssh-key-title" name="title" value="{{.title}}" autofocus required>
|
||||
</div>
|
||||
<div class="field {{if .Err_Content}}error{{end}}">
|
||||
<label for="content">{{.locale.Tr "repo.settings.secret_content"}}</label>
|
||||
<textarea id="ssh-key-content" name="content" placeholder="{{.locale.Tr "repo.settings.secret_value_content_placeholder"}}" required>{{.content}}</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox {{if .Err_IsWritable}}error{{end}}">
|
||||
<input id="pull_request_read" name="pull_request_read" class="hidden" type="checkbox" value="1">
|
||||
<label for="is_writable">
|
||||
{{.locale.Tr "repo.settings.pull_request_read"}}
|
||||
</label>
|
||||
<small style="padding-left: 26px;">{{$.locale.Tr "repo.settings.pull_request_read_info" | Str2html}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui green button">
|
||||
{{.locale.Tr "repo.settings.add_secret"}}
|
||||
</button>
|
||||
<button class="ui hide-panel button" data-panel="#add-secret-panel">
|
||||
{{.locale.Tr "cancel"}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{{if .Secrets}}
|
||||
<div class="ui key list">
|
||||
{{range .Secrets}}
|
||||
<div class="item">
|
||||
<div class="right floated content">
|
||||
<button class="ui red tiny button delete-button" data-url="{{$.Link}}/delete?act=secret" data-id="{{.ID}}">
|
||||
{{$.locale.Tr "settings.delete_key"}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="left floated content">
|
||||
<i class="tooltip">{{svg "octicon-key" 32}}</i>
|
||||
</div>
|
||||
<div class="content">
|
||||
<strong>{{.Name}}</strong>
|
||||
<div class="print meta">
|
||||
{{Shadow .Data}}
|
||||
</div>
|
||||
<div class="activity meta">
|
||||
<i>{{$.locale.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span>
|
||||
{{if .PullRequest}} — {{svg "octicon-info"}} - <span> {{$.locale.Tr "repo.settings.pull_request_read_hint"}} </span>{{end}}</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<h4 class="ui top attached header">
|
||||
{{.locale.Tr "secrets.secrets"}}
|
||||
<div class="ui right">
|
||||
<div class="ui primary tiny show-panel button" data-panel="#add-secret-panel">{{.locale.Tr "secrets.creation"}}</div>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<div class="{{if not .HasError}}hide {{end}}mb-4" id="add-secret-panel">
|
||||
<form class="ui form" action="{{.Link}}/secrets" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field">
|
||||
{{.locale.Tr "secrets.description"}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{.locale.Tr "repo.settings.no_secret"}}
|
||||
{{end}}
|
||||
<div class="field{{if .Err_Title}} error{{end}}">
|
||||
<label for="secret-title">{{.locale.Tr "secrets.name"}}</label>
|
||||
<input id="secret-title" name="title" value="{{.title}}" autofocus required pattern="^[a-zA-Z_][a-zA-Z0-9_]*$" placeholder="{{.locale.Tr "secrets.creation.name_placeholder"}}">
|
||||
</div>
|
||||
<div class="field{{if .Err_Content}} error{{end}}">
|
||||
<label for="secret-content">{{.locale.Tr "secrets.value"}}</label>
|
||||
<textarea id="secret-content" name="content" required placeholder="{{.locale.Tr "secrets.creation.value_placeholder"}}">{{.content}}</textarea>
|
||||
</div>
|
||||
<button class="ui green button">
|
||||
{{.locale.Tr "secrets.creation"}}
|
||||
</button>
|
||||
<button class="ui hide-panel button" data-panel="#add-secret-panel">
|
||||
{{.locale.Tr "cancel"}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{{if .Secrets}}
|
||||
<div class="ui key list">
|
||||
{{range .Secrets}}
|
||||
<div class="item">
|
||||
<div class="right floated content">
|
||||
<button class="ui red tiny button delete-button" data-modal-id="delete-secret-modal" data-url="{{$.Link}}/secrets/delete" data-id="{{.ID}}">
|
||||
{{$.locale.Tr "settings.delete_key"}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="left floated content">
|
||||
<i>{{svg "octicon-key" 32}}</i>
|
||||
</div>
|
||||
<div class="content">
|
||||
<strong>{{.Name}}</strong>
|
||||
<div class="print meta">******</div>
|
||||
<div class="activity meta">
|
||||
<i>
|
||||
{{$.locale.Tr "settings.add_on"}}
|
||||
<span>{{.CreatedUnix.FormatShort}}</span>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{.locale.Tr "secrets.none"}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small basic delete modal" id="delete-secret-modal">
|
||||
<div class="ui icon header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "secrets.deletion"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "secrets.deletion.description"}}</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui red basic inverted cancel button">
|
||||
<i class="remove icon"></i>
|
||||
{{.locale.Tr "modal.no"}}
|
||||
</div>
|
||||
<div class="ui green basic inverted ok button">
|
||||
<i class="checkmark icon"></i>
|
||||
{{.locale.Tr "modal.yes"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
func TestAPITeam(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{})
|
||||
teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{ID: 1})
|
||||
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamUser.TeamID})
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser.UID})
|
||||
|
||||
|
@ -264,18 +264,45 @@ var tokenCounter int64
|
||||
|
||||
func getTokenForLoggedInUser(t testing.TB, session *TestSession) string {
|
||||
t.Helper()
|
||||
var token string
|
||||
req := NewRequest(t, "GET", "/user/settings/applications")
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
var csrf string
|
||||
for _, cookie := range resp.Result().Cookies() {
|
||||
if cookie.Name != "_csrf" {
|
||||
continue
|
||||
}
|
||||
csrf = cookie.Value
|
||||
break
|
||||
}
|
||||
if csrf == "" {
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
csrf = doc.GetCSRF()
|
||||
}
|
||||
assert.NotEmpty(t, csrf)
|
||||
req = NewRequestWithValues(t, "POST", "/user/settings/applications", map[string]string{
|
||||
"_csrf": doc.GetCSRF(),
|
||||
"_csrf": csrf,
|
||||
"name": fmt.Sprintf("api-testing-token-%d", atomic.AddInt64(&tokenCounter, 1)),
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
resp = session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
||||
// Log the flash values on failure
|
||||
if !assert.Equal(t, resp.Result().Header["Location"], []string{"/user/settings/applications"}) {
|
||||
for _, cookie := range resp.Result().Cookies() {
|
||||
if cookie.Name != "macaron_flash" {
|
||||
continue
|
||||
}
|
||||
flash, _ := url.ParseQuery(cookie.Value)
|
||||
for key, value := range flash {
|
||||
t.Logf("Flash %q: %q", key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req = NewRequest(t, "GET", "/user/settings/applications")
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
token := htmlDoc.doc.Find(".ui.info p").Text()
|
||||
token = htmlDoc.doc.Find(".ui.info p").Text()
|
||||
assert.NotEmpty(t, token)
|
||||
return token
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {defineConfig} from 'vitest/dist/config.js';
|
||||
import {readFile} from 'fs/promises';
|
||||
import {readFile} from 'node:fs/promises';
|
||||
import {dataToEsm} from '@rollup/pluginutils';
|
||||
import {extname} from 'path';
|
||||
import {extname} from 'node:path';
|
||||
|
||||
function stringPlugin() {
|
||||
return {
|
||||
|
@ -32,6 +32,7 @@ export default {
|
||||
},
|
||||
data: () => ({
|
||||
colorRange: [
|
||||
'var(--color-secondary-alpha-70)',
|
||||
'var(--color-secondary-alpha-70)',
|
||||
'var(--color-primary-light-4)',
|
||||
'var(--color-primary-light-2)',
|
||||
@ -50,6 +51,12 @@ export default {
|
||||
return s;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// work around issue with first legend color being rendered twice and legend cut off
|
||||
const legend = document.querySelector('.vch__external-legend-wrapper');
|
||||
legend.setAttribute('viewBox', '12 0 80 10');
|
||||
legend.style.marginRight = '-12px';
|
||||
},
|
||||
methods: {
|
||||
handleDayClick(e) {
|
||||
// Reset filter if same date is clicked
|
||||
|
@ -49,6 +49,8 @@ async function initRepoProjectSortable() {
|
||||
filter: '[data-id="0"]',
|
||||
animation: 150,
|
||||
ghostClass: 'card-ghost',
|
||||
delayOnTouchOnly: true,
|
||||
delay: 500,
|
||||
onSort: () => {
|
||||
boardColumns = mainBoard.getElementsByClassName('board-column');
|
||||
for (let i = 0; i < boardColumns.length; i++) {
|
||||
@ -76,6 +78,8 @@ async function initRepoProjectSortable() {
|
||||
ghostClass: 'card-ghost',
|
||||
onAdd: moveIssue,
|
||||
onUpdate: moveIssue,
|
||||
delayOnTouchOnly: true,
|
||||
delay: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -200,7 +204,7 @@ function getRelativeColor(color) {
|
||||
}
|
||||
|
||||
function rgbToHex(rgb) {
|
||||
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
||||
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+).*\)$/);
|
||||
return `#${hex(rgb[1])}${hex(rgb[2])}${hex(rgb[3])}`;
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,10 @@ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
|
||||
import {VueLoaderPlugin} from 'vue-loader';
|
||||
import EsBuildLoader from 'esbuild-loader';
|
||||
import {parse, dirname} from 'path';
|
||||
import {parse, dirname} from 'node:path';
|
||||
import webpack from 'webpack';
|
||||
import {fileURLToPath} from 'url';
|
||||
import {readFileSync} from 'fs';
|
||||
import {fileURLToPath} from 'node:url';
|
||||
import {readFileSync} from 'node:fs';
|
||||
|
||||
const {ESBuildMinifyPlugin} = EsBuildLoader;
|
||||
const {SourceMapDevToolPlugin} = webpack;
|
||||
|
Loading…
x
Reference in New Issue
Block a user