forked from NYANDEV/forgejo
Compare commits
25 commits
forgejo
...
forgejo-fe
Author | SHA1 | Date | |
---|---|---|---|
|
f43e9fc4fd | ||
|
7adaafa760 | ||
|
34212791ee | ||
|
e11dcc60f2 | ||
|
c1d14c5fff | ||
|
6623630d10 | ||
|
c240b34f59 | ||
|
7426c1edb4 | ||
|
2edac36701 | ||
|
f0bc5decfb | ||
|
0803eaa2e3 | ||
|
54ece82417 | ||
|
e66b8edbc6 | ||
|
7757a5c34c | ||
|
c41ba7a148 | ||
|
be59270696 | ||
|
d7c09d9cc8 | ||
|
5d02454155 | ||
|
79bbbe2dd2 | ||
|
9247594970 | ||
|
a74d7ce6c5 | ||
|
818c7f4ca9 | ||
|
86bf362a3c | ||
|
b570eca0b9 | ||
|
83646119fb |
3578 changed files with 69202 additions and 104007 deletions
|
@ -13,42 +13,46 @@ groups:
|
|||
-
|
||||
name: BREAKING
|
||||
labels:
|
||||
- pr/breaking
|
||||
- kind/breaking
|
||||
-
|
||||
name: SECURITY
|
||||
labels:
|
||||
- topic/security
|
||||
- kind/security
|
||||
-
|
||||
name: FEATURES
|
||||
labels:
|
||||
- type/feature
|
||||
- kind/feature
|
||||
-
|
||||
name: API
|
||||
labels:
|
||||
- modifies/api
|
||||
- kind/api
|
||||
-
|
||||
name: ENHANCEMENTS
|
||||
labels:
|
||||
- type/enhancement
|
||||
- type/refactoring
|
||||
- topic/ui
|
||||
- kind/enhancement
|
||||
- kind/refactor
|
||||
- kind/ui
|
||||
-
|
||||
name: BUGFIXES
|
||||
labels:
|
||||
- type/bug
|
||||
- kind/bug
|
||||
-
|
||||
name: TESTING
|
||||
labels:
|
||||
- type/testing
|
||||
- kind/testing
|
||||
-
|
||||
name: TRANSLATION
|
||||
labels:
|
||||
- kind/translation
|
||||
-
|
||||
name: BUILD
|
||||
labels:
|
||||
- topic/build
|
||||
- topic/code-linting
|
||||
- kind/build
|
||||
- kind/lint
|
||||
-
|
||||
name: DOCS
|
||||
labels:
|
||||
- type/docs
|
||||
- kind/docs
|
||||
-
|
||||
name: MISC
|
||||
default: true
|
||||
|
|
342
.deadcode-out
342
.deadcode-out
|
@ -1,342 +0,0 @@
|
|||
package "code.gitea.io/gitea/cmd"
|
||||
func NoMainListener
|
||||
|
||||
package "code.gitea.io/gitea/cmd/forgejo"
|
||||
func ContextSetNoInit
|
||||
func ContextSetNoExit
|
||||
func ContextSetStderr
|
||||
func ContextGetStderr
|
||||
func ContextSetStdout
|
||||
func ContextSetStdin
|
||||
|
||||
package "code.gitea.io/gitea/models"
|
||||
func IsErrUpdateTaskNotExist
|
||||
func (ErrUpdateTaskNotExist).Error
|
||||
func (ErrUpdateTaskNotExist).Unwrap
|
||||
func IsErrSHANotFound
|
||||
func GetYamlFixturesAccess
|
||||
|
||||
package "code.gitea.io/gitea/models/actions"
|
||||
func (ScheduleList).GetUserIDs
|
||||
func (ScheduleList).GetRepoIDs
|
||||
func (ScheduleList).LoadTriggerUser
|
||||
func (ScheduleList).LoadRepos
|
||||
func GetVariableByID
|
||||
|
||||
package "code.gitea.io/gitea/models/asymkey"
|
||||
func (ErrGPGKeyAccessDenied).Error
|
||||
func (ErrGPGKeyAccessDenied).Unwrap
|
||||
func HasDeployKey
|
||||
|
||||
package "code.gitea.io/gitea/models/auth"
|
||||
func GetSourceByName
|
||||
func GetWebAuthnCredentialByID
|
||||
func WebAuthnCredentials
|
||||
|
||||
package "code.gitea.io/gitea/models/db"
|
||||
func TruncateBeans
|
||||
func InTransaction
|
||||
func DumpTables
|
||||
|
||||
package "code.gitea.io/gitea/models/dbfs"
|
||||
func (*file).renameTo
|
||||
func Create
|
||||
func Rename
|
||||
|
||||
package "code.gitea.io/gitea/models/forgejo/semver"
|
||||
func GetVersion
|
||||
func SetVersionString
|
||||
func SetVersion
|
||||
|
||||
package "code.gitea.io/gitea/models/git"
|
||||
func RemoveDeletedBranchByID
|
||||
|
||||
package "code.gitea.io/gitea/models/issues"
|
||||
func IsErrUnknownDependencyType
|
||||
func (ErrNewIssueInsert).Error
|
||||
func IsErrIssueWasClosed
|
||||
func ChangeMilestoneStatus
|
||||
|
||||
package "code.gitea.io/gitea/models/migrations/base"
|
||||
func removeAllWithRetry
|
||||
func newXORMEngine
|
||||
func deleteDB
|
||||
func PrepareTestEnv
|
||||
func MainTest
|
||||
|
||||
package "code.gitea.io/gitea/models/migrations/v1_22"
|
||||
func AddIgnoreStaleApprovalsColumnToProtectedBranchTable
|
||||
|
||||
package "code.gitea.io/gitea/models/organization"
|
||||
func UpdateTeamUnits
|
||||
func (SearchMembersOptions).ToConds
|
||||
func UsersInTeamsCount
|
||||
|
||||
package "code.gitea.io/gitea/models/perm/access"
|
||||
func GetRepoWriters
|
||||
|
||||
package "code.gitea.io/gitea/models/project"
|
||||
func UpdateBoardSorting
|
||||
func ChangeProjectStatus
|
||||
|
||||
package "code.gitea.io/gitea/models/repo"
|
||||
func DeleteAttachmentsByIssue
|
||||
func (*releaseSorter).Len
|
||||
func (*releaseSorter).Less
|
||||
func (*releaseSorter).Swap
|
||||
func SortReleases
|
||||
func FindReposMapByIDs
|
||||
func RepositoryListOfMap
|
||||
func (SearchOrderBy).String
|
||||
func IsErrTopicNotExist
|
||||
func (ErrTopicNotExist).Error
|
||||
func (ErrTopicNotExist).Unwrap
|
||||
func GetTopicByName
|
||||
func WatchRepoMode
|
||||
|
||||
package "code.gitea.io/gitea/models/unittest"
|
||||
func CheckConsistencyFor
|
||||
func checkForConsistency
|
||||
func GetXORMEngine
|
||||
func OverrideFixtures
|
||||
func InitFixtures
|
||||
func LoadFixtures
|
||||
func Copy
|
||||
func CopyDir
|
||||
func NewMockWebServer
|
||||
func NormalizedFullPath
|
||||
func FixturesDir
|
||||
func fatalTestError
|
||||
func InitSettings
|
||||
func MainTest
|
||||
func CreateTestEngine
|
||||
func PrepareTestDatabase
|
||||
func PrepareTestEnv
|
||||
func Cond
|
||||
func OrderBy
|
||||
func LoadBeanIfExists
|
||||
func BeanExists
|
||||
func AssertExistsAndLoadBean
|
||||
func GetCount
|
||||
func AssertNotExistsBean
|
||||
func AssertExistsIf
|
||||
func AssertSuccessfulInsert
|
||||
func AssertCount
|
||||
func AssertInt64InRange
|
||||
|
||||
package "code.gitea.io/gitea/models/user"
|
||||
func IsErrPrimaryEmailCannotDelete
|
||||
func (ErrUserInactive).Error
|
||||
func (ErrUserInactive).Unwrap
|
||||
func IsErrExternalLoginUserAlreadyExist
|
||||
func IsErrExternalLoginUserNotExist
|
||||
func IsErrUserSettingIsNotExist
|
||||
func GetUserAllSettings
|
||||
func DeleteUserSetting
|
||||
func GetUserEmailsByNames
|
||||
|
||||
package "code.gitea.io/gitea/modules/activitypub"
|
||||
func CurrentTime
|
||||
func containsRequiredHTTPHeaders
|
||||
func NewClient
|
||||
func (*Client).NewRequest
|
||||
func (*Client).Post
|
||||
func GetPrivateKey
|
||||
|
||||
package "code.gitea.io/gitea/modules/assetfs"
|
||||
func Bindata
|
||||
|
||||
package "code.gitea.io/gitea/modules/auth/password/hash"
|
||||
func (*DummyHasher).HashWithSaltBytes
|
||||
func NewDummyHasher
|
||||
|
||||
package "code.gitea.io/gitea/modules/auth/password/pwn"
|
||||
func WithHTTP
|
||||
|
||||
package "code.gitea.io/gitea/modules/base"
|
||||
func SetupGiteaRoot
|
||||
|
||||
package "code.gitea.io/gitea/modules/cache"
|
||||
func GetInt
|
||||
func WithNoCacheContext
|
||||
func RemoveContextData
|
||||
|
||||
package "code.gitea.io/gitea/modules/charset"
|
||||
func (*BreakWriter).Write
|
||||
func ToUTF8
|
||||
|
||||
package "code.gitea.io/gitea/modules/context"
|
||||
func GetPrivateContext
|
||||
|
||||
package "code.gitea.io/gitea/modules/emoji"
|
||||
func ReplaceCodes
|
||||
|
||||
package "code.gitea.io/gitea/modules/eventsource"
|
||||
func (*Event).String
|
||||
|
||||
package "code.gitea.io/gitea/modules/git"
|
||||
func AllowLFSFiltersArgs
|
||||
func AddChanges
|
||||
func AddChangesWithArgs
|
||||
func CommitChanges
|
||||
func CommitChangesWithArgs
|
||||
func IsErrExecTimeout
|
||||
func (ErrExecTimeout).Error
|
||||
func (ErrUnsupportedVersion).Error
|
||||
func SetUpdateHook
|
||||
func openRepositoryWithDefaultContext
|
||||
func GetBranchCommitID
|
||||
func IsTagExist
|
||||
func ToEntryMode
|
||||
func (*LimitedReaderCloser).Read
|
||||
func (*LimitedReaderCloser).Close
|
||||
|
||||
package "code.gitea.io/gitea/modules/gitgraph"
|
||||
func (*Parser).Reset
|
||||
|
||||
package "code.gitea.io/gitea/modules/graceful"
|
||||
func (*Manager).TerminateContext
|
||||
func (*Manager).Err
|
||||
func (*Manager).Value
|
||||
func (*Manager).Deadline
|
||||
|
||||
package "code.gitea.io/gitea/modules/hcaptcha"
|
||||
func WithHTTP
|
||||
|
||||
package "code.gitea.io/gitea/modules/json"
|
||||
func (StdJSON).Marshal
|
||||
func (StdJSON).Unmarshal
|
||||
func (StdJSON).NewEncoder
|
||||
func (StdJSON).NewDecoder
|
||||
func (StdJSON).Indent
|
||||
|
||||
package "code.gitea.io/gitea/modules/markup"
|
||||
func IsSameDomain
|
||||
func GetRendererByType
|
||||
func RenderString
|
||||
func IsMarkupFile
|
||||
|
||||
package "code.gitea.io/gitea/modules/markup/console"
|
||||
func Render
|
||||
func RenderString
|
||||
|
||||
package "code.gitea.io/gitea/modules/markup/markdown"
|
||||
func IsDetails
|
||||
func IsSummary
|
||||
func IsTaskCheckBoxListItem
|
||||
func IsIcon
|
||||
func IsColorPreview
|
||||
func RenderRawString
|
||||
|
||||
package "code.gitea.io/gitea/modules/markup/markdown/math"
|
||||
func WithInlineDollarParser
|
||||
func WithBlockDollarParser
|
||||
|
||||
package "code.gitea.io/gitea/modules/markup/mdstripper"
|
||||
func StripMarkdown
|
||||
|
||||
package "code.gitea.io/gitea/modules/markup/orgmode"
|
||||
func RenderString
|
||||
|
||||
package "code.gitea.io/gitea/modules/private"
|
||||
func ActionsRunnerRegister
|
||||
|
||||
package "code.gitea.io/gitea/modules/process"
|
||||
func (*Manager).ExecTimeout
|
||||
|
||||
package "code.gitea.io/gitea/modules/queue"
|
||||
func newBaseChannelSimple
|
||||
func newBaseChannelUnique
|
||||
func newBaseRedisSimple
|
||||
func newBaseRedisUnique
|
||||
func newWorkerPoolQueueForTest
|
||||
|
||||
package "code.gitea.io/gitea/modules/queue/lqinternal"
|
||||
func QueueItemIDBytes
|
||||
func QueueItemKeyBytes
|
||||
func ListLevelQueueKeys
|
||||
|
||||
package "code.gitea.io/gitea/modules/setting"
|
||||
func NewConfigProviderFromData
|
||||
func (*GitConfigType).GetOption
|
||||
func InitLoggersForTest
|
||||
|
||||
package "code.gitea.io/gitea/modules/storage"
|
||||
func (ErrInvalidConfiguration).Error
|
||||
func IsErrInvalidConfiguration
|
||||
|
||||
package "code.gitea.io/gitea/modules/structs"
|
||||
func ParseCreateHook
|
||||
func ParsePushHook
|
||||
|
||||
package "code.gitea.io/gitea/modules/sync"
|
||||
func (*StatusTable).Start
|
||||
func (*StatusTable).IsRunning
|
||||
|
||||
package "code.gitea.io/gitea/modules/testlogger"
|
||||
func (*testLoggerWriterCloser).pushT
|
||||
func (*testLoggerWriterCloser).Write
|
||||
func (*testLoggerWriterCloser).popT
|
||||
func (*testLoggerWriterCloser).Close
|
||||
func (*testLoggerWriterCloser).Reset
|
||||
func PrintCurrentTest
|
||||
func Printf
|
||||
func NewTestLoggerWriter
|
||||
|
||||
package "code.gitea.io/gitea/modules/timeutil"
|
||||
func GetExecutableModTime
|
||||
func MockSet
|
||||
func MockUnset
|
||||
|
||||
package "code.gitea.io/gitea/modules/translation"
|
||||
func (MockLocale).Language
|
||||
func (MockLocale).Tr
|
||||
func (MockLocale).TrN
|
||||
func (MockLocale).PrettyNumber
|
||||
|
||||
package "code.gitea.io/gitea/modules/util"
|
||||
func UnsafeStringToBytes
|
||||
|
||||
package "code.gitea.io/gitea/modules/util/filebuffer"
|
||||
func CreateFromReader
|
||||
|
||||
package "code.gitea.io/gitea/modules/web"
|
||||
func RouteMock
|
||||
func RouteMockReset
|
||||
|
||||
package "code.gitea.io/gitea/modules/web/middleware"
|
||||
func DeleteLocaleCookie
|
||||
|
||||
package "code.gitea.io/gitea/routers/web"
|
||||
func NotFound
|
||||
|
||||
package "code.gitea.io/gitea/routers/web/org"
|
||||
func MustEnableProjects
|
||||
func getActionIssues
|
||||
func UpdateIssueProject
|
||||
|
||||
package "code.gitea.io/gitea/services/convert"
|
||||
func ToSecret
|
||||
|
||||
package "code.gitea.io/gitea/services/forms"
|
||||
func (*DeadlineForm).Validate
|
||||
|
||||
package "code.gitea.io/gitea/services/pull"
|
||||
func IsCommitStatusContextSuccess
|
||||
|
||||
package "code.gitea.io/gitea/services/repository"
|
||||
func GetBranchCommitID
|
||||
func IsErrForkAlreadyExist
|
||||
|
||||
package "code.gitea.io/gitea/services/repository/archiver"
|
||||
func ArchiveRepository
|
||||
|
||||
package "code.gitea.io/gitea/services/repository/files"
|
||||
func (*ContentType).String
|
||||
func GetFileResponseFromCommit
|
||||
func (*TemporaryUploadRepository).GetLastCommit
|
||||
func (*TemporaryUploadRepository).GetLastCommitByRef
|
||||
|
||||
package "code.gitea.io/gitea/services/webhook"
|
||||
func NewNotifier
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"name": "Gitea DevContainer",
|
||||
"image": "mcr.microsoft.com/devcontainers/go:1.21-bullseye",
|
||||
"features": {
|
||||
// installs nodejs into container
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version":"20"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/git-lfs:1.1.0": {},
|
||||
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
|
||||
"ghcr.io/devcontainers/features/python:1": {}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {},
|
||||
// same extensions as Gitpod, should match /.gitpod.yml
|
||||
"extensions": [
|
||||
"editorconfig.editorconfig",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"golang.go",
|
||||
"stylelint.vscode-stylelint",
|
||||
"DavidAnson.vscode-markdownlint",
|
||||
"Vue.volar",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"zixuanchen.vitest-explorer",
|
||||
"qwtel.sqlite-viewer",
|
||||
"GitHub.vscode-pull-request-github"
|
||||
]
|
||||
}
|
||||
},
|
||||
"portsAttributes": {
|
||||
"3000": {
|
||||
"label": "Gitea Web",
|
||||
"onAutoForward": "notify"
|
||||
}
|
||||
},
|
||||
"postCreateCommand": "make deps"
|
||||
}
|
|
@ -75,10 +75,10 @@ cpu.out
|
|||
/yarn.lock
|
||||
/yarn-error.log
|
||||
/npm-debug.log*
|
||||
/public/assets/js
|
||||
/public/assets/css
|
||||
/public/assets/fonts
|
||||
/public/assets/img/webpack
|
||||
/public/js
|
||||
/public/css
|
||||
/public/fonts
|
||||
/public/img/webpack
|
||||
/vendor
|
||||
/web_src/fomantic/node_modules
|
||||
/web_src/fomantic/build/*
|
||||
|
|
865
.drone.yml
Normal file
865
.drone.yml
Normal file
|
@ -0,0 +1,865 @@
|
|||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: release-latest
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
workspace:
|
||||
base: /source
|
||||
path: /
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
- "release/*"
|
||||
event:
|
||||
- push
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
temp: {}
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: deps-frontend
|
||||
image: node:20
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-frontend
|
||||
|
||||
- name: deps-backend
|
||||
image: gitea/test_env:linux-1.20-amd64
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-backend
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
||||
- name: static
|
||||
image: techknowlogick/xgo:go-1.20.x
|
||||
pull: always
|
||||
commands:
|
||||
# Upgrade to node 20 once https://github.com/techknowlogick/xgo/issues/163 is resolved
|
||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get -qqy install nodejs
|
||||
- export PATH=$PATH:$GOPATH/bin
|
||||
- make release
|
||||
environment:
|
||||
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
||||
- name: gpg-sign
|
||||
image: plugins/gpgsign:1
|
||||
pull: always
|
||||
settings:
|
||||
detach_sign: true
|
||||
excludes:
|
||||
- "dist/release/*.sha256"
|
||||
files:
|
||||
- "dist/release/*"
|
||||
environment:
|
||||
GPGSIGN_KEY:
|
||||
from_secret: gpgsign_key
|
||||
GPGSIGN_PASSPHRASE:
|
||||
from_secret: gpgsign_passphrase
|
||||
|
||||
- name: release-branch
|
||||
image: woodpeckerci/plugin-s3:latest
|
||||
pull: always
|
||||
settings:
|
||||
acl:
|
||||
from_secret: aws_s3_acl
|
||||
region:
|
||||
from_secret: aws_s3_region
|
||||
bucket:
|
||||
from_secret: aws_s3_bucket
|
||||
endpoint:
|
||||
from_secret: aws_s3_endpoint
|
||||
path_style:
|
||||
from_secret: aws_s3_path_style
|
||||
source: "dist/release/*"
|
||||
strip_prefix: dist/release/
|
||||
target: "/gitea/${DRONE_BRANCH##release/v}"
|
||||
environment:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
from_secret: aws_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
from_secret: aws_secret_access_key
|
||||
when:
|
||||
branch:
|
||||
- "release/*"
|
||||
event:
|
||||
- push
|
||||
|
||||
- name: release-main
|
||||
image: woodpeckerci/plugin-s3:latest
|
||||
settings:
|
||||
acl:
|
||||
from_secret: aws_s3_acl
|
||||
region:
|
||||
from_secret: aws_s3_region
|
||||
bucket:
|
||||
from_secret: aws_s3_bucket
|
||||
endpoint:
|
||||
from_secret: aws_s3_endpoint
|
||||
path_style:
|
||||
from_secret: aws_s3_path_style
|
||||
source: "dist/release/*"
|
||||
strip_prefix: dist/release/
|
||||
target: /gitea/main
|
||||
environment:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
from_secret: aws_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
from_secret: aws_secret_access_key
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: release-version
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
workspace:
|
||||
base: /source
|
||||
path: /
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
temp: {}
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: deps-frontend
|
||||
image: node:20
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-frontend
|
||||
|
||||
- name: deps-backend
|
||||
image: gitea/test_env:linux-1.20-amd64
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-backend
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
||||
- name: static
|
||||
image: techknowlogick/xgo:go-1.20.x
|
||||
pull: always
|
||||
commands:
|
||||
# Upgrade to node 20 once https://github.com/techknowlogick/xgo/issues/163 is resolved
|
||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get -qqy install nodejs
|
||||
- export PATH=$PATH:$GOPATH/bin
|
||||
- make release
|
||||
environment:
|
||||
GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
depends_on: [fetch-tags]
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
||||
- name: gpg-sign
|
||||
image: plugins/gpgsign:1
|
||||
pull: always
|
||||
settings:
|
||||
detach_sign: true
|
||||
excludes:
|
||||
- "dist/release/*.sha256"
|
||||
files:
|
||||
- "dist/release/*"
|
||||
environment:
|
||||
GPGSIGN_KEY:
|
||||
from_secret: gpgsign_key
|
||||
GPGSIGN_PASSPHRASE:
|
||||
from_secret: gpgsign_passphrase
|
||||
depends_on: [static]
|
||||
|
||||
- name: release-tag
|
||||
image: woodpeckerci/plugin-s3:latest
|
||||
pull: always
|
||||
settings:
|
||||
acl:
|
||||
from_secret: aws_s3_acl
|
||||
region:
|
||||
from_secret: aws_s3_region
|
||||
bucket:
|
||||
from_secret: aws_s3_bucket
|
||||
endpoint:
|
||||
from_secret: aws_s3_endpoint
|
||||
path_style:
|
||||
from_secret: aws_s3_path_style
|
||||
source: "dist/release/*"
|
||||
strip_prefix: dist/release/
|
||||
target: "/gitea/${DRONE_TAG##v}"
|
||||
environment:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
from_secret: aws_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
from_secret: aws_secret_access_key
|
||||
depends_on: [gpg-sign]
|
||||
|
||||
- name: github
|
||||
image: plugins/github-release:latest
|
||||
pull: always
|
||||
settings:
|
||||
files:
|
||||
- "dist/release/*"
|
||||
file_exists: overwrite
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: github_token
|
||||
depends_on: [gpg-sign]
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-linux-amd64-release-version
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
include:
|
||||
- "refs/tags/**"
|
||||
exclude:
|
||||
- "refs/tags/**-rc*"
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-amd64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-amd64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-linux-amd64-release-candidate-version
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- "refs/tags/**-rc*"
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
tags: ${DRONE_TAG##v}-linux-amd64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
tags: ${DRONE_TAG##v}-linux-amd64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-linux-amd64-release
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
tags: nightly-linux-amd64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
tags: nightly-linux-amd64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: docker-linux-amd64-release-branch
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- "refs/heads/release/v*"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-nightly-linux-amd64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-nightly-linux-amd64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-linux-arm64-release-version
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
include:
|
||||
- "refs/tags/**"
|
||||
exclude:
|
||||
- "refs/tags/**-rc*"
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-arm64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-arm64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-linux-arm64-release-candidate-version
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- "refs/tags/**-rc*"
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
tags: ${DRONE_TAG##v}-linux-arm64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
tags: ${DRONE_TAG##v}-linux-arm64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-linux-arm64-release
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
tags: nightly-linux-arm64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
tags: nightly-linux-arm64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: docker-linux-arm64-release-branch
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- "refs/heads/release/v*"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
image: docker:git
|
||||
pull: always
|
||||
commands:
|
||||
- git fetch --tags --force
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker:latest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-nightly-linux-arm64
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
- name: publish-rootless
|
||||
image: plugins/docker:latest
|
||||
settings:
|
||||
dockerfile: Dockerfile.rootless
|
||||
auto_tag: false
|
||||
tags: ${DRONE_BRANCH##release/v}-nightly-linux-arm64-rootless
|
||||
repo: gitea/gitea
|
||||
build_args:
|
||||
- GOPROXY=https://goproxy.io
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
environment:
|
||||
PLUGIN_MIRROR:
|
||||
from_secret: plugin_mirror
|
||||
DOCKER_BUILDKIT: 1
|
||||
when:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-manifest-version
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: manifest-rootless
|
||||
image: plugins/manifest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: true
|
||||
ignore_missing: true
|
||||
spec: docker/manifest.rootless.tmpl
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
|
||||
- name: manifest
|
||||
image: plugins/manifest
|
||||
settings:
|
||||
auto_tag: true
|
||||
ignore_missing: true
|
||||
spec: docker/manifest.tmpl
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- "refs/tags/**"
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
depends_on:
|
||||
- docker-linux-amd64-release-version
|
||||
- docker-linux-amd64-release-candidate-version
|
||||
- docker-linux-arm64-release-version
|
||||
- docker-linux-arm64-release-candidate-version
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: docker-manifest
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: manifest-rootless
|
||||
image: plugins/manifest
|
||||
pull: always
|
||||
settings:
|
||||
auto_tag: false
|
||||
ignore_missing: true
|
||||
spec: docker/manifest.rootless.tmpl
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
|
||||
- name: manifest
|
||||
image: plugins/manifest
|
||||
settings:
|
||||
auto_tag: false
|
||||
ignore_missing: true
|
||||
spec: docker/manifest.tmpl
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
- "refs/heads/release/v*"
|
||||
paths:
|
||||
exclude:
|
||||
- "docs/**"
|
||||
|
||||
depends_on:
|
||||
- docker-linux-amd64-release
|
||||
- docker-linux-arm64-release
|
||||
- docker-linux-amd64-release-branch
|
||||
- docker-linux-arm64-release-branch
|
335
.eslintrc.yaml
335
.eslintrc.yaml
|
@ -10,100 +10,41 @@ parserOptions:
|
|||
|
||||
plugins:
|
||||
- "@eslint-community/eslint-plugin-eslint-comments"
|
||||
- "@stylistic/eslint-plugin-js"
|
||||
- eslint-plugin-array-func
|
||||
- eslint-plugin-i
|
||||
- eslint-plugin-custom-elements
|
||||
- eslint-plugin-import
|
||||
- eslint-plugin-jquery
|
||||
- eslint-plugin-no-jquery
|
||||
- eslint-plugin-no-use-extend-native
|
||||
- eslint-plugin-regexp
|
||||
- eslint-plugin-sonarjs
|
||||
- eslint-plugin-unicorn
|
||||
- eslint-plugin-vitest
|
||||
- eslint-plugin-vitest-globals
|
||||
- eslint-plugin-wc
|
||||
|
||||
env:
|
||||
es2024: true
|
||||
es2022: true
|
||||
node: true
|
||||
|
||||
globals:
|
||||
__webpack_public_path__: true
|
||||
|
||||
overrides:
|
||||
- files: ["web_src/**/*"]
|
||||
globals:
|
||||
__webpack_public_path__: true
|
||||
process: false # https://github.com/webpack/webpack/issues/15833
|
||||
- files: ["web_src/**/*", "docs/**/*"]
|
||||
- files: ["web_src/**/*.js", "docs/**/*.js"]
|
||||
env:
|
||||
browser: true
|
||||
node: false
|
||||
- files: ["web_src/**/*worker.*"]
|
||||
- files: ["web_src/**/*worker.js"]
|
||||
env:
|
||||
worker: true
|
||||
rules:
|
||||
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top]
|
||||
- files: ["build/generate-images.js"]
|
||||
rules:
|
||||
i/no-unresolved: [0]
|
||||
i/no-extraneous-dependencies: [0]
|
||||
- files: ["*.config.*"]
|
||||
import/no-unresolved: [0]
|
||||
import/no-extraneous-dependencies: [0]
|
||||
- files: ["*.config.js"]
|
||||
rules:
|
||||
i/no-unused-modules: [0]
|
||||
- files: ["**/*.test.*", "web_src/js/test/setup.js"]
|
||||
env:
|
||||
vitest-globals/env: true
|
||||
rules:
|
||||
vitest/consistent-test-filename: [0]
|
||||
vitest/consistent-test-it: [0]
|
||||
vitest/expect-expect: [0]
|
||||
vitest/max-expects: [0]
|
||||
vitest/max-nested-describe: [0]
|
||||
vitest/no-alias-methods: [0]
|
||||
vitest/no-commented-out-tests: [0]
|
||||
vitest/no-conditional-expect: [0]
|
||||
vitest/no-conditional-in-test: [0]
|
||||
vitest/no-conditional-tests: [0]
|
||||
vitest/no-disabled-tests: [0]
|
||||
vitest/no-done-callback: [0]
|
||||
vitest/no-duplicate-hooks: [0]
|
||||
vitest/no-focused-tests: [0]
|
||||
vitest/no-hooks: [0]
|
||||
vitest/no-identical-title: [2]
|
||||
vitest/no-interpolation-in-snapshots: [0]
|
||||
vitest/no-large-snapshots: [0]
|
||||
vitest/no-mocks-import: [0]
|
||||
vitest/no-restricted-matchers: [0]
|
||||
vitest/no-restricted-vi-methods: [0]
|
||||
vitest/no-standalone-expect: [0]
|
||||
vitest/no-test-prefixes: [0]
|
||||
vitest/no-test-return-statement: [0]
|
||||
vitest/prefer-called-with: [0]
|
||||
vitest/prefer-comparison-matcher: [0]
|
||||
vitest/prefer-each: [0]
|
||||
vitest/prefer-equality-matcher: [0]
|
||||
vitest/prefer-expect-resolves: [0]
|
||||
vitest/prefer-hooks-in-order: [0]
|
||||
vitest/prefer-hooks-on-top: [2]
|
||||
vitest/prefer-lowercase-title: [0]
|
||||
vitest/prefer-mock-promise-shorthand: [0]
|
||||
vitest/prefer-snapshot-hint: [0]
|
||||
vitest/prefer-spy-on: [0]
|
||||
vitest/prefer-strict-equal: [0]
|
||||
vitest/prefer-to-be: [0]
|
||||
vitest/prefer-to-be-falsy: [0]
|
||||
vitest/prefer-to-be-object: [0]
|
||||
vitest/prefer-to-be-truthy: [0]
|
||||
vitest/prefer-to-contain: [0]
|
||||
vitest/prefer-to-have-length: [0]
|
||||
vitest/prefer-todo: [0]
|
||||
vitest/require-hook: [0]
|
||||
vitest/require-to-throw-message: [0]
|
||||
vitest/require-top-level-describe: [0]
|
||||
vitest/valid-describe-callback: [2]
|
||||
vitest/valid-expect: [2]
|
||||
vitest/valid-title: [2]
|
||||
- files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"]
|
||||
rules:
|
||||
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
|
||||
import/no-unused-modules: [0]
|
||||
|
||||
rules:
|
||||
"@eslint-community/eslint-comments/disable-enable-pair": [2]
|
||||
|
@ -115,74 +56,11 @@ rules:
|
|||
"@eslint-community/eslint-comments/no-unused-enable": [2]
|
||||
"@eslint-community/eslint-comments/no-use": [0]
|
||||
"@eslint-community/eslint-comments/require-description": [0]
|
||||
"@stylistic/js/array-bracket-newline": [0]
|
||||
"@stylistic/js/array-bracket-spacing": [2, never]
|
||||
"@stylistic/js/array-element-newline": [0]
|
||||
"@stylistic/js/arrow-parens": [2, always]
|
||||
"@stylistic/js/arrow-spacing": [2, {before: true, after: true}]
|
||||
"@stylistic/js/block-spacing": [0]
|
||||
"@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}]
|
||||
"@stylistic/js/comma-dangle": [2, only-multiline]
|
||||
"@stylistic/js/comma-spacing": [2, {before: false, after: true}]
|
||||
"@stylistic/js/comma-style": [2, last]
|
||||
"@stylistic/js/computed-property-spacing": [2, never]
|
||||
"@stylistic/js/dot-location": [2, property]
|
||||
"@stylistic/js/eol-last": [2]
|
||||
"@stylistic/js/function-call-spacing": [2, never]
|
||||
"@stylistic/js/function-call-argument-newline": [0]
|
||||
"@stylistic/js/function-paren-newline": [0]
|
||||
"@stylistic/js/generator-star-spacing": [0]
|
||||
"@stylistic/js/implicit-arrow-linebreak": [0]
|
||||
"@stylistic/js/indent": [2, 2, {ignoreComments: true, SwitchCase: 1}]
|
||||
"@stylistic/js/key-spacing": [2]
|
||||
"@stylistic/js/keyword-spacing": [2]
|
||||
"@stylistic/js/linebreak-style": [2, unix]
|
||||
"@stylistic/js/lines-around-comment": [0]
|
||||
"@stylistic/js/lines-between-class-members": [0]
|
||||
"@stylistic/js/max-len": [0]
|
||||
"@stylistic/js/max-statements-per-line": [0]
|
||||
"@stylistic/js/multiline-ternary": [0]
|
||||
"@stylistic/js/new-parens": [2]
|
||||
"@stylistic/js/newline-per-chained-call": [0]
|
||||
"@stylistic/js/no-confusing-arrow": [0]
|
||||
"@stylistic/js/no-extra-parens": [0]
|
||||
"@stylistic/js/no-extra-semi": [2]
|
||||
"@stylistic/js/no-floating-decimal": [0]
|
||||
"@stylistic/js/no-mixed-operators": [0]
|
||||
"@stylistic/js/no-mixed-spaces-and-tabs": [2]
|
||||
"@stylistic/js/no-multi-spaces": [2, {ignoreEOLComments: true, exceptions: {Property: true}}]
|
||||
"@stylistic/js/no-multiple-empty-lines": [2, {max: 1, maxEOF: 0, maxBOF: 0}]
|
||||
"@stylistic/js/no-tabs": [2]
|
||||
"@stylistic/js/no-trailing-spaces": [2]
|
||||
"@stylistic/js/no-whitespace-before-property": [2]
|
||||
"@stylistic/js/nonblock-statement-body-position": [2]
|
||||
"@stylistic/js/object-curly-newline": [0]
|
||||
"@stylistic/js/object-curly-spacing": [2, never]
|
||||
"@stylistic/js/object-property-newline": [0]
|
||||
"@stylistic/js/one-var-declaration-per-line": [0]
|
||||
"@stylistic/js/operator-linebreak": [2, after]
|
||||
"@stylistic/js/padded-blocks": [2, never]
|
||||
"@stylistic/js/padding-line-between-statements": [0]
|
||||
"@stylistic/js/quote-props": [0]
|
||||
"@stylistic/js/quotes": [2, single, {avoidEscape: true, allowTemplateLiterals: true}]
|
||||
"@stylistic/js/rest-spread-spacing": [2, never]
|
||||
"@stylistic/js/semi": [2, always, {omitLastInOneLineBlock: true}]
|
||||
"@stylistic/js/semi-spacing": [2, {before: false, after: true}]
|
||||
"@stylistic/js/semi-style": [2, last]
|
||||
"@stylistic/js/space-before-blocks": [2, always]
|
||||
"@stylistic/js/space-before-function-paren": [0]
|
||||
"@stylistic/js/space-in-parens": [2, never]
|
||||
"@stylistic/js/space-infix-ops": [2]
|
||||
"@stylistic/js/space-unary-ops": [2]
|
||||
"@stylistic/js/spaced-comment": [2, always]
|
||||
"@stylistic/js/switch-colon-spacing": [2]
|
||||
"@stylistic/js/template-curly-spacing": [2, never]
|
||||
"@stylistic/js/template-tag-spacing": [2, never]
|
||||
"@stylistic/js/wrap-iife": [2, inside]
|
||||
"@stylistic/js/wrap-regex": [0]
|
||||
"@stylistic/js/yield-star-spacing": [2, after]
|
||||
accessor-pairs: [2]
|
||||
array-bracket-newline: [0]
|
||||
array-bracket-spacing: [2, never]
|
||||
array-callback-return: [2, {checkForEach: true}]
|
||||
array-element-newline: [0]
|
||||
array-func/avoid-reverse: [2]
|
||||
array-func/from-map: [2]
|
||||
array-func/no-unnecessary-this-arg: [2]
|
||||
|
@ -190,73 +68,101 @@ rules:
|
|||
array-func/prefer-flat-map: [0] # handled by unicorn/prefer-array-flat-map
|
||||
array-func/prefer-flat: [0] # handled by unicorn/prefer-array-flat
|
||||
arrow-body-style: [0]
|
||||
arrow-parens: [2, always]
|
||||
arrow-spacing: [2, {before: true, after: true}]
|
||||
block-scoped-var: [2]
|
||||
brace-style: [2, 1tbs, {allowSingleLine: true}]
|
||||
camelcase: [0]
|
||||
capitalized-comments: [0]
|
||||
class-methods-use-this: [0]
|
||||
comma-dangle: [2, only-multiline]
|
||||
comma-spacing: [2, {before: false, after: true}]
|
||||
comma-style: [2, last]
|
||||
complexity: [0]
|
||||
computed-property-spacing: [2, never]
|
||||
consistent-return: [0]
|
||||
consistent-this: [0]
|
||||
constructor-super: [2]
|
||||
curly: [0]
|
||||
custom-elements/expose-class-on-global: [0]
|
||||
custom-elements/extends-correct-class: [2]
|
||||
custom-elements/file-name-matches-element: [2]
|
||||
custom-elements/no-constructor: [2]
|
||||
custom-elements/no-customized-built-in-elements: [2]
|
||||
custom-elements/no-dom-traversal-in-attributechangedcallback: [2]
|
||||
custom-elements/no-dom-traversal-in-connectedcallback: [2]
|
||||
custom-elements/no-exports-with-element: [2]
|
||||
custom-elements/no-method-prefixed-with-on: [2]
|
||||
custom-elements/no-unchecked-define: [0]
|
||||
custom-elements/one-element-per-file: [0]
|
||||
custom-elements/tag-name-matches-class: [2]
|
||||
custom-elements/valid-tag-name: [2]
|
||||
default-case-last: [2]
|
||||
default-case: [0]
|
||||
default-param-last: [0]
|
||||
dot-location: [2, property]
|
||||
dot-notation: [0]
|
||||
eol-last: [2]
|
||||
eqeqeq: [2]
|
||||
for-direction: [2]
|
||||
func-call-spacing: [2, never]
|
||||
func-name-matching: [2]
|
||||
func-names: [0]
|
||||
func-style: [0]
|
||||
function-call-argument-newline: [0]
|
||||
function-paren-newline: [0]
|
||||
generator-star-spacing: [0]
|
||||
getter-return: [2]
|
||||
grouped-accessor-pairs: [2]
|
||||
guard-for-in: [0]
|
||||
id-blacklist: [0]
|
||||
id-length: [0]
|
||||
id-match: [0]
|
||||
i/consistent-type-specifier-style: [0]
|
||||
i/default: [0]
|
||||
i/dynamic-import-chunkname: [0]
|
||||
i/export: [2]
|
||||
i/exports-last: [0]
|
||||
i/extensions: [2, always, {ignorePackages: true}]
|
||||
i/first: [2]
|
||||
i/group-exports: [0]
|
||||
i/max-dependencies: [0]
|
||||
i/named: [2]
|
||||
i/namespace: [0]
|
||||
i/newline-after-import: [0]
|
||||
i/no-absolute-path: [0]
|
||||
i/no-amd: [2]
|
||||
i/no-anonymous-default-export: [0]
|
||||
i/no-commonjs: [2]
|
||||
i/no-cycle: [2, {ignoreExternal: true, maxDepth: 1}]
|
||||
i/no-default-export: [0]
|
||||
i/no-deprecated: [0]
|
||||
i/no-dynamic-require: [0]
|
||||
i/no-empty-named-blocks: [2]
|
||||
i/no-extraneous-dependencies: [2]
|
||||
i/no-import-module-exports: [0]
|
||||
i/no-internal-modules: [0]
|
||||
i/no-mutable-exports: [0]
|
||||
i/no-named-as-default-member: [0]
|
||||
i/no-named-as-default: [2]
|
||||
i/no-named-default: [0]
|
||||
i/no-named-export: [0]
|
||||
i/no-namespace: [0]
|
||||
i/no-nodejs-modules: [0]
|
||||
i/no-relative-packages: [0]
|
||||
i/no-relative-parent-imports: [0]
|
||||
i/no-restricted-paths: [0]
|
||||
i/no-self-import: [2]
|
||||
i/no-unassigned-import: [0]
|
||||
i/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$", ^vitest/]}]
|
||||
i/no-unused-modules: [2, {unusedExports: true}]
|
||||
i/no-useless-path-segments: [2, {commonjs: true}]
|
||||
i/no-webpack-loader-syntax: [2]
|
||||
i/order: [0]
|
||||
i/prefer-default-export: [0]
|
||||
i/unambiguous: [0]
|
||||
implicit-arrow-linebreak: [0]
|
||||
import/consistent-type-specifier-style: [0]
|
||||
import/default: [0]
|
||||
import/dynamic-import-chunkname: [0]
|
||||
import/export: [2]
|
||||
import/exports-last: [0]
|
||||
import/extensions: [2, always, {ignorePackages: true}]
|
||||
import/first: [2]
|
||||
import/group-exports: [0]
|
||||
import/max-dependencies: [0]
|
||||
import/named: [2]
|
||||
import/namespace: [0]
|
||||
import/newline-after-import: [0]
|
||||
import/no-absolute-path: [0]
|
||||
import/no-amd: [2]
|
||||
import/no-anonymous-default-export: [0]
|
||||
import/no-commonjs: [2]
|
||||
import/no-cycle: [2, {ignoreExternal: true, maxDepth: 1}]
|
||||
import/no-default-export: [0]
|
||||
import/no-deprecated: [0]
|
||||
import/no-dynamic-require: [0]
|
||||
import/no-empty-named-blocks: [2]
|
||||
import/no-extraneous-dependencies: [2]
|
||||
import/no-import-module-exports: [0]
|
||||
import/no-internal-modules: [0]
|
||||
import/no-mutable-exports: [0]
|
||||
import/no-named-as-default-member: [0]
|
||||
import/no-named-as-default: [2]
|
||||
import/no-named-default: [0]
|
||||
import/no-named-export: [0]
|
||||
import/no-namespace: [0]
|
||||
import/no-nodejs-modules: [0]
|
||||
import/no-relative-packages: [0]
|
||||
import/no-relative-parent-imports: [0]
|
||||
import/no-restricted-paths: [0]
|
||||
import/no-self-import: [2]
|
||||
import/no-unassigned-import: [0]
|
||||
import/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}]
|
||||
import/no-unused-modules: [2, {unusedExports: true}]
|
||||
import/no-useless-path-segments: [2, {commonjs: true}]
|
||||
import/no-webpack-loader-syntax: [2]
|
||||
import/order: [0]
|
||||
import/prefer-default-export: [0]
|
||||
import/unambiguous: [0]
|
||||
indent: [2, 2, {SwitchCase: 1}]
|
||||
init-declarations: [0]
|
||||
jquery/no-ajax-events: [2]
|
||||
jquery/no-ajax: [0]
|
||||
|
@ -307,17 +213,27 @@ rules:
|
|||
jquery/no-val: [0]
|
||||
jquery/no-when: [2]
|
||||
jquery/no-wrap: [2]
|
||||
key-spacing: [2]
|
||||
keyword-spacing: [2]
|
||||
line-comment-position: [0]
|
||||
linebreak-style: [2, unix]
|
||||
lines-around-comment: [0]
|
||||
lines-between-class-members: [0]
|
||||
logical-assignment-operators: [0]
|
||||
max-classes-per-file: [0]
|
||||
max-depth: [0]
|
||||
max-len: [0]
|
||||
max-lines-per-function: [0]
|
||||
max-lines: [0]
|
||||
max-nested-callbacks: [0]
|
||||
max-params: [0]
|
||||
max-statements-per-line: [0]
|
||||
max-statements: [0]
|
||||
multiline-comment-style: [2, separate-lines]
|
||||
multiline-ternary: [0]
|
||||
new-cap: [0]
|
||||
new-parens: [2]
|
||||
newline-per-chained-call: [0]
|
||||
no-alert: [0]
|
||||
no-array-constructor: [2]
|
||||
no-async-promise-executor: [0]
|
||||
|
@ -329,6 +245,7 @@ rules:
|
|||
no-class-assign: [2]
|
||||
no-compare-neg-zero: [2]
|
||||
no-cond-assign: [2, except-parens]
|
||||
no-confusing-arrow: [0]
|
||||
no-console: [1, {allow: [debug, info, warn, error]}]
|
||||
no-const-assign: [2]
|
||||
no-constant-binary-expression: [2]
|
||||
|
@ -358,7 +275,10 @@ rules:
|
|||
no-extra-bind: [2]
|
||||
no-extra-boolean-cast: [2]
|
||||
no-extra-label: [0]
|
||||
no-extra-parens: [0]
|
||||
no-extra-semi: [2]
|
||||
no-fallthrough: [2]
|
||||
no-floating-decimal: [0]
|
||||
no-func-assign: [2]
|
||||
no-global-assign: [2]
|
||||
no-implicit-coercion: [2]
|
||||
|
@ -472,7 +392,10 @@ rules:
|
|||
no-loss-of-precision: [2]
|
||||
no-magic-numbers: [0]
|
||||
no-misleading-character-class: [2]
|
||||
no-mixed-operators: [0]
|
||||
no-mixed-spaces-and-tabs: [2]
|
||||
no-multi-assign: [0]
|
||||
no-multi-spaces: [2, {ignoreEOLComments: true, exceptions: {Property: true}}]
|
||||
no-multi-str: [2]
|
||||
no-negated-condition: [0]
|
||||
no-nested-ternary: [0]
|
||||
|
@ -496,8 +419,9 @@ rules:
|
|||
no-restricted-exports: [0]
|
||||
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename]
|
||||
no-restricted-imports: [0]
|
||||
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression, {selector: "CallExpression[callee.name='fetch']", message: "use modules/fetch.js instead"}]
|
||||
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement]
|
||||
no-return-assign: [0]
|
||||
no-return-await: [0]
|
||||
no-script-url: [2]
|
||||
no-self-assign: [2, {props: true}]
|
||||
no-self-compare: [2]
|
||||
|
@ -506,10 +430,12 @@ rules:
|
|||
no-shadow-restricted-names: [2]
|
||||
no-shadow: [0]
|
||||
no-sparse-arrays: [2]
|
||||
no-tabs: [2]
|
||||
no-template-curly-in-string: [2]
|
||||
no-ternary: [0]
|
||||
no-this-before-super: [2]
|
||||
no-throw-literal: [2]
|
||||
no-trailing-spaces: [2]
|
||||
no-undef-init: [2]
|
||||
no-undef: [2, {typeof: true}]
|
||||
no-undefined: [0]
|
||||
|
@ -539,25 +465,32 @@ rules:
|
|||
no-var: [2]
|
||||
no-void: [2]
|
||||
no-warning-comments: [0]
|
||||
no-whitespace-before-property: [2]
|
||||
no-with: [0] # handled by no-restricted-syntax
|
||||
nonblock-statement-body-position: [2]
|
||||
object-curly-newline: [0]
|
||||
object-curly-spacing: [2, never]
|
||||
object-shorthand: [2, always]
|
||||
one-var-declaration-per-line: [0]
|
||||
one-var: [0]
|
||||
operator-assignment: [2, always]
|
||||
operator-linebreak: [2, after]
|
||||
padded-blocks: [2, never]
|
||||
padding-line-between-statements: [0]
|
||||
prefer-arrow-callback: [2, {allowNamedFunctions: true, allowUnboundThis: true}]
|
||||
prefer-const: [2, {destructuring: all, ignoreReadBeforeAssign: true}]
|
||||
prefer-destructuring: [0]
|
||||
prefer-exponentiation-operator: [2]
|
||||
prefer-named-capture-group: [0]
|
||||
prefer-numeric-literals: [2]
|
||||
prefer-object-has-own: [2]
|
||||
prefer-object-has-own: [0]
|
||||
prefer-object-spread: [2]
|
||||
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
||||
prefer-regex-literals: [2]
|
||||
prefer-rest-params: [2]
|
||||
prefer-spread: [2]
|
||||
prefer-template: [2]
|
||||
quote-props: [0]
|
||||
quotes: [2, single, {avoidEscape: true, allowTemplateLiterals: true}]
|
||||
radix: [2, as-needed]
|
||||
regexp/confusing-quantifier: [2]
|
||||
|
@ -575,7 +508,6 @@ rules:
|
|||
regexp/no-empty-character-class: [0]
|
||||
regexp/no-empty-group: [2]
|
||||
regexp/no-empty-lookarounds-assertion: [2]
|
||||
regexp/no-empty-string-literal: [2]
|
||||
regexp/no-escape-backspace: [2]
|
||||
regexp/no-extra-lookaround-assertions: [0]
|
||||
regexp/no-invalid-regexp: [2]
|
||||
|
@ -606,8 +538,6 @@ rules:
|
|||
regexp/no-useless-non-capturing-group: [2]
|
||||
regexp/no-useless-quantifier: [2]
|
||||
regexp/no-useless-range: [2]
|
||||
regexp/no-useless-set-operand: [2]
|
||||
regexp/no-useless-string-literal: [2]
|
||||
regexp/no-useless-two-nums-quantifier: [2]
|
||||
regexp/no-zero-quantifier: [2]
|
||||
regexp/optimal-lookaround-quantifier: [2]
|
||||
|
@ -627,12 +557,10 @@ rules:
|
|||
regexp/prefer-regexp-exec: [2]
|
||||
regexp/prefer-regexp-test: [2]
|
||||
regexp/prefer-result-array-groups: [0]
|
||||
regexp/prefer-set-operation: [2]
|
||||
regexp/prefer-star-quantifier: [2]
|
||||
regexp/prefer-unicode-codepoint-escapes: [2]
|
||||
regexp/prefer-w: [0]
|
||||
regexp/require-unicode-regexp: [0]
|
||||
regexp/simplify-set-operations: [2]
|
||||
regexp/sort-alternatives: [0]
|
||||
regexp/sort-character-class-elements: [0]
|
||||
regexp/sort-flags: [0]
|
||||
|
@ -643,6 +571,10 @@ rules:
|
|||
require-await: [0]
|
||||
require-unicode-regexp: [0]
|
||||
require-yield: [2]
|
||||
rest-spread-spacing: [2, never]
|
||||
semi-spacing: [2, {before: false, after: true}]
|
||||
semi-style: [2, last]
|
||||
semi: [2, always, {omitLastInOneLineBlock: true}]
|
||||
sonarjs/cognitive-complexity: [0]
|
||||
sonarjs/elseif-without-else: [0]
|
||||
sonarjs/max-switch-cases: [0]
|
||||
|
@ -678,8 +610,16 @@ rules:
|
|||
sort-imports: [0]
|
||||
sort-keys: [0]
|
||||
sort-vars: [0]
|
||||
space-before-blocks: [2, always]
|
||||
space-in-parens: [2, never]
|
||||
space-infix-ops: [2]
|
||||
space-unary-ops: [2]
|
||||
spaced-comment: [2, always]
|
||||
strict: [0]
|
||||
switch-colon-spacing: [2]
|
||||
symbol-description: [2]
|
||||
template-curly-spacing: [2, never]
|
||||
template-tag-spacing: [2, never]
|
||||
unicode-bom: [2, never]
|
||||
unicorn/better-regex: [0]
|
||||
unicorn/catch-error-name: [0]
|
||||
|
@ -725,6 +665,7 @@ rules:
|
|||
unicorn/no-unnecessary-await: [2]
|
||||
unicorn/no-unreadable-array-destructuring: [0]
|
||||
unicorn/no-unreadable-iife: [2]
|
||||
unicorn/no-unsafe-regex: [0]
|
||||
unicorn/no-unused-properties: [2]
|
||||
unicorn/no-useless-fallback-in-spread: [2]
|
||||
unicorn/no-useless-length-check: [2]
|
||||
|
@ -751,7 +692,7 @@ rules:
|
|||
unicorn/prefer-dom-node-remove: [2]
|
||||
unicorn/prefer-dom-node-text-content: [2]
|
||||
unicorn/prefer-event-target: [2]
|
||||
unicorn/prefer-export-from: [0]
|
||||
unicorn/prefer-export-from: [2, {ignoreUsedVariables: true}]
|
||||
unicorn/prefer-includes: [2]
|
||||
unicorn/prefer-json-parse-buffer: [0]
|
||||
unicorn/prefer-keyboard-event-key: [2]
|
||||
|
@ -797,25 +738,15 @@ rules:
|
|||
valid-typeof: [2, {requireStringLiterals: true}]
|
||||
vars-on-top: [0]
|
||||
wc/attach-shadow-constructor: [2]
|
||||
wc/define-tag-after-class-definition: [0]
|
||||
wc/expose-class-on-global: [0]
|
||||
wc/file-name-matches-element: [2]
|
||||
wc/guard-define-call: [0]
|
||||
wc/guard-super-call: [2]
|
||||
wc/max-elements-per-file: [0]
|
||||
wc/no-child-traversal-in-attributechangedcallback: [2]
|
||||
wc/no-child-traversal-in-connectedcallback: [2]
|
||||
wc/no-closed-shadow-root: [2]
|
||||
wc/no-constructor-attributes: [2]
|
||||
wc/no-constructor-params: [2]
|
||||
wc/no-constructor: [2]
|
||||
wc/no-customized-built-in-elements: [2]
|
||||
wc/no-exports-with-element: [2]
|
||||
wc/no-invalid-element-name: [2]
|
||||
wc/no-invalid-extends: [2]
|
||||
wc/no-method-prefixed-with-on: [2]
|
||||
wc/no-invalid-element-name: [0] # covered by custom-elements/valid-tag-name
|
||||
wc/no-self-class: [2]
|
||||
wc/no-typos: [2]
|
||||
wc/require-listener-teardown: [2]
|
||||
wc/tag-name-matches-class: [2]
|
||||
wrap-iife: [2, inside]
|
||||
wrap-regex: [0]
|
||||
yield-star-spacing: [2, after]
|
||||
yoda: [2, never]
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
end_to_end=$1
|
||||
end_to_end_pr=$2
|
||||
forgejo=$3
|
||||
forgejo_pr=$4
|
||||
|
||||
head_url=$(jq --raw-output .head.repo.html_url < $forgejo_pr)
|
||||
test "$head_url" != null
|
||||
branch=$(jq --raw-output .head.ref < $forgejo_pr)
|
||||
test "$branch" != null
|
||||
cd $end_to_end
|
||||
echo $head_url $branch 7.0.0+0-gitea-1.22.0 > forgejo/sources/1.22
|
||||
date > last-upgrade
|
||||
|
||||
base_url=$(jq --raw-output .base.repo.html_url < $forgejo_pr)
|
||||
test "$base_url" != null
|
||||
test "$GITHUB_RUN_NUMBER"
|
||||
echo $base_url/actions/runs/$GITHUB_RUN_NUMBER/artifacts/forgejo > forgejo/binary-url
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
end_to_end=$1
|
||||
end_to_end_pr=$2
|
||||
forgejo=$3
|
||||
forgejo_ref=$4
|
||||
|
||||
cd $end_to_end
|
||||
date > last-upgrade
|
||||
echo $FORGEJO_BINARY > forgejo/binary-url
|
3
.forgejo/testdata/build-release/Dockerfile
vendored
3
.forgejo/testdata/build-release/Dockerfile
vendored
|
@ -1,3 +0,0 @@
|
|||
FROM public.ecr.aws/docker/library/alpine:3.18
|
||||
RUN mkdir -p /app/gitea
|
||||
RUN ( echo '#!/bin/sh' ; echo "echo forgejo v1.2.3" ) > /app/gitea/gitea ; chmod +x /app/gitea/gitea
|
5
.forgejo/testdata/build-release/Makefile
vendored
5
.forgejo/testdata/build-release/Makefile
vendored
|
@ -1,5 +0,0 @@
|
|||
VERSION ?= $(shell cat VERSION 2>/dev/null)
|
||||
sources-tarbal:
|
||||
mkdir -p dist/release
|
||||
echo $(VERSION) > VERSION
|
||||
sources=forgejo-src-$(VERSION).tar.gz ; tar --transform 's|^./|forgejo-src-$(VERSION)/|' -czf dist/release/forgejo-src-$(VERSION).tar.gz . ; cd dist/release ; shasum -a 256 $$sources > $$sources.sha256
|
|
@ -1,107 +0,0 @@
|
|||
name: Integration tests for the release process
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- Makefile
|
||||
- Dockerfile
|
||||
- Dockerfile.rootless
|
||||
- docker/**
|
||||
- .forgejo/workflows/build-release.yml
|
||||
- .forgejo/workflows/build-release-integration.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- Makefile
|
||||
- Dockerfile
|
||||
- Dockerfile.rootless
|
||||
- docker/**
|
||||
- .forgejo/workflows/build-release.yml
|
||||
- .forgejo/workflows/build-release-integration.yml
|
||||
|
||||
jobs:
|
||||
release-simulation:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- id: forgejo
|
||||
uses: https://code.forgejo.org/actions/setup-forgejo@v1
|
||||
with:
|
||||
user: root
|
||||
password: admin1234
|
||||
image-version: 1.21
|
||||
lxc-ip-prefix: 10.0.9
|
||||
|
||||
- name: publish the forgejo release
|
||||
run: |
|
||||
set -x
|
||||
|
||||
version=1.2.3
|
||||
cat > /etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"insecure-registries" : ["${{ steps.forgejo.outputs.host-port }}"]
|
||||
}
|
||||
EOF
|
||||
systemctl restart docker
|
||||
|
||||
apt-get install -qq -y xz-utils
|
||||
|
||||
dir=$(mktemp -d)
|
||||
trap "rm -fr $dir" EXIT
|
||||
|
||||
url=http://root:admin1234@${{ steps.forgejo.outputs.host-port }}
|
||||
export FORGEJO_RUNNER_LOGS="${{ steps.forgejo.outputs.runner-logs }}"
|
||||
|
||||
#
|
||||
# Create a new project with a fake forgejo and the release workflow only
|
||||
#
|
||||
cp -a .forgejo/testdata/build-release/* $dir
|
||||
mkdir -p $dir/.forgejo/workflows
|
||||
cp .forgejo/workflows/build-release.yml $dir/.forgejo/workflows
|
||||
cp $dir/Dockerfile $dir/Dockerfile.rootless
|
||||
|
||||
forgejo-test-helper.sh push $dir $url root forgejo
|
||||
sha=$(forgejo-test-helper.sh branch_tip $url root/forgejo main)
|
||||
|
||||
#
|
||||
# Push a tag to trigger the release workflow and wait for it to complete
|
||||
#
|
||||
forgejo-curl.sh api_json --data-raw '{"tag_name": "v'$version'", "target": "'$sha'"}' $url/api/v1/repos/root/forgejo/tags
|
||||
forgejo-curl.sh api_json -X PUT --data-raw '{"data":"${{ steps.forgejo.outputs.token }}"}' $url/api/v1/repos/root/forgejo/actions/secrets/TOKEN
|
||||
forgejo-curl.sh api_json -X PUT --data-raw '{"data":"root"}' $url/api/v1/repos/root/forgejo/actions/secrets/DOER
|
||||
LOOPS=180 forgejo-test-helper.sh wait_success "$url" root/forgejo $sha
|
||||
|
||||
#
|
||||
# uncomment to see the logs even when everything is reported to be working ok
|
||||
#
|
||||
#cat $FORGEJO_RUNNER_LOGS
|
||||
|
||||
#
|
||||
# Minimal sanity checks. e2e test is for the setup-forgejo
|
||||
# action and the infrastructure playbook. Since the binary
|
||||
# is a script shell it does not test the sanity of the cross
|
||||
# build, only the sanity of the naming of the binaries.
|
||||
#
|
||||
for arch in amd64 arm64 arm-6 ; do
|
||||
binary=forgejo-$version-linux-$arch
|
||||
for suffix in '' '.xz' ; do
|
||||
curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$binary$suffix > $binary$suffix
|
||||
if test "$suffix" = .xz ; then
|
||||
unxz --keep $binary$suffix
|
||||
fi
|
||||
chmod +x $binary
|
||||
./$binary --version | grep $version
|
||||
curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$binary$suffix.sha256 > $binary$suffix.sha256
|
||||
shasum -a 256 --check $binary$suffix.sha256
|
||||
rm $binary$suffix
|
||||
done
|
||||
done
|
||||
|
||||
sources=forgejo-src-$version.tar.gz
|
||||
curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$sources > $sources
|
||||
curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$sources.sha256 > $sources.sha256
|
||||
shasum -a 256 --check $sources.sha256
|
||||
|
||||
docker pull ${{ steps.forgejo.outputs.host-port }}/root/forgejo:$version
|
||||
docker pull ${{ steps.forgejo.outputs.host-port }}/root/forgejo:$version-rootless
|
|
@ -1,169 +0,0 @@
|
|||
#
|
||||
# See also https://forgejo.org/docs/next/developer/RELEASE/#release-process
|
||||
#
|
||||
# https://codeberg.org/forgejo-integration/forgejo
|
||||
#
|
||||
# Builds a release from a codeberg.org/forgejo-integration tag
|
||||
#
|
||||
# vars.ROLE: forgejo-integration
|
||||
#
|
||||
# secrets.DOER: forgejo-experimental-ci
|
||||
# secrets.TOKEN: <generated from codeberg.org/forgejo-experimental-ci> scope read:user, write:repository, write:package
|
||||
#
|
||||
# secrets.CASCADE_ORIGIN_TOKEN: <generated from codeberg.org/forgejo-experimental-ci> scope read:user, write:repository, write:issue
|
||||
# secrets.CASCADE_DESTINATION_TOKEN: <generated from code.forgejo.org/forgejo-ci> scope read:user, write:repository, write:issue
|
||||
# vars.CASCADE_DESTINATION_DOER: forgejo-ci
|
||||
#
|
||||
name: Build release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: 'v*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: self-hosted
|
||||
# root is used for testing, allow it
|
||||
if: vars.ROLE == 'forgejo-integration' || github.repository_owner == 'root'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Sanitize the name of the repository
|
||||
id: repository
|
||||
run: |
|
||||
repository="${{ github.repository }}"
|
||||
echo "value=${repository##*/}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: https://code.forgejo.org/actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
check-latest: true
|
||||
|
||||
- name: version from ref_name
|
||||
id: tag-version
|
||||
run: |
|
||||
version="${{ github.ref_name }}"
|
||||
version=${version##*v}
|
||||
echo "value=$version" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: release notes
|
||||
id: release-notes
|
||||
run: |
|
||||
anchor=${{ steps.tag-version.outputs.value }}
|
||||
anchor=${anchor//./-}
|
||||
cat >> "$GITHUB_OUTPUT" <<EOF
|
||||
value<<ENDVAR
|
||||
See https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md#$anchor
|
||||
ENDVAR
|
||||
EOF
|
||||
|
||||
- name: Build sources
|
||||
run: |
|
||||
set -x
|
||||
apt-get -qq install -y make
|
||||
version=${{ steps.tag-version.outputs.value }}
|
||||
#
|
||||
# Make sure all files are owned by the current user.
|
||||
# When run as root `npx webpack` will assume the identity
|
||||
# of the owner of the current working directory and may
|
||||
# fail to create files if some sub-directories are not owned
|
||||
# by the same user.
|
||||
#
|
||||
# Binaries:
|
||||
# Node: 18.17.0 - /usr/local/node-v18.17.0-linux-x64/bin/node
|
||||
# npm: 9.6.7 - /usr/local/node-v18.17.0-linux-x64/bin/npm
|
||||
# Packages:
|
||||
# add-asset-webpack-plugin: 2.0.1 => 2.0.1
|
||||
# css-loader: 6.8.1 => 6.8.1
|
||||
# esbuild-loader: 3.0.1 => 3.0.1
|
||||
# license-checker-webpack-plugin: 0.2.1 => 0.2.1
|
||||
# monaco-editor-webpack-plugin: 7.0.1 => 7.0.1
|
||||
# vue-loader: 17.2.2 => 17.2.2
|
||||
# webpack: 5.87.0 => 5.87.0
|
||||
# webpack-cli: 5.1.4 => 5.1.4
|
||||
#
|
||||
chown -R $(id -u) .
|
||||
make VERSION=$version TAGS=bindata sources-tarbal
|
||||
mv dist/release release
|
||||
|
||||
(
|
||||
tmp=$(mktemp -d)
|
||||
tar --directory $tmp -zxvf release/*$version*.tar.gz
|
||||
cd $tmp/*
|
||||
#
|
||||
# Verify `make frontend` files are available
|
||||
#
|
||||
test -d public/assets/css
|
||||
test -d public/assets/fonts
|
||||
test -d public/assets/js
|
||||
#
|
||||
# Verify `make generate` files are available
|
||||
#
|
||||
test -f modules/public/bindata.go
|
||||
#
|
||||
# Sanity check to verify that the source tarbal knows the
|
||||
# version and is able to rebuild itself from it.
|
||||
#
|
||||
# When in sources the version is determined with git.
|
||||
# When in the tarbal the version is determined from a VERSION file.
|
||||
#
|
||||
make sources-tarbal
|
||||
tarbal=$(echo dist/release/*$version*.tar.gz)
|
||||
if ! test -f $tarbal ; then
|
||||
echo $tarbal does not exist
|
||||
find dist release
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
- name: build container & release
|
||||
if: ${{ secrets.TOKEN != '' }}
|
||||
uses: https://code.forgejo.org/forgejo/forgejo-build-publish/build@v1
|
||||
with:
|
||||
forgejo: "${{ env.GITHUB_SERVER_URL }}"
|
||||
owner: "${{ env.GITHUB_REPOSITORY_OWNER }}"
|
||||
repository: "${{ steps.repository.outputs.value }}"
|
||||
doer: "${{ secrets.DOER }}"
|
||||
tag-version: "${{ steps.tag-version.outputs.value }}"
|
||||
token: "${{ secrets.TOKEN }}"
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v6
|
||||
release-notes: "${{ steps.release-notes.outputs.value }}"
|
||||
binary-name: forgejo
|
||||
binary-path: /app/gitea/gitea
|
||||
verbose: ${{ vars.VERBOSE || 'false' }}
|
||||
|
||||
- name: build rootless container
|
||||
if: ${{ secrets.TOKEN != '' }}
|
||||
uses: https://code.forgejo.org/forgejo/forgejo-build-publish/build@v1
|
||||
with:
|
||||
forgejo: "${{ env.GITHUB_SERVER_URL }}"
|
||||
owner: "${{ env.GITHUB_REPOSITORY_OWNER }}"
|
||||
repository: "${{ steps.repository.outputs.value }}"
|
||||
doer: "${{ secrets.DOER }}"
|
||||
tag-version: "${{ steps.tag-version.outputs.value }}"
|
||||
token: "${{ secrets.TOKEN }}"
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v6
|
||||
suffix: -rootless
|
||||
dockerfile: Dockerfile.rootless
|
||||
verbose: ${{ vars.VERBOSE || 'false' }}
|
||||
|
||||
- name: end-to-end tests
|
||||
if: ${{ secrets.TOKEN != '' && vars.ROLE == 'forgejo-integration' }}
|
||||
uses: https://code.forgejo.org/actions/cascading-pr@v1
|
||||
with:
|
||||
origin-url: ${{ env.GITHUB_SERVER_URL }}
|
||||
origin-repo: ${{ github.repository }}
|
||||
origin-token: ${{ secrets.CASCADE_ORIGIN_TOKEN }}
|
||||
origin-ref: refs/heads/forgejo
|
||||
destination-url: https://code.forgejo.org
|
||||
destination-fork-repo: ${{ vars.CASCADE_DESTINATION_DOER }}/end-to-end
|
||||
destination-repo: forgejo/end-to-end
|
||||
destination-branch: forgejo-pr
|
||||
destination-token: ${{ secrets.CASCADE_DESTINATION_TOKEN }}
|
||||
update: .forgejo/cascading-release-end-to-end
|
||||
env:
|
||||
FORGEJO_BINARY: "${{ env.GITHUB_SERVER_URL }}/${{ github.repository }}/releases/download/v${{ steps.tag-version.outputs.value }}/forgejo-${{ steps.tag-version.outputs.value }}-linux-amd64"
|
|
@ -1,83 +0,0 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- labeled
|
||||
|
||||
env:
|
||||
FEATURE_BRANCHES: "privacy i18n moderation branding dependency"
|
||||
|
||||
jobs:
|
||||
info:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
container:
|
||||
image: node:20-bookworm
|
||||
steps:
|
||||
- name: event
|
||||
run: |
|
||||
echo github.event.pull_request.head.repo.fork = ${{ github.event.pull_request.head.repo.fork }}
|
||||
echo github.event.action = ${{ github.event.action }}
|
||||
echo github.event.pull_request.merged = ${{ github.event.pull_request.merged }}
|
||||
echo github.event.pull_request.labels.*.name
|
||||
cat <<'EOF'
|
||||
${{ toJSON(github.event.pull_request.labels.*.name) }}
|
||||
EOF
|
||||
|
||||
build:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') && github.event.action == 'label_updated' && contains(github.event.pull_request.labels.*.name, 'run-end-to-end-tests') }}
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
show-progress: 'false'
|
||||
- name: adduser forgejo
|
||||
run: |
|
||||
git config --add safe.directory '*'
|
||||
git config user.email "you@example.com"
|
||||
git config user.name "Your Name"
|
||||
adduser --quiet --comment forgejo --disabled-password forgejo
|
||||
chown -R forgejo:forgejo .
|
||||
- name: merge feature branches
|
||||
run: |
|
||||
su forgejo -c 'set -ex ; for b in ${{ env.FEATURE_BRANCHES }} ; do git merge -m $b origin/forgejo-$b ; done'
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
- name: make deps-backend
|
||||
run: |
|
||||
su forgejo -c 'make deps-backend'
|
||||
- name: make forgejo
|
||||
run: |
|
||||
su forgejo -c 'make generate-backend static-executable && ln gitea forgejo'
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: forgejo
|
||||
path: forgejo
|
||||
|
||||
cascade:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') && github.event.action == 'label_updated' && contains(github.event.pull_request.labels.*.name, 'run-end-to-end-tests') }}
|
||||
needs: [build]
|
||||
runs-on: docker
|
||||
container:
|
||||
image: node:20-bookworm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cascading-pr@v1
|
||||
with:
|
||||
origin-url: ${{ env.GITHUB_SERVER_URL }}
|
||||
origin-repo: ${{ github.repository }}
|
||||
origin-token: ${{ secrets.END_TO_END_CASCADING_PR_ORIGIN }}
|
||||
origin-pr: ${{ github.event.pull_request.number }}
|
||||
destination-url: https://code.forgejo.org
|
||||
destination-fork-repo: cascading-pr/end-to-end
|
||||
destination-repo: forgejo/end-to-end
|
||||
destination-branch: forgejo-pr
|
||||
destination-token: ${{ secrets.END_TO_END_CASCADING_PR_DESTINATION }}
|
||||
close-merge: true
|
||||
update: .forgejo/cascading-pr-end-to-end
|
32
.forgejo/workflows/compliance.yml
Normal file
32
.forgejo/workflows/compliance.yml
Normal file
|
@ -0,0 +1,32 @@
|
|||
name: compliance
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'forgejo*'
|
||||
- 'v*/forgejo*'
|
||||
|
||||
jobs:
|
||||
lint-backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.20"
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make lint-backend
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
checks-backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.20"
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make --always-make checks-backend # ensure the "go-licenses" make target runs
|
|
@ -1,37 +0,0 @@
|
|||
name: e2e
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- Makefile
|
||||
- .forgejo/workflows/e2e.yml
|
||||
- tests/e2e/**
|
||||
|
||||
jobs:
|
||||
test-e2e:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v4
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: "~1.21"
|
||||
check-latest: true
|
||||
- run: |
|
||||
apt-get -qq update
|
||||
apt-get -qq install -q sudo
|
||||
sed -i -e 's/%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/' /etc/sudoers
|
||||
git config --add safe.directory '*'
|
||||
adduser --quiet --comment forgejo --disabled-password forgejo
|
||||
adduser forgejo sudo
|
||||
chown -R forgejo:forgejo .
|
||||
- run: |
|
||||
su forgejo -c 'make deps-frontend frontend deps-backend'
|
||||
- run: |
|
||||
su forgejo -c 'make generate test-e2e-sqlite'
|
||||
timeout-minutes: 40
|
||||
env:
|
||||
DEPS_PLAYWRIGHT: 1
|
||||
USE_REPO_TEST_DIR: 1
|
|
@ -1,27 +0,0 @@
|
|||
name: mirror
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'forgejo'
|
||||
- 'v*/forgejo'
|
||||
|
||||
jobs:
|
||||
mirror:
|
||||
if: ${{ secrets.MIRROR_TOKEN != '' }}
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
steps:
|
||||
- name: git push {v*/,}forgejo
|
||||
run: |
|
||||
git init --bare .
|
||||
git remote add origin ${{ env.GITHUB_SERVER_URL }}/${{ env.GITHUB_REPOSITORY }}
|
||||
git fetch origin refs/heads/forgejo:refs/mirror/forgejo
|
||||
git ls-remote origin refs/heads/v*/forgejo | while read sha full_ref ; do
|
||||
ref=${full_ref#refs/heads/}
|
||||
echo git fetch origin $full_ref:refs/mirror/$ref
|
||||
git fetch origin $full_ref:refs/mirror/$ref
|
||||
done
|
||||
echo git push --force https://${{ vars.MIRROR_DESTINATION }} refs/mirror/*:refs/heads/*
|
||||
git push --force https://any:${{ secrets.MIRROR_TOKEN }}@${{ vars.MIRROR_DESTINATION }} refs/mirror/*:refs/heads/*
|
|
@ -1,76 +0,0 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# See also https://forgejo.org/docs/next/developer/RELEASE/#release-process
|
||||
#
|
||||
# https://codeberg.org/forgejo-experimental/forgejo
|
||||
#
|
||||
# Copies a release from codeberg.org/forgejo-integration to codeberg.org/forgejo-experimental
|
||||
#
|
||||
# vars.ROLE: forgejo-experimental
|
||||
# vars.FORGEJO: https://codeberg.org
|
||||
# vars.FROM_OWNER: forgejo-integration
|
||||
# vars.TO_OWNER: forgejo-experimental
|
||||
# vars.REPO: forgejo
|
||||
# vars.DOER: forgejo-experimental-ci
|
||||
# secrets.TOKEN: <generated from codeberg.org/forgejo-experimental-ci>
|
||||
#
|
||||
# http://private.forgejo.org/forgejo/forgejo
|
||||
#
|
||||
# Copies & sign a release from codeberg.org/forgejo-integration to codeberg.org/forgejo
|
||||
#
|
||||
# vars.ROLE: forgejo-release
|
||||
# vars.FORGEJO: https://codeberg.org
|
||||
# vars.FROM_OWNER: forgejo-integration
|
||||
# vars.TO_OWNER: forgejo
|
||||
# vars.REPO: forgejo
|
||||
# vars.DOER: release-team
|
||||
# secrets.TOKEN: <generated from codeberg.org/release-team>
|
||||
# secrets.GPG_PRIVATE_KEY: <XYZ>
|
||||
# secrets.GPG_PASSPHRASE: <ABC>
|
||||
#
|
||||
name: Pubish release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: 'v*'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: self-hosted
|
||||
if: vars.DOER != '' && vars.FORGEJO != '' && vars.TO_OWNER != '' && vars.FROM_OWNER != '' && secrets.TOKEN != ''
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: copy & sign
|
||||
uses: https://code.forgejo.org/forgejo/forgejo-build-publish/publish@v1
|
||||
with:
|
||||
forgejo: ${{ vars.FORGEJO }}
|
||||
from-owner: ${{ vars.FROM_OWNER }}
|
||||
to-owner: ${{ vars.TO_OWNER }}
|
||||
repo: ${{ vars.REPO }}
|
||||
ref-name: ${{ github.ref_name }}
|
||||
release-notes: "See https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md#{ANCHOR}"
|
||||
doer: ${{ vars.DOER }}
|
||||
token: ${{ secrets.TOKEN }}
|
||||
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
|
||||
verbose: ${{ vars.VERBOSE }}
|
||||
|
||||
|
||||
- name: set up go for the DNS update below
|
||||
if: vars.ROLE == 'forgejo-experimental' && secrets.OVH_APP_KEY != ''
|
||||
uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
check-latest: true
|
||||
- name: update the _release.experimental DNS record
|
||||
if: vars.ROLE == 'forgejo-experimental' && secrets.OVH_APP_KEY != ''
|
||||
uses: https://code.forgejo.org/actions/ovh-dns-update@v1
|
||||
with:
|
||||
subdomain: _release.experimental
|
||||
domain: forgejo.com # there is a CNAME from .org to .com (for security reasons)
|
||||
record-id: 5283602601
|
||||
value: v=${{ github.ref_name }}
|
||||
ovh-app-key: ${{ secrets.OVH_APP_KEY }}
|
||||
ovh-app-secret: ${{ secrets.OVH_APP_SECRET }}
|
||||
ovh-consumer-key: ${{ secrets.OVH_CON_KEY }}
|
42
.forgejo/workflows/testing-mysql.yml
Normal file
42
.forgejo/workflows/testing-mysql.yml
Normal file
|
@ -0,0 +1,42 @@
|
|||
name: testing MySQL
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'forgejo*'
|
||||
- 'v*/forgejo*'
|
||||
|
||||
jobs:
|
||||
test-mysql:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: codeberg.org/forgejo/test_env:main
|
||||
services:
|
||||
mysql8:
|
||||
image: mysql:8
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: testgitea
|
||||
ports:
|
||||
- "3306:3306"
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.20.0"
|
||||
- run: |
|
||||
git config --add safe.directory '*'
|
||||
chown -R gitea:gitea . /go
|
||||
- run: |
|
||||
su gitea -c 'make deps-backend'
|
||||
- run: |
|
||||
su gitea -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: |
|
||||
su gitea -c 'make test-mysql8-migration test-mysql8'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata
|
||||
USE_REPO_TEST_DIR: 1
|
44
.forgejo/workflows/testing-psql.yml
Normal file
44
.forgejo/workflows/testing-psql.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
name: testing PostgreSQL
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'forgejo*'
|
||||
- 'v*/forgejo*'
|
||||
|
||||
jobs:
|
||||
test-pgsql:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: codeberg.org/forgejo/test_env:main
|
||||
services:
|
||||
pgsql:
|
||||
image: postgres:15
|
||||
env:
|
||||
POSTGRES_DB: test
|
||||
POSTGRES_PASSWORD: postgres
|
||||
ports:
|
||||
- "5432:5432"
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.20.0"
|
||||
- run: |
|
||||
git config --add safe.directory '*'
|
||||
chown -R gitea:gitea . /go
|
||||
- run: |
|
||||
su gitea -c 'make deps-backend'
|
||||
- run: |
|
||||
su gitea -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: |
|
||||
su gitea -c 'make test-pgsql-migration test-pgsql'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata gogit
|
||||
RACE_ENABLED: true
|
||||
TEST_TAGS: gogit
|
||||
USE_REPO_TEST_DIR: 1
|
36
.forgejo/workflows/testing-sqlite.yml
Normal file
36
.forgejo/workflows/testing-sqlite.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
name: testing SQLite
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'forgejo*'
|
||||
- 'v*/forgejo*'
|
||||
|
||||
jobs:
|
||||
test-sqlite:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: codeberg.org/forgejo/test_env:main
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.20.0"
|
||||
- run: |
|
||||
git config --add safe.directory '*'
|
||||
chown -R gitea:gitea . /go
|
||||
- run: |
|
||||
su gitea -c 'make deps-backend'
|
||||
- run: |
|
||||
su gitea -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||
- run: |
|
||||
su gitea -c 'make test-sqlite-migration test-sqlite'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||
RACE_ENABLED: true
|
||||
TEST_TAGS: gogit sqlite sqlite_unlock_notify
|
||||
USE_REPO_TEST_DIR: 1
|
34
.forgejo/workflows/testing-unit.yml
Normal file
34
.forgejo/workflows/testing-unit.yml
Normal file
|
@ -0,0 +1,34 @@
|
|||
name: testing unit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'forgejo*'
|
||||
- 'v*/forgejo*'
|
||||
|
||||
jobs:
|
||||
test-unit:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: codeberg.org/forgejo/test_env:main
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.20.0"
|
||||
- run: |
|
||||
git config --add safe.directory '*'
|
||||
chown -R gitea:gitea . /go
|
||||
- run: |
|
||||
su gitea -c 'make deps-backend'
|
||||
- run: |
|
||||
su gitea -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: |
|
||||
su gitea -c 'make unit-test-coverage test-check'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
RACE_ENABLED: 'true'
|
||||
TAGS: bindata
|
|
@ -1,195 +0,0 @@
|
|||
name: testing
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'forgejo*'
|
||||
- 'v*/forgejo*'
|
||||
|
||||
jobs:
|
||||
lint-backend:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make lint-backend
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
checks-backend:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make --always-make checks-backend # ensure the "go-licenses" make target runs
|
||||
test-unit:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
needs: [lint-backend, checks-backend]
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
services:
|
||||
minio:
|
||||
image: 'docker.io/bitnami/minio:2023.8.31'
|
||||
env:
|
||||
MINIO_ROOT_USER: 123456
|
||||
MINIO_ROOT_PASSWORD: 12345678
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
- run: |
|
||||
git config --add safe.directory '*'
|
||||
adduser --quiet --comment forgejo --disabled-password forgejo
|
||||
chown -R forgejo:forgejo .
|
||||
- run: |
|
||||
su forgejo -c 'make deps-backend'
|
||||
- run: |
|
||||
su forgejo -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: |
|
||||
su forgejo -c 'make test-backend test-check'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
RACE_ENABLED: 'true'
|
||||
TAGS: bindata
|
||||
test-mysql:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
needs: [lint-backend, checks-backend]
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
services:
|
||||
mysql:
|
||||
image: 'docker.io/mysql:8-debian'
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: testgitea
|
||||
#
|
||||
# See also https://codeberg.org/forgejo/forgejo/issues/976
|
||||
#
|
||||
cmd: ['mysqld', '--innodb-adaptive-flushing=OFF', '--innodb-buffer-pool-size=4G', '--innodb-log-buffer-size=128M', '--innodb-flush-log-at-trx-commit=0', '--innodb-flush-log-at-timeout=30', '--innodb-flush-method=nosync', '--innodb-fsync-threshold=1000000000']
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.21"
|
||||
- name: install dependencies
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install --no-install-recommends -qq -y git-lfs
|
||||
- name: setup user and permissions
|
||||
run: |
|
||||
git config --add safe.directory '*'
|
||||
adduser --quiet --comment forgejo --disabled-password forgejo
|
||||
chown -R forgejo:forgejo .
|
||||
- run: |
|
||||
su forgejo -c 'make deps-backend'
|
||||
- run: |
|
||||
su forgejo -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: |
|
||||
su forgejo -c 'make test-mysql-migration test-mysql'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata
|
||||
USE_REPO_TEST_DIR: 1
|
||||
test-pgsql:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
needs: [lint-backend, checks-backend]
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
services:
|
||||
minio:
|
||||
image: bitnami/minio:2021.3.17
|
||||
env:
|
||||
MINIO_ACCESS_KEY: 123456
|
||||
MINIO_SECRET_KEY: 12345678
|
||||
pgsql:
|
||||
image: 'docker.io/postgres:15'
|
||||
env:
|
||||
POSTGRES_DB: test
|
||||
POSTGRES_PASSWORD: postgres
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.21"
|
||||
- name: install dependencies
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install --no-install-recommends -qq -y git-lfs
|
||||
- name: setup user and permissions
|
||||
run: |
|
||||
git config --add safe.directory '*'
|
||||
adduser --quiet --comment forgejo --disabled-password forgejo
|
||||
chown -R forgejo:forgejo .
|
||||
- run: |
|
||||
su forgejo -c 'make deps-backend'
|
||||
- run: |
|
||||
su forgejo -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: |
|
||||
su forgejo -c 'make test-pgsql-migration test-pgsql'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata gogit
|
||||
RACE_ENABLED: true
|
||||
TEST_TAGS: gogit
|
||||
USE_REPO_TEST_DIR: 1
|
||||
test-sqlite:
|
||||
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
|
||||
runs-on: docker
|
||||
needs: [lint-backend, checks-backend]
|
||||
container:
|
||||
image: 'docker.io/node:20-bookworm'
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/actions/checkout@v3
|
||||
- uses: https://code.forgejo.org/actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.21"
|
||||
- name: install dependencies
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install --no-install-recommends -qq -y git-lfs
|
||||
- name: setup user and permissions
|
||||
run: |
|
||||
git config --add safe.directory '*'
|
||||
adduser --quiet --comment forgejo --disabled-password forgejo
|
||||
chown -R forgejo:forgejo .
|
||||
- run: |
|
||||
su forgejo -c 'make deps-backend'
|
||||
- run: |
|
||||
su forgejo -c 'make backend'
|
||||
env:
|
||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||
- run: |
|
||||
su forgejo -c 'make test-sqlite-migration test-sqlite'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||
RACE_ENABLED: true
|
||||
TEST_TAGS: gogit sqlite sqlite_unlock_notify
|
||||
USE_REPO_TEST_DIR: 1
|
5
.gitattributes
vendored
5
.gitattributes
vendored
|
@ -1,10 +1,9 @@
|
|||
* text=auto eol=lf
|
||||
*.tmpl linguist-language=go-html-template
|
||||
*.tmpl linguist-language=Handlebars
|
||||
/assets/*.json linguist-generated
|
||||
/public/assets/img/svg/*.svg linguist-generated
|
||||
/public/img/svg/*.svg linguist-generated
|
||||
/templates/swagger/v1_json.tmpl linguist-generated
|
||||
/vendor/** -text -eol linguist-vendored
|
||||
/web_src/fomantic/build/** linguist-generated
|
||||
/web_src/fomantic/_site/globals/site.variables linguist-language=Less
|
||||
/web_src/js/vendor/** -text -eol linguist-vendored
|
||||
Dockerfile.* linguist-language=Dockerfile
|
||||
|
|
57
.gitea/ISSUE_TEMPLATE/bug-report.md
Normal file
57
.gitea/ISSUE_TEMPLATE/bug-report.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
name: "Bug Report"
|
||||
about: "Found something you weren't expecting? Report it here!"
|
||||
title: "[BUG] "
|
||||
---
|
||||
<!--
|
||||
NOTE: If your issue is a security concern, please email security@forgejo.org (GPG: A4676E79) instead of opening a public issue.
|
||||
|
||||
1. Please speak English, as this is the language all maintainers can
|
||||
speak and write.
|
||||
|
||||
2. Please ask questions or troubleshoot configuration/deploy problems
|
||||
in our Matrix space (https://matrix.to/#/#forgejo:matrix.org).
|
||||
|
||||
3. Please make sure you are using the latest release of Forgejo and
|
||||
take a moment to check that your issue hasn't been reported before.
|
||||
|
||||
4. Please give all relevant information below for bug reports, because
|
||||
incomplete details will be handled as an invalid report.
|
||||
|
||||
5. If you are using a proxy or a CDN (e.g. CloudFlare) in front of
|
||||
Forgejo, please disable the proxy/CDN fully and connect to Forgejo
|
||||
directly to confirm the issue still persists without those services.
|
||||
-->
|
||||
|
||||
- Can you reproduce the problem on [Forgejo Next](https://next.forgejo.org/)?
|
||||
- Forgejo version (or commit ref):
|
||||
- Git version:
|
||||
- Operating system:
|
||||
- Database (use `[x]`):
|
||||
- [ ] PostgreSQL
|
||||
- [ ] MySQL
|
||||
- [ ] MSSQL
|
||||
- [ ] SQLite
|
||||
- How are you running Forgejo?
|
||||
<!--
|
||||
Please include information on whether you built Forgejo yourself, used one of our downloads, or are using some other package.
|
||||
Please also tell us how you are running Forgejo, e.g. if it is being run from docker, a command-line, systemd etc.
|
||||
If you are using a package or systemd tell us what distribution you are using.
|
||||
-->
|
||||
|
||||
## Description
|
||||
<!-- Please describe the issue you are having as clearly and succinctly as possible. -->
|
||||
|
||||
## Reproducing
|
||||
<!-- Please explain how to cause the problem to occur on demand if possible. -->
|
||||
|
||||
## Logs
|
||||
<!--
|
||||
It is really important to provide pertinent logs. We need DEBUG level logs.
|
||||
Please read https://docs.gitea.io/en-us/logging-configuration/#debugging-problems
|
||||
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of `app.ini`.
|
||||
Please copy and paste your logs here, with any sensitive information (e.g. API keys) removed/hidden.
|
||||
-->
|
||||
|
||||
## Screenshots
|
||||
<!-- If this issue involves the Web Interface, please provide one or more screenshots -->
|
24
.gitea/ISSUE_TEMPLATE/feature-request.md
Normal file
24
.gitea/ISSUE_TEMPLATE/feature-request.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
name: "Feature Request"
|
||||
about: "Got an idea for a feature that Forgejo doesn't have yet? Submit it here!"
|
||||
title: "[FEAT] "
|
||||
---
|
||||
<!--
|
||||
1. Please speak English, as this is the language all maintainers can
|
||||
speak and write.
|
||||
|
||||
2. Please ask questions or troubleshoot configuration/deploy problems
|
||||
in our Matrix space (https://matrix.to/#/#forgejo:matrix.org).
|
||||
|
||||
3. Please make sure you are using the latest release of Forgejo and
|
||||
take a moment to check that your feature hasn't already been suggested.
|
||||
-->
|
||||
|
||||
## Needs and benefits
|
||||
<!-- Please describe the needs this feature intends to address and the benefits it brings. -->
|
||||
|
||||
## Feature Description
|
||||
<!-- Please describe the feature you would like to see added as clearly and succinctly as possible. -->
|
||||
|
||||
## Screenshots
|
||||
<!-- If you can, provide screenshots of an implementation on another site, e.g. GitHub. -->
|
|
@ -1,63 +0,0 @@
|
|||
name: 🦋 Bug Report (web interface / frontend)
|
||||
description: Something doesn't look quite as it should? Report it here!
|
||||
title: "[BUG] "
|
||||
labels: ["bug", "forgejo/ui"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE: If your issue is a security concern, please email <security@forgejo.org> (GPG: `A4676E79`) instead of opening a public issue.**
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
- Please speak English, as this is the language all maintainers can speak and write.
|
||||
- Be as clear and concise as possible. A very verbose report is harder to interpret in a concrete way.
|
||||
- Be civil, and follow the [Forgejo Code of Conduct](https://codeberg.org/forgejo/code-of-conduct).
|
||||
- Please make sure you are using the latest release of Forgejo and take a moment to [check that your issue hasn't been reported before](https://codeberg.org/forgejo/forgejo/issues?q=&type=all&labels=78137).
|
||||
- Please give all relevant information below for bug reports, as incomplete details may result in the issue not being considered.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below).
|
||||
If you think this is a JavaScript error, show us the JavaScript console.
|
||||
If the error appears to relate to Forgejo the server, please also give us `DEBUG` level logs. (See https://forgejo.org/docs/latest/admin/logging-documentation/)
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: Please provide at least one screenshot showing the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: forgejo-ver
|
||||
attributes:
|
||||
label: Forgejo Version
|
||||
description: Forgejo version (or commit reference) your instance is running
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: can-reproduce
|
||||
attributes:
|
||||
label: Can you reproduce the bug on Forgejo Next?
|
||||
description: |
|
||||
Please try reproducing your issue at [Forgejo Next](https://next.forgejo.org).
|
||||
If you can reproduce it, please provide a URL in the Description field.
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: browser-ver
|
||||
attributes:
|
||||
label: Browser Version
|
||||
description: The browser and version that you are using to access Forgejo
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-ver
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: The operating system you are using to access Forgejo
|
|
@ -1,90 +0,0 @@
|
|||
name: 🐛 Bug Report (server / backend)
|
||||
description: Found something you weren't expecting? Report it here!
|
||||
title: "[BUG] "
|
||||
labels: bug
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE: If your issue is a security concern, please email <security@forgejo.org> (GPG: `A4676E79`) instead of opening a public issue.**
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
- Please speak English, as this is the language all maintainers can speak and write.
|
||||
- Be as clear and concise as possible. A very verbose report is harder to interpret in a concrete way.
|
||||
- Be civil, and follow the [Forgejo Code of Conduct](https://codeberg.org/forgejo/code-of-conduct).
|
||||
- Please make sure you are using the latest release of Forgejo and take a moment to [check that your issue hasn't been reported before](https://codeberg.org/forgejo/forgejo/issues?q=&type=all&labels=78137).
|
||||
- Please give all relevant information below for bug reports, as incomplete details may result in the issue not being considered.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below).
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: forgejo-ver
|
||||
attributes:
|
||||
label: Forgejo Version
|
||||
description: Forgejo version (or commit reference) of your instance
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: can-reproduce
|
||||
attributes:
|
||||
label: Can you reproduce the bug on Forgejo Next?
|
||||
description: |
|
||||
Please try reproducing your issue at [Forgejo Next](https://next.forgejo.org).
|
||||
If you can reproduce it, please provide a URL in the Description field.
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Logs
|
||||
description: |
|
||||
It's really important to provide pertinent logs. You must give us `DEBUG` level logs.
|
||||
Please read https://forgejo.org/docs/latest/admin/logging-documentation/.
|
||||
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of `app.ini`.
|
||||
|
||||
Please copy and paste your logs here, with any sensitive information (e.g. API keys) removed/hidden.
|
||||
You can wrap your logs in `<details>...</details>` tags so it doesn't take up too much space in the issue.
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If this issue involves the Web Interface, please provide one or more screenshots
|
||||
- type: input
|
||||
id: git-ver
|
||||
attributes:
|
||||
label: Git Version
|
||||
description: The version of git running on the server
|
||||
- type: input
|
||||
id: os-ver
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: The operating system you are using to run Forgejo
|
||||
- type: textarea
|
||||
id: run-info
|
||||
attributes:
|
||||
label: How are you running Forgejo?
|
||||
description: |
|
||||
Please include information on whether you built Forgejo yourself, used one of our downloads, or are using some other package.
|
||||
Please also tell us how you are running Forgejo, e.g. if it is being run from docker, a command-line, systemd etc.
|
||||
If you are using a package or systemd tell us what distribution you are using.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: database
|
||||
attributes:
|
||||
label: Database
|
||||
description: What database system are you running?
|
||||
options:
|
||||
- SQLite
|
||||
- PostgreSQL
|
||||
- MySQL
|
||||
- MSSQL
|
|
@ -1,17 +0,0 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 🔓 Security Reports
|
||||
url: mailto:security@forgejo.org
|
||||
about: "Please email <security@forgejo.org> (GPG: `A4676E79`) instead of opening a public issue."
|
||||
- name: 💬 Matrix Chat Room
|
||||
url: https://matrix.to/#/#forgejo-chat:matrix.org
|
||||
about: Please ask questions and discuss configuration or deployment problems here.
|
||||
- name: 💬 Matrix Space
|
||||
url: https://matrix.to/#/#forgejo:matrix.org
|
||||
about: A collection of Matrix rooms relating to Forgejo in addition to the main chat room.
|
||||
- name: 📚 Documentation
|
||||
url: https://forgejo.org/docs/latest/
|
||||
about: Documentation about Forgejo.
|
||||
- name: ❓ Frequently Asked Questions
|
||||
url: https://forgejo.org/faq/
|
||||
about: Please check if your question is mentioned here.
|
|
@ -1,31 +0,0 @@
|
|||
name: 💡 Feature Request
|
||||
description: Got an idea for a feature that Forgejo doesn't have yet? Suggest it here!
|
||||
title: "[FEAT] "
|
||||
labels: ["enhancement/feature"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
- Please speak English, as this is the language all maintainers can speak and write.
|
||||
- Be as clear and concise as possible. A very verbose request is harder to interpret in a concrete way.
|
||||
- Be civil, and follow the [Forgejo Code of Conduct](https://codeberg.org/forgejo/code-of-conduct).
|
||||
- Please make sure you are using the latest release of Forgejo and take a moment to [check that your feature hasn't already been suggested](https://codeberg.org/forgejo/forgejo/issues?q=&type=all&labels=78139).
|
||||
- type: textarea
|
||||
id: needs-benefits
|
||||
attributes:
|
||||
label: Needs and benefits
|
||||
description: As concisely as possible, describe the benefits your feature request will provide or the problems it will try to solve.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description: As concisely as possible, describe the feature you would like to see added or the changes you would like to see made to Forgejo.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If you can, provide screenshots of an implementation on another site, e.g. GitHub.
|
53
.github/workflows/files-changed.yml
vendored
Normal file
53
.github/workflows/files-changed.yml
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
name: files-changed
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
outputs:
|
||||
backend:
|
||||
description: "whether backend files changed"
|
||||
value: ${{ jobs.detect.outputs.backend }}
|
||||
frontend:
|
||||
description: "whether frontend files changed"
|
||||
value: ${{ jobs.detect.outputs.frontend }}
|
||||
docs:
|
||||
description: "whether docs files changed"
|
||||
value: ${{ jobs.detect.outputs.docs }}
|
||||
actions:
|
||||
description: "whether actions files changed"
|
||||
value: ${{ jobs.detect.outputs.actions }}
|
||||
|
||||
jobs:
|
||||
detect:
|
||||
name: detect which files changed
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 3
|
||||
# Map a step output to a job output
|
||||
outputs:
|
||||
backend: ${{ steps.changes.outputs.backend }}
|
||||
frontend: ${{ steps.changes.outputs.frontend }}
|
||||
docs: ${{ steps.changes.outputs.docs }}
|
||||
actions: ${{ steps.changes.outputs.actions }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
backend:
|
||||
- "**/*.go"
|
||||
- "**/*.tmpl"
|
||||
- "go.mod"
|
||||
- "go.sum"
|
||||
|
||||
frontend:
|
||||
- "**/*.js"
|
||||
- "web_src/**"
|
||||
- "package.json"
|
||||
- "package-lock.json"
|
||||
|
||||
docs:
|
||||
- "**/*.md"
|
||||
- "docs/**"
|
||||
|
||||
actions:
|
||||
- ".github/workflows/*"
|
25
.gitignore
vendored
25
.gitignore
vendored
|
@ -14,12 +14,15 @@ _test
|
|||
.idea
|
||||
# Goland's output filename can not be set manually
|
||||
/go_build_*
|
||||
/gitea_*
|
||||
|
||||
# MS VSCode
|
||||
.vscode
|
||||
__debug_bin
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
|
@ -28,9 +31,6 @@ _cgo_export.*
|
|||
|
||||
_testmain.go
|
||||
|
||||
# folder for project related local files
|
||||
/local/
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
@ -60,6 +60,8 @@ cpu.out
|
|||
/bin
|
||||
/dist
|
||||
/custom/*
|
||||
!/custom/conf
|
||||
/custom/conf/*
|
||||
!/custom/conf/app.example.ini
|
||||
/data
|
||||
/indexers
|
||||
|
@ -75,15 +77,13 @@ cpu.out
|
|||
/tests/*.ini
|
||||
/tests/**/*.git/**/*.sample
|
||||
/node_modules
|
||||
/.venv
|
||||
/yarn.lock
|
||||
/yarn-error.log
|
||||
/npm-debug.log*
|
||||
/public/assets/js
|
||||
/public/assets/css
|
||||
/public/assets/fonts
|
||||
/public/assets/licenses.txt
|
||||
/public/assets/img/webpack
|
||||
/public/js
|
||||
/public/css
|
||||
/public/fonts
|
||||
/public/img/webpack
|
||||
/vendor
|
||||
/web_src/fomantic/node_modules
|
||||
/web_src/fomantic/build/*
|
||||
|
@ -100,10 +100,8 @@ cpu.out
|
|||
/VERSION
|
||||
/.air
|
||||
/.go-licenses
|
||||
/.cur-deadcode-out
|
||||
|
||||
# Snapcraft
|
||||
/gitea_a*.txt
|
||||
snap/.snapcraft/
|
||||
parts/
|
||||
stage/
|
||||
|
@ -118,6 +116,3 @@ prime/
|
|||
|
||||
# Manpage
|
||||
/man
|
||||
|
||||
# Generated merged Forgejo+Gitea language files
|
||||
/options/locale/locale_*
|
||||
|
|
|
@ -34,8 +34,7 @@ vscode:
|
|||
- Vue.volar
|
||||
- ms-azuretools.vscode-docker
|
||||
- zixuanchen.vitest-explorer
|
||||
- qwtel.sqlite-viewer
|
||||
- GitHub.vscode-pull-request-github
|
||||
- alexcvzz.vscode-sqlite
|
||||
|
||||
ports:
|
||||
- name: Gitea
|
||||
|
|
|
@ -29,6 +29,7 @@ linters:
|
|||
fast: false
|
||||
|
||||
run:
|
||||
go: "1.20"
|
||||
timeout: 10m
|
||||
skip-dirs:
|
||||
- node_modules
|
||||
|
@ -74,22 +75,18 @@ linters-settings:
|
|||
- name: modifies-value-receiver
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
lang-version: "1.20"
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: encoding/json
|
||||
desc: use gitea's modules/json instead of encoding/json
|
||||
- pkg: github.com/unknwon/com
|
||||
desc: use gitea's util and replacements
|
||||
- pkg: io/ioutil
|
||||
desc: use os or io instead
|
||||
- pkg: golang.org/x/exp
|
||||
desc: it's experimental and unreliable
|
||||
- pkg: code.gitea.io/gitea/modules/git/internal
|
||||
desc: do not use the internal package, use AddXxx function instead
|
||||
- pkg: gopkg.in/ini.v1
|
||||
desc: do not use the ini package, use gitea's config system instead
|
||||
list-type: denylist
|
||||
# Check the list against standard lib.
|
||||
include-go-root: true
|
||||
packages-with-error-message:
|
||||
- encoding/json: "use gitea's modules/json instead of encoding/json"
|
||||
- github.com/unknwon/com: "use gitea's util and replacements"
|
||||
- io/ioutil: "use os or io instead"
|
||||
- golang.org/x/exp: "it's experimental and unreliable."
|
||||
- code.gitea.io/gitea/modules/git/internal: "do not use the internal package, use AddXxx function instead"
|
||||
- gopkg.in/ini.v1: "do not use the ini package, use gitea's config system instead"
|
||||
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
|
|
1
.ignore
1
.ignore
|
@ -5,5 +5,4 @@
|
|||
/modules/public/bindata.go
|
||||
/modules/templates/bindata.go
|
||||
/vendor
|
||||
/public/assets
|
||||
node_modules
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
commands-show-output: false
|
||||
fenced-code-language: false
|
||||
first-line-h1: false
|
||||
heading-increment: false
|
||||
header-increment: false
|
||||
line-length: {code_blocks: false, tables: false, stern: true, line_length: -1}
|
||||
no-alt-text: false
|
||||
no-bare-urls: false
|
||||
no-blanks-blockquote: false
|
||||
no-emphasis-as-heading: false
|
||||
no-duplicate-header: {allow_different_nesting: true}
|
||||
no-emphasis-as-header: false
|
||||
no-empty-links: false
|
||||
no-hard-tabs: {code_blocks: false}
|
||||
no-inline-html: false
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
plugins:
|
||||
- stylelint-declaration-strict-value
|
||||
- stylelint-declaration-block-no-ignored-properties
|
||||
- stylelint-stylistic
|
||||
|
||||
ignoreFiles:
|
||||
- "**/*.go"
|
||||
|
@ -50,7 +48,7 @@ rules:
|
|||
declaration-no-important: null
|
||||
declaration-property-max-values: null
|
||||
declaration-property-unit-allowed-list: null
|
||||
declaration-property-unit-disallowed-list: {line-height: [em]}
|
||||
declaration-property-unit-disallowed-list: null
|
||||
declaration-property-value-allowed-list: null
|
||||
declaration-property-value-disallowed-list: null
|
||||
declaration-property-value-no-unknown: true
|
||||
|
@ -74,7 +72,7 @@ rules:
|
|||
keyframe-declaration-no-important: true
|
||||
keyframe-selector-notation: null
|
||||
keyframes-name-pattern: null
|
||||
length-zero-no-unit: [true, ignore: [custom-properties], ignoreFunctions: [var]]
|
||||
length-zero-no-unit: true
|
||||
max-nesting-depth: null
|
||||
media-feature-name-allowed-list: null
|
||||
media-feature-name-disallowed-list: null
|
||||
|
@ -82,9 +80,7 @@ rules:
|
|||
media-feature-name-no-vendor-prefix: true
|
||||
media-feature-name-unit-allowed-list: null
|
||||
media-feature-name-value-allowed-list: null
|
||||
media-feature-name-value-no-unknown: true
|
||||
media-feature-range-notation: null
|
||||
media-query-no-invalid: true
|
||||
named-grid-areas-no-invalid: true
|
||||
no-descending-specificity: null
|
||||
no-duplicate-at-import-rules: true
|
||||
|
@ -96,14 +92,13 @@ rules:
|
|||
no-unknown-animations: null
|
||||
no-unknown-custom-properties: null
|
||||
number-max-precision: null
|
||||
plugin/declaration-block-no-ignored-properties: true
|
||||
property-allowed-list: null
|
||||
property-disallowed-list: null
|
||||
property-no-unknown: true
|
||||
property-no-vendor-prefix: null
|
||||
rule-empty-line-before: null
|
||||
rule-selector-property-disallowed-list: null
|
||||
scale-unlimited/declaration-strict-value: [[/color$/, font-weight], {ignoreValues: /^(inherit|transparent|unset|initial|currentcolor|none)$/, ignoreFunctions: false, disableFix: true, expandShorthand: true}]
|
||||
scale-unlimited/declaration-strict-value: [[color, background-color, border-color, font-weight], {ignoreValues: /^(inherit|transparent|unset|initial|currentcolor|none)$/, ignoreFunctions: false, disableFix: true}]
|
||||
selector-attribute-name-disallowed-list: null
|
||||
selector-attribute-operator-allowed-list: null
|
||||
selector-attribute-operator-disallowed-list: null
|
||||
|
@ -137,82 +132,6 @@ rules:
|
|||
selector-type-no-unknown: [true, {ignore: [custom-elements]}]
|
||||
shorthand-property-no-redundant-values: true
|
||||
string-no-newline: true
|
||||
stylistic/at-rule-name-case: null
|
||||
stylistic/at-rule-name-newline-after: null
|
||||
stylistic/at-rule-name-space-after: null
|
||||
stylistic/at-rule-semicolon-newline-after: null
|
||||
stylistic/at-rule-semicolon-space-before: null
|
||||
stylistic/block-closing-brace-empty-line-before: null
|
||||
stylistic/block-closing-brace-newline-after: null
|
||||
stylistic/block-closing-brace-newline-before: null
|
||||
stylistic/block-closing-brace-space-after: null
|
||||
stylistic/block-closing-brace-space-before: null
|
||||
stylistic/block-opening-brace-newline-after: null
|
||||
stylistic/block-opening-brace-newline-before: null
|
||||
stylistic/block-opening-brace-space-after: null
|
||||
stylistic/block-opening-brace-space-before: null
|
||||
stylistic/color-hex-case: lower
|
||||
stylistic/declaration-bang-space-after: never
|
||||
stylistic/declaration-bang-space-before: null
|
||||
stylistic/declaration-block-semicolon-newline-after: null
|
||||
stylistic/declaration-block-semicolon-newline-before: null
|
||||
stylistic/declaration-block-semicolon-space-after: null
|
||||
stylistic/declaration-block-semicolon-space-before: never
|
||||
stylistic/declaration-block-trailing-semicolon: null
|
||||
stylistic/declaration-colon-newline-after: null
|
||||
stylistic/declaration-colon-space-after: null
|
||||
stylistic/declaration-colon-space-before: never
|
||||
stylistic/function-comma-newline-after: null
|
||||
stylistic/function-comma-newline-before: null
|
||||
stylistic/function-comma-space-after: null
|
||||
stylistic/function-comma-space-before: null
|
||||
stylistic/function-max-empty-lines: 0
|
||||
stylistic/function-parentheses-newline-inside: never-multi-line
|
||||
stylistic/function-parentheses-space-inside: null
|
||||
stylistic/function-whitespace-after: null
|
||||
stylistic/indentation: 2
|
||||
stylistic/linebreaks: null
|
||||
stylistic/max-empty-lines: 1
|
||||
stylistic/max-line-length: null
|
||||
stylistic/media-feature-colon-space-after: null
|
||||
stylistic/media-feature-colon-space-before: never
|
||||
stylistic/media-feature-name-case: null
|
||||
stylistic/media-feature-parentheses-space-inside: null
|
||||
stylistic/media-feature-range-operator-space-after: always
|
||||
stylistic/media-feature-range-operator-space-before: always
|
||||
stylistic/media-query-list-comma-newline-after: null
|
||||
stylistic/media-query-list-comma-newline-before: null
|
||||
stylistic/media-query-list-comma-space-after: null
|
||||
stylistic/media-query-list-comma-space-before: null
|
||||
stylistic/no-empty-first-line: null
|
||||
stylistic/no-eol-whitespace: true
|
||||
stylistic/no-extra-semicolons: true
|
||||
stylistic/no-missing-end-of-source-newline: null
|
||||
stylistic/number-leading-zero: null
|
||||
stylistic/number-no-trailing-zeros: null
|
||||
stylistic/property-case: lower
|
||||
stylistic/selector-attribute-brackets-space-inside: null
|
||||
stylistic/selector-attribute-operator-space-after: null
|
||||
stylistic/selector-attribute-operator-space-before: null
|
||||
stylistic/selector-combinator-space-after: null
|
||||
stylistic/selector-combinator-space-before: null
|
||||
stylistic/selector-descendant-combinator-no-non-space: null
|
||||
stylistic/selector-list-comma-newline-after: null
|
||||
stylistic/selector-list-comma-newline-before: null
|
||||
stylistic/selector-list-comma-space-after: always-single-line
|
||||
stylistic/selector-list-comma-space-before: never-single-line
|
||||
stylistic/selector-max-empty-lines: 0
|
||||
stylistic/selector-pseudo-class-case: lower
|
||||
stylistic/selector-pseudo-class-parentheses-space-inside: never
|
||||
stylistic/selector-pseudo-element-case: lower
|
||||
stylistic/string-quotes: double
|
||||
stylistic/unicode-bom: null
|
||||
stylistic/unit-case: lower
|
||||
stylistic/value-list-comma-newline-after: null
|
||||
stylistic/value-list-comma-newline-before: null
|
||||
stylistic/value-list-comma-space-after: null
|
||||
stylistic/value-list-comma-space-before: null
|
||||
stylistic/value-list-max-empty-lines: 0
|
||||
time-min-milliseconds: null
|
||||
unit-allowed-list: null
|
||||
unit-disallowed-list: null
|
||||
|
|
75
.woodpecker/compliance.yml
Normal file
75
.woodpecker/compliance.yml
Normal file
|
@ -0,0 +1,75 @@
|
|||
platform: linux/amd64
|
||||
|
||||
when:
|
||||
event: [ push, pull_request, manual ]
|
||||
branch:
|
||||
exclude: [ soft-fork/*/*, soft-fork/*/*/* ]
|
||||
|
||||
variables:
|
||||
- &golang_image 'golang:1.20'
|
||||
- &test_image 'codeberg.org/forgejo/test_env:main'
|
||||
- &goproxy_override ''
|
||||
- &goproxy_setup |-
|
||||
if [ -n "$${GOPROXY_OVERRIDE:-}" ]; then
|
||||
export GOPROXY="$${GOPROXY_OVERRIDE}";
|
||||
echo "Using goproxy from goproxy_override \"$${GOPROXY}\"";
|
||||
elif [ -n "$${GOPROXY_DEFAULT:-}" ]; then
|
||||
export GOPROXY="$${GOPROXY_DEFAULT}";
|
||||
echo "Using goproxy from goproxy_default (secret) not displaying";
|
||||
else
|
||||
export GOPROXY="https://proxy.golang.org,direct";
|
||||
echo "No goproxy overrides or defaults given, using \"$${GOPROXY}\"";
|
||||
fi
|
||||
|
||||
workspace:
|
||||
base: /go
|
||||
path: src/codeberg/gitea
|
||||
|
||||
pipeline:
|
||||
deps-backend:
|
||||
image: *golang_image
|
||||
pull: true
|
||||
environment:
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- goproxy_default
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- make deps-backend
|
||||
|
||||
security-check:
|
||||
image: *golang_image
|
||||
group: checks
|
||||
pull: true
|
||||
environment:
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- goproxy_default
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- make security-check
|
||||
|
||||
lint-backend:
|
||||
image: *test_image
|
||||
pull: true
|
||||
group: checks
|
||||
environment:
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
TAGS: 'bindata sqlite sqlite_unlock_notify'
|
||||
GOSUMDB: 'sum.golang.org'
|
||||
secrets:
|
||||
- goproxy_default
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- make lint-backend
|
||||
|
||||
checks-backend:
|
||||
image: *test_image
|
||||
group: checks
|
||||
environment:
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- goproxy_default
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- make --always-make checks-backend
|
141
.woodpecker/testing-amd64.yml
Normal file
141
.woodpecker/testing-amd64.yml
Normal file
|
@ -0,0 +1,141 @@
|
|||
platform: linux/amd64
|
||||
|
||||
when:
|
||||
event: [ push, pull_request, manual ]
|
||||
branch:
|
||||
exclude: [ soft-fork/*/*, soft-fork/*/*/* ]
|
||||
|
||||
depends_on:
|
||||
- compliance
|
||||
|
||||
variables:
|
||||
- &golang_image 'golang:1.20'
|
||||
- &test_image 'codeberg.org/forgejo/test_env:main'
|
||||
- &mysql_image 'mysql:8'
|
||||
- &pgsql_image 'postgres:10'
|
||||
- &goproxy_override ''
|
||||
- &goproxy_setup |-
|
||||
if [ -n "$${GOPROXY_OVERRIDE:-}" ]; then
|
||||
export GOPROXY="$${GOPROXY_OVERRIDE}";
|
||||
echo "Using goproxy from goproxy_override \"$${GOPROXY}\"";
|
||||
elif [ -n "$${GOPROXY_DEFAULT:-}" ]; then
|
||||
export GOPROXY="$${GOPROXY_DEFAULT}";
|
||||
echo "Using goproxy from goproxy_default (secret) not displaying";
|
||||
else
|
||||
export GOPROXY="https://proxy.golang.org,direct";
|
||||
echo "No goproxy overrides or defaults given, using \"$${GOPROXY}\"";
|
||||
fi
|
||||
|
||||
services:
|
||||
mysql8:
|
||||
image: *mysql_image
|
||||
pull: true
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: testgitea
|
||||
|
||||
pgsql:
|
||||
image: *pgsql_image
|
||||
pull: true
|
||||
environment:
|
||||
POSTGRES_DB: test
|
||||
POSTGRES_PASSWORD: postgres
|
||||
|
||||
workspace:
|
||||
base: /go
|
||||
path: src/codeberg/gitea
|
||||
|
||||
pipeline:
|
||||
git-safe:
|
||||
image: *golang_image
|
||||
pull: true
|
||||
commands:
|
||||
- git config --add safe.directory '*'
|
||||
|
||||
deps-backend:
|
||||
image: *golang_image
|
||||
pull: true
|
||||
environment:
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- goproxy_default
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- make deps-backend
|
||||
|
||||
tag-pre-condition:
|
||||
image: *golang_image
|
||||
pull: true
|
||||
commands:
|
||||
- git update-ref refs/heads/tag_test ${CI_COMMIT_SHA}
|
||||
|
||||
prepare-test-env:
|
||||
image: *test_image
|
||||
pull: true
|
||||
commands:
|
||||
- ./build/test-env-prepare.sh
|
||||
|
||||
build:
|
||||
image: *test_image
|
||||
environment:
|
||||
GOSUMDB: sum.golang.org
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- goproxy_default
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- su gitea -c './build/test-env-check.sh'
|
||||
- su gitea -c 'make backend'
|
||||
|
||||
unit-test:
|
||||
image: *test_image
|
||||
environment:
|
||||
TAGS: 'bindata sqlite sqlite_unlock_notify'
|
||||
RACE_ENABLED: 'true'
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- github_read_token
|
||||
- goproxy_default
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- su gitea -c 'make unit-test-coverage test-check'
|
||||
|
||||
test-mysql8:
|
||||
group: integration
|
||||
image: *test_image
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- su gitea -c 'timeout -s ABRT 50m make test-mysql8-migration test-mysql8'
|
||||
environment:
|
||||
TAGS: 'bindata'
|
||||
RACE_ENABLED: 'true'
|
||||
USE_REPO_TEST_DIR: '1'
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- goproxy_default
|
||||
|
||||
test-pgsql:
|
||||
group: integration
|
||||
image: *test_image
|
||||
commands:
|
||||
- *goproxy_setup
|
||||
- su gitea -c 'timeout -s ABRT 50m make test-pgsql-migration test-pgsql'
|
||||
environment:
|
||||
TAGS: 'bindata'
|
||||
RACE_ENABLED: 'true'
|
||||
USE_REPO_TEST_DIR: '1'
|
||||
GOPROXY_OVERRIDE: *goproxy_override
|
||||
secrets:
|
||||
- goproxy_default
|
||||
|
||||
test-sqlite:
|
||||
group: integration
|
||||
image: *test_image
|
||||
environment:
|
||||
- USE_REPO_TEST_DIR=1
|
||||
- GOPROXY=off
|
||||
- TAGS=bindata gogit sqlite sqlite_unlock_notify
|
||||
- TEST_TAGS=bindata gogit sqlite sqlite_unlock_notify
|
||||
commands:
|
||||
- su gitea -c 'timeout -s ABRT 120m make test-sqlite-migration test-sqlite'
|
|
@ -1,44 +0,0 @@
|
|||
extends: default
|
||||
|
||||
rules:
|
||||
braces:
|
||||
min-spaces-inside: 0
|
||||
max-spaces-inside: 1
|
||||
min-spaces-inside-empty: 0
|
||||
max-spaces-inside-empty: 0
|
||||
|
||||
brackets:
|
||||
min-spaces-inside: 0
|
||||
max-spaces-inside: 1
|
||||
min-spaces-inside-empty: 0
|
||||
max-spaces-inside-empty: 0
|
||||
|
||||
comments:
|
||||
require-starting-space: true
|
||||
ignore-shebangs: true
|
||||
min-spaces-from-content: 1
|
||||
|
||||
comments-indentation:
|
||||
level: error
|
||||
|
||||
document-start:
|
||||
level: error
|
||||
present: false
|
||||
|
||||
document-end:
|
||||
present: false
|
||||
|
||||
empty-lines:
|
||||
max: 1
|
||||
|
||||
indentation:
|
||||
spaces: 2
|
||||
|
||||
line-length: disable
|
||||
|
||||
truthy:
|
||||
allowed-values: ["true", "false", "on", "off"]
|
||||
|
||||
ignore: |
|
||||
.venv
|
||||
node_modules
|
|
@ -42,13 +42,13 @@ GARGS = "--no-print-directory"
|
|||
|
||||
# The GNU convention is to use the lowercased `prefix` variable/macro to
|
||||
# specify the installation directory. Humor them.
|
||||
GPREFIX =
|
||||
GPREFIX = ""
|
||||
.if defined(PREFIX) && ! defined(prefix)
|
||||
GPREFIX = 'prefix = "$(PREFIX)"'
|
||||
.endif
|
||||
|
||||
.BEGIN: .SILENT
|
||||
which $(GMAKE) || (printf "Error: GNU Make is required!\n\n" 1>&2 && false)
|
||||
which $(GMAKE) || printf "Error: GNU Make is required!\n\n" 1>&2 && false
|
||||
|
||||
.PHONY: FRC
|
||||
$(.TARGETS): FRC
|
||||
|
|
1283
CHANGELOG.md
1283
CHANGELOG.md
File diff suppressed because it is too large
Load diff
32
CODEOWNERS
32
CODEOWNERS
|
@ -1,32 +0,0 @@
|
|||
# This file describes the expected reviewers for a PR based on the changed
|
||||
# files. Unlike what the name of the file suggests they don't own the code, but
|
||||
# merely have a good understanding of that area of the codebase and therefore
|
||||
# are usually suited as a reviewer.
|
||||
|
||||
|
||||
# Please mind the alphabetic order of reviewers.
|
||||
|
||||
# Files related to the CI of the Forgejo project.
|
||||
.forgejo/.* @dachary @earl-warren
|
||||
|
||||
# Files related to frontend development.
|
||||
|
||||
# Javascript and CSS code.
|
||||
web_src/.* @caesar @crystal @gusted
|
||||
|
||||
# HTML templates used by the backend.
|
||||
templates/.* @caesar @crystal @gusted
|
||||
|
||||
# Files related to Go development.
|
||||
|
||||
# The modules usually don't require much knowledge about Forgejo and could
|
||||
# be reviewed by Go developers.
|
||||
modules/.* @dachary @earl-warren @gusted
|
||||
|
||||
# Models has code related to SQL queries, general database knowledge and XORM.
|
||||
models/.* @dachary @earl-warren @gusted
|
||||
|
||||
# The routers directory contains the most amount code that requires a good grasp
|
||||
# of how Forgejo comes together. It's tedious to write good integration testing
|
||||
# for code that lives in here.
|
||||
routers/.* @dachary @earl-warren @gusted
|
96
CODE_OF_CONDUCT.md
Normal file
96
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,96 @@
|
|||
# Gitea Community Code of Conduct
|
||||
|
||||
## About
|
||||
|
||||
Online communities include people from many different backgrounds. The Gitea contributors are committed to providing a friendly, safe and welcoming environment for all, regardless of gender identity and expression, sexual orientation, disabilities, neurodiversity, physical appearance, body size, ethnicity, nationality, race, age, religion, or similar personal characteristics.
|
||||
|
||||
The first goal of the Code of Conduct is to specify a baseline standard of behavior so that people with different social values and communication styles can talk about Gitea effectively, productively, and respectfully.
|
||||
|
||||
The second goal is to provide a mechanism for resolving conflicts in the community when they arise.
|
||||
|
||||
The third goal of the Code of Conduct is to make our community welcoming to people from different backgrounds. Diversity is critical to the project; for Gitea to be successful, it needs contributors and users from all backgrounds.
|
||||
|
||||
We believe that healthy debate and disagreement are essential to a healthy project and community. However, it is never ok to be disrespectful. We value diverse opinions, but we value respectful behavior more.
|
||||
|
||||
## Community values
|
||||
|
||||
These are the values to which people in the Gitea community should aspire.
|
||||
|
||||
- **Be friendly and welcoming.**
|
||||
- **Be patient.**
|
||||
- Remember that people have varying communication styles and that not everyone is using their native language. (Meaning and tone can be lost in translation.)
|
||||
- **Be thoughtful.**
|
||||
- Productive communication requires effort. Think about how your words will be interpreted.
|
||||
- Remember that sometimes it is best to refrain entirely from commenting.
|
||||
- **Be respectful.**
|
||||
- In particular, respect differences of opinion.
|
||||
- **Be charitable.**
|
||||
- Interpret the arguments of others in good faith, do not seek to disagree.
|
||||
- When we do disagree, try to understand why.
|
||||
- **Be constructive.**
|
||||
- Avoid derailing: stay on topic; if you want to talk about something else, start a new conversation.
|
||||
- Avoid unconstructive criticism: don't merely decry the current state of affairs; offer—or at least solicit—suggestions as to how things may be improved.
|
||||
- Avoid snarking (pithy, unproductive, sniping comments)
|
||||
- Avoid discussing potentially offensive or sensitive issues; this all too often leads to unnecessary conflict.
|
||||
- Avoid microaggressions (brief and commonplace verbal, behavioral and environmental indignities that communicate hostile, derogatory or negative slights and insults to a person or group).
|
||||
- **Be responsible.**
|
||||
- What you say and do matters. Take responsibility for your words and actions, including their consequences, whether intended or otherwise.
|
||||
|
||||
People are complicated. You should expect to be misunderstood and to misunderstand others; when this inevitably occurs, resist the urge to be defensive or assign blame. Try not to take offense where no offense was intended. Give people the benefit of the doubt. Even if the intent was to provoke, do not rise to it. It is the responsibility of all parties to de-escalate conflict when it arises.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
### Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
### Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others’ private information, such as a physical or electronic address, without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
### Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject: comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, as well as to ban (temporarily or permanently) any contributor for behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
### Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
This Code of Conduct also applies outside the project spaces when the Project Stewards have a reasonable belief that an individual’s behavior may have a negative impact on the project or its community.
|
||||
|
||||
### Conflict Resolution
|
||||
|
||||
We do not believe that all conflict is bad; healthy debate and disagreement often yield positive results. However, it is never okay to be disrespectful or to engage in behavior that violates the project’s code of conduct.
|
||||
|
||||
If you see someone violating the code of conduct, you are encouraged to address the behavior directly with those involved. Many issues can be resolved quickly and easily, and this gives people more control over the outcome of their dispute. If you are unable to resolve the matter for any reason, or if the behavior is threatening or harassing, report it. We are dedicated to providing an environment where participants feel welcome and safe.
|
||||
|
||||
Reports should be directed to the Gitea Project Stewards at conduct@gitea.com. It is the Project Stewards’ duty to receive and address reported violations of the code of conduct. They will then work with a committee consisting of representatives from the technical-oversight-committee.
|
||||
|
||||
We will investigate every complaint, but you may not receive a direct response. We will use our discretion in determining when and how to follow up on reported incidents, which may range from not taking action to permanent expulsion from the project and project-sponsored spaces. Under normal circumstances, we will notify the accused of the report and provide them an opportunity to discuss it before any action is taken. If there is a consensus between maintainers that such an endeavor would be useless (i.e. in case of an obvious spammer), we reserve the right to take action without notifying the accused first. The identity of the reporter will be omitted from the details of the report supplied to the accused. In potentially harmful situations, such as ongoing harassment or threats to anyone’s safety, we may take action without notice.
|
||||
|
||||
### Attribution
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
## Summary
|
||||
|
||||
- Treat everyone with respect and kindness.
|
||||
- Be thoughtful in how you communicate.
|
||||
- Don’t be destructive or inflammatory.
|
||||
- If you encounter an issue, please mail conduct@gitea.com.
|
|
@ -7,18 +7,17 @@ Sensitive security-related issues should be reported to [security@forgejo.org](m
|
|||
## For everyone involved
|
||||
|
||||
- [Documentation](https://forgejo.org/docs/next/)
|
||||
- [Code of Conduct](https://forgejo.org/docs/latest/developer/coc/)
|
||||
- [Bugs, features, security and others discussions](https://forgejo.org/docs/latest/developer/discussions/)
|
||||
- [Governance](https://forgejo.org/docs/latest/developer/governance/)
|
||||
- [Sustainability and funding](https://codeberg.org/forgejo/sustainability/src/branch/main/README.md)
|
||||
- [Code of Conduct](https://forgejo.org/docs/next/developer/COC/)
|
||||
- [Bugs, features, security and others discussions](https://forgejo.org/docs/next/developer/DISCUSSIONS/)
|
||||
- [Governance](https://forgejo.org/docs/next/developer/GOVERNANCE/)
|
||||
- [Sustainability and funding](https://codeberg.org/forgejo/sustainability/src/branch/master/README.md)
|
||||
|
||||
## For contributors
|
||||
|
||||
- [Developer Certificate of Origin (DCO)](https://forgejo.org/docs/latest/developer/dco/)
|
||||
- [Development workflow](https://forgejo.org/docs/latest/developer/workflow/)
|
||||
- [Compiling from source](https://forgejo.org/docs/latest/developer/from-source/)
|
||||
- [Developer Certificate of Origin (DCO)](https://forgejo.org/docs/next/developer/DCO/)
|
||||
- [Development workflow](https://forgejo.org/docs/next/developer/WORKFLOW/)
|
||||
|
||||
## For maintainers
|
||||
|
||||
- [Release management](https://forgejo.org/docs/latest/developer/release/)
|
||||
- [Secrets](https://forgejo.org/docs/latest/developer/secrets/)
|
||||
- [Release management](https://forgejo.org/docs/next/developer/RELEASE/)
|
||||
- [Secrets](https://forgejo.org/docs/next/developer/SECRETS/)
|
||||
|
|
57
Dockerfile
57
Dockerfile
|
@ -1,6 +1,5 @@
|
|||
FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
|
||||
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.21-alpine3.19 as build-env
|
||||
#Build stage
|
||||
FROM docker.io/library/golang:1.20-alpine3.18 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
|
@ -10,48 +9,21 @@ ARG TAGS="sqlite sqlite_unlock_notify"
|
|||
ENV TAGS "bindata timetzdata $TAGS"
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
|
||||
#
|
||||
# Transparently cross compile for the target platform
|
||||
#
|
||||
COPY --from=xx / /
|
||||
ARG TARGETPLATFORM
|
||||
RUN apk --no-cache add clang lld
|
||||
RUN xx-apk --no-cache add gcc musl-dev
|
||||
ENV CGO_ENABLED=1
|
||||
RUN xx-go --wrap
|
||||
#
|
||||
# for go generate and binfmt to find
|
||||
# without it the generate phase will fail with
|
||||
# #19 25.04 modules/public/public_bindata.go:8: running "go": exit status 1
|
||||
# #19 25.39 aarch64-binfmt-P: Could not open '/lib/ld-musl-aarch64.so.1': No such file or directory
|
||||
# why exactly is it needed? where is binfmt involved?
|
||||
#
|
||||
RUN cp /*-alpine-linux-musl*/lib/ld-musl-*.so.1 /lib || true
|
||||
|
||||
#Build deps
|
||||
RUN apk --no-cache add build-base git nodejs npm
|
||||
|
||||
#Setup repo
|
||||
COPY . ${GOPATH}/src/code.gitea.io/gitea
|
||||
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||
|
||||
RUN make clean-all
|
||||
RUN make frontend
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
|
||||
RUN make go-check generate-backend static-executable && xx-verify gitea
|
||||
#Checkout version if set
|
||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
&& make clean-all build
|
||||
|
||||
# Copy local files
|
||||
COPY docker/root /tmp/local
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
|
||||
# Set permissions
|
||||
RUN chmod 755 /tmp/local/usr/bin/entrypoint \
|
||||
/tmp/local/usr/local/bin/gitea \
|
||||
/tmp/local/etc/s6/gitea/* \
|
||||
/tmp/local/etc/s6/openssh/* \
|
||||
/tmp/local/etc/s6/.s6-svscan/* \
|
||||
/go/src/code.gitea.io/gitea/gitea \
|
||||
/go/src/code.gitea.io/gitea/environment-to-ini
|
||||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM docker.io/library/alpine:3.19
|
||||
FROM docker.io/library/alpine:3.18
|
||||
LABEL maintainer="contact@forgejo.org"
|
||||
|
||||
EXPOSE 22 3000
|
||||
|
@ -67,8 +39,7 @@ RUN apk --no-cache add \
|
|||
s6 \
|
||||
sqlite \
|
||||
su-exec \
|
||||
gnupg \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
gnupg
|
||||
|
||||
RUN addgroup \
|
||||
-S -g 1000 \
|
||||
|
@ -90,8 +61,10 @@ VOLUME ["/data"]
|
|||
ENTRYPOINT ["/usr/bin/entrypoint"]
|
||||
CMD ["/bin/s6-svscan", "/etc/s6"]
|
||||
|
||||
COPY --from=build-env /tmp/local /
|
||||
RUN cd /usr/local/bin ; ln -s gitea forgejo
|
||||
COPY docker/root /
|
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
|
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
|
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh
|
||||
RUN chmod 755 /usr/bin/entrypoint /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini
|
||||
RUN chmod 755 /etc/s6/gitea/* /etc/s6/openssh/* /etc/s6/.s6-svscan/*
|
||||
RUN chmod 644 /etc/profile.d/gitea_bash_autocomplete.sh
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
|
||||
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.21-alpine3.19 as build-env
|
||||
#Build stage
|
||||
FROM docker.io/library/golang:1.20-alpine3.18 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
|
@ -10,46 +9,21 @@ ARG TAGS="sqlite sqlite_unlock_notify"
|
|||
ENV TAGS "bindata timetzdata $TAGS"
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
|
||||
#
|
||||
# Transparently cross compile for the target platform
|
||||
#
|
||||
COPY --from=xx / /
|
||||
ARG TARGETPLATFORM
|
||||
RUN apk --no-cache add clang lld
|
||||
RUN xx-apk --no-cache add gcc musl-dev
|
||||
ENV CGO_ENABLED=1
|
||||
RUN xx-go --wrap
|
||||
#
|
||||
# for go generate and binfmt to find
|
||||
# without it the generate phase will fail with
|
||||
# #19 25.04 modules/public/public_bindata.go:8: running "go": exit status 1
|
||||
# #19 25.39 aarch64-binfmt-P: Could not open '/lib/ld-musl-aarch64.so.1': No such file or directory
|
||||
# why exactly is it needed? where is binfmt involved?
|
||||
#
|
||||
RUN cp /*-alpine-linux-musl*/lib/ld-musl-*.so.1 /lib || true
|
||||
|
||||
#Build deps
|
||||
RUN apk --no-cache add build-base git nodejs npm
|
||||
|
||||
#Setup repo
|
||||
COPY . ${GOPATH}/src/code.gitea.io/gitea
|
||||
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||
|
||||
RUN make clean-all
|
||||
RUN make frontend
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
|
||||
RUN make go-check generate-backend static-executable && xx-verify gitea
|
||||
#Checkout version if set
|
||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
&& make clean-all build
|
||||
|
||||
# Copy local files
|
||||
COPY docker/rootless /tmp/local
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
|
||||
# Set permissions
|
||||
RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
|
||||
/tmp/local/usr/local/bin/docker-setup.sh \
|
||||
/tmp/local/usr/local/bin/gitea \
|
||||
/go/src/code.gitea.io/gitea/gitea \
|
||||
/go/src/code.gitea.io/gitea/environment-to-ini
|
||||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM docker.io/library/alpine:3.19
|
||||
FROM docker.io/library/alpine:3.18
|
||||
LABEL maintainer="contact@forgejo.org"
|
||||
|
||||
EXPOSE 2222 3000
|
||||
|
@ -61,8 +35,7 @@ RUN apk --no-cache add \
|
|||
gettext \
|
||||
git \
|
||||
curl \
|
||||
gnupg \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
gnupg
|
||||
|
||||
RUN addgroup \
|
||||
-S -g 1000 \
|
||||
|
@ -78,11 +51,12 @@ RUN addgroup \
|
|||
RUN mkdir -p /var/lib/gitea /etc/gitea
|
||||
RUN chown git:git /var/lib/gitea /etc/gitea
|
||||
|
||||
COPY --from=build-env /tmp/local /
|
||||
RUN cd /usr/local/bin ; ln -s gitea forgejo
|
||||
COPY docker/rootless /
|
||||
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
|
||||
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
|
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh
|
||||
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh /usr/local/bin/docker-setup.sh /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini
|
||||
RUN chmod 644 /etc/profile.d/gitea_bash_autocomplete.sh
|
||||
|
||||
#git:git
|
||||
USER 1000:1000
|
||||
|
|
|
@ -52,10 +52,3 @@ Xinyi Gong <hestergong@gmail.com> (@HesterG)
|
|||
wxiaoguang <wxiaoguang@gmail.com> (@wxiaoguang)
|
||||
Gary Moon <gary@garymoon.net> (@garymoon)
|
||||
Philip Peterson <philip.c.peterson@gmail.com> (@philip-peterson)
|
||||
Denys Konovalov <kontakt@denyskon.de> (@denyskon)
|
||||
Punit Inani <punitinani1@gmail.com> (@puni9869)
|
||||
CaiCandong <1290147055@qq.com> (@caicandong)
|
||||
Rui Chen <rui@chenrui.dev> (@chenrui333)
|
||||
Nanguan Lin <nanguanlin6@gmail.com> (@lng2020)
|
||||
kerwin612 <kerwin612@qq.com> (@kerwin612)
|
||||
Gary Wang <git@blumia.net> (@BLumia)
|
||||
|
|
258
Makefile
258
Makefile
|
@ -22,22 +22,20 @@ GO ?= go
|
|||
SHASUM ?= shasum -a 256
|
||||
HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes)
|
||||
COMMA := ,
|
||||
DIFF ?= diff --unified
|
||||
|
||||
XGO_VERSION := go-1.21.x
|
||||
XGO_VERSION := go-1.20.x
|
||||
|
||||
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.44.0
|
||||
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.43.0
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.7.0
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.5.0
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.0
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.52.2
|
||||
GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
|
||||
MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.4
|
||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0
|
||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.0.1
|
||||
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.6.25
|
||||
DEADCODE_PACKAGE ?= golang.org/x/tools/internal/cmd/deadcode@v0.14.0
|
||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@latest
|
||||
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@latest
|
||||
|
||||
DOCKER_IMAGE ?= gitea/gitea
|
||||
DOCKER_TAG ?= latest
|
||||
|
@ -51,14 +49,10 @@ ifeq ($(HAS_GO), yes)
|
|||
CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(GOOS),windows)
|
||||
IS_WINDOWS := yes
|
||||
else ifeq ($(patsubst Windows%,Windows,$(OS)),Windows)
|
||||
ifeq ($(GOOS),)
|
||||
IS_WINDOWS := yes
|
||||
endif
|
||||
endif
|
||||
ifeq ($(IS_WINDOWS),yes)
|
||||
ifeq ($(OS), Windows_NT)
|
||||
GOFLAGS := -v -buildmode=exe
|
||||
EXECUTABLE ?= gitea.exe
|
||||
else ifeq ($(OS), Windows)
|
||||
GOFLAGS := -v -buildmode=exe
|
||||
EXECUTABLE ?= gitea.exe
|
||||
else
|
||||
|
@ -74,7 +68,7 @@ endif
|
|||
|
||||
EXTRA_GOFLAGS ?=
|
||||
|
||||
MAKE_VERSION := $(shell "$(MAKE)" -v | cat | head -n 1)
|
||||
MAKE_VERSION := $(shell "$(MAKE)" -v | head -n 1)
|
||||
MAKE_EVIDENCE_DIR := .make_evidence
|
||||
|
||||
ifeq ($(RACE_ENABLED),true)
|
||||
|
@ -85,38 +79,52 @@ endif
|
|||
STORED_VERSION_FILE := VERSION
|
||||
HUGO_VERSION ?= 0.111.3
|
||||
|
||||
|
||||
STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null)
|
||||
ifneq ($(STORED_VERSION),)
|
||||
GITEA_VERSION ?= $(STORED_VERSION)
|
||||
ifneq ($(DRONE_TAG),)
|
||||
VERSION ?= $(subst v,,$(DRONE_TAG))
|
||||
GITEA_VERSION ?= $(VERSION)
|
||||
else
|
||||
GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
|
||||
ifneq ($(DRONE_BRANCH),)
|
||||
VERSION ?= $(shell echo $(DRONE_BRANCH) | sed -e 's|v\([0-9.][0-9.]*\)/.*|\1|')
|
||||
else
|
||||
VERSION ?= main
|
||||
endif
|
||||
|
||||
STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null)
|
||||
ifneq ($(STORED_VERSION),)
|
||||
GITEA_VERSION ?= $(STORED_VERSION)
|
||||
else
|
||||
GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
|
||||
endif
|
||||
endif
|
||||
|
||||
# if version = "main" then update version to "nightly"
|
||||
ifeq ($(VERSION),main)
|
||||
VERSION := main-nightly
|
||||
endif
|
||||
VERSION = ${GITEA_VERSION}
|
||||
|
||||
# SemVer
|
||||
FORGEJO_VERSION := 7.0.0+0-gitea-1.22.0
|
||||
FORGEJO_VERSION := 3.0.0+0-gitea-1.19.0
|
||||
|
||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "main.ForgejoVersion=$(FORGEJO_VERSION)"
|
||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "code.gitea.io/gitea/routers/api/forgejo/v1.ForgejoVersion=$(FORGEJO_VERSION)"
|
||||
|
||||
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
|
||||
|
||||
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) $(shell $(GO) list code.gitea.io/gitea/models/forgejo_migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
|
||||
FOMANTIC_WORK_DIR := web_src/fomantic
|
||||
|
||||
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
|
||||
WEBPACK_CONFIGS := webpack.config.js
|
||||
WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css
|
||||
WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts public/assets/img/webpack
|
||||
WEBPACK_DEST := public/js/index.js public/css/index.css
|
||||
WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/img/webpack
|
||||
|
||||
BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
|
||||
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
|
||||
|
||||
GENERATED_GO_DEST := modules/charset/invisible_gen.go modules/charset/ambiguous_gen.go
|
||||
|
||||
SVG_DEST_DIR := public/assets/img/svg
|
||||
SVG_DEST_DIR := public/img/svg
|
||||
|
||||
AIR_TMP_DIR := .air
|
||||
|
||||
|
@ -149,19 +157,22 @@ ifdef DEPS_PLAYWRIGHT
|
|||
PLAYWRIGHT_FLAGS += --with-deps
|
||||
endif
|
||||
|
||||
FORGEJO_API_SPEC := public/assets/forgejo/api.v1.yml
|
||||
FORGEJO_API_SPEC := public/forgejo/api.v1.yml
|
||||
|
||||
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
||||
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
|
||||
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
|
||||
SWAGGER_EXCLUDE := code.gitea.io/sdk
|
||||
SWAGGER_NEWLINE_COMMAND := -e '$$a\'
|
||||
SWAGGER_SPEC_BRANDING := s|Gitea API|Forgejo API|g
|
||||
|
||||
TEST_MYSQL_HOST ?= mysql:3306
|
||||
TEST_MYSQL_DBNAME ?= testgitea
|
||||
TEST_MYSQL_USERNAME ?= root
|
||||
TEST_MYSQL_PASSWORD ?=
|
||||
TEST_MYSQL8_HOST ?= mysql8:3306
|
||||
TEST_MYSQL8_DBNAME ?= testgitea
|
||||
TEST_MYSQL8_USERNAME ?= root
|
||||
TEST_MYSQL8_PASSWORD ?=
|
||||
TEST_PGSQL_HOST ?= pgsql:5432
|
||||
TEST_PGSQL_DBNAME ?= testgitea
|
||||
TEST_PGSQL_USERNAME ?= postgres
|
||||
|
@ -188,10 +199,10 @@ help:
|
|||
@echo " - clean delete backend and integration files"
|
||||
@echo " - clean-all delete backend, frontend and integration files"
|
||||
@echo " - deps install dependencies"
|
||||
@echo " - deps-docs install docs dependencies"
|
||||
@echo " - deps-frontend install frontend dependencies"
|
||||
@echo " - deps-backend install backend dependencies"
|
||||
@echo " - deps-tools install tool dependencies"
|
||||
@echo " - deps-py install python dependencies"
|
||||
@echo " - lint lint everything"
|
||||
@echo " - lint-fix lint everything and fix issues"
|
||||
@echo " - lint-actions lint action workflow files"
|
||||
|
@ -208,8 +219,6 @@ help:
|
|||
@echo " - lint-css-fix lint css files and fix issues"
|
||||
@echo " - lint-md lint markdown files"
|
||||
@echo " - lint-swagger lint swagger files"
|
||||
@echo " - lint-templates lint template files"
|
||||
@echo " - lint-yaml lint yaml files"
|
||||
@echo " - checks run various consistency checks"
|
||||
@echo " - checks-frontend check frontend files"
|
||||
@echo " - checks-backend check backend files"
|
||||
|
@ -217,9 +226,6 @@ help:
|
|||
@echo " - test-frontend test frontend files"
|
||||
@echo " - test-backend test backend files"
|
||||
@echo " - test-e2e[\#TestSpecificName] test end to end using playwright"
|
||||
@echo " - update update js and py dependencies"
|
||||
@echo " - update-js update js dependencies"
|
||||
@echo " - update-py update py dependencies"
|
||||
@echo " - webpack build webpack files"
|
||||
@echo " - svg build svg files"
|
||||
@echo " - fomantic build fomantic files"
|
||||
|
@ -271,15 +277,16 @@ clean-all: clean
|
|||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(GO) clean -i ./...
|
||||
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST) $(BINDATA_HASH) \
|
||||
integrations*.test \
|
||||
e2e*.test \
|
||||
tests/integration/gitea-integration-* \
|
||||
tests/integration/indexers-* \
|
||||
tests/mysql.ini tests/pgsql.ini tests/mssql.ini man/ \
|
||||
tests/e2e/gitea-e2e-*/ \
|
||||
tests/e2e/indexers-*/ \
|
||||
tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/
|
||||
tests/integration/gitea-integration-pgsql/ tests/integration/gitea-integration-mysql/ tests/integration/gitea-integration-mysql8/ tests/integration/gitea-integration-sqlite/ \
|
||||
tests/integration/gitea-integration-mssql/ tests/integration/indexers-mysql/ tests/integration/indexers-mysql8/ tests/integration/indexers-pgsql tests/integration/indexers-sqlite \
|
||||
tests/integration/indexers-mssql tests/mysql.ini tests/mysql8.ini tests/pgsql.ini tests/mssql.ini man/ \
|
||||
tests/e2e/gitea-e2e-pgsql/ tests/e2e/gitea-e2e-mysql/ tests/e2e/gitea-e2e-mysql8/ tests/e2e/gitea-e2e-sqlite/ \
|
||||
tests/e2e/gitea-e2e-mssql/ tests/e2e/indexers-mysql/ tests/e2e/indexers-mysql8/ tests/e2e/indexers-pgsql/ tests/e2e/indexers-sqlite/ \
|
||||
tests/e2e/indexers-mssql/ tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
|
@ -342,7 +349,6 @@ $(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA)
|
|||
$(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)'
|
||||
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
|
||||
$(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)'
|
||||
$(SED_INPLACE) '$(SWAGGER_SPEC_BRANDING)' './$(SWAGGER_SPEC)'
|
||||
|
||||
.PHONY: swagger-check
|
||||
swagger-check: generate-swagger
|
||||
|
@ -375,10 +381,10 @@ lint: lint-frontend lint-backend
|
|||
lint-fix: lint-frontend-fix lint-backend-fix
|
||||
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: lint-js lint-css
|
||||
lint-frontend: lint-js lint-css lint-md lint-swagger
|
||||
|
||||
.PHONY: lint-frontend-fix
|
||||
lint-frontend-fix: lint-js-fix lint-css-fix
|
||||
lint-frontend-fix: lint-js-fix lint-css-fix lint-md lint-swagger
|
||||
|
||||
.PHONY: lint-backend
|
||||
lint-backend: lint-go lint-go-vet lint-editorconfig
|
||||
|
@ -388,11 +394,11 @@ lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
|
|||
|
||||
.PHONY: lint-js
|
||||
lint-js: node_modules
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e
|
||||
|
||||
.PHONY: lint-js-fix
|
||||
lint-js-fix: node_modules
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e --fix
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e --fix
|
||||
|
||||
.PHONY: lint-css
|
||||
lint-css: node_modules
|
||||
|
@ -412,18 +418,11 @@ lint-md: node_modules
|
|||
|
||||
.PHONY: lint-go
|
||||
lint-go:
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS)
|
||||
$(GO) run $(DEADCODE_PACKAGE) -generated=false -test code.gitea.io/gitea > .cur-deadcode-out
|
||||
@$(DIFF) .deadcode-out .cur-deadcode-out; \
|
||||
if [ $$? -eq 1 ]; then \
|
||||
echo "Please run 'make lint-go-fix' and commit the result"; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
|
||||
|
||||
.PHONY: lint-go-fix
|
||||
lint-go-fix:
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) --fix
|
||||
$(GO) run $(DEADCODE_PACKAGE) -generated=false -test code.gitea.io/gitea > .deadcode-out
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run --fix
|
||||
|
||||
# workaround step for the lint-go-windows CI task because 'go run' can not
|
||||
# have distinct GOOS/GOARCH for its build and run steps
|
||||
|
@ -439,20 +438,12 @@ lint-go-vet:
|
|||
|
||||
.PHONY: lint-editorconfig
|
||||
lint-editorconfig:
|
||||
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .forgejo/workflows
|
||||
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .github/workflows
|
||||
|
||||
.PHONY: lint-actions
|
||||
lint-actions:
|
||||
$(GO) run $(ACTIONLINT_PACKAGE)
|
||||
|
||||
.PHONY: lint-templates
|
||||
lint-templates: .venv
|
||||
@poetry run djlint $(shell find templates -type f -iname '*.tmpl')
|
||||
|
||||
.PHONY: lint-yaml
|
||||
lint-yaml: .venv
|
||||
@poetry run yamllint .
|
||||
|
||||
.PHONY: watch
|
||||
watch:
|
||||
@bash build/watch.sh
|
||||
|
@ -571,6 +562,27 @@ test-mysql\#%: integrations.mysql.test generate-ini-mysql
|
|||
.PHONY: test-mysql-migration
|
||||
test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test
|
||||
|
||||
generate-ini-mysql8:
|
||||
sed -e 's|{{TEST_MYSQL8_HOST}}|${TEST_MYSQL8_HOST}|g' \
|
||||
-e 's|{{TEST_MYSQL8_DBNAME}}|${TEST_MYSQL8_DBNAME}|g' \
|
||||
-e 's|{{TEST_MYSQL8_USERNAME}}|${TEST_MYSQL8_USERNAME}|g' \
|
||||
-e 's|{{TEST_MYSQL8_PASSWORD}}|${TEST_MYSQL8_PASSWORD}|g' \
|
||||
-e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
|
||||
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
|
||||
-e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
|
||||
tests/mysql8.ini.tmpl > tests/mysql8.ini
|
||||
|
||||
.PHONY: test-mysql8
|
||||
test-mysql8: integrations.mysql8.test generate-ini-mysql8
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./integrations.mysql8.test
|
||||
|
||||
.PHONY: test-mysql8\#%
|
||||
test-mysql8\#%: integrations.mysql8.test generate-ini-mysql8
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./integrations.mysql8.test -test.run $(subst .,/,$*)
|
||||
|
||||
.PHONY: test-mysql8-migration
|
||||
test-mysql8-migration: migrations.mysql8.test migrations.individual.mysql8.test
|
||||
|
||||
generate-ini-pgsql:
|
||||
sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \
|
||||
-e 's|{{TEST_PGSQL_DBNAME}}|${TEST_PGSQL_DBNAME}|g' \
|
||||
|
@ -643,6 +655,14 @@ test-e2e-mysql: playwright e2e.mysql.test generate-ini-mysql
|
|||
test-e2e-mysql\#%: playwright e2e.mysql.test generate-ini-mysql
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e/$*
|
||||
|
||||
.PHONY: test-e2e-mysql8
|
||||
test-e2e-mysql8: playwright e2e.mysql8.test generate-ini-mysql8
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./e2e.mysql8.test
|
||||
|
||||
.PHONY: test-e2e-mysql8\#%
|
||||
test-e2e-mysql8\#%: playwright e2e.mysql8.test generate-ini-mysql8
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./e2e.mysql8.test -test.run TestE2e/$*
|
||||
|
||||
.PHONY: test-e2e-pgsql
|
||||
test-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test
|
||||
|
@ -686,6 +706,9 @@ integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sq
|
|||
integrations.mysql.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test
|
||||
|
||||
integrations.mysql8.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql8.test
|
||||
|
||||
integrations.pgsql.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.pgsql.test
|
||||
|
||||
|
@ -706,6 +729,11 @@ migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql
|
|||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test
|
||||
|
||||
.PHONY: migrations.mysql8.test
|
||||
migrations.mysql8.test: $(GO_SOURCES) generate-ini-mysql8
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql8.test
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./migrations.mysql8.test
|
||||
|
||||
.PHONY: migrations.pgsql.test
|
||||
migrations.pgsql.test: $(GO_SOURCES) generate-ini-pgsql
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test
|
||||
|
@ -723,17 +751,23 @@ migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
|
|||
|
||||
.PHONY: migrations.individual.mysql.test
|
||||
migrations.individual.mysql.test: $(GO_SOURCES)
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
|
||||
done
|
||||
|
||||
.PHONY: migrations.individual.sqlite.test\#%
|
||||
.PHONY: migrations.individual.mysql8.test
|
||||
migrations.individual.mysql8.test: $(GO_SOURCES)
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
|
||||
done
|
||||
|
||||
.PHONY: migrations.individual.mysql8.test\#%
|
||||
migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
|
||||
|
||||
.PHONY: migrations.individual.pgsql.test
|
||||
migrations.individual.pgsql.test: $(GO_SOURCES)
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
|
||||
done
|
||||
|
||||
|
@ -744,7 +778,7 @@ migrations.individual.pgsql.test\#%: $(GO_SOURCES) generate-ini-pgsql
|
|||
|
||||
.PHONY: migrations.individual.mssql.test
|
||||
migrations.individual.mssql.test: $(GO_SOURCES) generate-ini-mssql
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg -test.failfast; \
|
||||
done
|
||||
|
||||
|
@ -754,7 +788,7 @@ migrations.individual.mssql.test\#%: $(GO_SOURCES) generate-ini-mssql
|
|||
|
||||
.PHONY: migrations.individual.sqlite.test
|
||||
migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
|
||||
done
|
||||
|
||||
|
@ -765,6 +799,9 @@ migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
|
|||
e2e.mysql.test: $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test
|
||||
|
||||
e2e.mysql8.test: $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql8.test
|
||||
|
||||
e2e.pgsql.test: $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.pgsql.test
|
||||
|
||||
|
@ -798,14 +835,10 @@ generate: generate-backend
|
|||
generate-backend: $(TAGS_PREREQ) generate-go
|
||||
|
||||
.PHONY: generate-go
|
||||
generate-go: $(TAGS_PREREQ) merge-locales
|
||||
generate-go: $(TAGS_PREREQ)
|
||||
@echo "Running go generate..."
|
||||
@CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' $(GO_PACKAGES)
|
||||
|
||||
.PHONY: merge-locales
|
||||
merge-locales:
|
||||
@CC= GOOS= GOARCH= $(GO) run build/merge-forgejo-locales.go
|
||||
|
||||
.PHONY: security-check
|
||||
security-check:
|
||||
go run $(GOVULNCHECK_PACKAGE) ./...
|
||||
|
@ -813,18 +846,9 @@ security-check:
|
|||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||
|
||||
forgejo: $(EXECUTABLE)
|
||||
ln -f $(EXECUTABLE) forgejo
|
||||
|
||||
static-executable: $(GO_SOURCES) $(TAGS_PREREQ)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w -linkmode external -extldflags "-static" $(LDFLAGS)' -o $(EXECUTABLE)
|
||||
|
||||
.PHONY: release
|
||||
release: frontend generate release-linux release-copy release-compress vendor release-sources release-check
|
||||
|
||||
# just the sources, with all assets builtin and frontend resources generated
|
||||
sources-tarbal: frontend generate vendor release-sources release-check
|
||||
|
||||
$(DIST_DIRS):
|
||||
mkdir -p $(DIST_DIRS)
|
||||
|
||||
|
@ -834,6 +858,9 @@ release-windows: | $(DIST_DIRS)
|
|||
ifeq (,$(findstring gogit,$(TAGS)))
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
|
||||
endif
|
||||
ifeq ($(CI),true)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
|
||||
.PHONY: release-linux
|
||||
release-linux: | $(DIST_DIRS)
|
||||
|
@ -845,10 +872,16 @@ endif
|
|||
.PHONY: release-darwin
|
||||
release-darwin: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
||||
ifeq ($(CI),true)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
|
||||
.PHONY: release-freebsd
|
||||
release-freebsd: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'freebsd/amd64' -out gitea-$(VERSION) .
|
||||
ifeq ($(CI),true)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
|
||||
.PHONY: release-copy
|
||||
release-copy: | $(DIST_DIRS)
|
||||
|
@ -860,7 +893,7 @@ release-check: | $(DIST_DIRS)
|
|||
|
||||
.PHONY: release-compress
|
||||
release-compress: | $(DIST_DIRS)
|
||||
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PACKAGE) -k -9 $${file}; done;
|
||||
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PAGAGE) -k -9 $${file}; done;
|
||||
|
||||
.PHONY: release-sources
|
||||
release-sources: | $(DIST_DIRS)
|
||||
|
@ -874,17 +907,20 @@ release-sources: | $(DIST_DIRS)
|
|||
|
||||
.PHONY: release-docs
|
||||
release-docs: | $(DIST_DIRS) docs
|
||||
tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs .
|
||||
tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs/public .
|
||||
|
||||
.PHONY: docs
|
||||
docs:
|
||||
cd docs; bash scripts/trans-copy.sh;
|
||||
docs: deps-docs
|
||||
cd docs; make trans-copy clean build-offline;
|
||||
|
||||
.PHONY: deps-docs
|
||||
deps-docs:
|
||||
@hash hugo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
curl -sL https://github.com/gohugoio/hugo/releases/download/v$(HUGO_VERSION)/hugo_$(HUGO_VERSION)_Linux-64bit.tar.gz | tar zxf - -C /tmp && mkdir -p ~/go/bin && mv /tmp/hugo ~/go/bin/hugo && chmod +x ~/go/bin/hugo; \
|
||||
fi
|
||||
|
||||
.PHONY: deps
|
||||
deps: deps-frontend deps-backend deps-tools deps-py
|
||||
|
||||
.PHONY: deps-py
|
||||
deps-py: .venv
|
||||
deps: deps-frontend deps-backend deps-tools deps-docs
|
||||
|
||||
.PHONY: deps-frontend
|
||||
deps-frontend: node_modules
|
||||
|
@ -899,7 +935,7 @@ deps-tools:
|
|||
$(GO) install $(EDITORCONFIG_CHECKER_PACKAGE)
|
||||
$(GO) install $(GOFUMPT_PACKAGE)
|
||||
$(GO) install $(GOLANGCI_LINT_PACKAGE)
|
||||
$(GO) install $(GXZ_PACKAGE)
|
||||
$(GO) install $(GXZ_PAGAGE)
|
||||
$(GO) install $(MISSPELL_PACKAGE)
|
||||
$(GO) install $(SWAGGER_PACKAGE)
|
||||
$(GO) install $(XGO_PACKAGE)
|
||||
|
@ -911,27 +947,13 @@ node_modules: package-lock.json
|
|||
npm install --no-save
|
||||
@touch node_modules
|
||||
|
||||
.venv: poetry.lock
|
||||
poetry install --no-root
|
||||
@touch .venv
|
||||
|
||||
.PHONY: update
|
||||
update: update-js update-py
|
||||
|
||||
.PHONY: update-js
|
||||
update-js: node-check | node_modules
|
||||
npx updates -u -f package.json
|
||||
.PHONY: npm-update
|
||||
npm-update: node-check | node_modules
|
||||
npx updates -cu
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install --package-lock
|
||||
@touch node_modules
|
||||
|
||||
.PHONY: update-py
|
||||
update-py: node-check | node_modules
|
||||
npx updates -u -f pyproject.toml
|
||||
rm -rf .venv poetry.lock
|
||||
poetry install --no-root
|
||||
@touch .venv
|
||||
|
||||
.PHONY: fomantic
|
||||
fomantic:
|
||||
rm -rf $(FOMANTIC_WORK_DIR)/build
|
||||
|
@ -981,7 +1003,13 @@ lockfile-check:
|
|||
|
||||
.PHONY: update-translations
|
||||
update-translations:
|
||||
# noop to detect merge conflicts (potentially needs updating the scripts) and avoid breaking with Gitea
|
||||
mkdir -p ./translations
|
||||
cd ./translations && curl -L https://crowdin.com/download/project/gitea.zip > gitea.zip && unzip gitea.zip
|
||||
rm ./translations/gitea.zip
|
||||
$(SED_INPLACE) -e 's/="/=/g' -e 's/"$$//g' ./translations/*.ini
|
||||
$(SED_INPLACE) -e 's/\\"/"/g' ./translations/*.ini
|
||||
mv ./translations/*.ini ./options/locale/
|
||||
rmdir ./translations
|
||||
|
||||
.PHONY: generate-license
|
||||
generate-license:
|
||||
|
@ -1009,5 +1037,9 @@ docker:
|
|||
docker build --disable-content-trust=false -t $(DOCKER_REF) .
|
||||
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .
|
||||
|
||||
.PHONY: docker-build
|
||||
docker-build:
|
||||
docker run -ti --rm -v "$(CURDIR):/srv/app/src/code.gitea.io/gitea" -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" CGO_EXTRA_CFLAGS="$(CGO_EXTRA_CFLAGS)" webhippie/golang:edge make clean build
|
||||
|
||||
# This endif closes the if at the top of the file
|
||||
endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div align="center">
|
||||
<img src="./assets/logo.svg" alt="" width="192" align="center" />
|
||||
<img src="https://codeberg.org/forgejo/meta/raw/branch/readme/logo/forgejo.svg" alt="" width="192" align="center" />
|
||||
<h1 align="center">Welcome to Forgejo</h1>
|
||||
</div>
|
||||
|
||||
|
|
798
RELEASE-NOTES.md
798
RELEASE-NOTES.md
|
@ -1,802 +1,8 @@
|
|||
# Release Notes
|
||||
|
||||
A Forgejo release is published shortly after a Gitea release is published and they have [matching release numbers](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/CONTRIBUTING/RELEASE.md#release-numbering). Additional Forgejo releases may be published to address urgent security issues or bug fixes.
|
||||
A Forgejo release is published shortly after a Gitea release is published and they have [matching release numbers](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/CONTRIBUTING/RELEASE.md#release-numbering). Additional Forgejo releases may be published to address urgent security issues or bug fixes. Forgejo release notes include all Gitea release notes.
|
||||
|
||||
The Forgejo admin should carefully read the required manual actions before upgrading. A point release (e.g. v1.21.1-0 or v1.21.2-0) does not require manual actions but others might (e.g. v1.20, v1.21).
|
||||
|
||||
## 1.21.4-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.21/forgejo) included in the `Forgejo v1.21.4-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.21.3-0..v1.21.4-0
|
||||
```
|
||||
|
||||
This stable release includes security and bug fixes as well as documentation improvements.
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.21/admin/upgrade/) to the latest version.
|
||||
|
||||
* Container image upgrades
|
||||
|
||||
In the Forgejo container images the ssh version was upgraded to [9.3_p2-r1](https://pkgs.alpinelinux.org/packages?name=openssh&branch=v3.18) which includes a fix for [CVE-2023-48795](https://nvd.nist.gov/vuln/detail/CVE-2023-48795).
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.21/user/semver/)
|
||||
|
||||
The semantic version was updated to `6.0.4+0-gitea-1.21.4`
|
||||
|
||||
* Security fixes
|
||||
|
||||
* [Require token for GET subscription endpoint](https://codeberg.org/forgejo/forgejo/commit/6a66e8c7486b0be873dfc55dfdef9ba056970a90)
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Gracefully handle missing branches](https://codeberg.org/forgejo/forgejo/commit/c2fa9c308f5cdb08dd84fb8ec6623a57e75d5152) when a branch is missing from Git but still lingering in the database.
|
||||
* [Fix panic in `canSoftDeleteContentHistory`](https://codeberg.org/forgejo/forgejo/commit/ab1ccc55dca7fd05e59a01343e6dfe53be6195d0)
|
||||
* [Check for Commit in opengraph](https://codeberg.org/forgejo/forgejo/commit/b473a44a2bb59591f3e24bfcdeed1d8fbb0f9204)
|
||||
* [Handle non-existant commit in Archive request](https://codeberg.org/forgejo/forgejo/commit/0fbf761d1930f9336be6da8d17ae6032203a9381)
|
||||
* [Fix NPE in `ToPullReviewList`](https://codeberg.org/forgejo/forgejo/commit/f5349b66b78968301d7dc4c45e8e08b46910aa6e)
|
||||
* [Fix URL in the mail to include the host](https://codeberg.org/forgejo/forgejo/commit/ac889d42903b2ce2129a02ace620a10a6f940920)
|
||||
* [Fix the event of a scheduled action](https://codeberg.org/forgejo/forgejo/commit/892a8e1f4a5cc09cc3136e0b0e6487c154c5ed2b) to be "schedule" instead of a semi-random event from the default branch.
|
||||
* [Use refname:strip-2 instead of refname:short when syncing tags](https://codeberg.org/forgejo/forgejo/commit/4df056a14ecaad3ff9d963599fff8c8d7ebe87e9)
|
||||
* [Fix button size in "attached header right"](https://codeberg.org/forgejo/forgejo/commit/10699872930005a79490dd47eb86438ff20f449d)
|
||||
* [Fix `convert.ToTeams` on empty input](https://codeberg.org/forgejo/forgejo/commit/453d27853c18991c13b6e457032406664b07751b)
|
||||
* [Hide code related setting options in repository when code unit is disabled](https://codeberg.org/forgejo/forgejo/commit/703ed272ccba55c08873f6a23e557cdc5cd498ee)
|
||||
* [Fix incorrect URL for "Reference in New Issue"](https://codeberg.org/forgejo/forgejo/commit/01285dc47cd77e7c0755423af96ba6bf0e23650e)
|
||||
* [Fix panic when parsing empty pgsql host](https://codeberg.org/forgejo/forgejo/commit/ad027c28181004cbf891be14bb383ed906b13521)
|
||||
* [Fix alpine package files are not rebuilt](https://codeberg.org/forgejo/forgejo/commit/881159f593b8f848d52afe8d420f4f3ced34de7f)
|
||||
* [Avoid cycle-redirecting user/login page](https://codeberg.org/forgejo/forgejo/commit/ea8ca5b5098d04bf5f6218ca099af32d20bb465f)
|
||||
* [Fix the scroll behavior for emoji/mention list](https://codeberg.org/forgejo/forgejo/commit/fef19bcf94b2265870d21897e9bc55d6a07975d7)
|
||||
* [Fix wrong due date rendering in issue list page](https://codeberg.org/forgejo/forgejo/commit/29a0e7738c0725ee8407e2714c3d890286a94fd0)
|
||||
* [Fix `status_check_contexts` matching bug](https://codeberg.org/forgejo/forgejo/commit/3fe44b87627612705413e80abbe8af55fae36666)
|
||||
* [Fix 405 method not allowed CORS / OIDC](https://codeberg.org/forgejo/forgejo/commit/9ad7a67fc127712f897a3c8348e9f55d7cb2f6ec)
|
||||
* [Fix `GetCommitStatuses`](https://codeberg.org/forgejo/forgejo/commit/c287b1383f91024a8eba1a3f47912eecd66e19be)
|
||||
* [Forbid removing the last admin user](https://codeberg.org/forgejo/forgejo/commit/5124be72aaac4ad814c1ec7a57a2e92c529d00f9)
|
||||
* [Fix issue dependencies](https://codeberg.org/forgejo/forgejo/commit/2ab54a9c0671b70ab83bd3c643815ac7424a6a36)
|
||||
* [Fix system webhooks API bug](https://codeberg.org/forgejo/forgejo/commit/f5764bbf269d82e7e344834a5eeb8de82356cfde)
|
||||
|
||||
* Documentation
|
||||
|
||||
* The Forgejo Actions [user reference guide](https://forgejo.org/docs/v1.21/user/actions/) includes [event payload examples](https://forgejo.org/docs/v1.21/user/actions/#githubevent) for pull requests and push events. It also covers most of the [jobs](https://forgejo.org/docs/v1.21/user/actions/#jobs) syntax.
|
||||
* The [Forgejo command line page](https://forgejo.org/docs/v1.21/admin/command-line/) was [entirely reworked](https://codeberg.org/forgejo/docs/pulls/340) and updates are now automated.
|
||||
|
||||
* Improvements
|
||||
|
||||
* [Rework markup link rendering](https://codeberg.org/forgejo/forgejo/commit/875b398e5e0c53a615c861eba77d4e0ff50ff49d)
|
||||
* [Modernize merge button](https://codeberg.org/forgejo/forgejo/commit/70c7ee54754e93fd2612287b1ccfc24006924651)
|
||||
* [Assign pull request to project during creation](https://codeberg.org/forgejo/forgejo/commit/10b555a52b0541fa5e4bc3ddb43001abc2ce0c76)
|
||||
* [Add download attribute to release attachments](https://codeberg.org/forgejo/forgejo/commit/fab93c6393f5365e2e985619f0b82e4c580874c9)
|
||||
|
||||
## 1.21.3-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.21/forgejo) included in the `Forgejo v1.21.3-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.21.2-1..v1.21.3-0
|
||||
```
|
||||
|
||||
This stable release includes bug fixes. It was built with an updated version of the [Go Cryptography](https://pkg.go.dev/golang.org/x/crypto) package that fixes [CVE-2023-48795](https://go.dev/issue/64784). As explained in the [corresponding Go issue](https://github.com/golang/vulndb/issues/2402): "The impact of this attack is relatively limited, as it does not compromise confidentiality of the channel."
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.21/admin/upgrade/) to the latest version.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.21/user/semver/)
|
||||
|
||||
The semantic version was updated to `6.0.3+0-gitea-1.21.3`
|
||||
|
||||
* Security fix
|
||||
|
||||
* The [Go Cryptography](https://pkg.go.dev/golang.org/x/crypto) package [is upgraded](https://codeberg.org/forgejo/forgejo/commit/9515a0ea38c179a2811e489079a68bbcc79f3cd3) to fix [CVE-2023-48795](https://go.dev/issue/64784).
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Fix a regression](https://codeberg.org/forgejo/forgejo/commit/dbd896ce42b2c5a1f4b4a69289fa3a38a875d04d) in how the markdown anchors are generated. For instance the anchor for `A.B.C` is `A-B-C` but was incorrectly set to `ABC`.
|
||||
* [Fix the branch name of scheduled actions](https://codeberg.org/forgejo/forgejo/commit/580f29d9a2f8986c02b6ac30f2f3c177866cc81a) which [was sometime incorrectly set](https://codeberg.org/forgejo/forgejo/issues/1926).
|
||||
* [Fix a visual glitch](https://codeberg.org/forgejo/forgejo/commit/b0874a0912ee97b11047bb2bd7d370b93c298d2a) when [setting an emoji in the web UI](https://codeberg.org/forgejo/forgejo/issues/1990).
|
||||
* [Recently Docker started to use the optional `POST /v2/token` endpoint](https://codeberg.org/forgejo/forgejo/commit/a77398cd344be76e1cd2474063d917b286f8e9b1) which should respond with a `404 Not Found` status code instead of the current `405 Method Not Allowed`.
|
||||
* [Fix a missing leading ssh:// when using a port other than 22](https://codeberg.org/forgejo/forgejo/commit/1475c1fcc4f1d5d526260a3f2068ae62c2ccaae3) when Git URLs are displayed in the web UI.
|
||||
* [Allow disabling the detection of ambiguous unicode characters](https://codeberg.org/forgejo/forgejo/commit/cd5a0ec1c88edc238469657731e209a0080e9bfc) with the new setting `AMBIGUOUS_UNICODE_DETECTION=false`.
|
||||
* [Fix a regression with the issue references rendering in wiki pages](https://codeberg.org/forgejo/forgejo/commit/40fa6a526a1cb42889eddd5135f2749cc092fff5).
|
||||
* [Fix merging artifact chunks error when minio storage basepath is set](https://codeberg.org/forgejo/forgejo/commit/bea2c52572d62781228099812e56b2e7051e7ab0)
|
||||
* [Fix missing information in the blame page web UI](https://codeberg.org/forgejo/forgejo/commit/1f8d01c74d75c0b426b7b7a95cc1ca3bfe1b853c).
|
||||
|
||||
## 1.21.2-1
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.21/forgejo) included in the `Forgejo v1.21.2-1` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.21.2-0..v1.21.2-1
|
||||
```
|
||||
|
||||
This stable release contains a **security fix**, as explained in the [v1.21.2-1 companion blog post](https://forgejo.org/2023-12-release-v1-21-2-1/).
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We **strongly recommend** that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.21/admin/upgrade/) to the latest version as soon as possible.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.21/user/semver/)
|
||||
|
||||
The semantic version was updated to `6.0.2+0-gitea-1.21.2`
|
||||
|
||||
* Security fix
|
||||
|
||||
The project page [of private users](https://forgejo.org/2023-12-release-v1-21-2-1/) is no longer publicly visible.
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* The default preferred licenses for the [[repository].PREFERRED_LICENSES](https://forgejo.org/docs/v1.21/admin/config-cheat-sheet/#repository-repository) setting were incorrect and have been [fixed to be `Apache-2.0` and `MIT`](https://codeberg.org/forgejo/forgejo/commit/5258e8f63d649b016d5c5d0e37422723bef26dac).
|
||||
* A failed cron job can [no longer cause the Forgejo instance to shutdown](https://codeberg.org/forgejo/forgejo/commit/026a4bb02d8ac0b0dd90eb8a89c25ae18abca34f).
|
||||
* A pull request merged by a workflow using the [automatic token](https://forgejo.org/docs/v1.21/user/actions/#automatic-token) with the `auto merge` flag [no longer cause an error 500 when displaying the pull request page](https://codeberg.org/forgejo/forgejo/commit/4148fb27dbc337a433b41d6d450d48fad73239cc).
|
||||
* [Tentative fix for when the database branch cache is out of sync with the branches found in Git repositories](https://codeberg.org/forgejo/forgejo/commit/14750f3d11c8d065d3f9af31b8b4ee8d28acd0a5). When in doubt it is recommended to click on `Sync missed branches from git data to databases` in the `/admin` dashboard.
|
||||
|
||||
## 1.21.2-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.21/forgejo) included in the `Forgejo v1.21.2-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.21.1-0..v1.21.2-0
|
||||
```
|
||||
|
||||
This stable release includes bug fixes. It was built with Go v1.21.5 that fixes [CVE-2023-39326](https://groups.google.com/g/golang-announce/c/iLGK3x6yuNo) which a malicious HTTP client can exploit to cause a server to automatically read a large amount of data. It allows for memory exhaustion in the situation that HTTP chuncked encoding requests can reach Forgejo.
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.21/admin/upgrade/) to the latest version.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.21/user/semver/)
|
||||
|
||||
The semantic version was updated to `6.0.1+0-gitea-1.21.2`
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [OAuth2 uses the link_account page when the email or username is missing](https://codeberg.org/forgejo/forgejo/commit/e6fb2107f2843a09c3a72c3629bcee50c4797a6c)
|
||||
* [Avoid conflicts of issue and PR numbers in GitLab migration](https://codeberg.org/forgejo/forgejo/commit/272d0a4c20987e33fa132fc94d996e0c6fdb86d7)
|
||||
* [Only pass selected repository IDs to pagination](https://codeberg.org/forgejo/forgejo/commit/2552bb7b6ec51a094c9d800589991b1556fba798)
|
||||
* [Add download URL for executable files](https://codeberg.org/forgejo/forgejo/commit/958a20865b897daaa4c26a3ba4b195ba2e854223)
|
||||
* [Fix Forgejo repositories migration to also include issues, prs etc.](https://codeberg.org/forgejo/forgejo/commit/61fc5c514a6b3f99560b0df5e4cdb7df94763984)
|
||||
* [Fix template substitution bug preventing notifications to be sent on new user registration](https://codeberg.org/forgejo/forgejo/commit/bc0078a50a6ab341ca4af15ce5d3fd221e6e9e0d)
|
||||
* [When searching for issues, require that all terms are matched instead of one of them](https://codeberg.org/forgejo/forgejo/commit/13c0df40de319db2c4c2ec11a9a9dc5cf9eaf681)
|
||||
* [Ignore temporary files when calculating the size of a repository](https://codeberg.org/forgejo/forgejo/commit/b17113bb06b57211b9c264b6953a783e7d0bb9a2)
|
||||
* [Convert git commit summary to valid UTF8](https://codeberg.org/forgejo/forgejo/commit/346635605da024c3a0a6e7f4d63de1632459f4d6)
|
||||
* [Fix incorrect default value of `[attachment].MAX_SIZE`](https://codeberg.org/forgejo/forgejo/commit/52f8fde69f121af6f72685fd08dc45b4b3e89004)
|
||||
* [Fix object does not exist error when checking citation file](https://codeberg.org/forgejo/forgejo/commit/1ce155c5a695f07a9252b4ffc8c9ae7d48ebf7ec)
|
||||
|
||||
* Improvements
|
||||
|
||||
* [new doctor check: fix-push-mirrors-without-git-remote](https://codeberg.org/forgejo/forgejo/commit/1fea3ce6592afca7f8d16c147effd343244746fa)
|
||||
* [Add `HEAD` support for RPM registry](https://codeberg.org/forgejo/forgejo/commit/ce3a24ef5f80413514e8de28ff47e77acccf0d2b)
|
||||
|
||||
## 1.21.1-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.21/forgejo) included in the `Forgejo v1.21.1-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges origin/v1.20/forgejo..origin/v1.21/forgejo
|
||||
```
|
||||
|
||||
- **[Forgejo Semantic Version](https://forgejo.org/docs/v1.21/user/semver/):**
|
||||
The semantic version was updated to `6.0.0+0-gitea-1.21.0` because it contains breaking changes.
|
||||
|
||||
- **Breaking:**
|
||||
Note that the modifications related to CSS, templates or assets (images, fonts, etc.) are not documented here.
|
||||
Although they can be extracted and modified, Forgejo does not provide any guarantee that such changes
|
||||
will be portable from one version to another (even a patch version). A [Q&A discussion is available](https://codeberg.org/forgejo/discussions/issues/84)
|
||||
to share tips and tricks. A new section was also added
|
||||
[to the developer documentation about interface customization](https://forgejo.org/docs/v1.21/developer/customization/).
|
||||
- If you have custom asset files, e.g. custom themes, inside `custom/public/*` (css included), you need to transfer these files to `custom/public/assets/*` for them to be detected. Read more [in the documentation](https://forgejo.org/docs/v1.21/developer/customization/) and the [Q&A discussion dedicated to interface customization](https://codeberg.org/forgejo/discussions/issues/84).
|
||||
- Git [branches are stored in the databases](https://codeberg.org/forgejo/forgejo/commit/6e19484f4d3bf372212f2da462110a1a8c10cbf2) to reduce the calls to a git process and improve performances. After upgrading, login as an admin, go to the `/admin` page and click run **Sync missed branches from git data to databases**. If this is not done there will be messages such as `LoadBranches: branch does not exist` in the logs.
|
||||
- [Some Forgejo CLI options have changed](https://codeberg.org/forgejo/forgejo/commit/d0dbe52e76f3038777c3b50066e3636105387ca3) and scripts may need to be updated. For instance `--verbose` is no longer a global option and is implemented on a per sub-command basis. Check `forgejo --help` or `forgejo docs` for more information.
|
||||
- [Remove "CHARSET" config option for MySQL and always use "utf8mb4"](https://codeberg.org/forgejo/forgejo/commit/ce46834b938eb687152a680669ada95a26304178). It has been a requirement for years and specifying anything else is likely to cause issues. Existing MySQL databases still using `utf8` can be converted using the CLI: `forgejo doctor convert`.
|
||||
- [Restrict certificate type for builtin SSH server](https://codeberg.org/forgejo/forgejo/pulls/1172). This is a breaking change for setups where the builtin SSH server is being used and for some reason host certificates were being used for authentication.
|
||||
- [Set SSH_AUTHORIZED_KEYS_BACKUP to false by default](https://codeberg.org/forgejo/forgejo/commit/469d89b95a1ce18dd34808a95c7230375e828e24). There is no automatic cleanup of these backups and can end up using a significant amount of disk space over time.
|
||||
- [The minimum RSA keylength is now 3072 instead of 2048](https://codeberg.org/forgejo/forgejo/commit/c533991519816313dfaa0ddcec183756a97b9348).
|
||||
- Prior to this release, a token scoped to read or write permissions on issues was allowed to access both issues and pull requests, regardless of the restrictions imposed to the team in which they belong. In a team it is possible to grant finer grained permissions, for instance to allow a user to access issues but not pull requests. These restrictions are [now enforced](https://codeberg.org/forgejo/forgejo/commit/f4310d74ee65500ef02064256808530e09da76a0) and API calls that previously succeeded on `/api/v1/repos/{org}/{repo}/issues` or other endpoints common to both issues and pull requests could return 404. Granting the user the necessary permissions in the team in which they belong will allow them to use that endpoint again.
|
||||
- **Forgejo Actions:**
|
||||
It is now enabled by default but should still be considered alpha stage and subject to unannounced breaking changes.
|
||||
- The API can now be used to manage secrets for [users](https://code.forgejo.org/api/swagger/#/user/updateUserSecret), [organizations](https://code.forgejo.org/api/swagger/#/organization/orgListActionsSecrets) and [repositories](https://code.forgejo.org/api/swagger/#/repository/updateRepoSecret).
|
||||
- [Registration tokens can register multiple runners](https://codeberg.org/forgejo/forgejo/commit/9b698362a333de2c388499f1a64d39545b0263bd) instead of a single one. Read more [about runner registration](https://forgejo.org/docs/v1.21/admin/actions/#registration).
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/35a653d7edbe0d693649604b8309bfc578dd988b) support for [variables in addition to secrets](https://forgejo.org/docs/v1.21/user/actions/#variables).
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/0d55f64e6cd3de2e1e5c0ee795605823efb14231) support for [recurring actions similar to cron jobs](https://forgejo.org/docs/v1.21/user/actions/#onschedule).
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/19872063a3c14256a1d89b2a104d63e7538a3a28) the possibility to [disable workflows from the user interface](https://forgejo.org/docs/v1.21/user/actions/#list-of-runners-and-their-tasks).
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/460a2b0edffe71d9e64633beaa1071fcf4a33369) automatic [cleanup of artificats](https://forgejo.org/docs/v1.21/user/actions/#artifacts).
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/44781f9f5c4ede618660d8cfe42437f0e8dc22a0) automatic cancelation [of jobs when pushing new commits](https://forgejo.org/docs/v1.21/user/actions/#auto-cancelation-of-workflows) to a PR.
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/f3d293d2bbe0b2eab047bdd403046069cffbc0c4) support for [uploading multiple artificats](https://forgejo.org/docs/v1.21/user/actions/#artifacts).
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/48e5a74f215d78813a816c57fc5a85a909a003d5) support for the [`pull_request_target` event](https://forgejo.org/docs/v1.21/user/actions/#onpull_request_target) which has access to secrets because it runs using the workflows from the base branch instead of the pull request.
|
||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/8228751c55d6a4263f0fec2932ca16181c09c97d) support for reading labels from the runner [instead of specifying them during registration](https://forgejo.org/docs/v1.21/admin/actions/#registration).
|
||||
- **Features:**
|
||||
- With the Chroma upgrade from [2.7.0](https://github.com/alecthomas/chroma/releases/tag/v2.7.0) to [2.10.0](https://github.com/alecthomas/chroma/releases/tag/v2.10.0) syntax highlighting is now available for [Smali](https://github.com/alecthomas/chroma/pull/765), [DHCP](https://github.com/alecthomas/chroma/pull/772), [WebGPU Shading Language](https://github.com/alecthomas/chroma/pull/776), [AutoHotkey](https://github.com/alecthomas/chroma/commit/4779f9035a3aaea3ec650f0923657c12e12dd35a), [AutoIt](https://github.com/alecthomas/chroma/commit/029798b351baa9c3d0dd5ec16e87ab98486d843c), [tal (uxntal)](https://github.com/alecthomas/chroma/commit/e422a6286fdc61393deb09afd270293eb590d023), [ArangoDB Query Language (AQL)](https://github.com/alecthomas/chroma/pull/794), [BIND DNS Zone](https://github.com/alecthomas/chroma/pull/796), [Odin](https://github.com/alecthomas/chroma/pull/802), [Sourcepawn](https://github.com/alecthomas/chroma/pull/804), [CPP](https://github.com/alecthomas/chroma/pull/813), [C](https://github.com/alecthomas/chroma/pull/815). New files and extensions are associated as follows: [.tpp as a c++](https://github.com/alecthomas/chroma/pull/817), [.eex as a Elixir](https://github.com/alecthomas/chroma/pull/820), [Pipfile and poetry.lock as a TOML](https://github.com/alecthomas/chroma/pull/821), [ISCdhcpd filename](https://github.com/alecthomas/chroma/pull/822), [.twig](https://github.com/alecthomas/chroma/pull/833), [Mathematica](https://github.com/alecthomas/chroma/pull/836).
|
||||
- With the go-enry upgrade from [v2.8.4](https://github.com/go-enry/go-enry/releases/tag/v2.8.4) to [v2.8.6](https://github.com/go-enry/go-enry/releases/tag/v2.8.6), language detection in the repository now includes:
|
||||
- Bluespec BH: [atom-haskell/language-haskell](https://github.com/atom-haskell/language-haskell)
|
||||
- D2: [terrastruct/d2-vscode](https://github.com/terrastruct/d2-vscode)
|
||||
- Go Workspace: [golang/vscode-go](https://github.com/golang/vscode-go)
|
||||
- Gradle Kotlin DSL: [nishtahir/language-kotlin](https://github.com/nishtahir/language-kotlin)
|
||||
- Hosts File: [Alhadis/language-etc](https://github.com/Alhadis/language-etc)
|
||||
- LOLCODE: [KrazIvan/LOLCODE-grammar-vscode](https://github.com/KrazIvan/LOLCODE-grammar-vscode)
|
||||
- MDX: [wooorm/markdown-tm-language](https://github.com/wooorm/markdown-tm-language)
|
||||
- Nasal: [BobDotCom/Nasal.tmbundle](https://github.com/BobDotCom/Nasal.tmbundle)
|
||||
- Nushell: [hustcer/nu-grammar](https://github.com/hustcer/nu-grammar)
|
||||
- Pact: [kadena-io/pact-atom](https://github.com/kadena-io/pact-atom)
|
||||
- RBS: [soutaro/vscode-rbs-syntax](https://github.com/soutaro/vscode-rbs-syntax)
|
||||
- Rez: [textmate/rez.tmbundle](https://github.com/textmate/rez.tmbundle)
|
||||
- Sweave: [textmate/sweave.tmbundle](https://github.com/textmate/sweave.tmbundle)
|
||||
- TL-Verilog: [adamint/tlv-vscode](https://github.com/adamint/tlv-vscode)
|
||||
- Typst: [michidk/typst-grammar](https://github.com/michidk/typst-grammar)
|
||||
- WDL: [broadinstitute/wdl-sublime-syntax-highlighter](https://github.com/broadinstitute/wdl-sublime-syntax-highlighter)
|
||||
- WGSL: [wgsl-analyzer/wgsl-analyzer](https://github.com/wgsl-analyzer/wgsl-analyzer)
|
||||
- WebAssembly Interface Type: [bytecodealliance/vscode-wit](https://github.com/bytecodealliance/vscode-wit)
|
||||
- [Newly pushed branches show in the web UI with a link to create a PR](https://codeberg.org/forgejo/forgejo/commit/6375419468edc95fdfac94aac3b0e10b23743557). Read more [about the `New Pull Request` button](https://forgejo.org/docs/v1.21/user/pull-requests-and-git-flow/#create-a-pull-request).
|
||||
- Labels that are no longer useful [can be archived](https://codeberg.org/forgejo/forgejo/commit/cafce3b4b5afb3f254a48e87f1516d7b5dc209b6). They can no longer be selected but they remain on existing issues. Read more [about archiving labels](https://forgejo.org/docs/v1.21/user/labels/#archiving-labels).
|
||||
- The blame view now [takes into account](https://codeberg.org/forgejo/forgejo/commit/ed64f1c2b835bf9332bf8347be9675ef29c8274b) the [`.git-blame-ignore-revs`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-blameignoreRevsFile) file.
|
||||
- [Pre-register OAuth2 applications for git credential helpers](https://codeberg.org/forgejo/forgejo/commit/63ab92d7971e4931e98f014f2c5385d2242fa780). Read more in the git authentication section of the [user guide](https://forgejo.org/docs/v1.21/user/oauth2-provider/#git-authentication) and the [administrator guide](https://forgejo.org/docs/v1.21/admin/oauth2-provider/#git-authentication).
|
||||
- Admins can be [notified via email](https://codeberg.org/forgejo/forgejo/commit/9b7bbae8c4cd5dc4d36726f10870462c8985e543) when a new user registers to help fight spam bots by setting `[admin].SEND_NOTIFICATION_EMAIL_ON_NEW_USER = true`.
|
||||
- When a page display the history of changes for a file, [file rename are detected and displayed](https://codeberg.org/forgejo/forgejo/commit/ea23594cdbb12c32dc28638f65bf40e37d344e5f).
|
||||
- Packages [can be configured to redirect requests to the S3 server](https://codeberg.org/forgejo/forgejo/commit/c890454769562e0ec2978e123aaf3d9a43e5ef4f) for clients that support this feature.
|
||||
- When a PR contains multiple commits, it is now possible [review to each commit independently](https://codeberg.org/forgejo/forgejo/commit/55532061c83d38d33ef48bdc5eeac0f652844e8a). Read more [about selecting commits for review](https://forgejo.org/docs/v1.21/user/pull-requests-and-git-flow/#reviews).
|
||||
- Issues can [be deleted in batch](https://codeberg.org/forgejo/forgejo/commit/a1c5057fe81c25dfd1777e9625eb5480c45897ea).
|
||||
- An email can be associated with [an Organisations](https://codeberg.org/forgejo/forgejo/commit/6598d0291cf7dfeb00cb5e5d18faf2bf46fad596).
|
||||
- The CODEOWNERS file is [interpreted to automatically set reviewers on PRs](https://codeberg.org/forgejo/forgejo/commit/3bdd48016f659c440d6e8bb57386fab7ad7b357b). The CODEOWNERS file is loaded from these paths in this order: `./CODEOWNERS`, `./docs/CODEOWNERS`.
|
||||
- Issue search [were reworked entirely](https://codeberg.org/forgejo/forgejo/commit/1e76a824bcd71acd59cdfb2c4547806bc34b3d86) to fix the shortcomings of the previous implementation.
|
||||
- [Allow "latest" to be used as a release tag when downloading a file](https://codeberg.org/forgejo/forgejo/commit/a7d9a70552410d797cefc87b177b33ca4a1a60c4).
|
||||
- [Authentication via reverse proxy is available and disabled by default](https://codeberg.org/forgejo/forgejo/commit/e97e883ad50774f249c8c694598c25a17227299b).
|
||||
- [Add API for changing avatars](https://codeberg.org/forgejo/forgejo/commit/254a82842addb1475611789107c3720e37394879).
|
||||
- **User Interface:**
|
||||
- [Show OpenID Connect and OAuth on the signup page](https://codeberg.org/forgejo/forgejo/commit/63b53af933d748f9b4e0f1273e3701b4c3d08ac3).
|
||||
- [Show branches and tags that contain the commit being displayed](https://codeberg.org/forgejo/forgejo/commit/bd6ef718548767ff209048eb8443a067106908bf)
|
||||
- [Add 'Show on a map' button to the location in the usr profile](https://codeberg.org/forgejo/forgejo/commit/d58c5425799335ea57f27461f99ddd1078e9b2de).
|
||||
- [Render plaintext task list items for markdown files](https://codeberg.org/forgejo/forgejo/commit/eaea530d6bc84b23e6ff14ff8c2a74aa3b67ecd0).
|
||||
- The administrators user details page [was modified](https://codeberg.org/forgejo/forgejo/commit/5b5bb8d3546e6504b689b01d3ac4897dda3aee3d).
|
||||
- When mirroring a repository fails, [a `Retry` button allows to re-create it](https://codeberg.org/forgejo/forgejo/commit/865d2221c0f4b2a8623ff9299930c9bab0da2c78).
|
||||
- Package cleanup [can be triggered from from administration web interface](https://codeberg.org/forgejo/forgejo/commit/0c6ae61229bce9d9ad3d359cee927464968a2dd1).
|
||||
- In the page displaying the [list of branches, it is now possible to search them by name](https://codeberg.org/forgejo/forgejo/commit/47b878858ada27fc4c74eeadcc1e467d2da90e04).
|
||||
- [Display all user types (including bots) org types on the administration web interface](https://codeberg.org/forgejo/forgejo/commit/198a9ca6350954a6d3327a408021fec2bc0fc805).
|
||||
- [Improve opengraph previews](https://codeberg.org/forgejo/forgejo/commit/5743d7cb5bcd85c88ad7d128e0162893a074418b).
|
||||
- [Render code blocks in the repository description](https://codeberg.org/forgejo/forgejo/commit/3d109861ddf95846905143b4cf39129bf253161e).
|
||||
- [Add `member`, `collaborator`, `contributor`, and `first-time contributor` roles and tooltips](https://codeberg.org/forgejo/forgejo/commit/d2e4039def61d9cc9952be462216001125327270) next to the author.
|
||||
- It is no longer possible to [change the run user in the installation page](https://codeberg.org/forgejo/forgejo/commit/d17a848fe275c3e8734a4dfcaf2eae8ca0dc361c).
|
||||
- [Update emoji set](https://codeberg.org/forgejo/forgejo/commit/e882398c5acb99db555553acc2da89db73713710) to [Unicode 15](https://unicode.org/versions/Unicode15.0.0/).
|
||||
- [Improve the image diff user interface](https://codeberg.org/forgejo/forgejo/commit/09faf43ef822ca4dbdfb2a2714ad43a782acf6e8).
|
||||
- Allow [rebuilding the issue index from the cron task list in the admin panel](https://codeberg.org/forgejo/forgejo/commit/47fddaadc8b4c8d4d4359d6209b9fe06d6387a30).
|
||||
- **Enhancements:**
|
||||
- [Improve the privacy of the user profile settings](https://codeberg.org/forgejo/forgejo/commit/ff90c87c878b03e7beabac5f19396e0db2c25a1e).
|
||||
- [Add the upload URL to the release API](https://codeberg.org/forgejo/forgejo/commit/a9ce570298d4541bc1b5598dc080d9e4541de17b).
|
||||
- [Allow editing existing push mirrors from the settings page of a repository](https://codeberg.org/forgejo/forgejo/commit/ab388deb0e52c058a19dbd844bdd890f7cf84d51).
|
||||
- [Add a link to the OpenID issuer URL in the WebFinger response](https://codeberg.org/forgejo/forgejo/commit/df55f9b189174767296e562389948e5250f1df73).
|
||||
- [Support copy protected branches with template repositories](https://codeberg.org/forgejo/forgejo/commit/037c9895a7406b42f88991295382db18f98dbef9).
|
||||
- [In the administration web interface, split the lfs size from repository size](https://codeberg.org/forgejo/forgejo/commit/4aba8a6a5ff96f0995ada7e183c7864f8f5bc05c).
|
||||
- **Bug fixes:**
|
||||
- [Allow empty Conan files](https://codeberg.org/forgejo/forgejo/commit/d513628db90415a27e887c3cf349309b3ad44d55).
|
||||
- [Fix the incorrect route path in the user edit page. ](https://codeberg.org/forgejo/forgejo/commit/323135b97b219d7fb10557fb9d9156c6bef3ae62).
|
||||
- [Add auth-required to config.json for Cargo sparse registry](https://codeberg.org/forgejo/forgejo/commit/a587d2526163153a4d992527fe6040d578beaa83).
|
||||
- [Rewrite the DiffFileTreeItem and fix misalignment ](https://codeberg.org/forgejo/forgejo/commit/48c4a7e75cf2717f00c9691ca26688aa4db0a17a).
|
||||
- [Do not "guess" the file encoding/BOM when using API to upload files](https://codeberg.org/forgejo/forgejo/commit/22eeede885327fca0328b7d5b153e7a6c4211ffa).
|
||||
- **Security:**
|
||||
- [Do not show the profile README when a repository is private](https://codeberg.org/forgejo/forgejo/commit/6a7a5ea32ab61a608b52029f778e8df76b04f489).
|
||||
- A [security.txt files is provided by default](https://codeberg.org/forgejo/forgejo/pulls/1201/files) and other static files [can also be added](https://codeberg.org/forgejo/forgejo/commit/52fb9367734100847249d074e2bc17f2aa91053e).
|
||||
|
||||
## 1.20.6-1
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.6-1` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.6-0..v1.20.6-1
|
||||
```
|
||||
|
||||
This stable release contains a **security fix**.
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We **strongly recommend** that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.20/admin/upgrade/) to the latest version as soon as possible.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.8+0-gitea-1.20.6`
|
||||
|
||||
* Security fix
|
||||
|
||||
The project page [of private users](https://forgejo.org/2023-12-release-v1-21-2-1/) is no longer publicly visible.
|
||||
|
||||
* Bug fix
|
||||
|
||||
* [Consider executable files as a valid case when returning a downloadURL for them](https://codeberg.org/forgejo/forgejo/issues/1825). They are just regular files with the difference being the executable permission bit being set.
|
||||
|
||||
* New doctor check and fix
|
||||
|
||||
* Adds a [new doctor check: fix-push-mirrors-without-git-remote](https://codeberg.org/forgejo/forgejo/pulls/1853). The new check looks for push mirrors that do not have their remotes configured in git. If automatic fixing is enabled, it will remove these push mirrors from the database.
|
||||
|
||||
## 1.20.6-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.6-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.5-1..v1.20.6-0
|
||||
```
|
||||
|
||||
This stable release contains a **security fix**, as explained in the [v1.20.6-0 companion blog post](https://forgejo.org/2023-11-release-v1-20-6-0/).
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We **strongly recommend** that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.20/admin/upgrade/) to the latest version as soon as possible.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.7+0-gitea-1.20.6`
|
||||
|
||||
* Breaking change
|
||||
|
||||
Prior to this release, a token scoped to read or write permissions on issues was allowed to access both issues and pull requests, regardless of the restrictions imposed to the team in which they belong. In a team it is possible to grant finer grained permissions, for instance to allow a user to access issues but not pull requests. These restrictions are now enforced and API calls that previously succeeded on `/api/v1/repos/{org}/{repo}/issues` or other endpoints common to both issues and pull requests could return 404. Granting the user the necessary permissions in the team in which they belong will allow them to use that endpoint again.
|
||||
|
||||
* Security fix
|
||||
|
||||
Additional API and web [endpoints now fail](https://forgejo.org/2023-11-release-v1-20-6-0/) when given manually crafted identifiers.
|
||||
|
||||
## 1.20.5-1
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.5-1` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.5-0..v1.20.5-1
|
||||
```
|
||||
|
||||
This stable release contains **critical security fixes**, as explained in the [v1.20.5-1 companion blog post](https://forgejo.org/2023-11-release-v1-20-5-1/).
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We **strongly recommend** that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.20/admin/upgrade/) to the latest version as soon as possible.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.6+0-gitea-1.20.5`
|
||||
|
||||
* Security fixes
|
||||
|
||||
* API and web [endpoints now fail](https://forgejo.org/2023-11-release-v1-20-5-1/) when given manually crafted identifiers.
|
||||
* When an extension is added to the URL of a user profile (e.g. `/myuser.rss`) it is now [verified to be visible](https://codeberg.org/forgejo/forgejo/commit/d7408d8b0b04afd2a3c8e23cc908e7bd3849f34d).
|
||||
* `docker login` now fails with basic auth [when 2FA is enabled](https://codeberg.org/forgejo/forgejo/commit/44df78edd40076b349d50dc5fb02af417a44cfab).
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent bug fixes are described below. Others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* Create the ActionTaskOutput [table for new Forgejo instances](https://codeberg.org/forgejo/forgejo/commit/c0ccd4c2d7ac586276ab65bd2dfbf4eba7e71cd6).
|
||||
* [Restricted users only see repos in orgs which their team was assigned to](https://codeberg.org/forgejo/forgejo/commit/f302373eb4ea04f3b655d8f8bb27bc3ff3027276).
|
||||
* Release assets are now [taken into account during a migration](https://codeberg.org/forgejo/forgejo/commit/1fd3cc32170ff9a36419083541bb2e1ad612df92) from GitLab, Forgejo or Gitea.
|
||||
* When `webhook.PROXY_URL` is set, the `ALLOWED_HOST_LIST` setting is [now properly enforced](https://codeberg.org/forgejo/forgejo/commit/d6798ae0159e58b427e9ad894ca3e0ee272efdb2).
|
||||
* It is now possible to access `/<username>/<reponame>/attachments/<uuid>` [with an application token](https://codeberg.org/forgejo/forgejo/commit/f142ae18c093d4cb5ccc7eeec8beac0212e466a0) and the attachments API download URL is usable.
|
||||
|
||||
## 1.20.5-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.5-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.4-1..v1.20.5-0
|
||||
```
|
||||
|
||||
This stable release contains an **important security fix**, as explained in the [v1.20.5-0 companion blog post](https://forgejo.org/2023-10-release-v1-20-5-0/).
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We **strongly recommend** that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.20/admin/upgrade/) to the latest version as soon as possible.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.5+0-gitea-1.20.5`
|
||||
|
||||
* Security fix
|
||||
|
||||
* When a user logs into Forgejo, they can click the **Remember This Device** checkbox and their browser will store a **Long-term authentication** token provided by the server, in a cookie that will allow them to stay logged in for an extended period of time. The implementation was inherently insecure and was [reworked](https://codeberg.org/forgejo/forgejo/commit/51988ef52bc93b63184d28395d10bf3b76914ad0). Read more about this issue in the [v1.20.5-0 blog post](https://forgejo.org/2023-10-release-v1-20-5-0/).
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent bug fixes are described below. Others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Fix the display of pull requests waiting for review](https://codeberg.org/forgejo/forgejo/commit/4b23f11864) on the `/pulls` page. It incorrectly included all reviews.
|
||||
* [Fix a v1.20 regression preventing access to files with OAuth2 tokens](https://codeberg.org/forgejo/forgejo/commit/3e8c3b7c09) in private repositories.
|
||||
* [Fix](https://codeberg.org/forgejo/forgejo/commit/101cfc1f82) a bug by which the `doctor` command [complains the `deleted_branch` table is missing](https://codeberg.org/forgejo/forgejo/issues/1522) although it should not.
|
||||
* [Fix the release URL in webhooks](https://codeberg.org/forgejo/forgejo/commit/1b1f878204) so that `URL` points to the API URL and `HTMLURL` points to the web page.
|
||||
* [Fix organization field being null in POST /orgs/{orgid}/teams](https://codeberg.org/forgejo/forgejo/commit/f8bf284794).
|
||||
|
||||
## 1.20.4-1
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.4-1` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.4-0..v1.20.4-1
|
||||
```
|
||||
|
||||
This stable release includes bug fixes.
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.20/admin/upgrade/) to the latest version.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.4+0-gitea-1.20.4`
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Fix the followers and following list that only showed the first page](https://codeberg.org/forgejo/forgejo/commit/c041114a20fcaaf0931da81dcb542a930e8f9c5f)
|
||||
* [Fix issue templates preventing the creation of any new issues when blank issues are not authorized](https://codeberg.org/forgejo/forgejo/commit/64a418dfc778665f56cb20d678f3c10dbb62ddca) (regression introduced in v1.20.4-0)
|
||||
|
||||
## 1.20.4-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.4-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.3-0..v1.20.4-0
|
||||
```
|
||||
|
||||
This stable release includes bug fixes and two features.
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.20/admin/upgrade/) to the latest version.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.3+0-gitea-1.20.4`
|
||||
|
||||
* Features
|
||||
|
||||
* [Log slow SQL queries](https://codeberg.org/forgejo/forgejo/commit/fa25b9eec63c073e16f4595459880e4ee8797913) to help identify bottlenecks on large Forgejo instances
|
||||
* [Add `branch_filter` to hooks API endpoints](https://codeberg.org/forgejo/forgejo/commit/19a49e763a013dec4c3fcf3e9e2be89c7009bb3b)
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Ignore the trailing slashes when comparing oauth2 redirect_uri](https://codeberg.org/forgejo/forgejo/commit/2f6d011503a35a1eede96f5a13b2a9868c06b3ae)
|
||||
* [Fix the reopen logic for agit flow pull request](https://codeberg.org/forgejo/forgejo/commit/5abca17b644ded3c3ab8869db1d34f9bd678f18e)
|
||||
* [Fix the missing display of user projects](https://codeberg.org/forgejo/forgejo/commit/ef46b01168e251fad92ed46102b5faad75a5bcb1)
|
||||
* [Fix](https://codeberg.org/forgejo/forgejo/commit/08762875d7362ee207bbd320123cbb0ad4cf70d2) issue templates [that failed to save checkboxes](https://codeberg.org/forgejo/forgejo/pulls/1317)
|
||||
* [Fix accessibility issues preventing focus and selection](https://codeberg.org/forgejo/forgejo/commit/66016b3fe3a9646e5d9c8b4c2d88b1da7a908ccf)
|
||||
* [Fix being unable to use a repo that prohibits accepting PRs as a PR source](https://codeberg.org/forgejo/forgejo/commit/1d228e6ee93525bd630c4a915febd98d159f1824)
|
||||
* [Forgejo doctor database fix](https://codeberg.org/forgejo/forgejo/commit/0b1175f21b403ff59c0c3f7a759de8d0fe13bee8) to repair a condition preventing the owner of an organization from creating a repository
|
||||
* [Fix dashboard filters having no effect](https://codeberg.org/forgejo/forgejo/commit/a6c2201dd41706a000ca96bdcd3e89df96e342fd)
|
||||
* [Also check the email blocklists when adding new emails to existing accounts](https://codeberg.org/forgejo/forgejo/commit/d5845521a842418ae8f6dfcad8368ba2a6035f54)
|
||||
* [Sync tags when adopting repos](https://codeberg.org/forgejo/forgejo/commit/6b5ef0fad754a863eb7d91eefa8301dd9a5a84b5)
|
||||
* [Fix an error when pushing a new branch and there is a requirement that all commits are signed](https://codeberg.org/forgejo/forgejo/commit/193e04c43b556e0a25c260149429945ba2164efa)
|
||||
|
||||
## 1.20.3-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.3-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.2-0..v1.20.3-0
|
||||
```
|
||||
|
||||
This stable release includes bug fixes and a safeguard against a
|
||||
regression that may lead to data loss. The `[storage*]` sections in the
|
||||
`app.ini` file may cause the files for some subsystems - Attachments,
|
||||
LFS, Avatars, Repository avatars, Repository archives, Packages - to
|
||||
be merged together or misplaced. The safeguard detects this situation
|
||||
and Forgejo will not start to prevent data loss. If your instance is in
|
||||
this situation, [follow the instructions in the companion blog post](https://forgejo.org/2023-08-release-v1-20-3-0/).
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are upgraded to the latest version.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.2+0-gitea-1.20.3`
|
||||
|
||||
* Breaking changes
|
||||
|
||||
* [Fix some bugs in how the storage sections are interpreted](https://codeberg.org/forgejo/forgejo/commit/815682c88) in the `app.ini` file. Read more about this issue in the [v1.20.3-0 blog post](https://forgejo.org/2023-08-release-v1-20-3-0/)
|
||||
* [Add sanity checks](https://codeberg.org/forgejo/forgejo/commit/ee0e4848e) to detect an `app.ini` configuration that [needs manual fixing to preserve storage](https://forgejo.org/2023-08-release-v1-20-3-0/)
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Fix links to pull request reviews sent via mail](https://codeberg.org/forgejo/forgejo/commit/88e179d5ef8ee41f71d068195685ff098b38ca31). The pull request link was correct but it did not go the the review and stayed at the beginning of the page
|
||||
* [Recognize OGG as an audio format](https://codeberg.org/forgejo/forgejo/commit/622ec5c79f299c32ac2667a1aa7b4bf5d7c2d6cf)
|
||||
* [Consistently show the last time a cron job was run in the admin panel](https://codeberg.org/forgejo/forgejo/commit/5f769ef20)
|
||||
* [Fix NuGet registry v2 & v3 API search endpoints](https://codeberg.org/forgejo/forgejo/commit/471138829b0c24fe8c621dbb866ae8bb45ebc674)
|
||||
* [Allow html <img /> code to be parsed in markdown files](https://codeberg.org/forgejo/forgejo/commit/e7d0475e1)
|
||||
* [Fix incorrect color of the selected assignees when creating an issue](https://codeberg.org/forgejo/forgejo/commit/c7d7490b2)
|
||||
* [Add missing MinIO region on client initialization](https://codeberg.org/forgejo/forgejo/commit/927cbe62b)
|
||||
* [Add pull request review request webhook event](https://codeberg.org/forgejo/forgejo/commit/99c8dab9d)
|
||||
* [Fix bad url in the wiki due to incorrect unescaping](https://codeberg.org/forgejo/forgejo/commit/e0f6956a4)
|
||||
* [Fix the sort menu that was broken when displaying a custom profile from the `.profile` repository](https://codeberg.org/forgejo/forgejo/commit/fa92a6a4c)
|
||||
* [Workaround](https://codeberg.org/forgejo/forgejo/commit/3d211dea2) MariaDB [performance issue on large Forgejo instances](https://codeberg.org/forgejo/forgejo/issues/1161)
|
||||
* [Display human-readable text](https://codeberg.org/forgejo/forgejo/commit/2729bb3c6) instead of [numerical file modes](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation)
|
||||
* [The CLI exit code now is different from zero when an error occurs](https://codeberg.org/forgejo/forgejo/commit/089af9ab1)
|
||||
* [Fix error when a Debian package has a double newline character at the end of the control block](https://codeberg.org/forgejo/forgejo/commit/dd7180846)
|
||||
* [Fix a condition that would cause git related tasks to hang for longer than necessary in the queues and use too many resources as a result](https://codeberg.org/forgejo/forgejo/commit/36f8fbe1b)
|
||||
* [Fix the topic validation rule and suport dots](https://codeberg.org/forgejo/forgejo/commit/a578b75d7)
|
||||
* [Fix pull request check list when there are more than 30](https://codeberg.org/forgejo/forgejo/commit/e226b9646)
|
||||
* [Fix attachment clipboard copy on insecure origin](https://codeberg.org/forgejo/forgejo/commit/12ac84c26)
|
||||
* [Fix the profile README rendering](https://codeberg.org/forgejo/forgejo/commit/84c3b60a4) that [was inconsistent with other markdown files renderings](https://codeberg.org/forgejo/forgejo/issues/833)
|
||||
* [Fix API leaking the user email when the caller is not authentified](https://codeberg.org/forgejo/forgejo/commit/d89003cc1)
|
||||
|
||||
## 1.20.2-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.2-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.20.1-0..v1.20.2-0
|
||||
```
|
||||
|
||||
This stable release includes bug fixes and displays [warnings in the administration panel](https://codeberg.org/forgejo/forgejo/commit/28f4029e40) when deprecated entries are found in `app.ini`.
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are upgraded to the latest version.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/)
|
||||
|
||||
The semantic version was updated to `5.0.1+0-gitea-1.20.2`
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Add missing assets to the Forgejo sources tarbal](https://codeberg.org/forgejo/forgejo/commit/e14d239005)
|
||||
* [Fix user type selection error when creating a user](https://codeberg.org/forgejo/forgejo/commit/268569b462) and selecting `public` or `private`.
|
||||
* [Fix access check for org-level project](https://codeberg.org/forgejo/forgejo/commit/5afb0294f4)
|
||||
* [Warn instead of reporting an error when a webhook cannot be found](https://codeberg.org/forgejo/forgejo/commit/4c3dcdf815)
|
||||
* [Set MAX_WORKERS](https://codeberg.org/forgejo/forgejo/commit/5a4b19435d) to a value lower than 10 if the number of available CPUs is low to avoid overloading the host.
|
||||
* [Fix bug when pushing to a pull request which enabled dismiss approval automatically](https://codeberg.org/forgejo/forgejo/commit/4640c53386)
|
||||
* [Fix handling of plenty Nuget package versions](https://codeberg.org/forgejo/forgejo/commit/7bb8526736)
|
||||
* [Update email-setup.en-us.md](https://codeberg.org/forgejo/forgejo/commit/31f2ce3998)
|
||||
* [Fix bugs](https://codeberg.org/forgejo/forgejo/commit/9654d71bb2) in [LFS meta garbage collection](https://codeberg.org/forgejo/forgejo/issues/1113)
|
||||
* [Fix UI regression of asciinema player](https://codeberg.org/forgejo/forgejo/commit/f3c26de1f4)
|
||||
* [Fix LFS object list style](https://codeberg.org/forgejo/forgejo/commit/f20cfc291c)
|
||||
* [Fix CLI allowing creation of multiple user access tokens with the same name](https://codeberg.org/forgejo/forgejo/commit/b699e1d340)
|
||||
* [Fix](https://codeberg.org/forgejo/forgejo/commit/f4a8f10f64) router logger [preventing separating the logs in different files](https://codeberg.org/forgejo/forgejo/issues/1123).
|
||||
* [added ssh mirror workaround description](https://codeberg.org/forgejo/forgejo/commit/d9d38b6244)
|
||||
* [Fix wrong workflow status when rerun a job in an already finished workflow](https://codeberg.org/forgejo/forgejo/commit/e2101ae572)
|
||||
* [Fix escape problems in the branch selector](https://codeberg.org/forgejo/forgejo/commit/9fae415030)
|
||||
* [Fix handling of Debian files with trailing slash](https://codeberg.org/forgejo/forgejo/commit/4be3270e87)
|
||||
* [fix Missing 404 swagger response docs for /admin/users/{username}](https://codeberg.org/forgejo/forgejo/commit/1cd4d4b00e)
|
||||
* [Use stderr as fallback if the log file can't be opened](https://codeberg.org/forgejo/forgejo/commit/942d02f8e9)
|
||||
|
||||
## 1.20.1-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.20/forgejo) included in the `Forgejo v1.20.1-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges origin/v1.19/forgejo..origin/v1.20/forgejo
|
||||
```
|
||||
|
||||
- **[Forgejo Semantic Version](https://forgejo.org/docs/v1.20/user/semver/):**
|
||||
The semantic version was updated to `5.0.0+0-gitea-1.20.1` because it contains breaking changes.
|
||||
- **Breaking:**
|
||||
- [Scoped access tokens](https://codeberg.org/forgejo/forgejo/commit/18de83b2a3fc120922096b7348d6375094ae1532) or (Personal Access Tokens), were refactored and although existing tokens are still valid, they may have a different scope than before. To ensure that no tokens have a larger scope than expected they must be removed and recreated.
|
||||
- If your `app.ini` has one of the the following `[indexer].ISSUE_INDEXER_QUEUE_TYPE`, `[indexer].ISSUE_INDEXER_QUEUE_BATCH_NUMBER`, `[indexer].`, `[indexer].ISSUE_INDEXER_QUEUE_DIR`, `[indexer].ISSUE_INDEXER_QUEUE_CONN_STR`, `[indexer].UPDATE_BUFFER_LEN`, `[mailer].SEND_BUFFER_LEN`, `[repository].PULL_REQUEST_QUEUE_LENGTH` or `[repository].MIRROR_QUEUE_LENGTH`, Forgejo will abort immediately. Unless you know exactly what you're doing, you must comment them out so the default values are used.
|
||||
- The `-p` option of `environment-to-ini` is [no longer supported](https://codeberg.org/forgejo/forgejo/commit/fa0b5b14c2faa6a5f76bb2e7bc9241a5e4354189)
|
||||
- The ".png" suffix for [user and organizations is now reserved](https://codeberg.org/forgejo/forgejo/commit/2b91841cd3e1213ff3e4ed4209d6a4be89c2fa79)
|
||||
- The section `[git.reflog]` is [now obsolete and its keys have been moved](https://codeberg.org/forgejo/forgejo/commit/2f149c5c9db97f20fbbc65e32d1f3133048b11a2) to the following replacements:
|
||||
* `[git.reflog].ENABLED` → `[git.config].core.logAllRefUpdates`
|
||||
* `[git.reflog].EXPIRATION` → `[git.config].gc.reflogExpire`
|
||||
- The [logger](https://codeberg.org/forgejo/forgejo/commit/4647660776436f0a83129b4ceb8426b1fb0599bb) used to display Forgejo's was refactored and has new settings, different from the previous one found at `log.<mode>.<logger>` in `app.ini`. Check the [documentation](https://forgejo.org/docs/v1.20/admin/config-cheat-sheet/#log-log) and `app.example.ini` for more information. The SMTP logger was removed.
|
||||
- Forgejo will refuse to start if [the refactored path & config system](https://codeberg.org/forgejo/forgejo/commit/061b68e99) does not pass sanity checks (e.g. WORK_PATH must be absolute).
|
||||
- Manually set [WORK_PATH](https://forgejo.org/docs/v1.20/admin/config-cheat-sheet/#overall-default) in `app.ini`.
|
||||
If the `app.ini` file is writable by the user under which the Forgejo server runs and `WORK_PATH` is not set,
|
||||
the server will add it. Otherwise it will log an error starting with `Unable to update WORK_PATH`.
|
||||
One of the consequences of not setting `WORK_PATH` in `app.ini` is that pushing to a repository via ssh is
|
||||
[likely to fail as explained in the corresponding bug report](https://codeberg.org/forgejo/forgejo/issues/1118).
|
||||
Read the technical details in the [commit that implements the WORK_PATH change](https://codeberg.org/forgejo/forgejo/commit/061b68e99).
|
||||
- The user profile can be customized with [a Markdown file](https://codeberg.org/forgejo/forgejo/commit/c090f87a8db5b51e0aa9c7278b38ddc862c048ac).
|
||||
The profile page of a user is rendered using the `README.md` file of the `.profile` repository, if it exists. It is a
|
||||
breaking change because **it will display the .profile/README.md of a pre-existing repository, private or not**.
|
||||
- The [API endpoint pagination](https://codeberg.org/forgejo/forgejo/commit/0a3c4d4a595cc7e12462dde393ed64186260f26b) for team members was fixed: it now starts at 1 instead of 0, just like all other paginated API endpoints.
|
||||
- The `SSH_KEYGEN_PATH` variable in `app.ini` now defaults to using the [Go SSH key parsing instead of the `ssh-keygen` binary](https://codeberg.org/forgejo/forgejo/commit/7a8a4f54321f208ebbb0f708a5f0e49c4cd4cc04). When `START_SSH_SERVER` is true, the decision to use the Go SSH key parsing or an external binary will now depend on the value of `SSH_KEYGEN_PATH` instead of always using the Go SSH key parsing.
|
||||
- The storage settings were [refactored](https://codeberg.org/forgejo/forgejo/commit/d6dd6d641b593c54fe1a1041c153111ce81dbc20). Read more about [storage settings](https://forgejo.org/docs/v1.20/admin/storage/).
|
||||
- [The [repository.editor] PREVIEWABLE_FILE_MODES setting was removed](https://codeberg.org/forgejo/forgejo/commit/84daddc2fa74393cdc13371b0cc44f0444cfdae0). This setting served no practical purpose and was not working correctly. Instead a preview tab is always shown in the file editor when supported.
|
||||
- In addition to the already deprecated options inside [queue], many options have been dropped as well. Those are WRAP_IF_NECESSARY, MAX_ATTEMPTS, TIMEOUT, WORKERS, BLOCK_TIMEOUT, BOOST_TIMEOUT, BOOST_WORKERS. You can remove them from your app.ini now. Additionally, some default values have changed in this section.
|
||||
- The default CSS and templates included in Forgejo were heavily refactored and a large number of variables renamed. These changes are not documented and there is a very high chance that a tempate extracted and modified for a particular Forgejo instance will no longer work as it did. Browsing through the git history of the template in the sources is the best way to figure out how and why it was modified.
|
||||
- **Moderation:**
|
||||
Blocking another user is desirable if they are acting maliciously or are spamming your repository. When you block a user, Forgejo does not explicitly notify them, but they may learn through an interaction with you that is blocked. [Read more about blocking users](https://forgejo.org/docs/v1.20/user/blocking-user/).
|
||||
- **Package:**
|
||||
New registries are available for [SWIFT](https://forgejo.org/docs/v1.20/user/packages/swift), [debian](https://forgejo.org/docs/v1.20/user/packages/debian), [RPM](https://forgejo.org/docs/v1.20/user/packages/rpm), [alpine](https://forgejo.org/docs/v1.20/user/packages/alpine), [Go](https://forgejo.org/docs/v1.20/user/packages/go) and [CRAN](https://forgejo.org/docs/v1.20/user/packages/cran).
|
||||
- **Accessibility:**
|
||||
numerous improvements for [issue comments](https://codeberg.org/forgejo/forgejo/commit/6c354546547cd3a9595a7db119a6480d9cd506a7), [the menu on the navbar](https://codeberg.org/forgejo/forgejo/commit/a78e0b7dade16bc6509b943fe86e74962f1b95b6), [scoped labels](https://codeberg.org/forgejo/forgejo/commit/e8935606f5f1fff3c59222ebca6d4615ab06fb0b), [checkboxes and dropdowns](https://codeberg.org/forgejo/forgejo/commit/d4f35bd681af0632da988e15306f330e020422b2), [RTL rendering support to Markdown](https://codeberg.org/forgejo/forgejo/commit/32d9c47ec7706d8f06e09b42e09a28d7a0e3c526), [file (re-)views](https://codeberg.org/forgejo/forgejo/commit/e95b42e187cde9ac4bd541cd714bdb4f5c1fd8bc), [interactive tooltips](https://codeberg.org/forgejo/forgejo/commit/87f0f7e670c6c0e6aeab8c4458bfdb9d954eacec), [using a button element](https://codeberg.org/forgejo/forgejo/commit/81fe5d61851c0e586af7d32c29171ceff9a571bb), [repository list](https://codeberg.org/forgejo/forgejo/commit/e82f1b15c7120ad13fd3b67cf7e2c6cb9915c22d) and more.
|
||||
- **Time:**
|
||||
The display and localization of time was improved for [tooltips](https://codeberg.org/forgejo/forgejo/commit/b7b58348317cbe0145dc453d45c886b8e2764b4c), [milestones](https://codeberg.org/forgejo/forgejo/commit/97176754beb4de23fa0f68df715c4737919c93b0), [due date and translations that contain dates](https://codeberg.org/forgejo/forgejo/commit/70bb4984cdad9a15d676708bd345b590aa42d72a), [commit graphs](https://codeberg.org/forgejo/forgejo/commit/5bc9f7fcf9aece92c3fa2a0ea56e5585261a7f28), [runners](https://codeberg.org/forgejo/forgejo/commit/62ca5825f73ad5a25ffeb6c3ef66f0eaf5d30cdf), [webhooks](https://codeberg.org/forgejo/forgejo/commit/dbb37367854d108ebfffcac27837c0afac199a8e), [tests](https://codeberg.org/forgejo/forgejo/commit/3d266dd0f3dbae7e417c0e790e266aebc0078814) and more. Previously each rendered timestamp would be static, now the real time since an event happend is show. If a comment was added 2 minutes before the page rendered it would show as "2 minutes ago" on the initial render and if another 8 minutes have passed, without a page refresh you'd see "10 minutes ago".
|
||||
- **[Wiki](https://forgejo.org/docs/v1.20/user/wiki/)**
|
||||
- Improve the [display of the table of content](https://codeberg.org/forgejo/forgejo/commit/1ab16e48cccc086e7f97fb3ae8a293fe47a3a452)
|
||||
- Fixed a bug [preventing team users who have wiki write permission from deleting a page](https://codeberg.org/forgejo/forgejo/commit/284b41f45244bbe46fc8feee15bbfdf66d150e79)
|
||||
- [Shows the External Link icon and URL in the header](https://codeberg.org/forgejo/forgejo/commit/d347208114966166ffa9655adc5b202676546c31) to indicate that the user will be sent to an external side to help prevent fishing
|
||||
- Allow dash in [titles](https://codeberg.org/forgejo/forgejo/commit/b39a5bbbd610ba30651218658caaec1c86d6bca1)
|
||||
- **[Actions](https://forgejo.org/docs/v1.20/user/actions/)**
|
||||
- The internal CI graduated from **experimental** to **[alpha](https://en.wikipedia.org/wiki/Software_release_life_cycle#Alpha)**. It now has with a [user](https://forgejo.org/docs/v1.20/user/actions) documentation that includes examples and an extensive [administrator](https://forgejo.org/docs/v1.20/admin/actions) guide to set it up.
|
||||
- [Forgejo Actions](https://forgejo.org/docs/v1.20/user/actions/) workflows are [now available](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/.forgejo/workflows) to run tests and publish releases for `Forgejo` itself.
|
||||
- The Woodpecker CI configuration for PR verification and building releases for Forgejo v1.18 and v1.19 is no longer maintained as part of Forgejo itself and was moved to its [own repository](https://codeberg.org/forgejo-contrib/forgejo-ci-woodpecker).
|
||||
- **[Templates](https://forgejo.org/docs/v1.20/user/issue-pull-request-templates/)**
|
||||
- [Configuration for the issue templates](https://codeberg.org/forgejo/forgejo/commit/f384b13f1cd44be3a87df5553a0099390dacd010). [Read more about issue config](https://forgejo.org/docs/v1.20/user/issue-pull-request-templates/#syntax-for-issue-config) in the documentation.
|
||||
- [Add validations.required check to the dropdown field](https://codeberg.org/forgejo/forgejo/commit/5c0745c0349f0709d0fc36fd8a97dcab86bce28a)
|
||||
- [Issue template support markdown edition](https://codeberg.org/forgejo/forgejo/commit/c4303efc23ea19f16ee826809f43888ee4583ebb)
|
||||
- [Use a general Eval function for expressions in templates](https://codeberg.org/forgejo/forgejo/commit/5b89670a318e52e271f65d96bfe1116d85d20988)
|
||||
- [reload-templates CLI](https://codeberg.org/forgejo/forgejo/commit/3588edbb08f93aaa56defa82dffdbb202cd9aa4a)
|
||||
- **User Interface and User eXperience**
|
||||
- The web editor used when creating issues, adding comments, etc. [changed](https://codeberg.org/forgejo/forgejo/commit/5cc0801de90d16b4d528e62de11c9b525be5d122) from [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) which was no longer actively maintained to [GitHub markdown](https://github.com/github/markdown-toolbar-element). To help with the transition it is still possible to switch back to using EasyMDE using the double arrow button in the menubar.
|
||||
- [Improve wiki sidebar and TOC](https://codeberg.org/forgejo/forgejo/commit/51789ba12)
|
||||
- [Show outdated comments in the files changed tab of a pull request review](https://codeberg.org/forgejo/forgejo/commit/30a783879)
|
||||
- [Redirect to package after version deletion](https://codeberg.org/forgejo/forgejo/commit/c27a3af72)
|
||||
- Use a [separate admin page to show stats](https://codeberg.org/forgejo/forgejo/commit/520eb57d7642a5fca3df319e5b5d1c7c9018087c)
|
||||
- [Improve avatar compression and resizing](https://codeberg.org/forgejo/forgejo/commit/82224c54e0488738dbd3b7eccf56ab08b6790627)
|
||||
- [Add button to compare force pushed commits in pull requests](https://codeberg.org/forgejo/forgejo/commit/545495dcb0a4cb9d820132dde4f1127f7fe91aa4)
|
||||
- [When creating a new file in a repository via the web user interface allow for a path to be pasted](https://codeberg.org/forgejo/forgejo/commit/7f9d58fab8a3c4fd1a8f18d58e36fbfab7b30f33)
|
||||
- [Allows "video" HTML tag to be used in MarkDown, with the src, autoplay, and controls attributes](https://codeberg.org/forgejo/forgejo/commit/de6c718b46ebd3b7f6362c766eed328044d95ec7)
|
||||
- [Add "Reviewed by you" filter for pull requests](https://codeberg.org/forgejo/forgejo/commit/10cdcb9ea8077098921d72720f9f36fcfd950452)
|
||||
- [Make Ctrl+Enter submit a pending comment (starting review) instead of submitting a single comment](https://codeberg.org/forgejo/forgejo/commit/188c8c12c290e131fb342e3203634828652b0af5)
|
||||
- If an instance chooses to disable new pull or push mirrors or mirrors entirely, an appropriate message will [now be shown to the user in the Repository Settings](https://codeberg.org/forgejo/forgejo/commit/35ce7ca25b5756441949312d79aa6382f98ce8d6)
|
||||
- [Change `Close` to either `Close issue` or `Close pull request`](https://codeberg.org/forgejo/forgejo/commit/39d3711f3036db42d7ddf73dbdb125be611bcbba)
|
||||
- [Make Issue/PR/projects more compact](https://codeberg.org/forgejo/forgejo/commit/4a722c9a45659e7732258397bbb3dd1039ea1952)
|
||||
- [Improve RSS user interface](https://codeberg.org/forgejo/forgejo/commit/59d060622d375c4123ea88e2fa6c4f34d4fea4d3)
|
||||
- [Add details summary for vertical menus in settings to allow toggling](https://codeberg.org/forgejo/forgejo/commit/58536093b3112841bc69edb542189893b57e7a47)
|
||||
- [Show visibility status of email in own profile](https://codeberg.org/forgejo/forgejo/commit/5e1bd8af5f16f9db88cfeb5b80bdf731435cacfb)
|
||||
- [Improve the protected branch setting page](https://codeberg.org/forgejo/forgejo/commit/72e956b79a3b2e055bb5d4d5e20e88eaa2eeec96)
|
||||
- [Improve the display of the pull request branch delete button](https://codeberg.org/forgejo/forgejo/commit/774d1a0fbdadd1136b6af895f8d449b0c8db54cb)
|
||||
- [Fix the color for repository transfer related buttons when having no permission to act](https://codeberg.org/forgejo/forgejo/commit/7abe958f5b507efa676fb3b2e27d30517f6d1908)
|
||||
- [Add a progressbar to Milestone Page](https://codeberg.org/forgejo/forgejo/commit/7d192cb674bc475b123c84b205aca821247c5dd1)
|
||||
- [Nicer display when the list of notifications is empty](https://codeberg.org/forgejo/forgejo/commit/8251b317f7b7a2b5f626a02fa3bb540a1495e81d)
|
||||
- [Rename board to column in projects](https://codeberg.org/forgejo/forgejo/commit/843f81113ebe71fd725210c5a382268333865cc7)
|
||||
- [Improve header bar on issue, pull requests and milestone](https://codeberg.org/forgejo/forgejo/commit/8f4dafcd4e6b0b5d307c3e060ffe908c2a96f047)
|
||||
- [Add organization visibility label when displayed on the dashboard](https://codeberg.org/forgejo/forgejo/commit/97b70a0cd40e8f73cdf6ba4397087b45061de3d8)
|
||||
- [Unification of registration fields order](https://codeberg.org/forgejo/forgejo/commit/b9fad73e9fcf40e81cde3304198105af6c668421)
|
||||
- [Append `(comment)` when a link points at a comment rather than the whole issue](https://codeberg.org/forgejo/forgejo/commit/ca905b82df7f1d2a823d8df4448d485e5902876d)
|
||||
- [Add visibility (private, limited) in the dashboard navbar](https://codeberg.org/forgejo/forgejo/commit/d949d8e074407a96dbcfa98a71ccd80527b5ad78)
|
||||
- [Show all activities in the dashboard, not just the most recent ones](https://codeberg.org/forgejo/forgejo/commit/f4920c9c7f5947d3b6476610f39bc3492ab4ef3b)
|
||||
- [Do not display the stars in the repository list of the dashboard](https://codeberg.org/forgejo/forgejo/commit/06c067bb0f9eeb8873ddc298819b30fc5913943f)
|
||||
- [Improve the display of tags to include the tag message](https://codeberg.org/forgejo/forgejo/commit/b78c955958301dde72d8caf189531f6e53c496b4)
|
||||
- [Hide the target selector if a tag exists when creating a new release](https://codeberg.org/forgejo/forgejo/commit/3de9e63fd04d61e08fcbdec035c9f138347d9f37)
|
||||
- [Show the calculated commit status state of the latest commit on the default branch for each repository in the dashboard repository list](https://codeberg.org/forgejo/forgejo/commit/4810fe55e3e73edb962052df46bef125eb1817b3)
|
||||
- [Sort users and orgs on the explore page by recency](https://codeberg.org/forgejo/forgejo/commit/4daf40505a5f89747982ddd2f1df2a4001720846)
|
||||
- [Show the number of repositories in the user or organization profile](https://codeberg.org/forgejo/forgejo/commit/52b17bfa07fea29441cd961da4edaf1ea97fe348)
|
||||
- [Review management (requesting again and discard) now happens at the top of the pull request](https://codeberg.org/forgejo/forgejo/commit/a70d853d064a97f0be1d3702a9c3912494b546ec)
|
||||
- [Add markdown preview when submitting a review](https://codeberg.org/forgejo/forgejo/commit/b5c26fa825e08122843ad6d27191d399a9af1c37)
|
||||
- [Support no label/assignee filter and batch clearing labels/assignees](https://codeberg.org/forgejo/forgejo/commit/b807d2f6205bf1ba60d3a543e8e1a16f7be956df)
|
||||
- [Display when a repo was archived](https://codeberg.org/forgejo/forgejo/commit/c41bc4f1279c9e1e6e11d7b5fcfe7ef089fc7577)
|
||||
- [Improve squash merge commit author and co-author with private emails](https://codeberg.org/forgejo/forgejo/commit/d647e74502fdf734c89b3e6592a9ad88c3005971)
|
||||
- [Allow adding new files to an empty repo](https://codeberg.org/forgejo/forgejo/commit/e422342eebc18034ef586ec58f1e2fff0340091d)
|
||||
- [Move `Rename branch` from repo settings page to the page of branches list](https://codeberg.org/forgejo/forgejo/commit/e8173c2c33f1dd5b0a2c044255434d414cab62d2)
|
||||
- [Add "Updated" column for admin repositories list](https://codeberg.org/forgejo/forgejo/commit/94d6b5b09d49b2622c2164a03cfae45dced96c74)
|
||||
- [Hide the merge box of a pull request if it is merged and the branch was deleted](https://codeberg.org/forgejo/forgejo/commit/e9b39250b285f1b9cbf9739f33c06fc57401f314)
|
||||
- [The repository migration can be canceled](https://codeberg.org/forgejo/forgejo/commit/f6e029e6c7849d4361abf7f1d749b5d528364ac4)
|
||||
- [Add button on the diff header to copy the file name](https://codeberg.org/forgejo/forgejo/commit/c5ede35124c8d5280219c24049bb0ad7da9f02ed)
|
||||
- [Add --quiet option to the dump CLI](https://codeberg.org/forgejo/forgejo/commit/cb1536471bcef4d78a3fe5cbd738b9f60fabbcc2)
|
||||
- [Support searching for an issue with its number in the the list of issues](https://codeberg.org/forgejo/forgejo/commit/1144b1d129de530b2c07dfdfaf55de383cd82212)
|
||||
- [Improve the list of notifications](https://codeberg.org/forgejo/forgejo/commit/f7ede92f82f7f3ec7bb31a1249f9524e5b728f34)
|
||||
- [When editing a file in the web UI, allow for a preview whenever possible](https://codeberg.org/forgejo/forgejo/commit/ac64c8297444ade63a2a364c4afb7e6c1de5a75f)
|
||||
- [Make release download URLs human readable](https://codeberg.org/forgejo/forgejo/commit/42919ccb7cd32ab67d0878baf2bac6cd007899a8)
|
||||
- [Add a tooltip to `Publish Review` explaining why they are disabled](https://codeberg.org/forgejo/forgejo/commit/a8c30a45fa49a3a551b1dca882960008c254bb3d)
|
||||
- [Show the file tree view by default when browsing the changes in a pull request](https://codeberg.org/forgejo/forgejo/commit/72eedfb91584720da774909d3f078b7d515c9fdd)
|
||||
- [Allow both fullname search in the author dropdown search of the issue list when `DEFAULT_SHOW_FULL_NAME` is true](https://codeberg.org/forgejo/forgejo/commit/661e78bed5c0879c32c53eb60f3d6898b93e1f08)
|
||||
- **Performance**
|
||||
- [Improve performances when listing issues](https://codeberg.org/forgejo/forgejo/commit/9bbb4d8d6)
|
||||
- [Speedup loading the list of authors in the dropdown of the list of issues](https://codeberg.org/forgejo/forgejo/commit/6eb678374b583079a0a08b7ed0c9ca220c0c0434)
|
||||
- [Use minio/sha256-simd for accelerated SHA256](https://codeberg.org/forgejo/forgejo/commit/1319ba6742a8562453646763adad22379674bab5)
|
||||
- [Speed up HasUserStopwatch & GetActiveStopwatch](https://codeberg.org/forgejo/forgejo/commit/ef4fc302468cc8a9fd8f65c4ebdc6f55138450d1)
|
||||
- [Do not create commit graph for temporary repos](https://codeberg.org/forgejo/forgejo/commit/0268ee5c37b8ad733678f02bc15ec8642da62c10)
|
||||
- [Faster git.GetDivergingCommits](https://codeberg.org/forgejo/forgejo/commit/75ea0d5dba5dbf2f84cef2d12460fdd566d43e62)
|
||||
- [Order pull request conflict checking by recently updated, for each push](https://codeberg.org/forgejo/forgejo/commit/df48af22296ccce8e9bd18e5d35c9a3cdf5acb0f)
|
||||
- [MySQL integration tests](https://codeberg.org/forgejo/forgejo/commit/49f68518c2a2bd36ca0106045bd84de01dec4b61) run twice faster low end machines and use an order of magnitude less disk I/O
|
||||
- **Authentication**
|
||||
- [Add ntlm authentication support for mail](https://codeberg.org/forgejo/forgejo/commit/8be6da3e2fd0b685aeb6b9e7fd9dee5a4571163a)
|
||||
- [LDAP filters include both username and email address](https://codeberg.org/forgejo/forgejo/commit/b8c19e7a11525da4174b6f80f87ff3e844d03d8a)
|
||||
- [Allow for PKCE flow without client secret](https://codeberg.org/forgejo/forgejo/commit/7d855efb1fe6b97c5d87492f67ed6aefd31b2474)
|
||||
- [Add the ability to set multiple redirect URIs in the OAuth application UI](https://codeberg.org/forgejo/forgejo/commit/ca35dec18b3d3d7dd5cde4c69a10ae830961faf7)
|
||||
- **Refactor:**
|
||||
Many essential sub-systems were refactored: the [queue system](https://codeberg.org/forgejo/forgejo/commit/6f9c278559789066aa831c1df25b0d866103d02d) that handles background tasks such as checking pull requests, [pull mirror](https://codeberg.org/forgejo/forgejo/commit/99283415bcbaa8acfe4d249ce3040de2f3a8b006), [git internal API](https://codeberg.org/forgejo/forgejo/commit/f4538791f5fc82b173608fcf9c30e36ec01dc9d3), [routes](https://codeberg.org/forgejo/forgejo/commit/92fd3fc4fd369b6a8c0a022a32a80dec2340223a) and [web routes](https://codeberg.org/forgejo/forgejo/commit/b9a97ccd0ea1ee44db85b0fbb80b75255af7c742), [merge & update logic](https://codeberg.org/forgejo/forgejo/commit/8598356df1eb21b6e33ecb9f9268ba36c5488e7c) and [git command calls](https://codeberg.org/forgejo/forgejo/commit/542cec98f8c07e0f046a35f1d516807416536e74), [listing commits](https://codeberg.org/forgejo/forgejo/commit/ec261b63e14f84da3e2d9a6e27c8b831a7750677), [cookie](https://codeberg.org/forgejo/forgejo/commit/5b9557aef59b190c55de9ea218bf51152bc04786), [issue stats](https://codeberg.org/forgejo/forgejo/commit/38cf43d0606c13c38f459659f38e26cf31dceccb), [renaming users and organizations](https://codeberg.org/forgejo/forgejo/commit/c59a057297c782f44a81a3e630b5094a58099edb), [app.ini handling](https://codeberg.org/forgejo/forgejo/commit/de4a21fcb4476772c69c36d086549e89ed4dcf6c), [diffFileInfo / DiffTreeStore](https://codeberg.org/forgejo/forgejo/commit/ee99cf6313ba565523b3c43f61ffda4b71e2c39b).... In theory these changes are transparent to the Forgejo user and admin but the risk of subtle regressions is real: do not hesitate to [reach out](https://codeberg.org/forgejo/forgejo/issues) if you suspect anything.
|
||||
- **RSS**
|
||||
- [Support "." char as user name for User/Orgs in RSS/ATOM/GPG/KEYS](https://codeberg.org/forgejo/forgejo/commit/88033438aa8214569913899a17b19b57bd609d97)
|
||||
- [Add RSS Feeds for branches and files](https://codeberg.org/forgejo/forgejo/commit/56d4893b2a996da6388801c9c8ff16b9b588ad55)
|
||||
- **API**
|
||||
- [Add admin API for email](https://codeberg.org/forgejo/forgejo/commit/d56bb7420184c0c2f451f4bcaa96c9b3b00c393d)
|
||||
- [Add admin API to rename a user](https://codeberg.org/forgejo/forgejo/commit/03591f0f95823a0b1dcca969d2a3ed505c7e6d73)
|
||||
- [Add login name and source id to admin user searching API](https://codeberg.org/forgejo/forgejo/commit/6f9cc617fcc42477dec5ccab83d06f0a96544403)
|
||||
- [Add missing units to create and edit repo API](https://codeberg.org/forgejo/forgejo/commit/574d8fe6d6675c8aa05e2b75fdbc01c009efd8be)
|
||||
- [Add API to manage issue dependencies](https://codeberg.org/forgejo/forgejo/commit/3cab9c6b0c050bfcb9f2f067e7dc1b0242875254)
|
||||
- [Add API for activity feeds](https://codeberg.org/forgejo/forgejo/commit/6b0df6d8da76d77a9b5c42dcfa78dbfe197fd56d)
|
||||
- [Add API for license templates](https://codeberg.org/forgejo/forgejo/commit/fb37eefa282543fd8ce63c361cd4cf0dfac9943c)
|
||||
- [Add API for gitignore templates](https://codeberg.org/forgejo/forgejo/commit/36a5d4c2f3b5670e5e921034cd5d25817534a6d4)
|
||||
- [Add API to upuload a file to an empty repository](https://codeberg.org/forgejo/forgejo/commit/cf465b472166ccf6d3e001e3043e4bf43e16e6b3)
|
||||
- [Allow for --not when listing the commits of a repo](https://codeberg.org/forgejo/forgejo/commit/f766b002938b5c81e343c81fda3c0669fa09809f)
|
||||
- [Add `files` and `verification` parameters to improve performances when listing the commits of a a repo](https://codeberg.org/forgejo/forgejo/commit/1dd83dbb917d55bd253001646d6743f247a4d98b)
|
||||
- [Allow for listing a single commit in a repository](https://codeberg.org/forgejo/forgejo/commit/5930ab5fdf7a970fcca3cd50b44cf1cacb615a54)
|
||||
- [Create a branch directly from commit on the create branch API](https://codeberg.org/forgejo/forgejo/commit/cd9a13ebb47d32f46b38439a524e3b2e0c619490)
|
||||
- [Add API for Label templates](https://codeberg.org/forgejo/forgejo/commit/25dc1556cd70b567a4920beb002a0addfbfd6ef2)
|
||||
- [Add API for changing/creating/deleting multiple files](https://codeberg.org/forgejo/forgejo/commit/275d4b7e3f4595206e5c4b1657d4f6d6969d9ce2)
|
||||
- **Miscellaneous Features**
|
||||
- [Any URL scheme may be used for links](https://codeberg.org/forgejo/forgejo/commit/f5ce2ed292a90041abd749a8db26671645648a43). Previously, non-standard URLs (like matrix:) were not rendered unless explicitly listed in `markdown.CUSTOM_URL_SCHEMES`. Now the default if `markdown.CUSTOM_URL_SCHEMES` is not set, all schemes are allowed and markdown links ([label](URL)) render as links.
|
||||
- [Always use "utf8mb4" for MySQL](https://codeberg.org/forgejo/forgejo/commit/cb3173a1e)
|
||||
- [Add Adopt repository event and handler](https://codeberg.org/forgejo/forgejo/commit/9d69a4758)
|
||||
- Add [meilisearch](https://www.meilisearch.com/) support to [index the content of repositories](https://codeberg.org/forgejo/forgejo/commit/92c160d8e716cb3d05215a97cf521e843596f562).
|
||||
- [Add support](https://codeberg.org/forgejo/forgejo/commit/985f76dc4b0692c4d6c6f37e82500ef859557c16) for [redis v7](https://raw.githubusercontent.com/redis/redis/7.0/00-RELEASENOTES)
|
||||
- Allow [webp](https://en.wikipedia.org/wiki/WebP) images [as avatars](https://codeberg.org/forgejo/forgejo/commit/65fe0fb22cfb264f0b756065d0c3ce7a17d7e55b)
|
||||
- [Add support](https://codeberg.org/forgejo/forgejo/commit/58caf422e67c78f87327bc9b00f89083a2432940) for rendering [.livemd](https://livebook.dev/)
|
||||
- The `forgejo forgejo-cli actions` [subcommand is added](https://codeberg.org/forgejo/forgejo/commit/d6efefbb63d59ba0251c10b6031f6b630b184eaf) to implement [offline registration with `actions register`](https://forgejo.org/docs/v1.20/admin/actions/#offline-registration) for the [Forgejo runner](https://code.forgejo.org/forgejo/runner).
|
||||
- When [called as `forgejo-cli`](https://codeberg.org/forgejo/forgejo/commit/935fb85e8b2a5f6a9c9c6c0b78a234abc14df4fe) (with `ln -f forgejo forgejo-cli`), Forgejo provides a new CLI that is not backward compatible with Gitea. It contains Forgejo specific additions such as [offline registration](https://forgejo.org/docs/v1.20/admin/actions/#offline-registration)
|
||||
- [Render list items](https://codeberg.org/forgejo/forgejo/commit/e1829f0728509c4c1b7810fe9f6df1aebb71b4c0) when an [org-mode](https://orgmode.org/) file is displayed
|
||||
- [A user can follow an organization](https://codeberg.org/forgejo/forgejo/commit/cc64a925602d54f3439dd19f16b5280bd0377a7a)
|
||||
- [When playing a video in the web UI, the player control can be dragged to play on the specified position](https://codeberg.org/forgejo/forgejo/commit/023a048f52b5bf8c4b715285245a129f04e05a8c)
|
||||
- The commit status required for a pull request to be merged can now be [specified as patterns](https://codeberg.org/forgejo/forgejo/commit/e7c2231dee356df5cbe5a47c07e31e3a8d090a6f) instead of being a hard coded list
|
||||
- [Support wildcard in email domain allow and block lists](https://codeberg.org/forgejo/forgejo/commit/2cb66fff60c95efbd58b797f1197f2421f4687ce). [Read more about EMAIL_DOMAIN_ALLOWLIST and EMAIL_DOMAIN_BLOCKLIST](https://forgejo.org/docs/v1.20/admin/config-cheat-sheet/).
|
||||
- When [installing with docker](https://forgejo.org/docs/v1.20/admin/installation/#installation-with-docker) the value of a configuration variable can now be fetched from a file by [adding the `__FILE` suffix](https://codeberg.org/forgejo/forgejo/commit/c21605951b581440bb08b65d5907b1cd4e0ab6c5). For instance `FORGEJO__security__INTERNAL_TOKEN__FILE=/etc/forgejo/token` can be used instead of `FORGEJO__security__INTERNAL_TOKEN=tokenvalue`.
|
||||
- The [new `[git.config]` section of `app.ini`](https://codeberg.org/forgejo/forgejo/commit/8080ace6fcf73a5fbe4a0dd71881228abd0c68b9) is used to `git set config`. [Read more about the defaults it contains](https://forgejo.org/docs/v1.20/admin/config-cheat-sheet/#git---config-options-gitconfig).
|
||||
- [Issues and pull requests can be pinned](https://codeberg.org/forgejo/forgejo/commit/aaa109466350c531b9238a61115b2877daca57d3). They will show on top of the list of issues (or pull requests) and can be re-arranged by dragging them.
|
||||
- [Implement systemd-notify protocol](https://codeberg.org/forgejo/forgejo/commit/7565e5c3de051400a9e3703f707049cbb9054cf3) and allows for using `Type=notify` in service files.
|
||||
- [Provide more control over the repositories that are indexed](https://codeberg.org/forgejo/forgejo/commit/033d92997fc16baee097d2b25f08e0984e628abd). [Read more about REPO_INDEXER_REPO_TYPES](https://forgejo.org/docs/v1.20/admin/config-cheat-sheet/).
|
||||
- **Webhook**
|
||||
- Similar to organization wide webhooks, it is now possible to have [user wide webhooks](https://codeberg.org/forgejo/forgejo/commit/2173f14708ff3b35d7821fc9b6dcb5fcd06b8494)
|
||||
- [Add webhook trigger when a Pull Request review requests is created](https://codeberg.org/forgejo/forgejo/commit/309354c70ee994a1e8f261d7bc24e7473e601d02)
|
||||
|
||||
* Container images upgraded to Alpine 3.18
|
||||
|
||||
The Forgejo container images are now based on [Alpine 3.18](https://alpinelinux.org/posts/Alpine-3.18.0-released.html) instead of Alpine 3.17.
|
||||
|
||||
## 1.19.4-0
|
||||
|
||||
The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.19/forgejo) included in the `Forgejo v1.19.4-0` release can be reviewed from the command line with:
|
||||
|
||||
```shell
|
||||
$ git clone https://codeberg.org/forgejo/forgejo/
|
||||
$ git -C forgejo log --oneline --no-merges v1.19.3-0..v1.19.4-0
|
||||
```
|
||||
|
||||
This stable release contains security fixes.
|
||||
|
||||
* Recommended Action
|
||||
|
||||
We recommend that all Forgejo installations are upgraded to the latest version.
|
||||
|
||||
* [Forgejo Semantic Version](https://forgejo.org/docs/v1.19/user/semver/)
|
||||
|
||||
The semantic version was updated from `4.2.1+0-gitea-1.19.3` to `4.2.2+0-gitea-1.19.4`.
|
||||
|
||||
* Security fixes
|
||||
|
||||
* [An additional verification](https://codeberg.org/forgejo/forgejo/commit/a259a928a) was implemented to prevent [open redirects](https://en.wikipedia.org/wiki/Open_redirect).
|
||||
|
||||
* Bug fixes
|
||||
|
||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||
|
||||
* [Fix an edge case](https://codeberg.org/forgejo/forgejo/commit/27796464c) where a user changing their `username` in their profile page could fail
|
||||
* The secrets are only meaningful in the context of `Frogejo Actions`, do not display them if `Forgejo Actions` is disabled ([patch 1](https://codeberg.org/forgejo/forgejo/commit/5883db45c), [patch 2](https://codeberg.org/forgejo/forgejo/commit/5fdac0d46))
|
||||
* Actions can now be triggered on mirrored repositories ([patch 1](https://codeberg.org/forgejo/forgejo/commit/58bdcae61), [patch 2](https://codeberg.org/forgejo/forgejo/commit/8d4d6f9b2))
|
||||
* [Return `404` in the API if the requested webhooks were not found](https://codeberg.org/forgejo/forgejo/commit/16bcceeff) instead of `500`
|
||||
* Ensure topics deleted via the API are [also deleted in the repository](https://codeberg.org/forgejo/forgejo/commit/5dc29fdeb)
|
||||
* [Tentative fix](https://codeberg.org/forgejo/forgejo/commit/9bc4887cb) to suppress the JavaScript error **TypeError: undefined is not an object (evaluating '_i18n.textEdited')** on safari. It is unclear if that fix is effective because it could not be reproduced, please report if it still happens for you.
|
||||
* [Respect original content when creating secrets](https://codeberg.org/forgejo/forgejo/commit/f6919e3e5)
|
||||
* If a mirror failed and left the database in an inconsistent state, make it so the repository page [does not fail with an error `500`](https://codeberg.org/forgejo/forgejo/commit/f37fba567)
|
||||
* If a user that triggered `Actions` is deleted, [allow for the page listing the tasks it launched to show](https://codeberg.org/forgejo/forgejo/commit/f9bf040a5) instead of failing with an error `500`
|
||||
* [Allow the selection of milestones](https://codeberg.org/forgejo/forgejo/commit/55d062003) when acting on multiple issues in the issue list page
|
||||
* [Fix the API error message when trying to create a fork that already exists](https://codeberg.org/forgejo/forgejo/commit/4dccac3db)
|
||||
* [Don't display a `create page` button in a mirror wiki repository](https://codeberg.org/forgejo/forgejo/commit/7a74957c1). A mirrored repository will also mirror a wiki and changes will be overridden.
|
||||
* [Do not allow for a repository to enable actions if it is not enabled in the configuration](https://codeberg.org/forgejo/forgejo/commit/257287954)
|
||||
* Allow for closed PRs to be re-opened and [synchronize with the latest content of the head branch](https://codeberg.org/forgejo/forgejo/commit/306b7b5d1)
|
||||
* [Fix the `close` button of projects within an organization](https://codeberg.org/forgejo/forgejo/commit/306b7b5d1). It was a noop and now effectively closes the project
|
||||
The Forgejo admin should carefully read the required manual actions before upgrading. A point release (e.g. v1.19.1 or v1.19.2) does not require manual actions but others might (e.g. v1.18.0, v1.19.0).
|
||||
|
||||
## 1.19.3-0
|
||||
|
||||
|
|
2
assets/emoji.json
generated
2
assets/emoji.json
generated
File diff suppressed because one or more lines are too long
|
@ -1,27 +1,31 @@
|
|||
<svg viewBox="0 0 212 212" xmlns="http://www.w3.org/2000/svg">
|
||||
<style type="text/css">
|
||||
circle {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
stroke-width: 15;
|
||||
}
|
||||
path {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
stroke-width: 25;
|
||||
}
|
||||
.orange {
|
||||
stroke:#ff6600;
|
||||
}
|
||||
.red {
|
||||
stroke:#d40000;
|
||||
}
|
||||
</style>
|
||||
<g transform="translate(6,6)">
|
||||
<path d="M58 168 v-98 a50 50 0 0 1 50-50 h20" class="orange" />
|
||||
<path d="M58 168 v-30 a50 50 0 0 1 50-50 h20" class="red" />
|
||||
<circle cx="142" cy="20" r="18" class="orange" />
|
||||
<circle cx="142" cy="88" r="18" class="red" />
|
||||
<circle cx="58" cy="180" r="18" class="red" />
|
||||
</g>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="main_outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve">
|
||||
<g>
|
||||
<path id="teabag" style="fill:#FFFFFF" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8
|
||||
c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4
|
||||
c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path style="fill:#609926" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2
|
||||
c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5
|
||||
c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5
|
||||
c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3
|
||||
c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1
|
||||
C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4
|
||||
c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7
|
||||
S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55
|
||||
c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8
|
||||
l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/>
|
||||
<path style="fill:#609926" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4
|
||||
c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1
|
||||
c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9
|
||||
c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3
|
||||
c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3
|
||||
c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29
|
||||
c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8
|
||||
C343.2,346.5,335,363.3,326.8,380.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 2.5 KiB |
129
assets/go-licenses.json
generated
129
assets/go-licenses.json
generated
File diff suppressed because one or more lines are too long
|
@ -1,27 +1,31 @@
|
|||
<svg viewBox="0 0 212 212" xmlns="http://www.w3.org/2000/svg">
|
||||
<style type="text/css">
|
||||
circle {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
stroke-width: 15;
|
||||
}
|
||||
path {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
stroke-width: 25;
|
||||
}
|
||||
.orange {
|
||||
stroke:#ff6600;
|
||||
}
|
||||
.red {
|
||||
stroke:#d40000;
|
||||
}
|
||||
</style>
|
||||
<g transform="translate(6,6)">
|
||||
<path d="M58 168 v-98 a50 50 0 0 1 50-50 h20" class="orange" />
|
||||
<path d="M58 168 v-30 a50 50 0 0 1 50-50 h20" class="red" />
|
||||
<circle cx="142" cy="20" r="18" class="orange" />
|
||||
<circle cx="142" cy="88" r="18" class="red" />
|
||||
<circle cx="58" cy="180" r="18" class="red" />
|
||||
</g>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="main_outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve">
|
||||
<g>
|
||||
<path id="teabag" style="fill:#FFFFFF" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8
|
||||
c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4
|
||||
c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path style="fill:#609926" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2
|
||||
c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5
|
||||
c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5
|
||||
c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3
|
||||
c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1
|
||||
C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4
|
||||
c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7
|
||||
S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55
|
||||
c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8
|
||||
l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/>
|
||||
<path style="fill:#609926" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4
|
||||
c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1
|
||||
c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9
|
||||
c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3
|
||||
c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3
|
||||
c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29
|
||||
c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8
|
||||
C343.2,346.5,335,363.3,326.8,380.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 2.5 KiB |
|
@ -12,7 +12,6 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
|
@ -59,7 +58,7 @@ func main() {
|
|||
|
||||
// use old en-US as the base, and copy the new translations to the old locales
|
||||
enUsOld := inisOld["options/locale/locale_en-US.ini"]
|
||||
brokenWarned := make(container.Set[string])
|
||||
brokenWarned := map[string]bool{}
|
||||
for path, iniOld := range inisOld {
|
||||
if iniOld == enUsOld {
|
||||
continue
|
||||
|
@ -78,7 +77,7 @@ func main() {
|
|||
broken := oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%")
|
||||
broken = broken || strings.Contains(oldStr, "\n") || strings.Contains(oldStr, "\n")
|
||||
if broken {
|
||||
brokenWarned.Add(secOld.Name() + "." + keyEnUs.Name())
|
||||
brokenWarned[secOld.Name()+"."+keyEnUs.Name()] = true
|
||||
fmt.Println("----")
|
||||
fmt.Printf("WARNING: skip broken locale: %s , [%s] %s\n", path, secEnUS.Name(), keyEnUs.Name())
|
||||
fmt.Printf("\told: %s\n", strings.ReplaceAll(oldStr, "\n", "\\n"))
|
||||
|
@ -104,7 +103,7 @@ func main() {
|
|||
broken = broken || strings.HasPrefix(str, "`\"")
|
||||
broken = broken || strings.Count(str, `"`)%2 == 1
|
||||
broken = broken || strings.Count(str, "`")%2 == 1
|
||||
if broken && !brokenWarned.Contains(sec.Name()+"."+key.Name()) {
|
||||
if broken && !brokenWarned[sec.Name()+"."+key.Name()] {
|
||||
fmt.Printf("WARNING: found broken locale: %s , [%s] %s\n", path, sec.Name(), key.Name())
|
||||
fmt.Printf("\tstr: %s\n", strings.ReplaceAll(str, "\n", "\\n"))
|
||||
fmt.Println("----")
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
|
||||
var optionLogVerbose bool
|
||||
|
||||
func logVerbose(msg string, args ...any) {
|
||||
func logVerbose(msg string, args ...interface{}) {
|
||||
if optionLogVerbose {
|
||||
log.Printf(msg, args...)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
|
||||
const (
|
||||
gemojiURL = "https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json"
|
||||
maxUnicodeVersion = 15
|
||||
maxUnicodeVersion = 14
|
||||
)
|
||||
|
||||
var flagOut = flag.String("o", "modules/emoji/emoji_data.go", "out")
|
||||
|
|
|
@ -15,8 +15,6 @@ import (
|
|||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
)
|
||||
|
||||
// regexp is based on go-license, excluding README and NOTICE
|
||||
|
@ -57,14 +55,20 @@ func main() {
|
|||
// yml
|
||||
//
|
||||
// It could be removed once we have a better regex.
|
||||
excludedExt := container.SetOf(".gitignore", ".go", ".mod", ".sum", ".toml", ".yml")
|
||||
|
||||
excludedExt := map[string]bool{
|
||||
".gitignore": true,
|
||||
".go": true,
|
||||
".mod": true,
|
||||
".sum": true,
|
||||
".toml": true,
|
||||
".yml": true,
|
||||
}
|
||||
var paths []string
|
||||
err := filepath.WalkDir(base, func(path string, entry fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if entry.IsDir() || !licenseRe.MatchString(entry.Name()) || excludedExt.Contains(filepath.Ext(entry.Name())) {
|
||||
if entry.IsDir() || !licenseRe.MatchString(entry.Name()) || excludedExt[filepath.Ext(entry.Name())] {
|
||||
return nil
|
||||
}
|
||||
paths = append(paths, path)
|
||||
|
|
|
@ -69,13 +69,13 @@ async function main() {
|
|||
const faviconSvg = await readFile(new URL('../assets/favicon.svg', import.meta.url), 'utf8');
|
||||
|
||||
await Promise.all([
|
||||
generate(logoSvg, '../public/assets/img/logo.svg', {size: 32}),
|
||||
generate(logoSvg, '../public/assets/img/logo.png', {size: 512}),
|
||||
generate(faviconSvg, '../public/assets/img/favicon.svg', {size: 32}),
|
||||
generate(faviconSvg, '../public/assets/img/favicon.png', {size: 180}),
|
||||
generate(logoSvg, '../public/assets/img/avatar_default.png', {size: 200}),
|
||||
generate(logoSvg, '../public/assets/img/apple-touch-icon.png', {size: 180, bg: true}),
|
||||
gitea && generate(logoSvg, '../public/assets/img/gitea.svg', {size: 32}),
|
||||
generate(logoSvg, '../public/img/logo.svg', {size: 32}),
|
||||
generate(logoSvg, '../public/img/logo.png', {size: 512}),
|
||||
generate(faviconSvg, '../public/img/favicon.svg', {size: 32}),
|
||||
generate(faviconSvg, '../public/img/favicon.png', {size: 180}),
|
||||
generate(logoSvg, '../public/img/avatar_default.png', {size: 200}),
|
||||
generate(logoSvg, '../public/img/apple-touch-icon.png', {size: 180, bg: true}),
|
||||
gitea && generate(logoSvg, '../public/img/gitea.svg', {size: 32}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ async function processFile(file, {prefix, fullName} = {}) {
|
|||
],
|
||||
});
|
||||
|
||||
await writeFile(fileURLToPath(new URL(`../public/assets/img/svg/${name}.svg`, import.meta.url)), data);
|
||||
await writeFile(fileURLToPath(new URL(`../public/img/svg/${name}.svg`, import.meta.url)), data);
|
||||
}
|
||||
|
||||
function processFiles(pattern, opts) {
|
||||
|
@ -53,13 +53,13 @@ function processFiles(pattern, opts) {
|
|||
|
||||
async function main() {
|
||||
try {
|
||||
await mkdir(fileURLToPath(new URL('../public/assets/img/svg', import.meta.url)), {recursive: true});
|
||||
await mkdir(fileURLToPath(new URL('../public/img/svg', import.meta.url)), {recursive: true});
|
||||
} catch {}
|
||||
|
||||
await Promise.all([
|
||||
...processFiles('node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}),
|
||||
...processFiles('web_src/svg/*.svg'),
|
||||
...processFiles('public/assets/img/gitea.svg', {fullName: 'gitea-gitea'}),
|
||||
...processFiles('public/img/gitea.svg', {fullName: 'gitea-gitea'}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
// Copyright 2022 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
trimPrefix = "gitea_"
|
||||
sourceFolder = "options/locales/"
|
||||
)
|
||||
|
||||
// returns list of locales, still containing the file extension!
|
||||
func generate_locale_list() []string {
|
||||
localeFiles, _ := os.ReadDir(sourceFolder)
|
||||
locales := []string{}
|
||||
for _, localeFile := range localeFiles {
|
||||
if !localeFile.IsDir() && strings.HasPrefix(localeFile.Name(), trimPrefix) {
|
||||
locales = append(locales, strings.TrimPrefix(localeFile.Name(), trimPrefix))
|
||||
}
|
||||
}
|
||||
return locales
|
||||
}
|
||||
|
||||
// replace all occurrences of Gitea with Forgejo
|
||||
func renameGiteaForgejo(filename string) []byte {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
replacements := []string{
|
||||
"Gitea", "Forgejo",
|
||||
"https://docs.gitea.com/installation/install-from-binary", "https://forgejo.org/download/#installation-from-binary",
|
||||
"https://github.com/go-gitea/gitea/tree/master/docker", "https://forgejo.org/download/#container-image",
|
||||
"https://docs.gitea.com/installation/install-from-package", "https://forgejo.org/download",
|
||||
"https://code.gitea.io/gitea", "https://forgejo.org/download",
|
||||
"code.gitea.io/gitea", "Forgejo",
|
||||
`<a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a>`, `<a href="https://codeberg.org/forgejo/forgejo/issues" target="_blank">Codeberg</a>`,
|
||||
"https://github.com/go-gitea/gitea", "https://codeberg.org/forgejo/forgejo",
|
||||
"https://blog.gitea.io", "https://forgejo.org/news",
|
||||
"https://docs.gitea.com/usage/protected-tags", "https://forgejo.org/docs/latest/user/protection/#protected-tags",
|
||||
"https://docs.gitea.com/usage/webhooks", "https://forgejo.org/docs/latest/user/webhooks/",
|
||||
}
|
||||
replacer := strings.NewReplacer(replacements...)
|
||||
replaced := make(map[string]bool, len(replacements)/2)
|
||||
count_replaced := func(original string) {
|
||||
for i := 0; i < len(replacements); i += 2 {
|
||||
if strings.Contains(original, replacements[i]) {
|
||||
replaced[replacements[i]] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out := make([]byte, 0, 1024)
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
if strings.HasPrefix(line, "license_desc=") {
|
||||
line = strings.Replace(line, "GitHub", "Forgejo", 1)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
|
||||
out = append(out, []byte("\n"+line+"\n")...)
|
||||
} else if strings.HasPrefix(line, "settings.web_hook_name_gitea") {
|
||||
out = append(out, []byte("\n"+line+"\n")...)
|
||||
out = append(out, []byte("settings.web_hook_name_forgejo = Forgejo\n")...)
|
||||
} else if strings.HasPrefix(line, "migrate.gitea.description") {
|
||||
re := regexp.MustCompile(`(.*Gitea)`)
|
||||
out = append(out, []byte(re.ReplaceAllString(line, "${1}/Forgejo")+"\n")...)
|
||||
} else {
|
||||
count_replaced(line)
|
||||
out = append(out, []byte(replacer.Replace(line)+"\n")...)
|
||||
}
|
||||
}
|
||||
file.Close()
|
||||
if strings.HasSuffix(filename, "gitea_en-US.ini") {
|
||||
for i := 0; i < len(replacements); i += 2 {
|
||||
if replaced[replacements[i]] == false {
|
||||
log.Fatalf("%s was never used to replace something in %s, it is obsolete and must be updated", replacements[i], filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func main() {
|
||||
locales := generate_locale_list()
|
||||
var err error
|
||||
var localeFile *ini.File
|
||||
for _, locale := range locales {
|
||||
giteaLocale := sourceFolder + "gitea_" + locale
|
||||
localeFile, err = ini.LoadSources(ini.LoadOptions{
|
||||
IgnoreInlineComment: true,
|
||||
}, giteaLocale, renameGiteaForgejo(giteaLocale))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = localeFile.SaveTo("options/locale/locale_" + locale)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,30 +9,30 @@ import (
|
|||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
// CmdActions represents the available actions sub-commands.
|
||||
CmdActions = &cli.Command{
|
||||
Name: "actions",
|
||||
Usage: "Manage Forgejo Actions",
|
||||
Subcommands: []*cli.Command{
|
||||
CmdActions = cli.Command{
|
||||
Name: "actions",
|
||||
Usage: "",
|
||||
Description: "Commands for managing Gitea Actions",
|
||||
Subcommands: []cli.Command{
|
||||
subcmdActionsGenRunnerToken,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdActionsGenRunnerToken = &cli.Command{
|
||||
subcmdActionsGenRunnerToken = cli.Command{
|
||||
Name: "generate-runner-token",
|
||||
Usage: "Generate a new token for a runner to use to register with the server",
|
||||
Action: runGenerateActionsRunnerToken,
|
||||
Aliases: []string{"grt"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "scope",
|
||||
Aliases: []string{"s"},
|
||||
Value: "",
|
||||
Usage: "{owner}[/{repo}] - leave empty for a global runner",
|
||||
cli.StringFlag{
|
||||
Name: "scope, s",
|
||||
Value: "",
|
||||
Usage: "{owner}[/{repo}] - leave empty for a global runner",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func runGenerateActionsRunnerToken(c *cli.Context) error {
|
|||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setting.MustInstalled()
|
||||
setting.Init(&setting.Options{})
|
||||
|
||||
scope := c.String("scope")
|
||||
|
||||
|
|
676
cmd/admin.go
676
cmd/admin.go
|
@ -5,24 +5,36 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
"code.gitea.io/gitea/services/auth/source/smtp"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
// CmdAdmin represents the available admin sub-command.
|
||||
CmdAdmin = &cli.Command{
|
||||
CmdAdmin = cli.Command{
|
||||
Name: "admin",
|
||||
Usage: "Perform common administrative operations",
|
||||
Subcommands: []*cli.Command{
|
||||
Usage: "Command line interface to perform common administrative operations",
|
||||
Subcommands: []cli.Command{
|
||||
subcmdUser,
|
||||
subcmdRepoSyncReleases,
|
||||
subcmdRegenerate,
|
||||
|
@ -31,31 +43,43 @@ var (
|
|||
},
|
||||
}
|
||||
|
||||
subcmdRepoSyncReleases = &cli.Command{
|
||||
subcmdRepoSyncReleases = cli.Command{
|
||||
Name: "repo-sync-releases",
|
||||
Usage: "Synchronize repository releases with tags",
|
||||
Action: runRepoSyncReleases,
|
||||
}
|
||||
|
||||
subcmdRegenerate = &cli.Command{
|
||||
subcmdRegenerate = cli.Command{
|
||||
Name: "regenerate",
|
||||
Usage: "Regenerate specific files",
|
||||
Subcommands: []*cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
microcmdRegenHooks,
|
||||
microcmdRegenKeys,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdAuth = &cli.Command{
|
||||
microcmdRegenHooks = cli.Command{
|
||||
Name: "hooks",
|
||||
Usage: "Regenerate git-hooks",
|
||||
Action: runRegenerateHooks,
|
||||
}
|
||||
|
||||
microcmdRegenKeys = cli.Command{
|
||||
Name: "keys",
|
||||
Usage: "Regenerate authorized_keys file",
|
||||
Action: runRegenerateKeys,
|
||||
}
|
||||
|
||||
subcmdAuth = cli.Command{
|
||||
Name: "auth",
|
||||
Usage: "Modify external auth providers",
|
||||
Subcommands: []*cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
microcmdAuthAddOauth,
|
||||
microcmdAuthUpdateOauth,
|
||||
microcmdAuthAddLdapBindDn,
|
||||
microcmdAuthUpdateLdapBindDn,
|
||||
microcmdAuthAddLdapSimpleAuth,
|
||||
microcmdAuthUpdateLdapSimpleAuth,
|
||||
cmdAuthAddLdapBindDn,
|
||||
cmdAuthUpdateLdapBindDn,
|
||||
cmdAuthAddLdapSimpleAuth,
|
||||
cmdAuthUpdateLdapSimpleAuth,
|
||||
microcmdAuthAddSMTP,
|
||||
microcmdAuthUpdateSMTP,
|
||||
microcmdAuthList,
|
||||
|
@ -63,33 +87,257 @@ var (
|
|||
},
|
||||
}
|
||||
|
||||
subcmdSendMail = &cli.Command{
|
||||
Name: "sendmail",
|
||||
Usage: "Send a message to all users",
|
||||
Action: runSendMail,
|
||||
microcmdAuthList = cli.Command{
|
||||
Name: "list",
|
||||
Usage: "List auth sources",
|
||||
Action: runListAuth,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "title",
|
||||
Usage: `a title of a message`,
|
||||
Value: "",
|
||||
cli.IntFlag{
|
||||
Name: "min-width",
|
||||
Usage: "Minimal cell width including any padding for the formatted table",
|
||||
Value: 0,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "content",
|
||||
Usage: "a content of a message",
|
||||
Value: "",
|
||||
cli.IntFlag{
|
||||
Name: "tab-width",
|
||||
Usage: "width of tab characters in formatted table (equivalent number of spaces)",
|
||||
Value: 8,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "force",
|
||||
Aliases: []string{"f"},
|
||||
Usage: "A flag to bypass a confirmation step",
|
||||
cli.IntFlag{
|
||||
Name: "padding",
|
||||
Usage: "padding added to a cell before computing its width",
|
||||
Value: 1,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "pad-char",
|
||||
Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
|
||||
Value: "\t",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "vertical-bars",
|
||||
Usage: "Set to true to print vertical bars between columns",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
idFlag = &cli.Int64Flag{
|
||||
idFlag = cli.Int64Flag{
|
||||
Name: "id",
|
||||
Usage: "ID of authentication source",
|
||||
}
|
||||
|
||||
microcmdAuthDelete = cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "Delete specific auth source",
|
||||
Flags: []cli.Flag{idFlag},
|
||||
Action: runDeleteAuth,
|
||||
}
|
||||
|
||||
oauthCLIFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "",
|
||||
Usage: "Application Name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "provider",
|
||||
Value: "",
|
||||
Usage: "OAuth2 Provider",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "key",
|
||||
Value: "",
|
||||
Usage: "Client ID (Key)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "secret",
|
||||
Value: "",
|
||||
Usage: "Client Secret",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "auto-discover-url",
|
||||
Value: "",
|
||||
Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "use-custom-urls",
|
||||
Value: "false",
|
||||
Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "custom-tenant-id",
|
||||
Value: "",
|
||||
Usage: "Use custom Tenant ID for OAuth endpoints",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "custom-auth-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "custom-token-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Token URL (option for GitLab/GitHub)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "custom-profile-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "custom-email-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Email URL (option for GitHub)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "icon-url",
|
||||
Value: "",
|
||||
Usage: "Custom icon URL for OAuth2 login source",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Set to true to skip local 2fa for users authenticated by this source",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "scopes",
|
||||
Value: nil,
|
||||
Usage: "Scopes to request when to authenticate against this OAuth2 source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "required-claim-name",
|
||||
Value: "",
|
||||
Usage: "Claim name that has to be set to allow users to login with this source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "required-claim-value",
|
||||
Value: "",
|
||||
Usage: "Claim value that has to be set to allow users to login with this source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "group-claim-name",
|
||||
Value: "",
|
||||
Usage: "Claim name providing group names for this source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "admin-group",
|
||||
Value: "",
|
||||
Usage: "Group Claim value for administrator users",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "restricted-group",
|
||||
Value: "",
|
||||
Usage: "Group Claim value for restricted users",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "group-team-map",
|
||||
Value: "",
|
||||
Usage: "JSON mapping between groups and org teams",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "group-team-map-removal",
|
||||
Usage: "Activate automatic team membership removal depending on groups",
|
||||
},
|
||||
}
|
||||
|
||||
microcmdAuthUpdateOauth = cli.Command{
|
||||
Name: "update-oauth",
|
||||
Usage: "Update existing Oauth authentication source",
|
||||
Action: runUpdateOauth,
|
||||
Flags: append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
|
||||
}
|
||||
|
||||
microcmdAuthAddOauth = cli.Command{
|
||||
Name: "add-oauth",
|
||||
Usage: "Add new Oauth authentication source",
|
||||
Action: runAddOauth,
|
||||
Flags: oauthCLIFlags,
|
||||
}
|
||||
|
||||
subcmdSendMail = cli.Command{
|
||||
Name: "sendmail",
|
||||
Usage: "Send a message to all users",
|
||||
Action: runSendMail,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "title",
|
||||
Usage: `a title of a message`,
|
||||
Value: "",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "content",
|
||||
Usage: "a content of a message",
|
||||
Value: "",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "force,f",
|
||||
Usage: "A flag to bypass a confirmation step",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
smtpCLIFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "",
|
||||
Usage: "Application Name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "auth-type",
|
||||
Value: "PLAIN",
|
||||
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "host",
|
||||
Value: "",
|
||||
Usage: "SMTP Host",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "port",
|
||||
Usage: "SMTP Port",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "force-smtps",
|
||||
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "skip-verify",
|
||||
Usage: "Skip TLS verify.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "helo-hostname",
|
||||
Value: "",
|
||||
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "disable-helo",
|
||||
Usage: "Disable SMTP helo.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "allowed-domains",
|
||||
Value: "",
|
||||
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Skip 2FA to log on.",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "active",
|
||||
Usage: "This Authentication Source is Activated.",
|
||||
},
|
||||
}
|
||||
|
||||
microcmdAuthAddSMTP = cli.Command{
|
||||
Name: "add-smtp",
|
||||
Usage: "Add new SMTP authentication source",
|
||||
Action: runAddSMTP,
|
||||
Flags: smtpCLIFlags,
|
||||
}
|
||||
|
||||
microcmdAuthUpdateSMTP = cli.Command{
|
||||
Name: "update-smtp",
|
||||
Usage: "Update existing SMTP authentication source",
|
||||
Action: runUpdateSMTP,
|
||||
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
|
||||
}
|
||||
)
|
||||
|
||||
func runRepoSyncReleases(_ *cli.Context) error {
|
||||
|
@ -100,10 +348,6 @@ func runRepoSyncReleases(_ *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := git.InitSimple(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Trace("Synchronizing repository releases (this may take a while)")
|
||||
for page := 1; ; page++ {
|
||||
repos, count, err := repo_model.SearchRepositoryByName(ctx, &repo_model.SearchRepoOptions{
|
||||
|
@ -128,19 +372,19 @@ func runRepoSyncReleases(_ *cli.Context) error {
|
|||
continue
|
||||
}
|
||||
|
||||
oldnum, err := getReleaseCount(ctx, repo.ID)
|
||||
oldnum, err := getReleaseCount(repo.ID)
|
||||
if err != nil {
|
||||
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
||||
}
|
||||
log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
|
||||
|
||||
if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
|
||||
if err = repo_module.SyncReleasesWithTags(repo, gitRepo); err != nil {
|
||||
log.Warn(" SyncReleasesWithTags: %v", err)
|
||||
gitRepo.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
count, err = getReleaseCount(ctx, repo.ID)
|
||||
count, err = getReleaseCount(repo.ID)
|
||||
if err != nil {
|
||||
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
||||
gitRepo.Close()
|
||||
|
@ -156,12 +400,360 @@ func runRepoSyncReleases(_ *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getReleaseCount(ctx context.Context, id int64) (int64, error) {
|
||||
return db.Count[repo_model.Release](
|
||||
ctx,
|
||||
func getReleaseCount(id int64) (int64, error) {
|
||||
return repo_model.GetReleaseCountByRepoID(
|
||||
db.DefaultContext,
|
||||
id,
|
||||
repo_model.FindReleasesOptions{
|
||||
RepoID: id,
|
||||
IncludeTags: true,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func runRegenerateHooks(_ *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
||||
}
|
||||
|
||||
func runRegenerateKeys(_ *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return asymkey_model.RewriteAllPublicKeys()
|
||||
}
|
||||
|
||||
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
|
||||
var customURLMapping *oauth2.CustomURLMapping
|
||||
if c.IsSet("use-custom-urls") {
|
||||
customURLMapping = &oauth2.CustomURLMapping{
|
||||
TokenURL: c.String("custom-token-url"),
|
||||
AuthURL: c.String("custom-auth-url"),
|
||||
ProfileURL: c.String("custom-profile-url"),
|
||||
EmailURL: c.String("custom-email-url"),
|
||||
Tenant: c.String("custom-tenant-id"),
|
||||
}
|
||||
} else {
|
||||
customURLMapping = nil
|
||||
}
|
||||
return &oauth2.Source{
|
||||
Provider: c.String("provider"),
|
||||
ClientID: c.String("key"),
|
||||
ClientSecret: c.String("secret"),
|
||||
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
|
||||
CustomURLMapping: customURLMapping,
|
||||
IconURL: c.String("icon-url"),
|
||||
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
|
||||
Scopes: c.StringSlice("scopes"),
|
||||
RequiredClaimName: c.String("required-claim-name"),
|
||||
RequiredClaimValue: c.String("required-claim-value"),
|
||||
GroupClaimName: c.String("group-claim-name"),
|
||||
AdminGroup: c.String("admin-group"),
|
||||
RestrictedGroup: c.String("restricted-group"),
|
||||
GroupTeamMap: c.String("group-team-map"),
|
||||
GroupTeamMapRemoval: c.Bool("group-team-map-removal"),
|
||||
}
|
||||
}
|
||||
|
||||
func runAddOauth(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config := parseOAuth2Config(c)
|
||||
if config.Provider == "openidConnect" {
|
||||
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
|
||||
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
|
||||
return fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", config.OpenIDConnectAutoDiscoveryURL)
|
||||
}
|
||||
}
|
||||
|
||||
return auth_model.CreateSource(&auth_model.Source{
|
||||
Type: auth_model.OAuth2,
|
||||
Name: c.String("name"),
|
||||
IsActive: true,
|
||||
Cfg: config,
|
||||
})
|
||||
}
|
||||
|
||||
func runUpdateOauth(c *cli.Context) error {
|
||||
if !c.IsSet("id") {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oAuth2Config := source.Cfg.(*oauth2.Source)
|
||||
|
||||
if c.IsSet("name") {
|
||||
source.Name = c.String("name")
|
||||
}
|
||||
|
||||
if c.IsSet("provider") {
|
||||
oAuth2Config.Provider = c.String("provider")
|
||||
}
|
||||
|
||||
if c.IsSet("key") {
|
||||
oAuth2Config.ClientID = c.String("key")
|
||||
}
|
||||
|
||||
if c.IsSet("secret") {
|
||||
oAuth2Config.ClientSecret = c.String("secret")
|
||||
}
|
||||
|
||||
if c.IsSet("auto-discover-url") {
|
||||
oAuth2Config.OpenIDConnectAutoDiscoveryURL = c.String("auto-discover-url")
|
||||
}
|
||||
|
||||
if c.IsSet("icon-url") {
|
||||
oAuth2Config.IconURL = c.String("icon-url")
|
||||
}
|
||||
|
||||
if c.IsSet("scopes") {
|
||||
oAuth2Config.Scopes = c.StringSlice("scopes")
|
||||
}
|
||||
|
||||
if c.IsSet("required-claim-name") {
|
||||
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
|
||||
}
|
||||
if c.IsSet("required-claim-value") {
|
||||
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
|
||||
}
|
||||
|
||||
if c.IsSet("group-claim-name") {
|
||||
oAuth2Config.GroupClaimName = c.String("group-claim-name")
|
||||
}
|
||||
if c.IsSet("admin-group") {
|
||||
oAuth2Config.AdminGroup = c.String("admin-group")
|
||||
}
|
||||
if c.IsSet("restricted-group") {
|
||||
oAuth2Config.RestrictedGroup = c.String("restricted-group")
|
||||
}
|
||||
if c.IsSet("group-team-map") {
|
||||
oAuth2Config.GroupTeamMap = c.String("group-team-map")
|
||||
}
|
||||
if c.IsSet("group-team-map-removal") {
|
||||
oAuth2Config.GroupTeamMapRemoval = c.Bool("group-team-map-removal")
|
||||
}
|
||||
|
||||
// update custom URL mapping
|
||||
customURLMapping := &oauth2.CustomURLMapping{}
|
||||
|
||||
if oAuth2Config.CustomURLMapping != nil {
|
||||
customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL
|
||||
customURLMapping.AuthURL = oAuth2Config.CustomURLMapping.AuthURL
|
||||
customURLMapping.ProfileURL = oAuth2Config.CustomURLMapping.ProfileURL
|
||||
customURLMapping.EmailURL = oAuth2Config.CustomURLMapping.EmailURL
|
||||
customURLMapping.Tenant = oAuth2Config.CustomURLMapping.Tenant
|
||||
}
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-token-url") {
|
||||
customURLMapping.TokenURL = c.String("custom-token-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-auth-url") {
|
||||
customURLMapping.AuthURL = c.String("custom-auth-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-profile-url") {
|
||||
customURLMapping.ProfileURL = c.String("custom-profile-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-email-url") {
|
||||
customURLMapping.EmailURL = c.String("custom-email-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-tenant-id") {
|
||||
customURLMapping.Tenant = c.String("custom-tenant-id")
|
||||
}
|
||||
|
||||
oAuth2Config.CustomURLMapping = customURLMapping
|
||||
source.Cfg = oAuth2Config
|
||||
|
||||
return auth_model.UpdateSource(source)
|
||||
}
|
||||
|
||||
func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
|
||||
if c.IsSet("auth-type") {
|
||||
conf.Auth = c.String("auth-type")
|
||||
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
|
||||
if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
|
||||
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
|
||||
}
|
||||
conf.Auth = c.String("auth-type")
|
||||
}
|
||||
if c.IsSet("host") {
|
||||
conf.Host = c.String("host")
|
||||
}
|
||||
if c.IsSet("port") {
|
||||
conf.Port = c.Int("port")
|
||||
}
|
||||
if c.IsSet("allowed-domains") {
|
||||
conf.AllowedDomains = c.String("allowed-domains")
|
||||
}
|
||||
if c.IsSet("force-smtps") {
|
||||
conf.ForceSMTPS = c.BoolT("force-smtps")
|
||||
}
|
||||
if c.IsSet("skip-verify") {
|
||||
conf.SkipVerify = c.BoolT("skip-verify")
|
||||
}
|
||||
if c.IsSet("helo-hostname") {
|
||||
conf.HeloHostname = c.String("helo-hostname")
|
||||
}
|
||||
if c.IsSet("disable-helo") {
|
||||
conf.DisableHelo = c.BoolT("disable-helo")
|
||||
}
|
||||
if c.IsSet("skip-local-2fa") {
|
||||
conf.SkipLocalTwoFA = c.BoolT("skip-local-2fa")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runAddSMTP(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.IsSet("name") || len(c.String("name")) == 0 {
|
||||
return errors.New("name must be set")
|
||||
}
|
||||
if !c.IsSet("host") || len(c.String("host")) == 0 {
|
||||
return errors.New("host must be set")
|
||||
}
|
||||
if !c.IsSet("port") {
|
||||
return errors.New("port must be set")
|
||||
}
|
||||
active := true
|
||||
if c.IsSet("active") {
|
||||
active = c.BoolT("active")
|
||||
}
|
||||
|
||||
var smtpConfig smtp.Source
|
||||
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If not set default to PLAIN
|
||||
if len(smtpConfig.Auth) == 0 {
|
||||
smtpConfig.Auth = "PLAIN"
|
||||
}
|
||||
|
||||
return auth_model.CreateSource(&auth_model.Source{
|
||||
Type: auth_model.SMTP,
|
||||
Name: c.String("name"),
|
||||
IsActive: active,
|
||||
Cfg: &smtpConfig,
|
||||
})
|
||||
}
|
||||
|
||||
func runUpdateSMTP(c *cli.Context) error {
|
||||
if !c.IsSet("id") {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
smtpConfig := source.Cfg.(*smtp.Source)
|
||||
|
||||
if err := parseSMTPConfig(c, smtpConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.IsSet("name") {
|
||||
source.Name = c.String("name")
|
||||
}
|
||||
|
||||
if c.IsSet("active") {
|
||||
source.IsActive = c.BoolT("active")
|
||||
}
|
||||
|
||||
source.Cfg = smtpConfig
|
||||
|
||||
return auth_model.UpdateSource(source)
|
||||
}
|
||||
|
||||
func runListAuth(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authSources, err := auth_model.Sources()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
flags := tabwriter.AlignRight
|
||||
if c.Bool("vertical-bars") {
|
||||
flags |= tabwriter.Debug
|
||||
}
|
||||
|
||||
padChar := byte('\t')
|
||||
if len(c.String("pad-char")) > 0 {
|
||||
padChar = c.String("pad-char")[0]
|
||||
}
|
||||
|
||||
// loop through each source and print
|
||||
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
|
||||
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
|
||||
for _, source := range authSources {
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, source.Type.String(), source.IsActive)
|
||||
}
|
||||
w.Flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runDeleteAuth(c *cli.Context) error {
|
||||
if !c.IsSet("id") {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return auth_service.DeleteSource(source)
|
||||
}
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
microcmdAuthDelete = &cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "Delete specific auth source",
|
||||
Flags: []cli.Flag{idFlag},
|
||||
Action: runDeleteAuth,
|
||||
}
|
||||
microcmdAuthList = &cli.Command{
|
||||
Name: "list",
|
||||
Usage: "List auth sources",
|
||||
Action: runListAuth,
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "min-width",
|
||||
Usage: "Minimal cell width including any padding for the formatted table",
|
||||
Value: 0,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "tab-width",
|
||||
Usage: "width of tab characters in formatted table (equivalent number of spaces)",
|
||||
Value: 8,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "padding",
|
||||
Usage: "padding added to a cell before computing its width",
|
||||
Value: 1,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "pad-char",
|
||||
Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
|
||||
Value: "\t",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "vertical-bars",
|
||||
Usage: "Set to true to print vertical bars between columns",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func runListAuth(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authSources, err := db.Find[auth_model.Source](ctx, auth_model.FindSourcesOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
flags := tabwriter.AlignRight
|
||||
if c.Bool("vertical-bars") {
|
||||
flags |= tabwriter.Debug
|
||||
}
|
||||
|
||||
padChar := byte('\t')
|
||||
if len(c.String("pad-char")) > 0 {
|
||||
padChar = c.String("pad-char")[0]
|
||||
}
|
||||
|
||||
// loop through each source and print
|
||||
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
|
||||
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
|
||||
for _, source := range authSources {
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, source.Type.String(), source.IsActive)
|
||||
}
|
||||
w.Flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runDeleteAuth(c *cli.Context) error {
|
||||
if !c.IsSet("id") {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return auth_service.DeleteSource(ctx, source)
|
||||
}
|
|
@ -11,131 +11,131 @@ import (
|
|||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/services/auth/source/ldap"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
type (
|
||||
authService struct {
|
||||
initDB func(ctx context.Context) error
|
||||
createAuthSource func(context.Context, *auth.Source) error
|
||||
updateAuthSource func(context.Context, *auth.Source) error
|
||||
getAuthSourceByID func(ctx context.Context, id int64) (*auth.Source, error)
|
||||
createAuthSource func(*auth.Source) error
|
||||
updateAuthSource func(*auth.Source) error
|
||||
getAuthSourceByID func(id int64) (*auth.Source, error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
commonLdapCLIFlags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Usage: "Authentication name.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "not-active",
|
||||
Usage: "Deactivate the authentication source.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "active",
|
||||
Usage: "Activate the authentication source.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "security-protocol",
|
||||
Usage: "Security protocol name.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "skip-tls-verify",
|
||||
Usage: "Disable TLS verification.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "host",
|
||||
Usage: "The address where the LDAP server can be reached.",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
cli.IntFlag{
|
||||
Name: "port",
|
||||
Usage: "The port to use when connecting to the LDAP server.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "user-search-base",
|
||||
Usage: "The LDAP base at which user accounts will be searched for.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "user-filter",
|
||||
Usage: "An LDAP filter declaring how to find the user record that is attempting to authenticate.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "admin-filter",
|
||||
Usage: "An LDAP filter specifying if a user should be given administrator privileges.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "restricted-filter",
|
||||
Usage: "An LDAP filter specifying if a user should be given restricted status.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "allow-deactivate-all",
|
||||
Usage: "Allow empty search results to deactivate all users.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "username-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user name.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "firstname-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user’s first name.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "surname-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user’s surname.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "email-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user’s email address.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "public-ssh-key-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user’s public ssh key.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Set to true to skip local 2fa for users authenticated by this source",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "avatar-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user’s avatar.",
|
||||
},
|
||||
}
|
||||
|
||||
ldapBindDnCLIFlags = append(commonLdapCLIFlags,
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "bind-dn",
|
||||
Usage: "The DN to bind to the LDAP server with when searching for the user.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "bind-password",
|
||||
Usage: "The password for the Bind DN, if any.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "attributes-in-bind",
|
||||
Usage: "Fetch attributes in bind DN context.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "synchronize-users",
|
||||
Usage: "Enable user synchronization.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "disable-synchronize-users",
|
||||
Usage: "Disable user synchronization.",
|
||||
},
|
||||
&cli.UintFlag{
|
||||
cli.UintFlag{
|
||||
Name: "page-size",
|
||||
Usage: "Search page size.",
|
||||
})
|
||||
|
||||
ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "user-dn",
|
||||
Usage: "The user's DN.",
|
||||
Usage: "The user’s DN.",
|
||||
})
|
||||
|
||||
microcmdAuthAddLdapBindDn = &cli.Command{
|
||||
cmdAuthAddLdapBindDn = cli.Command{
|
||||
Name: "add-ldap",
|
||||
Usage: "Add new LDAP (via Bind DN) authentication source",
|
||||
Action: func(c *cli.Context) error {
|
||||
|
@ -144,7 +144,7 @@ var (
|
|||
Flags: ldapBindDnCLIFlags,
|
||||
}
|
||||
|
||||
microcmdAuthUpdateLdapBindDn = &cli.Command{
|
||||
cmdAuthUpdateLdapBindDn = cli.Command{
|
||||
Name: "update-ldap",
|
||||
Usage: "Update existing LDAP (via Bind DN) authentication source",
|
||||
Action: func(c *cli.Context) error {
|
||||
|
@ -153,7 +153,7 @@ var (
|
|||
Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
|
||||
}
|
||||
|
||||
microcmdAuthAddLdapSimpleAuth = &cli.Command{
|
||||
cmdAuthAddLdapSimpleAuth = cli.Command{
|
||||
Name: "add-ldap-simple",
|
||||
Usage: "Add new LDAP (simple auth) authentication source",
|
||||
Action: func(c *cli.Context) error {
|
||||
|
@ -162,7 +162,7 @@ var (
|
|||
Flags: ldapSimpleAuthCLIFlags,
|
||||
}
|
||||
|
||||
microcmdAuthUpdateLdapSimpleAuth = &cli.Command{
|
||||
cmdAuthUpdateLdapSimpleAuth = cli.Command{
|
||||
Name: "update-ldap-simple",
|
||||
Usage: "Update existing LDAP (simple auth) authentication source",
|
||||
Action: func(c *cli.Context) error {
|
||||
|
@ -289,12 +289,12 @@ func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
|
|||
|
||||
// getAuthSource gets the login source by its id defined in the command line flags.
|
||||
// It returns an error if the id is not set, does not match any source or if the source is not of expected type.
|
||||
func (a *authService) getAuthSource(ctx context.Context, c *cli.Context, authType auth.Type) (*auth.Source, error) {
|
||||
func (a *authService) getAuthSource(c *cli.Context, authType auth.Type) (*auth.Source, error) {
|
||||
if err := argsSet(c, "id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authSource, err := a.getAuthSourceByID(ctx, c.Int64("id"))
|
||||
authSource, err := a.getAuthSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ func (a *authService) addLdapBindDn(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return a.createAuthSource(ctx, authSource)
|
||||
return a.createAuthSource(authSource)
|
||||
}
|
||||
|
||||
// updateLdapBindDn updates a new LDAP via Bind DN authentication source.
|
||||
|
@ -344,7 +344,7 @@ func (a *authService) updateLdapBindDn(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
authSource, err := a.getAuthSource(ctx, c, auth.LDAP)
|
||||
authSource, err := a.getAuthSource(c, auth.LDAP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ func (a *authService) updateLdapBindDn(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return a.updateAuthSource(ctx, authSource)
|
||||
return a.updateAuthSource(authSource)
|
||||
}
|
||||
|
||||
// addLdapSimpleAuth adds a new LDAP (simple auth) authentication source.
|
||||
|
@ -383,7 +383,7 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return a.createAuthSource(ctx, authSource)
|
||||
return a.createAuthSource(authSource)
|
||||
}
|
||||
|
||||
// updateLdapBindDn updates a new LDAP (simple auth) authentication source.
|
||||
|
@ -395,7 +395,7 @@ func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
authSource, err := a.getAuthSource(ctx, c, auth.DLDAP)
|
||||
authSource, err := a.getAuthSource(c, auth.DLDAP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -405,5 +405,5 @@ func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return a.updateAuthSource(ctx, authSource)
|
||||
return a.updateAuthSource(authSource)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"code.gitea.io/gitea/services/auth/source/ldap"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func TestAddLdapBindDn(t *testing.T) {
|
||||
|
@ -210,15 +210,15 @@ func TestAddLdapBindDn(t *testing.T) {
|
|||
initDB: func(context.Context) error {
|
||||
return nil
|
||||
},
|
||||
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
createAuthSource: func(authSource *auth.Source) error {
|
||||
createdAuthSource = authSource
|
||||
return nil
|
||||
},
|
||||
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
updateAuthSource: func(authSource *auth.Source) error {
|
||||
assert.FailNow(t, "case %d: should not call updateAuthSource", n)
|
||||
return nil
|
||||
},
|
||||
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
|
||||
getAuthSourceByID: func(id int64) (*auth.Source, error) {
|
||||
assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
|
||||
return nil, nil
|
||||
},
|
||||
|
@ -226,7 +226,7 @@ func TestAddLdapBindDn(t *testing.T) {
|
|||
|
||||
// Create a copy of command to test
|
||||
app := cli.NewApp()
|
||||
app.Flags = microcmdAuthAddLdapBindDn.Flags
|
||||
app.Flags = cmdAuthAddLdapBindDn.Flags
|
||||
app.Action = service.addLdapBindDn
|
||||
|
||||
// Run it
|
||||
|
@ -441,15 +441,15 @@ func TestAddLdapSimpleAuth(t *testing.T) {
|
|||
initDB: func(context.Context) error {
|
||||
return nil
|
||||
},
|
||||
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
createAuthSource: func(authSource *auth.Source) error {
|
||||
createdAuthSource = authSource
|
||||
return nil
|
||||
},
|
||||
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
updateAuthSource: func(authSource *auth.Source) error {
|
||||
assert.FailNow(t, "case %d: should not call updateAuthSource", n)
|
||||
return nil
|
||||
},
|
||||
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
|
||||
getAuthSourceByID: func(id int64) (*auth.Source, error) {
|
||||
assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
|
||||
return nil, nil
|
||||
},
|
||||
|
@ -457,7 +457,7 @@ func TestAddLdapSimpleAuth(t *testing.T) {
|
|||
|
||||
// Create a copy of command to test
|
||||
app := cli.NewApp()
|
||||
app.Flags = microcmdAuthAddLdapSimpleAuth.Flags
|
||||
app.Flags = cmdAuthAddLdapSimpleAuth.Flags
|
||||
app.Action = service.addLdapSimpleAuth
|
||||
|
||||
// Run it
|
||||
|
@ -896,15 +896,15 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
|||
initDB: func(context.Context) error {
|
||||
return nil
|
||||
},
|
||||
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
createAuthSource: func(authSource *auth.Source) error {
|
||||
assert.FailNow(t, "case %d: should not call createAuthSource", n)
|
||||
return nil
|
||||
},
|
||||
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
updateAuthSource: func(authSource *auth.Source) error {
|
||||
updatedAuthSource = authSource
|
||||
return nil
|
||||
},
|
||||
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
|
||||
getAuthSourceByID: func(id int64) (*auth.Source, error) {
|
||||
if c.id != 0 {
|
||||
assert.Equal(t, c.id, id, "case %d: wrong id", n)
|
||||
}
|
||||
|
@ -920,7 +920,7 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
|||
|
||||
// Create a copy of command to test
|
||||
app := cli.NewApp()
|
||||
app.Flags = microcmdAuthUpdateLdapBindDn.Flags
|
||||
app.Flags = cmdAuthUpdateLdapBindDn.Flags
|
||||
app.Action = service.updateLdapBindDn
|
||||
|
||||
// Run it
|
||||
|
@ -1286,15 +1286,15 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
|||
initDB: func(context.Context) error {
|
||||
return nil
|
||||
},
|
||||
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
createAuthSource: func(authSource *auth.Source) error {
|
||||
assert.FailNow(t, "case %d: should not call createAuthSource", n)
|
||||
return nil
|
||||
},
|
||||
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
||||
updateAuthSource: func(authSource *auth.Source) error {
|
||||
updatedAuthSource = authSource
|
||||
return nil
|
||||
},
|
||||
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
|
||||
getAuthSourceByID: func(id int64) (*auth.Source, error) {
|
||||
if c.id != 0 {
|
||||
assert.Equal(t, c.id, id, "case %d: wrong id", n)
|
||||
}
|
||||
|
@ -1310,7 +1310,7 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
|||
|
||||
// Create a copy of command to test
|
||||
app := cli.NewApp()
|
||||
app.Flags = microcmdAuthUpdateLdapSimpleAuth.Flags
|
||||
app.Flags = cmdAuthUpdateLdapSimpleAuth.Flags
|
||||
app.Action = service.updateLdapSimpleAuth
|
||||
|
||||
// Run it
|
||||
|
|
|
@ -1,298 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
oauthCLIFlags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "",
|
||||
Usage: "Application Name",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "provider",
|
||||
Value: "",
|
||||
Usage: "OAuth2 Provider",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "key",
|
||||
Value: "",
|
||||
Usage: "Client ID (Key)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "secret",
|
||||
Value: "",
|
||||
Usage: "Client Secret",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "auto-discover-url",
|
||||
Value: "",
|
||||
Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "use-custom-urls",
|
||||
Value: "false",
|
||||
Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "custom-tenant-id",
|
||||
Value: "",
|
||||
Usage: "Use custom Tenant ID for OAuth endpoints",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "custom-auth-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "custom-token-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Token URL (option for GitLab/GitHub)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "custom-profile-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "custom-email-url",
|
||||
Value: "",
|
||||
Usage: "Use a custom Email URL (option for GitHub)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "icon-url",
|
||||
Value: "",
|
||||
Usage: "Custom icon URL for OAuth2 login source",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Set to true to skip local 2fa for users authenticated by this source",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "scopes",
|
||||
Value: nil,
|
||||
Usage: "Scopes to request when to authenticate against this OAuth2 source",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "required-claim-name",
|
||||
Value: "",
|
||||
Usage: "Claim name that has to be set to allow users to login with this source",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "required-claim-value",
|
||||
Value: "",
|
||||
Usage: "Claim value that has to be set to allow users to login with this source",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "group-claim-name",
|
||||
Value: "",
|
||||
Usage: "Claim name providing group names for this source",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "admin-group",
|
||||
Value: "",
|
||||
Usage: "Group Claim value for administrator users",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "restricted-group",
|
||||
Value: "",
|
||||
Usage: "Group Claim value for restricted users",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "group-team-map",
|
||||
Value: "",
|
||||
Usage: "JSON mapping between groups and org teams",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "group-team-map-removal",
|
||||
Usage: "Activate automatic team membership removal depending on groups",
|
||||
},
|
||||
}
|
||||
|
||||
microcmdAuthAddOauth = &cli.Command{
|
||||
Name: "add-oauth",
|
||||
Usage: "Add new Oauth authentication source",
|
||||
Action: runAddOauth,
|
||||
Flags: oauthCLIFlags,
|
||||
}
|
||||
|
||||
microcmdAuthUpdateOauth = &cli.Command{
|
||||
Name: "update-oauth",
|
||||
Usage: "Update existing Oauth authentication source",
|
||||
Action: runUpdateOauth,
|
||||
Flags: append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
|
||||
}
|
||||
)
|
||||
|
||||
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
|
||||
var customURLMapping *oauth2.CustomURLMapping
|
||||
if c.IsSet("use-custom-urls") {
|
||||
customURLMapping = &oauth2.CustomURLMapping{
|
||||
TokenURL: c.String("custom-token-url"),
|
||||
AuthURL: c.String("custom-auth-url"),
|
||||
ProfileURL: c.String("custom-profile-url"),
|
||||
EmailURL: c.String("custom-email-url"),
|
||||
Tenant: c.String("custom-tenant-id"),
|
||||
}
|
||||
} else {
|
||||
customURLMapping = nil
|
||||
}
|
||||
return &oauth2.Source{
|
||||
Provider: c.String("provider"),
|
||||
ClientID: c.String("key"),
|
||||
ClientSecret: c.String("secret"),
|
||||
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
|
||||
CustomURLMapping: customURLMapping,
|
||||
IconURL: c.String("icon-url"),
|
||||
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
|
||||
Scopes: c.StringSlice("scopes"),
|
||||
RequiredClaimName: c.String("required-claim-name"),
|
||||
RequiredClaimValue: c.String("required-claim-value"),
|
||||
GroupClaimName: c.String("group-claim-name"),
|
||||
AdminGroup: c.String("admin-group"),
|
||||
RestrictedGroup: c.String("restricted-group"),
|
||||
GroupTeamMap: c.String("group-team-map"),
|
||||
GroupTeamMapRemoval: c.Bool("group-team-map-removal"),
|
||||
}
|
||||
}
|
||||
|
||||
func runAddOauth(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config := parseOAuth2Config(c)
|
||||
if config.Provider == "openidConnect" {
|
||||
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
|
||||
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
|
||||
return fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", config.OpenIDConnectAutoDiscoveryURL)
|
||||
}
|
||||
}
|
||||
|
||||
return auth_model.CreateSource(ctx, &auth_model.Source{
|
||||
Type: auth_model.OAuth2,
|
||||
Name: c.String("name"),
|
||||
IsActive: true,
|
||||
Cfg: config,
|
||||
})
|
||||
}
|
||||
|
||||
func runUpdateOauth(c *cli.Context) error {
|
||||
if !c.IsSet("id") {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oAuth2Config := source.Cfg.(*oauth2.Source)
|
||||
|
||||
if c.IsSet("name") {
|
||||
source.Name = c.String("name")
|
||||
}
|
||||
|
||||
if c.IsSet("provider") {
|
||||
oAuth2Config.Provider = c.String("provider")
|
||||
}
|
||||
|
||||
if c.IsSet("key") {
|
||||
oAuth2Config.ClientID = c.String("key")
|
||||
}
|
||||
|
||||
if c.IsSet("secret") {
|
||||
oAuth2Config.ClientSecret = c.String("secret")
|
||||
}
|
||||
|
||||
if c.IsSet("auto-discover-url") {
|
||||
oAuth2Config.OpenIDConnectAutoDiscoveryURL = c.String("auto-discover-url")
|
||||
}
|
||||
|
||||
if c.IsSet("icon-url") {
|
||||
oAuth2Config.IconURL = c.String("icon-url")
|
||||
}
|
||||
|
||||
if c.IsSet("scopes") {
|
||||
oAuth2Config.Scopes = c.StringSlice("scopes")
|
||||
}
|
||||
|
||||
if c.IsSet("required-claim-name") {
|
||||
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
|
||||
}
|
||||
if c.IsSet("required-claim-value") {
|
||||
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
|
||||
}
|
||||
|
||||
if c.IsSet("group-claim-name") {
|
||||
oAuth2Config.GroupClaimName = c.String("group-claim-name")
|
||||
}
|
||||
if c.IsSet("admin-group") {
|
||||
oAuth2Config.AdminGroup = c.String("admin-group")
|
||||
}
|
||||
if c.IsSet("restricted-group") {
|
||||
oAuth2Config.RestrictedGroup = c.String("restricted-group")
|
||||
}
|
||||
if c.IsSet("group-team-map") {
|
||||
oAuth2Config.GroupTeamMap = c.String("group-team-map")
|
||||
}
|
||||
if c.IsSet("group-team-map-removal") {
|
||||
oAuth2Config.GroupTeamMapRemoval = c.Bool("group-team-map-removal")
|
||||
}
|
||||
|
||||
// update custom URL mapping
|
||||
customURLMapping := &oauth2.CustomURLMapping{}
|
||||
|
||||
if oAuth2Config.CustomURLMapping != nil {
|
||||
customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL
|
||||
customURLMapping.AuthURL = oAuth2Config.CustomURLMapping.AuthURL
|
||||
customURLMapping.ProfileURL = oAuth2Config.CustomURLMapping.ProfileURL
|
||||
customURLMapping.EmailURL = oAuth2Config.CustomURLMapping.EmailURL
|
||||
customURLMapping.Tenant = oAuth2Config.CustomURLMapping.Tenant
|
||||
}
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-token-url") {
|
||||
customURLMapping.TokenURL = c.String("custom-token-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-auth-url") {
|
||||
customURLMapping.AuthURL = c.String("custom-auth-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-profile-url") {
|
||||
customURLMapping.ProfileURL = c.String("custom-profile-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-email-url") {
|
||||
customURLMapping.EmailURL = c.String("custom-email-url")
|
||||
}
|
||||
|
||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-tenant-id") {
|
||||
customURLMapping.Tenant = c.String("custom-tenant-id")
|
||||
}
|
||||
|
||||
oAuth2Config.CustomURLMapping = customURLMapping
|
||||
source.Cfg = oAuth2Config
|
||||
|
||||
return auth_model.UpdateSource(ctx, source)
|
||||
}
|
|
@ -1,201 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/auth/source/smtp"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
smtpCLIFlags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "",
|
||||
Usage: "Application Name",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "auth-type",
|
||||
Value: "PLAIN",
|
||||
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "host",
|
||||
Value: "",
|
||||
Usage: "SMTP Host",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "port",
|
||||
Usage: "SMTP Port",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "force-smtps",
|
||||
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
|
||||
Value: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "skip-verify",
|
||||
Usage: "Skip TLS verify.",
|
||||
Value: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "helo-hostname",
|
||||
Value: "",
|
||||
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "disable-helo",
|
||||
Usage: "Disable SMTP helo.",
|
||||
Value: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "allowed-domains",
|
||||
Value: "",
|
||||
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Skip 2FA to log on.",
|
||||
Value: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "active",
|
||||
Usage: "This Authentication Source is Activated.",
|
||||
Value: true,
|
||||
},
|
||||
}
|
||||
|
||||
microcmdAuthAddSMTP = &cli.Command{
|
||||
Name: "add-smtp",
|
||||
Usage: "Add new SMTP authentication source",
|
||||
Action: runAddSMTP,
|
||||
Flags: smtpCLIFlags,
|
||||
}
|
||||
|
||||
microcmdAuthUpdateSMTP = &cli.Command{
|
||||
Name: "update-smtp",
|
||||
Usage: "Update existing SMTP authentication source",
|
||||
Action: runUpdateSMTP,
|
||||
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
|
||||
}
|
||||
)
|
||||
|
||||
func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
|
||||
if c.IsSet("auth-type") {
|
||||
conf.Auth = c.String("auth-type")
|
||||
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
|
||||
if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
|
||||
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
|
||||
}
|
||||
conf.Auth = c.String("auth-type")
|
||||
}
|
||||
if c.IsSet("host") {
|
||||
conf.Host = c.String("host")
|
||||
}
|
||||
if c.IsSet("port") {
|
||||
conf.Port = c.Int("port")
|
||||
}
|
||||
if c.IsSet("allowed-domains") {
|
||||
conf.AllowedDomains = c.String("allowed-domains")
|
||||
}
|
||||
if c.IsSet("force-smtps") {
|
||||
conf.ForceSMTPS = c.Bool("force-smtps")
|
||||
}
|
||||
if c.IsSet("skip-verify") {
|
||||
conf.SkipVerify = c.Bool("skip-verify")
|
||||
}
|
||||
if c.IsSet("helo-hostname") {
|
||||
conf.HeloHostname = c.String("helo-hostname")
|
||||
}
|
||||
if c.IsSet("disable-helo") {
|
||||
conf.DisableHelo = c.Bool("disable-helo")
|
||||
}
|
||||
if c.IsSet("skip-local-2fa") {
|
||||
conf.SkipLocalTwoFA = c.Bool("skip-local-2fa")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runAddSMTP(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.IsSet("name") || len(c.String("name")) == 0 {
|
||||
return errors.New("name must be set")
|
||||
}
|
||||
if !c.IsSet("host") || len(c.String("host")) == 0 {
|
||||
return errors.New("host must be set")
|
||||
}
|
||||
if !c.IsSet("port") {
|
||||
return errors.New("port must be set")
|
||||
}
|
||||
active := true
|
||||
if c.IsSet("active") {
|
||||
active = c.Bool("active")
|
||||
}
|
||||
|
||||
var smtpConfig smtp.Source
|
||||
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If not set default to PLAIN
|
||||
if len(smtpConfig.Auth) == 0 {
|
||||
smtpConfig.Auth = "PLAIN"
|
||||
}
|
||||
|
||||
return auth_model.CreateSource(ctx, &auth_model.Source{
|
||||
Type: auth_model.SMTP,
|
||||
Name: c.String("name"),
|
||||
IsActive: active,
|
||||
Cfg: &smtpConfig,
|
||||
})
|
||||
}
|
||||
|
||||
func runUpdateSMTP(c *cli.Context) error {
|
||||
if !c.IsSet("id") {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
smtpConfig := source.Cfg.(*smtp.Source)
|
||||
|
||||
if err := parseSMTPConfig(c, smtpConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.IsSet("name") {
|
||||
source.Name = c.String("name")
|
||||
}
|
||||
|
||||
if c.IsSet("active") {
|
||||
source.IsActive = c.Bool("active")
|
||||
}
|
||||
|
||||
source.Cfg = smtpConfig
|
||||
|
||||
return auth_model.UpdateSource(ctx, source)
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
microcmdRegenHooks = &cli.Command{
|
||||
Name: "hooks",
|
||||
Usage: "Regenerate git-hooks",
|
||||
Action: runRegenerateHooks,
|
||||
}
|
||||
|
||||
microcmdRegenKeys = &cli.Command{
|
||||
Name: "keys",
|
||||
Usage: "Regenerate authorized_keys file",
|
||||
Action: runRegenerateKeys,
|
||||
}
|
||||
)
|
||||
|
||||
func runRegenerateHooks(_ *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
||||
}
|
||||
|
||||
func runRegenerateKeys(_ *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return asymkey_model.RewriteAllPublicKeys(ctx)
|
||||
}
|
|
@ -4,13 +4,13 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var subcmdUser = &cli.Command{
|
||||
var subcmdUser = cli.Command{
|
||||
Name: "user",
|
||||
Usage: "Modify users",
|
||||
Subcommands: []*cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
microcmdUserCreate,
|
||||
microcmdUserList,
|
||||
microcmdUserChangePassword,
|
||||
|
|
|
@ -12,25 +12,23 @@ import (
|
|||
pwd "code.gitea.io/gitea/modules/auth/password"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var microcmdUserChangePassword = &cli.Command{
|
||||
var microcmdUserChangePassword = cli.Command{
|
||||
Name: "change-password",
|
||||
Usage: "Change a user's password",
|
||||
Action: runChangePassword,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "username",
|
||||
Aliases: []string{"u"},
|
||||
Value: "",
|
||||
Usage: "The user to change password for",
|
||||
cli.StringFlag{
|
||||
Name: "username,u",
|
||||
Value: "",
|
||||
Usage: "The user to change password for",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "password",
|
||||
Aliases: []string{"p"},
|
||||
Value: "",
|
||||
Usage: "New password to set for user",
|
||||
cli.StringFlag{
|
||||
Name: "password,p",
|
||||
Value: "",
|
||||
Usage: "New password to set for user",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ package cmd
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
@ -13,52 +14,52 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var microcmdUserCreate = &cli.Command{
|
||||
var microcmdUserCreate = cli.Command{
|
||||
Name: "create",
|
||||
Usage: "Create a new user in database",
|
||||
Action: runCreateUser,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Usage: "Username. DEPRECATED: use username instead",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "username",
|
||||
Usage: "Username",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "password",
|
||||
Usage: "User password",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "email",
|
||||
Usage: "User email address",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "admin",
|
||||
Usage: "User is an admin",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "random-password",
|
||||
Usage: "Generate a random password for the user",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "must-change-password",
|
||||
Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
cli.IntFlag{
|
||||
Name: "random-password-length",
|
||||
Usage: "Length of the random password to be generated",
|
||||
Value: 12,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "access-token",
|
||||
Usage: "Generate access token for the user",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "restricted",
|
||||
Usage: "Make a restricted user account",
|
||||
},
|
||||
|
@ -86,7 +87,7 @@ func runCreateUser(c *cli.Context) error {
|
|||
username = c.String("username")
|
||||
} else {
|
||||
username = c.String("name")
|
||||
_, _ = fmt.Fprintf(c.App.ErrWriter, "--name flag is deprecated. Use --username instead.\n")
|
||||
fmt.Fprintf(os.Stderr, "--name flag is deprecated. Use --username instead.\n")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
|
@ -115,7 +116,7 @@ func runCreateUser(c *cli.Context) error {
|
|||
|
||||
// If this is the first user being created.
|
||||
// Take it as the admin and don't force a password update.
|
||||
if n := user_model.CountUsers(ctx, nil); n == 0 {
|
||||
if n := user_model.CountUsers(nil); n == 0 {
|
||||
changePassword = false
|
||||
}
|
||||
|
||||
|
@ -146,7 +147,7 @@ func runCreateUser(c *cli.Context) error {
|
|||
IsRestricted: restricted,
|
||||
}
|
||||
|
||||
if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
|
||||
if err := user_model.CreateUser(u, overwriteDefault); err != nil {
|
||||
return fmt.Errorf("CreateUser: %w", err)
|
||||
}
|
||||
|
||||
|
@ -156,7 +157,7 @@ func runCreateUser(c *cli.Context) error {
|
|||
UID: u.ID,
|
||||
}
|
||||
|
||||
if err := auth_model.NewAccessToken(ctx, t); err != nil {
|
||||
if err := auth_model.NewAccessToken(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -11,28 +11,26 @@ import (
|
|||
"code.gitea.io/gitea/modules/storage"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var microcmdUserDelete = &cli.Command{
|
||||
var microcmdUserDelete = cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "Delete specific user by id, name or email",
|
||||
Flags: []cli.Flag{
|
||||
&cli.Int64Flag{
|
||||
cli.Int64Flag{
|
||||
Name: "id",
|
||||
Usage: "ID of user of the user to delete",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "username",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Username of the user to delete",
|
||||
cli.StringFlag{
|
||||
Name: "username,u",
|
||||
Usage: "Username of the user to delete",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "email",
|
||||
Aliases: []string{"e"},
|
||||
Usage: "Email of the user to delete",
|
||||
cli.StringFlag{
|
||||
Name: "email,e",
|
||||
Usage: "Email of the user to delete",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "purge",
|
||||
Usage: "Purge user, all their repositories, organizations and comments",
|
||||
},
|
||||
|
|
|
@ -9,29 +9,27 @@ import (
|
|||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var microcmdUserGenerateAccessToken = &cli.Command{
|
||||
var microcmdUserGenerateAccessToken = cli.Command{
|
||||
Name: "generate-access-token",
|
||||
Usage: "Generate an access token for a specific user",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "username",
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Username",
|
||||
cli.StringFlag{
|
||||
Name: "username,u",
|
||||
Usage: "Username",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "token-name",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Token name",
|
||||
Value: "gitea-admin",
|
||||
cli.StringFlag{
|
||||
Name: "token-name,t",
|
||||
Usage: "Token name",
|
||||
Value: "gitea-admin",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "raw",
|
||||
Usage: "Display only the token value",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "scopes",
|
||||
Value: "",
|
||||
Usage: "Comma separated list of scopes to apply to access token",
|
||||
|
@ -57,29 +55,18 @@ func runGenerateAccessToken(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// construct token with name and user so we can make sure it is unique
|
||||
t := &auth_model.AccessToken{
|
||||
Name: c.String("token-name"),
|
||||
UID: user.ID,
|
||||
}
|
||||
|
||||
exist, err := auth_model.AccessTokenByNameExists(ctx, t)
|
||||
accessTokenScope, err := auth_model.AccessTokenScope(c.String("scopes")).Normalize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exist {
|
||||
return fmt.Errorf("access token name has been used already")
|
||||
|
||||
t := &auth_model.AccessToken{
|
||||
Name: c.String("token-name"),
|
||||
UID: user.ID,
|
||||
Scope: accessTokenScope,
|
||||
}
|
||||
|
||||
// make sure the scopes are valid
|
||||
accessTokenScope, err := auth_model.AccessTokenScope(c.String("scopes")).Normalize()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid access token scope provided: %w", err)
|
||||
}
|
||||
t.Scope = accessTokenScope
|
||||
|
||||
// create the token
|
||||
if err := auth_model.NewAccessToken(ctx, t); err != nil {
|
||||
if err := auth_model.NewAccessToken(t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -10,15 +10,15 @@ import (
|
|||
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var microcmdUserList = &cli.Command{
|
||||
var microcmdUserList = cli.Command{
|
||||
Name: "list",
|
||||
Usage: "List users",
|
||||
Action: runListUsers,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "admin",
|
||||
Usage: "List only admin users",
|
||||
},
|
||||
|
@ -33,7 +33,7 @@ func runListUsers(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
users, err := user_model.GetAllUsers(ctx)
|
||||
users, err := user_model.GetAllUsers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func runListUsers(c *cli.Context) error {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
twofa := user_model.UserList(users).GetTwoFaStatus(ctx)
|
||||
twofa := user_model.UserList(users).GetTwoFaStatus()
|
||||
fmt.Fprintf(w, "ID\tUsername\tEmail\tIsActive\tIsAdmin\t2FA\n")
|
||||
for _, u := range users {
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%t\t%t\t%t\n", u.ID, u.Name, u.Email, u.IsActive, u.IsAdmin, twofa[u.ID])
|
||||
|
|
|
@ -9,25 +9,23 @@ import (
|
|||
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var microcmdUserMustChangePassword = &cli.Command{
|
||||
var microcmdUserMustChangePassword = cli.Command{
|
||||
Name: "must-change-password",
|
||||
Usage: "Set the must change password flag for the provided users or all users",
|
||||
Action: runMustChangePassword,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "all",
|
||||
Aliases: []string{"A"},
|
||||
Usage: "All users must change password, except those explicitly excluded with --exclude",
|
||||
cli.BoolFlag{
|
||||
Name: "all,A",
|
||||
Usage: "All users must change password, except those explicitly excluded with --exclude",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "exclude",
|
||||
Aliases: []string{"e"},
|
||||
Usage: "Do not change the must-change-password flag for these users",
|
||||
cli.StringSliceFlag{
|
||||
Name: "exclude,e",
|
||||
Usage: "Do not change the must-change-password flag for these users",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "unset",
|
||||
Usage: "Instead of setting the must-change-password flag, unset it",
|
||||
},
|
||||
|
@ -50,7 +48,7 @@ func runMustChangePassword(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
n, err := user_model.SetMustChangePassword(ctx, all, mustChangePassword, c.Args().Slice(), exclude)
|
||||
n, err := user_model.SetMustChangePassword(ctx, all, mustChangePassword, c.Args(), exclude)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
26
cmd/cert.go
26
cmd/cert.go
|
@ -20,50 +20,50 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdCert represents the available cert sub-command.
|
||||
var CmdCert = &cli.Command{
|
||||
var CmdCert = cli.Command{
|
||||
Name: "cert",
|
||||
Usage: "Generate self-signed certificate",
|
||||
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
|
||||
Action: runCert,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "host",
|
||||
Value: "",
|
||||
Usage: "Comma-separated hostnames and IPs to generate a certificate for",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "ecdsa-curve",
|
||||
Value: "",
|
||||
Usage: "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
cli.IntFlag{
|
||||
Name: "rsa-bits",
|
||||
Value: 3072,
|
||||
Value: 2048,
|
||||
Usage: "Size of RSA key to generate. Ignored if --ecdsa-curve is set",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "start-date",
|
||||
Value: "",
|
||||
Usage: "Creation date formatted as Jan 1 15:04:05 2011",
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
cli.DurationFlag{
|
||||
Name: "duration",
|
||||
Value: 365 * 24 * time.Hour,
|
||||
Usage: "Duration that certificate is valid for",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "ca",
|
||||
Usage: "whether this cert should be its own Certificate Authority",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func publicKey(priv any) any {
|
||||
func publicKey(priv interface{}) interface{} {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &k.PublicKey
|
||||
|
@ -74,7 +74,7 @@ func publicKey(priv any) any {
|
|||
}
|
||||
}
|
||||
|
||||
func pemBlockForKey(priv any) *pem.Block {
|
||||
func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
|
||||
|
@ -94,7 +94,7 @@ func runCert(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var priv any
|
||||
var priv interface{}
|
||||
var err error
|
||||
switch c.String("ecdsa-curve") {
|
||||
case "":
|
||||
|
@ -136,7 +136,7 @@ func runCert(c *cli.Context) error {
|
|||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"Acme Co"},
|
||||
CommonName: "Forgejo",
|
||||
CommonName: "Gitea",
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
|
|
31
cmd/cmd.go
31
cmd/cmd.go
|
@ -20,7 +20,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// argsSet checks that all the required arguments are set. args is a list of
|
||||
|
@ -58,7 +58,7 @@ func confirm() (bool, error) {
|
|||
}
|
||||
|
||||
func initDB(ctx context.Context) error {
|
||||
setting.MustInstalled()
|
||||
setting.Init(&setting.Options{})
|
||||
setting.LoadDBSetting()
|
||||
setting.InitSQLLoggersForCli(log.INFO)
|
||||
|
||||
|
@ -106,30 +106,5 @@ func setupConsoleLogger(level log.Level, colorize bool, out io.Writer) {
|
|||
WriterOption: log.WriterConsoleOption{Stderr: out == os.Stderr},
|
||||
}
|
||||
writer := log.NewEventWriterConsole("console-default", writeMode)
|
||||
log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
|
||||
}
|
||||
|
||||
func globalBool(c *cli.Context, name string) bool {
|
||||
for _, ctx := range c.Lineage() {
|
||||
if ctx.Bool(name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout.
|
||||
// Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
|
||||
func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(*cli.Context) error {
|
||||
return func(c *cli.Context) error {
|
||||
level := defaultLevel
|
||||
if globalBool(c, "quiet") {
|
||||
level = log.FATAL
|
||||
}
|
||||
if globalBool(c, "debug") || globalBool(c, "verbose") {
|
||||
level = log.TRACE
|
||||
}
|
||||
log.SetConsoleLogger(log.DEFAULT, "console-default", level)
|
||||
return nil
|
||||
}
|
||||
log.GetManager().GetLogger(log.DEFAULT).RemoveAllWriters().AddWriters(writer)
|
||||
}
|
||||
|
|
|
@ -10,18 +10,18 @@ import (
|
|||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// cmdDoctorConvert represents the available convert sub-command.
|
||||
var cmdDoctorConvert = &cli.Command{
|
||||
// CmdConvert represents the available convert sub-command.
|
||||
var CmdConvert = cli.Command{
|
||||
Name: "convert",
|
||||
Usage: "Convert the database",
|
||||
Description: "A command to convert an existing MySQL database from utf8 to utf8mb4 or MSSQL database from varchar to nvarchar",
|
||||
Action: runDoctorConvert,
|
||||
Action: runConvert,
|
||||
}
|
||||
|
||||
func runDoctorConvert(ctx *cli.Context) error {
|
||||
func runConvert(ctx *cli.Context) error {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
|
@ -37,8 +37,8 @@ func runDoctorConvert(ctx *cli.Context) error {
|
|||
|
||||
switch {
|
||||
case setting.Database.Type.IsMySQL():
|
||||
if err := db.ConvertDatabaseTable(); err != nil {
|
||||
log.Fatal("Failed to convert database & table: %v", err)
|
||||
if err := db.ConvertUtf8ToUtf8mb4(); err != nil {
|
||||
log.Fatal("Failed to convert database from utf8 to utf8mb4: %v", err)
|
||||
return err
|
||||
}
|
||||
fmt.Println("Converted successfully, please confirm your database's character set is now utf8mb4")
|
11
cmd/docs.go
11
cmd/docs.go
|
@ -8,14 +8,14 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdDocs represents the available docs sub-command.
|
||||
var CmdDocs = &cli.Command{
|
||||
var CmdDocs = cli.Command{
|
||||
Name: "docs",
|
||||
Usage: "Output CLI documentation",
|
||||
Description: "A command to output Forgejo's CLI documentation, optionally to a file.",
|
||||
Description: "A command to output Gitea's CLI documentation, optionally to a file.",
|
||||
Action: runDocs,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
|
@ -23,9 +23,8 @@ var CmdDocs = &cli.Command{
|
|||
Usage: "Output man pages instead",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "output",
|
||||
Aliases: []string{"o"},
|
||||
Usage: "Path to output to instead of stdout (will overwrite if exists)",
|
||||
Name: "output, o",
|
||||
Usage: "Path to output to instead of stdout (will overwrite if exists)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -14,77 +14,66 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/migrations"
|
||||
migrate_base "code.gitea.io/gitea/models/migrations/base"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/doctor"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// CmdDoctor represents the available doctor sub-command.
|
||||
var CmdDoctor = &cli.Command{
|
||||
var CmdDoctor = cli.Command{
|
||||
Name: "doctor",
|
||||
Usage: "Diagnose and optionally fix problems, convert or re-create database tables",
|
||||
Description: "A command to diagnose problems with the current Forgejo instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
|
||||
|
||||
Subcommands: []*cli.Command{
|
||||
cmdDoctorCheck,
|
||||
cmdRecreateTable,
|
||||
cmdDoctorConvert,
|
||||
},
|
||||
}
|
||||
|
||||
var cmdDoctorCheck = &cli.Command{
|
||||
Name: "check",
|
||||
Usage: "Diagnose and optionally fix problems",
|
||||
Description: "A command to diagnose problems with the current Forgejo instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
|
||||
Action: runDoctorCheck,
|
||||
Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
|
||||
Action: runDoctor,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "list",
|
||||
Usage: "List the available checks",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "default",
|
||||
Usage: "Run the default checks (if neither --run or --all is set, this is the default behaviour)",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
cli.StringSliceFlag{
|
||||
Name: "run",
|
||||
Usage: "Run the provided checks - (if --default is set, the default checks will also run)",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "all",
|
||||
Usage: "Run all the available checks",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "fix",
|
||||
Usage: "Automatically fix what we can",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "log-file",
|
||||
Usage: `Name of the log file (no verbose log output by default). Set to "-" to output to stdout`,
|
||||
Usage: `Name of the log file (default: "doctor.log"). Set to "-" to output to stdout, set to "" to disable`,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "color",
|
||||
Aliases: []string{"H"},
|
||||
Usage: "Use color for outputted information",
|
||||
cli.BoolFlag{
|
||||
Name: "color, H",
|
||||
Usage: "Use color for outputted information",
|
||||
},
|
||||
},
|
||||
Subcommands: []cli.Command{
|
||||
cmdRecreateTable,
|
||||
},
|
||||
}
|
||||
|
||||
var cmdRecreateTable = &cli.Command{
|
||||
var cmdRecreateTable = cli.Command{
|
||||
Name: "recreate-table",
|
||||
Usage: "Recreate tables from XORM definitions and copy the data.",
|
||||
ArgsUsage: "[TABLE]... : (TABLEs to recreate - leave blank for all)",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
Usage: "Print SQL commands sent",
|
||||
},
|
||||
},
|
||||
Description: `The database definitions Forgejo uses change across versions, sometimes changing default values and leaving old unused columns.
|
||||
Description: `The database definitions Gitea uses change across versions, sometimes changing default values and leaving old unused columns.
|
||||
|
||||
This command will cause Xorm to recreate tables, copying over the data and deleting the old table.
|
||||
|
||||
|
@ -102,7 +91,7 @@ func runRecreateTable(ctx *cli.Context) error {
|
|||
golog.SetOutput(log.LoggerToWriter(log.GetLogger(log.DEFAULT).Info))
|
||||
|
||||
debug := ctx.Bool("debug")
|
||||
setting.MustInstalled()
|
||||
setting.Init(&setting.Options{})
|
||||
setting.LoadDBSetting()
|
||||
|
||||
if debug {
|
||||
|
@ -143,9 +132,16 @@ func setupDoctorDefaultLogger(ctx *cli.Context, colorize bool) {
|
|||
setupConsoleLogger(log.FATAL, log.CanColorStderr, os.Stderr)
|
||||
|
||||
logFile := ctx.String("log-file")
|
||||
if logFile == "" {
|
||||
return // if no doctor log-file is set, do not show any log from default logger
|
||||
} else if logFile == "-" {
|
||||
if !ctx.IsSet("log-file") {
|
||||
logFile = "doctor.log"
|
||||
}
|
||||
|
||||
if len(logFile) == 0 {
|
||||
// if no doctor log-file is set, do not show any log from default logger
|
||||
return
|
||||
}
|
||||
|
||||
if logFile == "-" {
|
||||
setupConsoleLogger(log.TRACE, colorize, os.Stdout)
|
||||
} else {
|
||||
logFile, _ = filepath.Abs(logFile)
|
||||
|
@ -155,11 +151,11 @@ func setupDoctorDefaultLogger(ctx *cli.Context, colorize bool) {
|
|||
log.FallbackErrorf("unable to create file log writer: %v", err)
|
||||
return
|
||||
}
|
||||
log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
|
||||
log.GetManager().GetLogger(log.DEFAULT).RemoveAllWriters().AddWriters(writer)
|
||||
}
|
||||
}
|
||||
|
||||
func runDoctorCheck(ctx *cli.Context) error {
|
||||
func runDoctor(ctx *cli.Context) error {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
|
@ -178,7 +174,6 @@ func runDoctorCheck(ctx *cli.Context) error {
|
|||
if ctx.IsSet("list") {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
|
||||
_, _ = w.Write([]byte("Default\tName\tTitle\n"))
|
||||
doctor.SortChecks(doctor.Checks)
|
||||
for _, check := range doctor.Checks {
|
||||
if check.IsDefault {
|
||||
_, _ = w.Write([]byte{'*'})
|
||||
|
@ -194,19 +189,25 @@ func runDoctorCheck(ctx *cli.Context) error {
|
|||
|
||||
var checks []*doctor.Check
|
||||
if ctx.Bool("all") {
|
||||
checks = make([]*doctor.Check, len(doctor.Checks))
|
||||
copy(checks, doctor.Checks)
|
||||
checks = doctor.Checks
|
||||
} else if ctx.IsSet("run") {
|
||||
addDefault := ctx.Bool("default")
|
||||
runNamesSet := container.SetOf(ctx.StringSlice("run")...)
|
||||
for _, check := range doctor.Checks {
|
||||
if (addDefault && check.IsDefault) || runNamesSet.Contains(check.Name) {
|
||||
checks = append(checks, check)
|
||||
runNamesSet.Remove(check.Name)
|
||||
}
|
||||
names := ctx.StringSlice("run")
|
||||
for i, name := range names {
|
||||
names[i] = strings.ToLower(strings.TrimSpace(name))
|
||||
}
|
||||
if len(runNamesSet) > 0 {
|
||||
return fmt.Errorf("unknown checks: %q", strings.Join(runNamesSet.Values(), ","))
|
||||
|
||||
for _, check := range doctor.Checks {
|
||||
if addDefault && check.IsDefault {
|
||||
checks = append(checks, check)
|
||||
continue
|
||||
}
|
||||
for _, name := range names {
|
||||
if name == check.Name {
|
||||
checks = append(checks, check)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, check := range doctor.Checks {
|
||||
|
@ -215,5 +216,6 @@ func runDoctorCheck(ctx *cli.Context) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return doctor.RunChecks(stdCtx, colorize, ctx.Bool("fix"), checks)
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/doctor"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func TestDoctorRun(t *testing.T) {
|
||||
doctor.Register(&doctor.Check{
|
||||
Title: "Test Check",
|
||||
Name: "test-check",
|
||||
Run: func(ctx context.Context, logger log.Logger, autofix bool) error { return nil },
|
||||
|
||||
SkipDatabaseInitialization: true,
|
||||
})
|
||||
app := cli.NewApp()
|
||||
app.Commands = []*cli.Command{cmdDoctorCheck}
|
||||
err := app.Run([]string{"./gitea", "check", "--run", "test-check"})
|
||||
assert.NoError(t, err)
|
||||
err = app.Run([]string{"./gitea", "check", "--run", "no-such"})
|
||||
assert.ErrorContains(t, err, `unknown checks: "no-such"`)
|
||||
err = app.Run([]string{"./gitea", "check", "--run", "test-check,no-such"})
|
||||
assert.ErrorContains(t, err, `unknown checks: "no-such"`)
|
||||
}
|
95
cmd/dump.go
95
cmd/dump.go
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
"gitea.com/go-chi/session"
|
||||
"github.com/mholt/archiver/v3"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func addReader(w archiver.Writer, r io.ReadCloser, info os.FileInfo, customName string, verbose bool) error {
|
||||
|
@ -96,71 +96,64 @@ var outputTypeEnum = &outputType{
|
|||
}
|
||||
|
||||
// CmdDump represents the available dump sub-command.
|
||||
var CmdDump = &cli.Command{
|
||||
var CmdDump = cli.Command{
|
||||
Name: "dump",
|
||||
Usage: "Dump Forgejo files and database",
|
||||
Usage: "Dump Gitea files and database",
|
||||
Description: `Dump compresses all related files and database into zip file.
|
||||
It can be used for backup and capture Forgejo server image to send to maintainer`,
|
||||
It can be used for backup and capture Gitea server image to send to maintainer`,
|
||||
Action: runDump,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "file",
|
||||
Aliases: []string{"f"},
|
||||
Value: fmt.Sprintf("forgejo-dump-%d.zip", time.Now().Unix()),
|
||||
Usage: "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
|
||||
cli.StringFlag{
|
||||
Name: "file, f",
|
||||
Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
|
||||
Usage: "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "verbose",
|
||||
Aliases: []string{"V"},
|
||||
Usage: "Show process details",
|
||||
cli.BoolFlag{
|
||||
Name: "verbose, V",
|
||||
Usage: "Show process details",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "quiet",
|
||||
Aliases: []string{"q"},
|
||||
Usage: "Only display warnings and errors",
|
||||
cli.BoolFlag{
|
||||
Name: "quiet, q",
|
||||
Usage: "Only display warnings and errors",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tempdir",
|
||||
Aliases: []string{"t"},
|
||||
Value: os.TempDir(),
|
||||
Usage: "Temporary dir path",
|
||||
cli.StringFlag{
|
||||
Name: "tempdir, t",
|
||||
Value: os.TempDir(),
|
||||
Usage: "Temporary dir path",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "database",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Specify the database SQL syntax: sqlite3, mysql, mssql, postgres",
|
||||
cli.StringFlag{
|
||||
Name: "database, d",
|
||||
Usage: "Specify the database SQL syntax",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "skip-repository",
|
||||
Aliases: []string{"R"},
|
||||
Usage: "Skip the repository dumping",
|
||||
cli.BoolFlag{
|
||||
Name: "skip-repository, R",
|
||||
Usage: "Skip the repository dumping",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "skip-log",
|
||||
Aliases: []string{"L"},
|
||||
Usage: "Skip the log dumping",
|
||||
cli.BoolFlag{
|
||||
Name: "skip-log, L",
|
||||
Usage: "Skip the log dumping",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "skip-custom-dir",
|
||||
Usage: "Skip custom directory",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "skip-lfs-data",
|
||||
Usage: "Skip LFS data",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "skip-attachment-data",
|
||||
Usage: "Skip attachment data",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "skip-package-data",
|
||||
Usage: "Skip package data",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "skip-index",
|
||||
Usage: "Skip bleve index data",
|
||||
},
|
||||
&cli.GenericFlag{
|
||||
cli.GenericFlag{
|
||||
Name: "type",
|
||||
Value: outputTypeEnum,
|
||||
Usage: fmt.Sprintf("Dump output format: %s", outputTypeEnum.Join()),
|
||||
|
@ -168,7 +161,7 @@ It can be used for backup and capture Forgejo server image to send to maintainer
|
|||
},
|
||||
}
|
||||
|
||||
func fatal(format string, args ...any) {
|
||||
func fatal(format string, args ...interface{}) {
|
||||
fmt.Fprintf(os.Stderr, format+"\n", args...)
|
||||
log.Fatal(format, args...)
|
||||
}
|
||||
|
@ -189,7 +182,7 @@ func runDump(ctx *cli.Context) error {
|
|||
}
|
||||
fileName += "." + outType
|
||||
}
|
||||
setting.MustInstalled()
|
||||
setting.Init(&setting.Options{})
|
||||
|
||||
// make sure we are logging to the console no matter what the configuration tells us do to
|
||||
// FIXME: don't use CfgProvider directly
|
||||
|
@ -209,7 +202,7 @@ func runDump(ctx *cli.Context) error {
|
|||
|
||||
if !setting.InstallLock {
|
||||
log.Error("Is '%s' really the right config path?\n", setting.CustomConf)
|
||||
return fmt.Errorf("forgejo is not initialized")
|
||||
return fmt.Errorf("gitea is not initialized")
|
||||
}
|
||||
setting.LoadSettings() // cannot access session settings otherwise
|
||||
|
||||
|
@ -243,7 +236,7 @@ func runDump(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var iface any
|
||||
var iface interface{}
|
||||
if fileName == "-" {
|
||||
iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType))
|
||||
} else {
|
||||
|
@ -288,7 +281,7 @@ func runDump(ctx *cli.Context) error {
|
|||
fatal("Path does not exist: %s", tmpDir)
|
||||
}
|
||||
|
||||
dbDump, err := os.CreateTemp(tmpDir, "forgejo-db.sql")
|
||||
dbDump, err := os.CreateTemp(tmpDir, "gitea-db.sql")
|
||||
if err != nil {
|
||||
fatal("Failed to create tmp file: %v", err)
|
||||
}
|
||||
|
@ -310,8 +303,8 @@ func runDump(ctx *cli.Context) error {
|
|||
fatal("Failed to dump database: %v", err)
|
||||
}
|
||||
|
||||
if err := addFile(w, "forgejo-db.sql", dbDump.Name(), verbose); err != nil {
|
||||
fatal("Failed to include forgejo-db.sql: %v", err)
|
||||
if err := addFile(w, "gitea-db.sql", dbDump.Name(), verbose); err != nil {
|
||||
fatal("Failed to include gitea-db.sql: %v", err)
|
||||
}
|
||||
|
||||
if len(setting.CustomConf) > 0 {
|
||||
|
@ -360,9 +353,9 @@ func runDump(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
excludes = append(excludes, setting.RepoRootPath)
|
||||
excludes = append(excludes, setting.LFS.Storage.Path)
|
||||
excludes = append(excludes, setting.Attachment.Storage.Path)
|
||||
excludes = append(excludes, setting.Packages.Storage.Path)
|
||||
excludes = append(excludes, setting.LFS.Path)
|
||||
excludes = append(excludes, setting.Attachment.Path)
|
||||
excludes = append(excludes, setting.Packages.Path)
|
||||
excludes = append(excludes, setting.Log.RootPath)
|
||||
excludes = append(excludes, absFileName)
|
||||
if err := addRecursiveExclude(w, "data", setting.AppDataPath, excludes, verbose); err != nil {
|
||||
|
@ -452,7 +445,7 @@ func addRecursiveExclude(w archiver.Writer, insidePath, absPath string, excludeA
|
|||
return err
|
||||
}
|
||||
for _, file := range files {
|
||||
currentAbsPath := filepath.Join(absPath, file.Name())
|
||||
currentAbsPath := path.Join(absPath, file.Name())
|
||||
currentInsidePath := path.Join(insidePath, file.Name())
|
||||
if file.IsDir() {
|
||||
if !util.SliceContainsString(excludeAbsPath, currentAbsPath) {
|
||||
|
|
|
@ -19,58 +19,57 @@ import (
|
|||
"code.gitea.io/gitea/services/convert"
|
||||
"code.gitea.io/gitea/services/migrations"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdDumpRepository represents the available dump repository sub-command.
|
||||
var CmdDumpRepository = &cli.Command{
|
||||
var CmdDumpRepository = cli.Command{
|
||||
Name: "dump-repo",
|
||||
Usage: "Dump the repository from git/github/gitea/gitlab",
|
||||
Description: "This is a command for dumping the repository data.",
|
||||
Action: runDumpRepository,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "git_service",
|
||||
Value: "",
|
||||
Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "repo_dir",
|
||||
Aliases: []string{"r"},
|
||||
Value: "./data",
|
||||
Usage: "Repository dir path to store the data",
|
||||
cli.StringFlag{
|
||||
Name: "repo_dir, r",
|
||||
Value: "./data",
|
||||
Usage: "Repository dir path to store the data",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "clone_addr",
|
||||
Value: "",
|
||||
Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "auth_username",
|
||||
Value: "",
|
||||
Usage: "The username to visit the clone_addr",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "auth_password",
|
||||
Value: "",
|
||||
Usage: "The password to visit the clone_addr",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "auth_token",
|
||||
Value: "",
|
||||
Usage: "The personal token to visit the clone_addr",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "owner_name",
|
||||
Value: "",
|
||||
Usage: "The data will be stored on a directory with owner name if not empty",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "repo_name",
|
||||
Value: "",
|
||||
Usage: "The data will be stored on a directory with repository name if not empty",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "units",
|
||||
Value: "",
|
||||
Usage: `Which items will be migrated, one or more units should be separated as comma.
|
||||
|
|
|
@ -19,74 +19,70 @@ import (
|
|||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdEmbedded represents the available extract sub-command.
|
||||
// Cmdembedded represents the available extract sub-command.
|
||||
var (
|
||||
CmdEmbedded = &cli.Command{
|
||||
Cmdembedded = cli.Command{
|
||||
Name: "embedded",
|
||||
Usage: "Extract embedded resources",
|
||||
Description: "A command for extracting embedded resources, like templates and images",
|
||||
Subcommands: []*cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
subcmdList,
|
||||
subcmdView,
|
||||
subcmdExtract,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdList = &cli.Command{
|
||||
subcmdList = cli.Command{
|
||||
Name: "list",
|
||||
Usage: "List files matching the given pattern",
|
||||
Action: runList,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "include-vendored",
|
||||
Aliases: []string{"vendor"},
|
||||
Usage: "Include files under public/vendor as well",
|
||||
cli.BoolFlag{
|
||||
Name: "include-vendored,vendor",
|
||||
Usage: "Include files under public/vendor as well",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
subcmdView = &cli.Command{
|
||||
subcmdView = cli.Command{
|
||||
Name: "view",
|
||||
Usage: "View a file matching the given pattern",
|
||||
Action: runView,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "include-vendored",
|
||||
Aliases: []string{"vendor"},
|
||||
Usage: "Include files under public/vendor as well",
|
||||
cli.BoolFlag{
|
||||
Name: "include-vendored,vendor",
|
||||
Usage: "Include files under public/vendor as well",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
subcmdExtract = &cli.Command{
|
||||
subcmdExtract = cli.Command{
|
||||
Name: "extract",
|
||||
Usage: "Extract resources",
|
||||
Action: runExtract,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "include-vendored",
|
||||
Aliases: []string{"vendor"},
|
||||
Usage: "Include files under public/vendor as well",
|
||||
cli.BoolFlag{
|
||||
Name: "include-vendored,vendor",
|
||||
Usage: "Include files under public/vendor as well",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "overwrite",
|
||||
Usage: "Overwrite files if they already exist",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "rename",
|
||||
Usage: "Rename files as {name}.bak if they already exist (overwrites previous .bak)",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "custom",
|
||||
Usage: "Extract to the 'custom' directory as per app.ini",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "destination",
|
||||
Aliases: []string{"dest-dir"},
|
||||
Usage: "Extract to the specified directory",
|
||||
cli.StringFlag{
|
||||
Name: "destination,dest-dir",
|
||||
Usage: "Extract to the specified directory",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -103,7 +99,12 @@ type assetFile struct {
|
|||
func initEmbeddedExtractor(c *cli.Context) error {
|
||||
setupConsoleLogger(log.ERROR, log.CanColorStderr, os.Stderr)
|
||||
|
||||
patterns, err := compileCollectPatterns(c.Args().Slice())
|
||||
// Read configuration file
|
||||
setting.Init(&setting.Options{
|
||||
AllowEmpty: true,
|
||||
})
|
||||
|
||||
patterns, err := compileCollectPatterns(c.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -179,7 +180,7 @@ func runExtractDo(c *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if c.NArg() == 0 {
|
||||
if len(c.Args()) == 0 {
|
||||
return fmt.Errorf("a list of pattern of files to extract is mandatory (e.g. '**' for all)")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,243 +0,0 @@
|
|||
// Copyright The Forgejo Authors.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
private_routers "code.gitea.io/gitea/routers/private"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func CmdActions(ctx context.Context) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "actions",
|
||||
Usage: "Commands for managing Forgejo Actions",
|
||||
Subcommands: []*cli.Command{
|
||||
SubcmdActionsGenerateRunnerToken(ctx),
|
||||
SubcmdActionsGenerateRunnerSecret(ctx),
|
||||
SubcmdActionsRegister(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func SubcmdActionsGenerateRunnerToken(ctx context.Context) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "generate-runner-token",
|
||||
Usage: "Generate a new token for a runner to use to register with the server",
|
||||
Action: prepareWorkPathAndCustomConf(ctx, func(cliCtx *cli.Context) error { return RunGenerateActionsRunnerToken(ctx, cliCtx) }),
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "scope",
|
||||
Aliases: []string{"s"},
|
||||
Value: "",
|
||||
Usage: "{owner}[/{repo}] - leave empty for a global runner",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func SubcmdActionsGenerateRunnerSecret(ctx context.Context) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "generate-secret",
|
||||
Usage: "Generate a secret suitable for input to the register subcommand",
|
||||
Action: func(cliCtx *cli.Context) error { return RunGenerateSecret(ctx, cliCtx) },
|
||||
}
|
||||
}
|
||||
|
||||
func SubcmdActionsRegister(ctx context.Context) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "register",
|
||||
Usage: "Idempotent registration of a runner using a shared secret",
|
||||
Action: prepareWorkPathAndCustomConf(ctx, func(cliCtx *cli.Context) error { return RunRegister(ctx, cliCtx) }),
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "secret",
|
||||
Usage: "the secret the runner will use to connect as a 40 character hexadecimal string",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "secret-stdin",
|
||||
Usage: "the secret the runner will use to connect as a 40 character hexadecimal string, read from stdin",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "secret-file",
|
||||
Usage: "path to the file containing the secret the runner will use to connect as a 40 character hexadecimal string",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "scope",
|
||||
Aliases: []string{"s"},
|
||||
Value: "",
|
||||
Usage: "{owner}[/{repo}] - leave empty for a global runner",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "labels",
|
||||
Value: "",
|
||||
Usage: "comma separated list of labels supported by the runner (e.g. docker,ubuntu-latest,self-hosted) (not required since v1.21)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "runner",
|
||||
Usage: "name of the runner (default runner)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "version",
|
||||
Value: "",
|
||||
Usage: "version of the runner (not required since v1.21)",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func readSecret(ctx context.Context, cliCtx *cli.Context) (string, error) {
|
||||
if cliCtx.IsSet("secret") {
|
||||
return cliCtx.String("secret"), nil
|
||||
}
|
||||
if cliCtx.IsSet("secret-stdin") {
|
||||
buf, err := io.ReadAll(ContextGetStdin(ctx))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
if cliCtx.IsSet("secret-file") {
|
||||
path := cliCtx.String("secret-file")
|
||||
buf, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
return "", fmt.Errorf("at least one of the --secret, --secret-stdin, --secret-file options is required")
|
||||
}
|
||||
|
||||
func validateSecret(secret string) error {
|
||||
secretLen := len(secret)
|
||||
if secretLen != 40 {
|
||||
return fmt.Errorf("the secret must be exactly 40 characters long, not %d: generate-secret can provide a secret matching the requirements", secretLen)
|
||||
}
|
||||
if _, err := hex.DecodeString(secret); err != nil {
|
||||
return fmt.Errorf("the secret must be an hexadecimal string: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RunRegister(ctx context.Context, cliCtx *cli.Context) error {
|
||||
if !ContextGetNoInit(ctx) {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = installSignals(ctx)
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
setting.MustInstalled()
|
||||
|
||||
secret, err := readSecret(ctx, cliCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateSecret(secret); err != nil {
|
||||
return err
|
||||
}
|
||||
scope := cliCtx.String("scope")
|
||||
labels := cliCtx.String("labels")
|
||||
name := cliCtx.String("name")
|
||||
version := cliCtx.String("version")
|
||||
|
||||
//
|
||||
// There are two kinds of tokens
|
||||
//
|
||||
// - "registration token" only used when a runner interacts to
|
||||
// register
|
||||
//
|
||||
// - "token" obtained after a successful registration and stored by
|
||||
// the runner to authenticate
|
||||
//
|
||||
// The register subcommand does not need a "registration token", it
|
||||
// needs a "token". Using the same name is confusing and secret is
|
||||
// preferred for this reason in the cli.
|
||||
//
|
||||
// The ActionsRunnerRegister argument is token to be consistent with
|
||||
// the internal naming. It is still confusing to the developer but
|
||||
// not to the user.
|
||||
//
|
||||
owner, repo, err := private_routers.ParseScope(ctx, scope)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
runner, err := actions_model.RegisterRunner(ctx, owner, repo, secret, strings.Split(labels, ","), name, version)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while registering runner: %v", err)
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(ContextGetStdout(ctx), "%s", runner.UUID); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RunGenerateSecret(ctx context.Context, cliCtx *cli.Context) error {
|
||||
runner := actions_model.ActionRunner{}
|
||||
if err := runner.GenerateToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(ContextGetStdout(ctx), "%s", runner.Token); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RunGenerateActionsRunnerToken(ctx context.Context, cliCtx *cli.Context) error {
|
||||
if !ContextGetNoInit(ctx) {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = installSignals(ctx)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
setting.MustInstalled()
|
||||
|
||||
scope := cliCtx.String("scope")
|
||||
|
||||
respText, extra := private.GenerateActionsRunnerToken(ctx, scope)
|
||||
if extra.HasError() {
|
||||
return handleCliResponseExtra(ctx, extra)
|
||||
}
|
||||
if _, err := fmt.Fprintf(ContextGetStdout(ctx), "%s", respText); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareWorkPathAndCustomConf(ctx context.Context, action cli.ActionFunc) func(cliCtx *cli.Context) error {
|
||||
return func(cliCtx *cli.Context) error {
|
||||
if !ContextGetNoInit(ctx) {
|
||||
var args setting.ArgWorkPathAndCustomConf
|
||||
// from children to parent, check the global flags
|
||||
for _, curCtx := range cliCtx.Lineage() {
|
||||
if curCtx.IsSet("work-path") && args.WorkPath == "" {
|
||||
args.WorkPath = curCtx.String("work-path")
|
||||
}
|
||||
if curCtx.IsSet("custom-path") && args.CustomPath == "" {
|
||||
args.CustomPath = curCtx.String("custom-path")
|
||||
}
|
||||
if curCtx.IsSet("config") && args.CustomConf == "" {
|
||||
args.CustomConf = curCtx.String("config")
|
||||
}
|
||||
}
|
||||
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
|
||||
}
|
||||
return action(cliCtx)
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
// Copyright The Forgejo Authors.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type key int
|
||||
|
||||
const (
|
||||
noInitKey key = iota + 1
|
||||
noExitKey
|
||||
stdoutKey
|
||||
stderrKey
|
||||
stdinKey
|
||||
)
|
||||
|
||||
func CmdForgejo(ctx context.Context) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "forgejo-cli",
|
||||
Usage: "Forgejo CLI",
|
||||
Flags: []cli.Flag{},
|
||||
Subcommands: []*cli.Command{
|
||||
CmdActions(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ContextSetNoInit(ctx context.Context, value bool) context.Context {
|
||||
return context.WithValue(ctx, noInitKey, value)
|
||||
}
|
||||
|
||||
func ContextGetNoInit(ctx context.Context) bool {
|
||||
value, ok := ctx.Value(noInitKey).(bool)
|
||||
return ok && value
|
||||
}
|
||||
|
||||
func ContextSetNoExit(ctx context.Context, value bool) context.Context {
|
||||
return context.WithValue(ctx, noExitKey, value)
|
||||
}
|
||||
|
||||
func ContextGetNoExit(ctx context.Context) bool {
|
||||
value, ok := ctx.Value(noExitKey).(bool)
|
||||
return ok && value
|
||||
}
|
||||
|
||||
func ContextSetStderr(ctx context.Context, value io.Writer) context.Context {
|
||||
return context.WithValue(ctx, stderrKey, value)
|
||||
}
|
||||
|
||||
func ContextGetStderr(ctx context.Context) io.Writer {
|
||||
value, ok := ctx.Value(stderrKey).(io.Writer)
|
||||
if !ok {
|
||||
return os.Stderr
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func ContextSetStdout(ctx context.Context, value io.Writer) context.Context {
|
||||
return context.WithValue(ctx, stdoutKey, value)
|
||||
}
|
||||
|
||||
func ContextGetStdout(ctx context.Context) io.Writer {
|
||||
value, ok := ctx.Value(stderrKey).(io.Writer)
|
||||
if !ok {
|
||||
return os.Stdout
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func ContextSetStdin(ctx context.Context, value io.Reader) context.Context {
|
||||
return context.WithValue(ctx, stdinKey, value)
|
||||
}
|
||||
|
||||
func ContextGetStdin(ctx context.Context) io.Reader {
|
||||
value, ok := ctx.Value(stdinKey).(io.Reader)
|
||||
if !ok {
|
||||
return os.Stdin
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// copied from ../cmd.go
|
||||
func initDB(ctx context.Context) error {
|
||||
setting.MustInstalled()
|
||||
setting.LoadDBSetting()
|
||||
setting.InitSQLLoggersForCli(log.INFO)
|
||||
|
||||
if setting.Database.Type == "" {
|
||||
log.Fatal(`Database settings are missing from the configuration file: %q.
|
||||
Ensure you are running in the correct environment or set the correct configuration file with -c.
|
||||
If this is the intended configuration file complete the [database] section.`, setting.CustomConf)
|
||||
}
|
||||
if err := db.InitEngine(ctx); err != nil {
|
||||
return fmt.Errorf("unable to initialize the database using the configuration in %q. Error: %w", setting.CustomConf, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// copied from ../cmd.go
|
||||
func installSignals(ctx context.Context) (context.Context, context.CancelFunc) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
go func() {
|
||||
// install notify
|
||||
signalChannel := make(chan os.Signal, 1)
|
||||
|
||||
signal.Notify(
|
||||
signalChannel,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
)
|
||||
select {
|
||||
case <-signalChannel:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
cancel()
|
||||
signal.Reset()
|
||||
}()
|
||||
|
||||
return ctx, cancel
|
||||
}
|
||||
|
||||
func handleCliResponseExtra(ctx context.Context, extra private.ResponseExtra) error {
|
||||
if false && extra.UserMsg != "" {
|
||||
if _, err := fmt.Fprintf(ContextGetStdout(ctx), "%s", extra.UserMsg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if ContextGetNoExit(ctx) {
|
||||
return extra.Error
|
||||
}
|
||||
return cli.Exit(extra.Error, 1)
|
||||
}
|
|
@ -11,43 +11,43 @@ import (
|
|||
"code.gitea.io/gitea/modules/generate"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
// CmdGenerate represents the available generate sub-command.
|
||||
CmdGenerate = &cli.Command{
|
||||
CmdGenerate = cli.Command{
|
||||
Name: "generate",
|
||||
Usage: "Generate Gitea's secrets/keys/tokens",
|
||||
Subcommands: []*cli.Command{
|
||||
Usage: "Command line interface for running generators",
|
||||
Subcommands: []cli.Command{
|
||||
subcmdSecret,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdSecret = &cli.Command{
|
||||
subcmdSecret = cli.Command{
|
||||
Name: "secret",
|
||||
Usage: "Generate a secret token",
|
||||
Subcommands: []*cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
microcmdGenerateInternalToken,
|
||||
microcmdGenerateLfsJwtSecret,
|
||||
microcmdGenerateSecretKey,
|
||||
},
|
||||
}
|
||||
|
||||
microcmdGenerateInternalToken = &cli.Command{
|
||||
microcmdGenerateInternalToken = cli.Command{
|
||||
Name: "INTERNAL_TOKEN",
|
||||
Usage: "Generate a new INTERNAL_TOKEN",
|
||||
Action: runGenerateInternalToken,
|
||||
}
|
||||
|
||||
microcmdGenerateLfsJwtSecret = &cli.Command{
|
||||
microcmdGenerateLfsJwtSecret = cli.Command{
|
||||
Name: "JWT_SECRET",
|
||||
Aliases: []string{"LFS_JWT_SECRET"},
|
||||
Usage: "Generate a new JWT_SECRET",
|
||||
Action: runGenerateLfsJwtSecret,
|
||||
}
|
||||
|
||||
microcmdGenerateSecretKey = &cli.Command{
|
||||
microcmdGenerateSecretKey = cli.Command{
|
||||
Name: "SECRET_KEY",
|
||||
Usage: "Generate a new SECRET_KEY",
|
||||
Action: runGenerateSecretKey,
|
||||
|
@ -70,12 +70,12 @@ func runGenerateInternalToken(c *cli.Context) error {
|
|||
}
|
||||
|
||||
func runGenerateLfsJwtSecret(c *cli.Context) error {
|
||||
_, jwtSecretBase64, err := generate.NewJwtSecretBase64()
|
||||
JWTSecretBase64, err := generate.NewJwtSecretBase64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%s", jwtSecretBase64)
|
||||
fmt.Printf("%s", JWTSecretBase64)
|
||||
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
fmt.Printf("\n")
|
||||
|
|
47
cmd/hook.go
47
cmd/hook.go
|
@ -15,12 +15,11 @@ import (
|
|||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -29,12 +28,11 @@ const (
|
|||
|
||||
var (
|
||||
// CmdHook represents the available hooks sub-command.
|
||||
CmdHook = &cli.Command{
|
||||
CmdHook = cli.Command{
|
||||
Name: "hook",
|
||||
Usage: "(internal) Should only be called by Git",
|
||||
Description: "Delegate commands to corresponding Git hooks",
|
||||
Before: PrepareConsoleLoggerLevel(log.FATAL),
|
||||
Subcommands: []*cli.Command{
|
||||
Usage: "Delegate commands to corresponding Git hooks",
|
||||
Description: "This should only be called by Git",
|
||||
Subcommands: []cli.Command{
|
||||
subcmdHookPreReceive,
|
||||
subcmdHookUpdate,
|
||||
subcmdHookPostReceive,
|
||||
|
@ -42,47 +40,47 @@ var (
|
|||
},
|
||||
}
|
||||
|
||||
subcmdHookPreReceive = &cli.Command{
|
||||
subcmdHookPreReceive = cli.Command{
|
||||
Name: "pre-receive",
|
||||
Usage: "Delegate pre-receive Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookPreReceive,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
}
|
||||
subcmdHookUpdate = &cli.Command{
|
||||
subcmdHookUpdate = cli.Command{
|
||||
Name: "update",
|
||||
Usage: "Delegate update Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookUpdate,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
}
|
||||
subcmdHookPostReceive = &cli.Command{
|
||||
subcmdHookPostReceive = cli.Command{
|
||||
Name: "post-receive",
|
||||
Usage: "Delegate post-receive Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookPostReceive,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
}
|
||||
// Note: new hook since git 2.29
|
||||
subcmdHookProcReceive = &cli.Command{
|
||||
subcmdHookProcReceive = cli.Command{
|
||||
Name: "proc-receive",
|
||||
Usage: "Delegate proc-receive Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookProcReceive,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
|
@ -172,9 +170,9 @@ func runHookPreReceive(c *cli.Context) error {
|
|||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||
return fail(ctx, `Rejecting changes as Forgejo environment not set.
|
||||
return fail(ctx, `Rejecting changes as Gitea environment not set.
|
||||
If you are pushing over SSH you must push with a key managed by
|
||||
Forgejo or set your environment appropriately.`, "")
|
||||
Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -316,9 +314,9 @@ func runHookPostReceive(c *cli.Context) error {
|
|||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||
return fail(ctx, `Rejecting changes as Forgejo environment not set.
|
||||
return fail(ctx, `Rejecting changes as Gitea environment not set.
|
||||
If you are pushing over SSH you must push with a key managed by
|
||||
Forgejo or set your environment appropriately.`, "")
|
||||
Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -376,9 +374,7 @@ Forgejo or set your environment appropriately.`, "")
|
|||
oldCommitIDs[count] = string(fields[0])
|
||||
newCommitIDs[count] = string(fields[1])
|
||||
refFullNames[count] = git.RefName(fields[2])
|
||||
|
||||
commitID, _ := git.NewIDFromString(newCommitIDs[count])
|
||||
if refFullNames[count] == git.BranchPrefix+"master" && !commitID.IsZero() && count == total {
|
||||
if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total {
|
||||
masterPushed = true
|
||||
}
|
||||
count++
|
||||
|
@ -487,9 +483,9 @@ func runHookProcReceive(c *cli.Context) error {
|
|||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||
return fail(ctx, `Rejecting changes as Forgejo environment not set.
|
||||
return fail(ctx, `Rejecting changes as Gitea environment not set.
|
||||
If you are pushing over SSH you must push with a key managed by
|
||||
Forgejo or set your environment appropriately.`, "")
|
||||
Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -671,8 +667,7 @@ Forgejo or set your environment appropriately.`, "")
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
commitID, _ := git.NewIDFromString(rs.OldOID)
|
||||
if !commitID.IsZero() {
|
||||
if rs.OldOID != git.EmptySHA {
|
||||
err = writeDataPktLine(ctx, os.Stdout, []byte("option old-oid "+rs.OldOID))
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
51
cmd/keys.go
51
cmd/keys.go
|
@ -8,43 +8,36 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdKeys represents the available keys sub-command
|
||||
var CmdKeys = &cli.Command{
|
||||
Name: "keys",
|
||||
Usage: "(internal) Should only be called by SSH server",
|
||||
Description: "Queries the Forgejo database to get the authorized command for a given ssh key fingerprint",
|
||||
Before: PrepareConsoleLoggerLevel(log.FATAL),
|
||||
Action: runKeys,
|
||||
var CmdKeys = cli.Command{
|
||||
Name: "keys",
|
||||
Usage: "This command queries the Gitea database to get the authorized command for a given ssh key fingerprint",
|
||||
Action: runKeys,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "expected",
|
||||
Aliases: []string{"e"},
|
||||
Value: "git",
|
||||
Usage: "Expected user for whom provide key commands",
|
||||
cli.StringFlag{
|
||||
Name: "expected, e",
|
||||
Value: "git",
|
||||
Usage: "Expected user for whom provide key commands",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "username",
|
||||
Aliases: []string{"u"},
|
||||
Value: "",
|
||||
Usage: "Username trying to log in by SSH",
|
||||
cli.StringFlag{
|
||||
Name: "username, u",
|
||||
Value: "",
|
||||
Usage: "Username trying to log in by SSH",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "type",
|
||||
Aliases: []string{"t"},
|
||||
Value: "",
|
||||
Usage: "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
|
||||
cli.StringFlag{
|
||||
Name: "type, t",
|
||||
Value: "",
|
||||
Usage: "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "content",
|
||||
Aliases: []string{"k"},
|
||||
Value: "",
|
||||
Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
|
||||
cli.StringFlag{
|
||||
Name: "content, k",
|
||||
Value: "",
|
||||
Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -78,6 +71,6 @@ func runKeys(c *cli.Context) error {
|
|||
if extra.Error != nil {
|
||||
return extra.Error
|
||||
}
|
||||
_, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString))
|
||||
fmt.Println(strings.TrimSpace(authorizedString))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ import (
|
|||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func runSendMail(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setting.MustInstalled()
|
||||
setting.Init(&setting.Options{})
|
||||
|
||||
if err := argsSet(c, "title"); err != nil {
|
||||
return err
|
||||
|
|
214
cmd/main.go
214
cmd/main.go
|
@ -1,214 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/cmd/forgejo"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// cmdHelp is our own help subcommand with more information
|
||||
// Keep in mind that the "./gitea help"(subcommand) is different from "./gitea --help"(flag), the flag doesn't parse the config or output "DEFAULT CONFIGURATION:" information
|
||||
func cmdHelp() *cli.Command {
|
||||
c := &cli.Command{
|
||||
Name: "help",
|
||||
Aliases: []string{"h"},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
Action: func(c *cli.Context) (err error) {
|
||||
lineage := c.Lineage() // The order is from child to parent: help, doctor, Gitea, {Command:nil}
|
||||
targetCmdIdx := 0
|
||||
if c.Command.Name == "help" {
|
||||
targetCmdIdx = 1
|
||||
}
|
||||
if lineage[targetCmdIdx+1].Command != nil {
|
||||
err = cli.ShowCommandHelp(lineage[targetCmdIdx+1], lineage[targetCmdIdx].Command.Name)
|
||||
} else {
|
||||
err = cli.ShowAppHelp(c)
|
||||
}
|
||||
_, _ = fmt.Fprintf(c.App.Writer, `
|
||||
DEFAULT CONFIGURATION:
|
||||
AppPath: %s
|
||||
WorkPath: %s
|
||||
CustomPath: %s
|
||||
ConfigFile: %s
|
||||
|
||||
`, setting.AppPath, setting.AppWorkPath, setting.CustomPath, setting.CustomConf)
|
||||
return err
|
||||
},
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func appGlobalFlags() []cli.Flag {
|
||||
return []cli.Flag{
|
||||
// make the builtin flags at the top
|
||||
cli.HelpFlag,
|
||||
|
||||
// shared configuration flags, they are for global and for each sub-command at the same time
|
||||
// eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed
|
||||
// keep in mind that the short flags like "-C", "-c" and "-w" are globally polluted, they can't be used for sub-commands anymore.
|
||||
&cli.StringFlag{
|
||||
Name: "custom-path",
|
||||
Aliases: []string{"C"},
|
||||
Usage: "Set custom path (defaults to '{WorkPath}/custom')",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "config",
|
||||
Aliases: []string{"c"},
|
||||
Value: setting.CustomConf,
|
||||
Usage: "Set custom config file (defaults to '{WorkPath}/custom/conf/app.ini')",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "work-path",
|
||||
Aliases: []string{"w"},
|
||||
Usage: "Set Forgejo's working path (defaults to the directory of the Forgejo binary)",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func prepareSubcommandWithConfig(command *cli.Command, globalFlags []cli.Flag) {
|
||||
command.Flags = append(append([]cli.Flag{}, globalFlags...), command.Flags...)
|
||||
command.Action = prepareWorkPathAndCustomConf(command.Action)
|
||||
command.HideHelp = true
|
||||
if command.Name != "help" {
|
||||
command.Subcommands = append(command.Subcommands, cmdHelp())
|
||||
}
|
||||
for i := range command.Subcommands {
|
||||
prepareSubcommandWithConfig(command.Subcommands[i], globalFlags)
|
||||
}
|
||||
}
|
||||
|
||||
// prepareWorkPathAndCustomConf wraps the Action to prepare the work path and custom config
|
||||
// It can't use "Before", because each level's sub-command's Before will be called one by one, so the "init" would be done multiple times
|
||||
func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context) error {
|
||||
return func(ctx *cli.Context) error {
|
||||
var args setting.ArgWorkPathAndCustomConf
|
||||
// from children to parent, check the global flags
|
||||
for _, curCtx := range ctx.Lineage() {
|
||||
if curCtx.IsSet("work-path") && args.WorkPath == "" {
|
||||
args.WorkPath = curCtx.String("work-path")
|
||||
}
|
||||
if curCtx.IsSet("custom-path") && args.CustomPath == "" {
|
||||
args.CustomPath = curCtx.String("custom-path")
|
||||
}
|
||||
if curCtx.IsSet("config") && args.CustomConf == "" {
|
||||
args.CustomConf = curCtx.String("config")
|
||||
}
|
||||
}
|
||||
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
|
||||
if ctx.Bool("help") || action == nil {
|
||||
// the default behavior of "urfave/cli": "nil action" means "show help"
|
||||
return cmdHelp().Action(ctx)
|
||||
}
|
||||
return action(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func NewMainApp(version, versionExtra string) *cli.App {
|
||||
path, err := os.Executable()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
executable := filepath.Base(path)
|
||||
|
||||
var subCmdsStandalone []*cli.Command = make([]*cli.Command, 0, 10)
|
||||
var subCmdWithConfig []*cli.Command = make([]*cli.Command, 0, 10)
|
||||
|
||||
//
|
||||
// If the executable is forgejo-cli, provide a Forgejo specific CLI
|
||||
// that is NOT compatible with Gitea.
|
||||
//
|
||||
if executable == "forgejo-cli" {
|
||||
subCmdsStandalone = append(subCmdsStandalone, forgejo.CmdActions(context.Background()))
|
||||
} else {
|
||||
//
|
||||
// Otherwise provide a Gitea compatible CLI which includes Forgejo
|
||||
// specific additions under the forgejo-cli subcommand. It allows
|
||||
// admins to migration from Gitea to Forgejo by replacing the gitea
|
||||
// binary and rename it to forgejo if they want.
|
||||
//
|
||||
subCmdsStandalone = append(subCmdsStandalone, forgejo.CmdForgejo(context.Background()))
|
||||
subCmdWithConfig = append(subCmdWithConfig, CmdActions)
|
||||
}
|
||||
|
||||
return innerNewMainApp(version, versionExtra, subCmdsStandalone, subCmdWithConfig)
|
||||
}
|
||||
|
||||
func innerNewMainApp(version, versionExtra string, subCmdsStandaloneArgs, subCmdWithConfigArgs []*cli.Command) *cli.App {
|
||||
app := cli.NewApp()
|
||||
app.HelpName = "forgejo"
|
||||
app.Name = "Forgejo"
|
||||
app.Usage = "Beyond coding. We forge."
|
||||
app.Description = `By default, forgejo will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".`
|
||||
app.Version = version + versionExtra
|
||||
app.EnableBashCompletion = true
|
||||
|
||||
// these sub-commands need to use config file
|
||||
subCmdWithConfig := []*cli.Command{
|
||||
cmdHelp(), // the "help" sub-command was used to show the more information for "work path" and "custom config"
|
||||
CmdWeb,
|
||||
CmdServ,
|
||||
CmdHook,
|
||||
CmdKeys,
|
||||
CmdDump,
|
||||
CmdAdmin,
|
||||
CmdMigrate,
|
||||
CmdDoctor,
|
||||
CmdManager,
|
||||
CmdEmbedded,
|
||||
CmdMigrateStorage,
|
||||
CmdDumpRepository,
|
||||
CmdRestoreRepository,
|
||||
}
|
||||
|
||||
subCmdWithConfig = append(subCmdWithConfig, subCmdWithConfigArgs...)
|
||||
|
||||
// these sub-commands do not need the config file, and they do not depend on any path or environment variable.
|
||||
subCmdStandalone := []*cli.Command{
|
||||
CmdCert,
|
||||
CmdGenerate,
|
||||
CmdDocs,
|
||||
}
|
||||
subCmdStandalone = append(subCmdStandalone, subCmdsStandaloneArgs...)
|
||||
|
||||
app.DefaultCommand = CmdWeb.Name
|
||||
|
||||
globalFlags := appGlobalFlags()
|
||||
app.Flags = append(app.Flags, cli.VersionFlag)
|
||||
app.Flags = append(app.Flags, globalFlags...)
|
||||
app.HideHelp = true // use our own help action to show helps (with more information like default config)
|
||||
app.Before = PrepareConsoleLoggerLevel(log.INFO)
|
||||
for i := range subCmdWithConfig {
|
||||
prepareSubcommandWithConfig(subCmdWithConfig[i], globalFlags)
|
||||
}
|
||||
app.Commands = append(app.Commands, subCmdWithConfig...)
|
||||
app.Commands = append(app.Commands, subCmdStandalone...)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func RunMainApp(app *cli.App, args ...string) error {
|
||||
err := app.Run(args)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if strings.HasPrefix(err.Error(), "flag provided but not defined:") {
|
||||
// the cli package should already have output the error message, so just exit
|
||||
cli.OsExiter(1)
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintf(app.ErrWriter, "Command error: %v\n", err)
|
||||
cli.OsExiter(1)
|
||||
return err
|
||||
}
|
166
cmd/main_test.go
166
cmd/main_test.go
|
@ -4,175 +4,13 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m)
|
||||
}
|
||||
|
||||
func makePathOutput(workPath, customPath, customConf string) string {
|
||||
return fmt.Sprintf("WorkPath=%s\nCustomPath=%s\nCustomConf=%s", workPath, customPath, customConf)
|
||||
}
|
||||
|
||||
func newTestApp(testCmdAction func(ctx *cli.Context) error) *cli.App {
|
||||
app := NewMainApp("version", "version-extra")
|
||||
testCmd := &cli.Command{Name: "test-cmd", Action: testCmdAction}
|
||||
prepareSubcommandWithConfig(testCmd, appGlobalFlags())
|
||||
app.Commands = append(app.Commands, testCmd)
|
||||
app.DefaultCommand = testCmd.Name
|
||||
return app
|
||||
}
|
||||
|
||||
type runResult struct {
|
||||
Stdout string
|
||||
Stderr string
|
||||
ExitCode int
|
||||
}
|
||||
|
||||
func runTestApp(app *cli.App, args ...string) (runResult, error) {
|
||||
outBuf := new(strings.Builder)
|
||||
errBuf := new(strings.Builder)
|
||||
app.Writer = outBuf
|
||||
app.ErrWriter = errBuf
|
||||
exitCode := -1
|
||||
defer test.MockVariableValue(&cli.ErrWriter, app.ErrWriter)()
|
||||
defer test.MockVariableValue(&cli.OsExiter, func(code int) {
|
||||
if exitCode == -1 {
|
||||
exitCode = code // save the exit code once and then reset the writer (to simulate the exit)
|
||||
app.Writer, app.ErrWriter, cli.ErrWriter = io.Discard, io.Discard, io.Discard
|
||||
}
|
||||
})()
|
||||
err := RunMainApp(app, args...)
|
||||
return runResult{outBuf.String(), errBuf.String(), exitCode}, err
|
||||
}
|
||||
|
||||
func TestCliCmd(t *testing.T) {
|
||||
defaultWorkPath := filepath.Dir(setting.AppPath)
|
||||
defaultCustomPath := filepath.Join(defaultWorkPath, "custom")
|
||||
defaultCustomConf := filepath.Join(defaultCustomPath, "conf/app.ini")
|
||||
|
||||
cli.CommandHelpTemplate = "(command help template)"
|
||||
cli.AppHelpTemplate = "(app help template)"
|
||||
cli.SubcommandHelpTemplate = "(subcommand help template)"
|
||||
|
||||
cases := []struct {
|
||||
env map[string]string
|
||||
cmd string
|
||||
exp string
|
||||
}{
|
||||
// main command help
|
||||
{
|
||||
cmd: "./gitea help",
|
||||
exp: "DEFAULT CONFIGURATION:",
|
||||
},
|
||||
|
||||
// parse paths
|
||||
{
|
||||
cmd: "./gitea test-cmd",
|
||||
exp: makePathOutput(defaultWorkPath, defaultCustomPath, defaultCustomConf),
|
||||
},
|
||||
{
|
||||
cmd: "./gitea -c /tmp/app.ini test-cmd",
|
||||
exp: makePathOutput(defaultWorkPath, defaultCustomPath, "/tmp/app.ini"),
|
||||
},
|
||||
{
|
||||
cmd: "./gitea test-cmd -c /tmp/app.ini",
|
||||
exp: makePathOutput(defaultWorkPath, defaultCustomPath, "/tmp/app.ini"),
|
||||
},
|
||||
{
|
||||
env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
|
||||
cmd: "./gitea test-cmd",
|
||||
exp: makePathOutput("/tmp", "/tmp/custom", "/tmp/custom/conf/app.ini"),
|
||||
},
|
||||
{
|
||||
env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
|
||||
cmd: "./gitea test-cmd --work-path /tmp/other",
|
||||
exp: makePathOutput("/tmp/other", "/tmp/other/custom", "/tmp/other/custom/conf/app.ini"),
|
||||
},
|
||||
{
|
||||
env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
|
||||
cmd: "./gitea test-cmd --config /tmp/app-other.ini",
|
||||
exp: makePathOutput("/tmp", "/tmp/custom", "/tmp/app-other.ini"),
|
||||
},
|
||||
}
|
||||
|
||||
app := newTestApp(func(ctx *cli.Context) error {
|
||||
_, _ = fmt.Fprint(ctx.App.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
|
||||
return nil
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: "..",
|
||||
})
|
||||
var envBackup []string
|
||||
for _, s := range os.Environ() {
|
||||
if strings.HasPrefix(s, "GITEA_") && strings.Contains(s, "=") {
|
||||
envBackup = append(envBackup, s)
|
||||
}
|
||||
}
|
||||
clearGiteaEnv := func() {
|
||||
for _, s := range os.Environ() {
|
||||
if strings.HasPrefix(s, "GITEA_") {
|
||||
_ = os.Unsetenv(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
clearGiteaEnv()
|
||||
for _, s := range envBackup {
|
||||
k, v, _ := strings.Cut(s, "=")
|
||||
_ = os.Setenv(k, v)
|
||||
}
|
||||
}()
|
||||
|
||||
for _, c := range cases {
|
||||
clearGiteaEnv()
|
||||
for k, v := range c.env {
|
||||
_ = os.Setenv(k, v)
|
||||
}
|
||||
args := strings.Split(c.cmd, " ") // for test only, "split" is good enough
|
||||
r, err := runTestApp(app, args...)
|
||||
assert.NoError(t, err, c.cmd)
|
||||
assert.NotEmpty(t, c.exp, c.cmd)
|
||||
assert.Contains(t, r.Stdout, c.exp, c.cmd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCliCmdError(t *testing.T) {
|
||||
app := newTestApp(func(ctx *cli.Context) error { return fmt.Errorf("normal error") })
|
||||
r, err := runTestApp(app, "./gitea", "test-cmd")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, 1, r.ExitCode)
|
||||
assert.Equal(t, "", r.Stdout)
|
||||
assert.Equal(t, "Command error: normal error\n", r.Stderr)
|
||||
|
||||
app = newTestApp(func(ctx *cli.Context) error { return cli.Exit("exit error", 2) })
|
||||
r, err = runTestApp(app, "./gitea", "test-cmd")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, 2, r.ExitCode)
|
||||
assert.Equal(t, "", r.Stdout)
|
||||
assert.Equal(t, "exit error\n", r.Stderr)
|
||||
|
||||
app = newTestApp(func(ctx *cli.Context) error { return nil })
|
||||
r, err = runTestApp(app, "./gitea", "test-cmd", "--no-such")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, 1, r.ExitCode)
|
||||
assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stdout)
|
||||
assert.Equal(t, "", r.Stderr) // the cli package's strange behavior, the error message is not in stderr ....
|
||||
|
||||
app = newTestApp(func(ctx *cli.Context) error { return nil })
|
||||
r, err = runTestApp(app, "./gitea", "test-cmd")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called
|
||||
assert.Equal(t, "", r.Stdout)
|
||||
assert.Equal(t, "", r.Stderr)
|
||||
}
|
||||
|
|
|
@ -9,16 +9,16 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
// CmdManager represents the manager command
|
||||
CmdManager = &cli.Command{
|
||||
CmdManager = cli.Command{
|
||||
Name: "manager",
|
||||
Usage: "Manage the running forgejo process",
|
||||
Description: "This is a command for managing the running forgejo process",
|
||||
Subcommands: []*cli.Command{
|
||||
Usage: "Manage the running gitea process",
|
||||
Description: "This is a command for managing the running gitea process",
|
||||
Subcommands: []cli.Command{
|
||||
subcmdShutdown,
|
||||
subcmdRestart,
|
||||
subcmdReloadTemplates,
|
||||
|
@ -27,80 +27,80 @@ var (
|
|||
subCmdProcesses,
|
||||
},
|
||||
}
|
||||
subcmdShutdown = &cli.Command{
|
||||
subcmdShutdown = cli.Command{
|
||||
Name: "shutdown",
|
||||
Usage: "Gracefully shutdown the running process",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
Action: runShutdown,
|
||||
}
|
||||
subcmdRestart = &cli.Command{
|
||||
subcmdRestart = cli.Command{
|
||||
Name: "restart",
|
||||
Usage: "Gracefully restart the running process - (not implemented for windows servers)",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
Action: runRestart,
|
||||
}
|
||||
subcmdReloadTemplates = &cli.Command{
|
||||
subcmdReloadTemplates = cli.Command{
|
||||
Name: "reload-templates",
|
||||
Usage: "Reload template files in the running process",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
Action: runReloadTemplates,
|
||||
}
|
||||
subcmdFlushQueues = &cli.Command{
|
||||
subcmdFlushQueues = cli.Command{
|
||||
Name: "flush-queues",
|
||||
Usage: "Flush queues in the running process",
|
||||
Action: runFlushQueues,
|
||||
Flags: []cli.Flag{
|
||||
&cli.DurationFlag{
|
||||
cli.DurationFlag{
|
||||
Name: "timeout",
|
||||
Value: 60 * time.Second,
|
||||
Usage: "Timeout for the flushing process",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "non-blocking",
|
||||
Usage: "Set to true to not wait for flush to complete before returning",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
}
|
||||
subCmdProcesses = &cli.Command{
|
||||
subCmdProcesses = cli.Command{
|
||||
Name: "processes",
|
||||
Usage: "Display running processes within the current process",
|
||||
Action: runProcesses,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "flat",
|
||||
Usage: "Show processes as flat table rather than as tree",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "no-system",
|
||||
Usage: "Do not show system processes",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "stacktraces",
|
||||
Usage: "Show stacktraces",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "json",
|
||||
Usage: "Output as json",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "cancel",
|
||||
Usage: "Process PID to cancel. (Only available for non-system processes.)",
|
||||
},
|
||||
|
|
|
@ -10,61 +10,49 @@ import (
|
|||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultLoggingFlags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "logger",
|
||||
Usage: `Logger name - will default to "default"`,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
}, cli.StringFlag{
|
||||
Name: "writer",
|
||||
Usage: "Name of the log writer - will default to mode",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
}, cli.StringFlag{
|
||||
Name: "level",
|
||||
Usage: "Logging level for the new logger",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "stacktrace-level",
|
||||
Aliases: []string{"L"},
|
||||
Usage: "Stacktrace logging level",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "flags",
|
||||
Aliases: []string{"F"},
|
||||
Usage: "Flags for the logger",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "expression",
|
||||
Aliases: []string{"e"},
|
||||
Usage: "Matching expression for the logger",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "prefix",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Prefix for the logger",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
}, cli.StringFlag{
|
||||
Name: "stacktrace-level, L",
|
||||
Usage: "Stacktrace logging level",
|
||||
}, cli.StringFlag{
|
||||
Name: "flags, F",
|
||||
Usage: "Flags for the logger",
|
||||
}, cli.StringFlag{
|
||||
Name: "expression, e",
|
||||
Usage: "Matching expression for the logger",
|
||||
}, cli.StringFlag{
|
||||
Name: "prefix, p",
|
||||
Usage: "Prefix for the logger",
|
||||
}, cli.BoolFlag{
|
||||
Name: "color",
|
||||
Usage: "Use color in the logs",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
}, cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
}
|
||||
|
||||
subcmdLogging = &cli.Command{
|
||||
subcmdLogging = cli.Command{
|
||||
Name: "logging",
|
||||
Usage: "Adjust logging commands",
|
||||
Subcommands: []*cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
{
|
||||
Name: "pause",
|
||||
Usage: "Pause logging (Forgejo will buffer logs up to a certain point and will drop them after that point)",
|
||||
Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
|
@ -73,16 +61,16 @@ var (
|
|||
Name: "resume",
|
||||
Usage: "Resume logging",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
Action: runResumeLogging,
|
||||
}, {
|
||||
Name: "release-and-reopen",
|
||||
Usage: "Cause Forgejo to release and re-open files used for logging",
|
||||
Usage: "Cause Gitea to release and re-open files used for logging",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
|
@ -92,9 +80,9 @@ var (
|
|||
Usage: "Remove a logger",
|
||||
ArgsUsage: "[name] Name of logger to remove",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
}, &cli.StringFlag{
|
||||
}, cli.StringFlag{
|
||||
Name: "logger",
|
||||
Usage: `Logger name - will default to "default"`,
|
||||
},
|
||||
|
@ -103,48 +91,32 @@ var (
|
|||
}, {
|
||||
Name: "add",
|
||||
Usage: "Add a logger",
|
||||
Subcommands: []*cli.Command{
|
||||
Subcommands: []cli.Command{
|
||||
{
|
||||
Name: "file",
|
||||
Usage: "Add a file logger",
|
||||
Flags: append(defaultLoggingFlags, []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "filename",
|
||||
Aliases: []string{"f"},
|
||||
Usage: "Filename for the logger - this must be set.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "rotate",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Rotate logs",
|
||||
Value: true,
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
Name: "max-size",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Maximum size in bytes before rotation",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "daily",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Rotate logs daily",
|
||||
Value: true,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "max-days",
|
||||
Aliases: []string{"D"},
|
||||
Usage: "Maximum number of daily logs to keep",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "compress",
|
||||
Aliases: []string{"z"},
|
||||
Usage: "Compress rotated logs",
|
||||
Value: true,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "compression-level",
|
||||
Aliases: []string{"Z"},
|
||||
Usage: "Compression level to use",
|
||||
cli.StringFlag{
|
||||
Name: "filename, f",
|
||||
Usage: "Filename for the logger - this must be set.",
|
||||
}, cli.BoolTFlag{
|
||||
Name: "rotate, r",
|
||||
Usage: "Rotate logs",
|
||||
}, cli.Int64Flag{
|
||||
Name: "max-size, s",
|
||||
Usage: "Maximum size in bytes before rotation",
|
||||
}, cli.BoolTFlag{
|
||||
Name: "daily, d",
|
||||
Usage: "Rotate logs daily",
|
||||
}, cli.IntFlag{
|
||||
Name: "max-days, D",
|
||||
Usage: "Maximum number of daily logs to keep",
|
||||
}, cli.BoolTFlag{
|
||||
Name: "compress, z",
|
||||
Usage: "Compress rotated logs",
|
||||
}, cli.IntFlag{
|
||||
Name: "compression-level, Z",
|
||||
Usage: "Compression level to use",
|
||||
},
|
||||
}...),
|
||||
Action: runAddFileLogger,
|
||||
|
@ -152,25 +124,18 @@ var (
|
|||
Name: "conn",
|
||||
Usage: "Add a net conn logger",
|
||||
Flags: append(defaultLoggingFlags, []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "reconnect-on-message",
|
||||
Aliases: []string{"R"},
|
||||
Usage: "Reconnect to host for every message",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "reconnect",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Reconnect to host when connection is dropped",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "protocol",
|
||||
Aliases: []string{"P"},
|
||||
Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "address",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Host address and port to connect to (defaults to :7020)",
|
||||
cli.BoolFlag{
|
||||
Name: "reconnect-on-message, R",
|
||||
Usage: "Reconnect to host for every message",
|
||||
}, cli.BoolFlag{
|
||||
Name: "reconnect, r",
|
||||
Usage: "Reconnect to host when connection is dropped",
|
||||
}, cli.StringFlag{
|
||||
Name: "protocol, P",
|
||||
Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
|
||||
}, cli.StringFlag{
|
||||
Name: "address, a",
|
||||
Usage: "Host address and port to connect to (defaults to :7020)",
|
||||
},
|
||||
}...),
|
||||
Action: runAddConnLogger,
|
||||
|
@ -180,10 +145,9 @@ var (
|
|||
Name: "log-sql",
|
||||
Usage: "Set LogSQL",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
}, cli.BoolFlag{
|
||||
Name: "off",
|
||||
Usage: "Switch off SQL logging",
|
||||
},
|
||||
|
@ -214,7 +178,7 @@ func runAddConnLogger(c *cli.Context) error {
|
|||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
vals := map[string]any{}
|
||||
vals := map[string]interface{}{}
|
||||
mode := "conn"
|
||||
vals["net"] = "tcp"
|
||||
if c.IsSet("protocol") {
|
||||
|
@ -244,7 +208,7 @@ func runAddFileLogger(c *cli.Context) error {
|
|||
defer cancel()
|
||||
|
||||
setup(ctx, c.Bool("debug"))
|
||||
vals := map[string]any{}
|
||||
vals := map[string]interface{}{}
|
||||
mode := "file"
|
||||
if c.IsSet("filename") {
|
||||
vals["filename"] = c.String("filename")
|
||||
|
@ -272,7 +236,7 @@ func runAddFileLogger(c *cli.Context) error {
|
|||
return commonAddLogger(c, mode, vals)
|
||||
}
|
||||
|
||||
func commonAddLogger(c *cli.Context, mode string, vals map[string]any) error {
|
||||
func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) error {
|
||||
if len(c.String("level")) > 0 {
|
||||
vals["level"] = log.LevelFromString(c.String("level")).String()
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ import (
|
|||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdMigrate represents the available migrate sub-command.
|
||||
var CmdMigrate = &cli.Command{
|
||||
var CmdMigrate = cli.Command{
|
||||
Name: "migrate",
|
||||
Usage: "Migrate the database",
|
||||
Description: "This is a command for migrating the database, so that you can run gitea admin create-user before starting the server.",
|
||||
|
|
|
@ -20,73 +20,70 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdMigrateStorage represents the available migrate storage sub-command.
|
||||
var CmdMigrateStorage = &cli.Command{
|
||||
var CmdMigrateStorage = cli.Command{
|
||||
Name: "migrate-storage",
|
||||
Usage: "Migrate the storage",
|
||||
Description: "Copies stored files from storage configured in app.ini to parameter-configured storage",
|
||||
Action: runMigrateStorage,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "type",
|
||||
Aliases: []string{"t"},
|
||||
Value: "",
|
||||
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log'",
|
||||
cli.StringFlag{
|
||||
Name: "type, t",
|
||||
Value: "",
|
||||
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log'",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "storage",
|
||||
Aliases: []string{"s"},
|
||||
Value: "",
|
||||
Usage: "New storage type: local (default) or minio",
|
||||
cli.StringFlag{
|
||||
Name: "storage, s",
|
||||
Value: "",
|
||||
Usage: "New storage type: local (default) or minio",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "path",
|
||||
Aliases: []string{"p"},
|
||||
Value: "",
|
||||
Usage: "New storage placement if store is local (leave blank for default)",
|
||||
cli.StringFlag{
|
||||
Name: "path, p",
|
||||
Value: "",
|
||||
Usage: "New storage placement if store is local (leave blank for default)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "minio-endpoint",
|
||||
Value: "",
|
||||
Usage: "Minio storage endpoint",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "minio-access-key-id",
|
||||
Value: "",
|
||||
Usage: "Minio storage accessKeyID",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "minio-secret-access-key",
|
||||
Value: "",
|
||||
Usage: "Minio storage secretAccessKey",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "minio-bucket",
|
||||
Value: "",
|
||||
Usage: "Minio storage bucket",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "minio-location",
|
||||
Value: "",
|
||||
Usage: "Minio storage location to create bucket",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "minio-base-path",
|
||||
Value: "",
|
||||
Usage: "Minio storage base path on the bucket",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "minio-use-ssl",
|
||||
Usage: "Enable SSL for minio",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "minio-insecure-skip-verify",
|
||||
Usage: "Skip SSL verification",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "minio-checksum-algorithm",
|
||||
Value: "",
|
||||
Usage: "Minio checksum algorithm (default/md5)",
|
||||
|
@ -182,32 +179,30 @@ func runMigrateStorage(ctx *cli.Context) error {
|
|||
switch strings.ToLower(ctx.String("storage")) {
|
||||
case "":
|
||||
fallthrough
|
||||
case string(setting.LocalStorageType):
|
||||
case string(storage.LocalStorageType):
|
||||
p := ctx.String("path")
|
||||
if p == "" {
|
||||
log.Fatal("Path must be given when storage is local")
|
||||
log.Fatal("Path must be given when storage is loal")
|
||||
return nil
|
||||
}
|
||||
dstStorage, err = storage.NewLocalStorage(
|
||||
stdCtx,
|
||||
&setting.Storage{
|
||||
storage.LocalStorageConfig{
|
||||
Path: p,
|
||||
})
|
||||
case string(setting.MinioStorageType):
|
||||
case string(storage.MinioStorageType):
|
||||
dstStorage, err = storage.NewMinioStorage(
|
||||
stdCtx,
|
||||
&setting.Storage{
|
||||
MinioConfig: setting.MinioStorageConfig{
|
||||
Endpoint: ctx.String("minio-endpoint"),
|
||||
AccessKeyID: ctx.String("minio-access-key-id"),
|
||||
SecretAccessKey: ctx.String("minio-secret-access-key"),
|
||||
Bucket: ctx.String("minio-bucket"),
|
||||
Location: ctx.String("minio-location"),
|
||||
BasePath: ctx.String("minio-base-path"),
|
||||
UseSSL: ctx.Bool("minio-use-ssl"),
|
||||
InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"),
|
||||
ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"),
|
||||
},
|
||||
storage.MinioStorageConfig{
|
||||
Endpoint: ctx.String("minio-endpoint"),
|
||||
AccessKeyID: ctx.String("minio-access-key-id"),
|
||||
SecretAccessKey: ctx.String("minio-secret-access-key"),
|
||||
Bucket: ctx.String("minio-bucket"),
|
||||
Location: ctx.String("minio-location"),
|
||||
BasePath: ctx.String("minio-base-path"),
|
||||
UseSSL: ctx.Bool("minio-use-ssl"),
|
||||
InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"),
|
||||
ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"),
|
||||
})
|
||||
default:
|
||||
return fmt.Errorf("unsupported storage type: %s", ctx.String("storage"))
|
||||
|
|
|
@ -9,12 +9,10 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/packages"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
packages_module "code.gitea.io/gitea/modules/packages"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
|
||||
|
@ -31,7 +29,7 @@ func TestMigratePackages(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
defer buf.Close()
|
||||
|
||||
v, f, err := packages_service.CreatePackageAndAddFile(db.DefaultContext, &packages_service.PackageCreationInfo{
|
||||
v, f, err := packages_service.CreatePackageAndAddFile(&packages_service.PackageCreationInfo{
|
||||
PackageInfo: packages_service.PackageInfo{
|
||||
Owner: creator,
|
||||
PackageType: packages.TypeGeneric,
|
||||
|
@ -59,7 +57,7 @@ func TestMigratePackages(t *testing.T) {
|
|||
|
||||
dstStorage, err := storage.NewLocalStorage(
|
||||
ctx,
|
||||
&setting.Storage{
|
||||
storage.LocalStorageConfig{
|
||||
Path: p,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
|
|
@ -9,39 +9,38 @@ import (
|
|||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// CmdRestoreRepository represents the available restore a repository sub-command.
|
||||
var CmdRestoreRepository = &cli.Command{
|
||||
var CmdRestoreRepository = cli.Command{
|
||||
Name: "restore-repo",
|
||||
Usage: "Restore the repository from disk",
|
||||
Description: "This is a command for restoring the repository data.",
|
||||
Action: runRestoreRepository,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "repo_dir",
|
||||
Aliases: []string{"r"},
|
||||
Value: "./data",
|
||||
Usage: "Repository dir path to restore from",
|
||||
cli.StringFlag{
|
||||
Name: "repo_dir, r",
|
||||
Value: "./data",
|
||||
Usage: "Repository dir path to restore from",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "owner_name",
|
||||
Value: "",
|
||||
Usage: "Restore destination owner name",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "repo_name",
|
||||
Value: "",
|
||||
Usage: "Restore destination repository name",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
cli.StringFlag{
|
||||
Name: "units",
|
||||
Value: "",
|
||||
Usage: `Which items will be restored, one or more units should be separated as comma.
|
||||
wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "validation",
|
||||
Usage: "Sanity check the content of the files before trying to load them",
|
||||
},
|
||||
|
@ -52,7 +51,7 @@ func runRestoreRepository(c *cli.Context) error {
|
|||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setting.MustInstalled()
|
||||
setting.Init(&setting.Options{})
|
||||
var units []string
|
||||
if s := c.String("units"); s != "" {
|
||||
units = strings.Split(s, ",")
|
||||
|
|
43
cmd/serv.go
43
cmd/serv.go
|
@ -30,9 +30,9 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/services/lfs"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/kballard/go-shellquote"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -40,17 +40,16 @@ const (
|
|||
)
|
||||
|
||||
// CmdServ represents the available serv sub-command.
|
||||
var CmdServ = &cli.Command{
|
||||
var CmdServ = cli.Command{
|
||||
Name: "serv",
|
||||
Usage: "(internal) Should only be called by SSH shell",
|
||||
Usage: "This command should only be called by SSH shell",
|
||||
Description: "Serv provides access auth for repositories",
|
||||
Before: PrepareConsoleLoggerLevel(log.FATAL),
|
||||
Action: runServ,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "enable-pprof",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
|
@ -62,7 +61,7 @@ func setup(ctx context.Context, debug bool) {
|
|||
} else {
|
||||
setupConsoleLogger(log.FATAL, false, os.Stderr)
|
||||
}
|
||||
setting.MustInstalled()
|
||||
setting.Init(&setting.Options{})
|
||||
if debug {
|
||||
setting.RunMode = "dev"
|
||||
}
|
||||
|
@ -95,7 +94,7 @@ var (
|
|||
|
||||
// fail prints message to stdout, it's mainly used for git serv and git hook commands.
|
||||
// The output will be passed to git client and shown to user.
|
||||
func fail(ctx context.Context, userMessage, logMsgFmt string, args ...any) error {
|
||||
func fail(ctx context.Context, userMessage, logMsgFmt string, args ...interface{}) error {
|
||||
if userMessage == "" {
|
||||
userMessage = "Internal Server Error (no specific error)"
|
||||
}
|
||||
|
@ -103,12 +102,12 @@ func fail(ctx context.Context, userMessage, logMsgFmt string, args ...any) error
|
|||
// There appears to be a chance to cause a zombie process and failure to read the Exit status
|
||||
// if nothing is outputted on stdout.
|
||||
_, _ = fmt.Fprintln(os.Stdout, "")
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Forgejo:", userMessage)
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
|
||||
|
||||
if logMsgFmt != "" {
|
||||
logMsg := fmt.Sprintf(logMsgFmt, args...)
|
||||
if !setting.IsProd {
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Forgejo:", logMsg)
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Gitea:", logMsg)
|
||||
}
|
||||
if userMessage != "" {
|
||||
if unicode.IsPunct(rune(userMessage[len(userMessage)-1])) {
|
||||
|
@ -119,7 +118,7 @@ func fail(ctx context.Context, userMessage, logMsgFmt string, args ...any) error
|
|||
}
|
||||
_ = private.SSHLog(ctx, true, logMsg)
|
||||
}
|
||||
return cli.Exit("", 1)
|
||||
return cli.NewExitError("", 1)
|
||||
}
|
||||
|
||||
// handleCliResponseExtra handles the extra response from the cli sub-commands
|
||||
|
@ -130,7 +129,7 @@ func handleCliResponseExtra(extra private.ResponseExtra) error {
|
|||
_, _ = fmt.Fprintln(os.Stdout, extra.UserMsg)
|
||||
}
|
||||
if extra.HasError() {
|
||||
return cli.Exit(extra.Error, 1)
|
||||
return cli.NewExitError(extra.Error, 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -143,24 +142,24 @@ func runServ(c *cli.Context) error {
|
|||
setup(ctx, c.Bool("debug"))
|
||||
|
||||
if setting.SSH.Disabled {
|
||||
println("Forgejo: SSH has been disabled")
|
||||
println("Gitea: SSH has been disabled")
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.NArg() < 1 {
|
||||
if len(c.Args()) < 1 {
|
||||
if err := cli.ShowSubcommandHelp(c); err != nil {
|
||||
fmt.Printf("error showing subcommand help: %v\n", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
keys := strings.Split(c.Args().First(), "-")
|
||||
keys := strings.Split(c.Args()[0], "-")
|
||||
if len(keys) != 2 || keys[0] != "key" {
|
||||
return fail(ctx, "Key ID format error", "Invalid key argument: %s", c.Args().First())
|
||||
return fail(ctx, "Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
||||
}
|
||||
keyID, err := strconv.ParseInt(keys[1], 10, 64)
|
||||
if err != nil {
|
||||
return fail(ctx, "Key ID parsing error", "Invalid key argument: %s", c.Args().Get(1))
|
||||
return fail(ctx, "Key ID parsing error", "Invalid key argument: %s", c.Args()[1])
|
||||
}
|
||||
|
||||
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
||||
|
@ -171,13 +170,13 @@ func runServ(c *cli.Context) error {
|
|||
}
|
||||
switch key.Type {
|
||||
case asymkey_model.KeyTypeDeploy:
|
||||
println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Forgejo does not provide shell access.")
|
||||
println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.")
|
||||
case asymkey_model.KeyTypePrincipal:
|
||||
println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Forgejo does not provide shell access.")
|
||||
println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Gitea does not provide shell access.")
|
||||
default:
|
||||
println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Forgejo does not provide shell access.")
|
||||
println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.")
|
||||
}
|
||||
println("If this is unexpected, please log in with password and setup Forgejo under another user.")
|
||||
println("If this is unexpected, please log in with password and setup Gitea under another user.")
|
||||
return nil
|
||||
} else if c.Bool("debug") {
|
||||
log.Debug("SSH_ORIGINAL_COMMAND: %s", os.Getenv("SSH_ORIGINAL_COMMAND"))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue