Compare commits
75 commits
forgejo
...
soft-fork/
Author | SHA1 | Date | |
---|---|---|---|
|
3d3d08c555 | ||
|
c63c00b39b | ||
|
cd1eadd923 | ||
|
de2905919d | ||
|
7e0812674d | ||
|
2084f3fa11 | ||
|
9fe826605f | ||
|
3e5d45a2ab | ||
|
6c6dba480c | ||
|
e18debcb6a | ||
|
598756833e | ||
|
8968396cbc | ||
|
31d86205d2 | ||
|
a57b214e36 | ||
|
c73ac63696 | ||
|
852b42bc7a | ||
|
5b2f1d7149 | ||
|
4570fb591a | ||
|
bd47ee33c2 | ||
|
2eb223c0f6 | ||
|
7a1c9fa236 | ||
|
134bf83982 | ||
|
59c0454c21 | ||
|
084e3b5e2f | ||
|
d187381f73 | ||
|
529c7a09f7 | ||
|
c806addcd0 | ||
|
e5bbc626c1 | ||
|
b0b44778b4 | ||
|
165409d8ff | ||
|
7632171832 | ||
|
c6e5a2962c | ||
|
5f93039e0d | ||
|
adf449a115 | ||
|
810a983f4b | ||
|
b84f38e71c | ||
|
665119370f | ||
|
aa9d06dbac | ||
|
e1402ca319 | ||
|
e9faa1f4e0 | ||
|
ba0b21b930 | ||
|
ee04baa5f9 | ||
|
b44dae67f3 | ||
|
538ca28ee8 | ||
|
28d7612b3e | ||
|
8d5277a7e1 | ||
|
85d91c420b | ||
|
a1ca01f37f | ||
|
2e43bd580d | ||
|
e8021f281f | ||
|
cd26466622 | ||
|
ba3df01314 | ||
|
e00eb6d9b3 | ||
|
861c05c2f3 | ||
|
33b4f02d90 | ||
|
f817d97f85 | ||
|
e603cd3dcf | ||
|
805c72c9ce | ||
|
22e63701a8 | ||
|
69894fbc82 | ||
|
225d6f7ab7 | ||
|
7e6ccb52ff | ||
|
5d05f7f9f6 | ||
|
aa3a7249f7 | ||
|
df4099247f | ||
|
929b75ee39 | ||
|
a427f8dae5 | ||
|
984081f08d | ||
|
98dbce5e14 | ||
|
b4fb5f64c6 | ||
|
59d0824a3d | ||
|
57069811d1 | ||
|
b6ab473395 | ||
|
08da63cc4d | ||
|
43a54a64e3 |
256 changed files with 9352 additions and 3141 deletions
337
.deadcode-out
Normal file
337
.deadcode-out
Normal file
|
@ -0,0 +1,337 @@
|
|||
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/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 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
|
||||
|
21
.forgejo/cascading-pr-end-to-end
Executable file
21
.forgejo/cascading-pr-end-to-end
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/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
|
12
.forgejo/cascading-release-end-to-end
Executable file
12
.forgejo/cascading-release-end-to-end
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/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
Normal file
3
.forgejo/testdata/build-release/Dockerfile
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
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
Normal file
5
.forgejo/testdata/build-release/Makefile
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
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
|
0
.forgejo/testdata/build-release/modules/public/bindata.go
vendored
Normal file
0
.forgejo/testdata/build-release/modules/public/bindata.go
vendored
Normal file
0
.forgejo/testdata/build-release/public/assets/css/placeholder
vendored
Normal file
0
.forgejo/testdata/build-release/public/assets/css/placeholder
vendored
Normal file
0
.forgejo/testdata/build-release/public/assets/fonts/placeholder
vendored
Normal file
0
.forgejo/testdata/build-release/public/assets/fonts/placeholder
vendored
Normal file
0
.forgejo/testdata/build-release/public/assets/js/placeholder
vendored
Normal file
0
.forgejo/testdata/build-release/public/assets/js/placeholder
vendored
Normal file
107
.forgejo/workflows/build-release-integration.yml
Normal file
107
.forgejo/workflows/build-release-integration.yml
Normal file
|
@ -0,0 +1,107 @@
|
|||
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
|
169
.forgejo/workflows/build-release.yml
Normal file
169
.forgejo/workflows/build-release.yml
Normal file
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# 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"
|
83
.forgejo/workflows/cascade-setup-end-to-end.yml
Normal file
83
.forgejo/workflows/cascade-setup-end-to-end.yml
Normal file
|
@ -0,0 +1,83 @@
|
|||
# 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
|
37
.forgejo/workflows/e2e.yml
Normal file
37
.forgejo/workflows/e2e.yml
Normal file
|
@ -0,0 +1,37 @@
|
|||
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
|
27
.forgejo/workflows/mirror.yml
Normal file
27
.forgejo/workflows/mirror.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
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/*
|
76
.forgejo/workflows/publish-release.yml
Normal file
76
.forgejo/workflows/publish-release.yml
Normal file
|
@ -0,0 +1,76 @@
|
|||
# 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 }}
|
211
.forgejo/workflows/testing.yml
Normal file
211
.forgejo/workflows/testing.yml
Normal file
|
@ -0,0 +1,211 @@
|
|||
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 .
|
||||
- name: install git >= 2.42
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
apt-get -q install -qq -y git
|
||||
rm /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
- 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 & git >= 2.42
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
apt-get install --no-install-recommends -qq -y git git-lfs
|
||||
rm /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
- 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 & git >= 2.42
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
apt-get install --no-install-recommends -qq -y git git-lfs
|
||||
rm /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
- 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
|
||||
RACE_ENABLED: true
|
||||
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 & git >= 2.42
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
apt-get install --no-install-recommends -qq -y git git-lfs
|
||||
rm /etc/apt/sources.list.d/testing.list
|
||||
apt-get update -qq
|
||||
- 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 sqlite sqlite_unlock_notify
|
||||
- run: |
|
||||
su forgejo -c 'make test-sqlite-migration test-sqlite'
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
RACE_ENABLED: true
|
||||
TEST_TAGS: sqlite sqlite_unlock_notify
|
||||
USE_REPO_TEST_DIR: 1
|
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -1,5 +1,5 @@
|
|||
* text=auto eol=lf
|
||||
*.tmpl linguist-language=Handlebars
|
||||
*.tmpl linguist-language=go-html-template
|
||||
/assets/*.json linguist-generated
|
||||
/public/assets/img/svg/*.svg linguist-generated
|
||||
/templates/swagger/v1_json.tmpl linguist-generated
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
<!-- NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue -->
|
||||
|
||||
<!--
|
||||
1. Please speak English, this is the language all maintainers can speak and write.
|
||||
2. Please ask questions or configuration/deploy problems on our Discord
|
||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
||||
3. Please take a moment to check that your issue doesn't already exist.
|
||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
|
||||
5. Please give all relevant information below for bug reports, because
|
||||
incomplete details will be handled as an invalid report.
|
||||
-->
|
||||
|
||||
- Gitea version (or commit ref):
|
||||
- Git version:
|
||||
- Operating system:
|
||||
<!-- Please include information on whether you built gitea yourself, used one of our downloads or are using some other package -->
|
||||
<!-- Please also tell us how you are running gitea, 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 -->
|
||||
- Database (use `[x]`):
|
||||
- [ ] PostgreSQL
|
||||
- [ ] MySQL
|
||||
- [ ] MSSQL
|
||||
- [ ] SQLite
|
||||
- Can you reproduce the bug at https://try.gitea.io:
|
||||
- [ ] Yes (provide example URL)
|
||||
- [ ] No
|
||||
- Log gist:
|
||||
<!-- It really is important to provide pertinent logs -->
|
||||
<!-- Please read https://docs.gitea.com/administration/logging-config#collecting-logs-for-help -->
|
||||
<!-- In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini -->
|
||||
|
||||
## Description
|
||||
<!-- If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please
|
||||
disable the proxy/CDN fully and connect to gitea directly to confirm
|
||||
the issue still persists without those services. -->
|
||||
|
||||
...
|
||||
|
||||
|
||||
## Screenshots
|
||||
|
||||
<!-- **If this issue involves the Web Interface, please include a screenshot** -->
|
63
.gitea/issue_template/bug-report-ui.yaml
Normal file
63
.gitea/issue_template/bug-report-ui.yaml
Normal file
|
@ -0,0 +1,63 @@
|
|||
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
|
90
.gitea/issue_template/bug-report.yaml
Normal file
90
.gitea/issue_template/bug-report.yaml
Normal file
|
@ -0,0 +1,90 @@
|
|||
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
|
16
.gitea/issue_template/config.yml
Normal file
16
.gitea/issue_template/config.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
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.
|
31
.gitea/issue_template/feature-request.yaml
Normal file
31
.gitea/issue_template/feature-request.yaml
Normal file
|
@ -0,0 +1,31 @@
|
|||
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.
|
4
.gitea/pull_request_template.md
Normal file
4
.gitea/pull_request_template.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
<!--
|
||||
Before submitting a PR, please read the contributing guidelines:
|
||||
https://codeberg.org/forgejo/forgejo/src/branch/main/CONTRIBUTING.md
|
||||
-->
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
|
@ -1,2 +0,0 @@
|
|||
open_collective: gitea
|
||||
custom: https://www.bountysource.com/teams/gitea
|
91
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
91
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
|
@ -1,91 +0,0 @@
|
|||
name: Bug Report
|
||||
description: Found something you weren't expecting? Report it here!
|
||||
labels: ["type/bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
1. Please speak English, this is the language all maintainers can speak and write.
|
||||
2. Please ask questions or configuration/deploy problems on our Discord
|
||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
||||
3. Make sure you are using the latest release and
|
||||
take a moment to check that your issue hasn't been reported before.
|
||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
|
||||
5. It's really important to provide pertinent details and logs (https://docs.gitea.com/help/support),
|
||||
incomplete details will be handled as an invalid report.
|
||||
- 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 are using a proxy or a CDN (e.g. Cloudflare) in front of Gitea, please disable the proxy/CDN fully and access Gitea directly to confirm the issue still persists without those services.
|
||||
- type: input
|
||||
id: gitea-ver
|
||||
attributes:
|
||||
label: Gitea Version
|
||||
description: Gitea version (or commit reference) of your instance
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: can-reproduce
|
||||
attributes:
|
||||
label: Can you reproduce the bug on the Gitea demo site?
|
||||
description: |
|
||||
If so, please provide a URL in the Description field
|
||||
URL of Gitea demo: https://try.gitea.io
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It's really important to provide pertinent logs
|
||||
Please read https://docs.gitea.com/administration/logging-config#collecting-logs-for-help
|
||||
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini
|
||||
- type: input
|
||||
id: logs
|
||||
attributes:
|
||||
label: Log Gist
|
||||
description: Please provide a gist URL of your logs, with any sensitive information (e.g. API keys) removed/hidden
|
||||
- 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 Gitea
|
||||
- type: textarea
|
||||
id: run-info
|
||||
attributes:
|
||||
label: How are you running Gitea?
|
||||
description: |
|
||||
Please include information on whether you built Gitea yourself, used one of our downloads, are using https://try.gitea.io or are using some other package
|
||||
Please also tell us how you are running Gitea, 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:
|
||||
- PostgreSQL
|
||||
- MySQL/MariaDB
|
||||
- MSSQL
|
||||
- SQLite
|
17
.github/ISSUE_TEMPLATE/config.yml
vendored
17
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,17 +0,0 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Security Concern
|
||||
url: https://tinyurl.com/security-gitea
|
||||
about: For security concerns, please send a mail to security@gitea.io instead of opening a public issue.
|
||||
- name: Discord Server
|
||||
url: https://discord.gg/Gitea
|
||||
about: Please ask questions and discuss configuration or deployment problems here.
|
||||
- name: Discourse Forum
|
||||
url: https://discourse.gitea.io
|
||||
about: Questions and configuration or deployment problems can also be discussed on our forum.
|
||||
- name: Frequently Asked Questions
|
||||
url: https://docs.gitea.com/help/faq
|
||||
about: Please check if your question isn't mentioned here.
|
||||
- name: Crowdin Translations
|
||||
url: https://crowdin.com/project/gitea
|
||||
about: Translations are managed here.
|
24
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
24
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
|
@ -1,24 +0,0 @@
|
|||
name: Feature Request
|
||||
description: Got an idea for a feature that Gitea doesn't have currently? Submit your idea here!
|
||||
labels: ["type/proposal"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
1. Please speak English, this is the language all maintainers can speak and write.
|
||||
2. Please ask questions or configuration/deploy problems on our Discord
|
||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
||||
3. Please take a moment to check that your feature hasn't already been suggested.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Feature Description
|
||||
placeholder: |
|
||||
I think it would be great if Gitea had...
|
||||
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
|
66
.github/ISSUE_TEMPLATE/ui.bug-report.yaml
vendored
66
.github/ISSUE_TEMPLATE/ui.bug-report.yaml
vendored
|
@ -1,66 +0,0 @@
|
|||
name: Web Interface Bug Report
|
||||
description: Something doesn't look quite as it should? Report it here!
|
||||
labels: ["type/bug", "topic/ui"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
1. Please speak English, this is the language all maintainers can speak and write.
|
||||
2. Please ask questions or configuration/deploy problems on our Discord
|
||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
||||
3. Please take a moment to check that your issue doesn't already exist.
|
||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
|
||||
5. Please give all relevant information below for bug reports, because
|
||||
incomplete details will be handled as an invalid report.
|
||||
6. In particular it's really important to provide pertinent logs. If you are certain that this is a javascript
|
||||
error, show us the javascript console. If the error appears to relate to Gitea the server you must also give us
|
||||
DEBUG level logs. (See https://docs.gitea.com/administration/logging-config#collecting-logs-for-help)
|
||||
- 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 using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please disable the proxy/CDN fully and connect to gitea directly to confirm the issue still persists without those services.
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: Please provide at least 1 screenshot showing the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: gitea-ver
|
||||
attributes:
|
||||
label: Gitea Version
|
||||
description: Gitea version (or commit reference) your instance is running
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: can-reproduce
|
||||
attributes:
|
||||
label: Can you reproduce the bug on the Gitea demo site?
|
||||
description: |
|
||||
If so, please provide a URL in the Description field
|
||||
URL of Gitea demo: https://try.gitea.io
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-ver
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: The operating system you are using to access Gitea
|
||||
- type: input
|
||||
id: browser-ver
|
||||
attributes:
|
||||
label: Browser Version
|
||||
description: The browser and version that you are using to access Gitea
|
||||
validations:
|
||||
required: true
|
5
.github/actionlint.yaml
vendored
5
.github/actionlint.yaml
vendored
|
@ -1,5 +0,0 @@
|
|||
self-hosted-runner:
|
||||
labels:
|
||||
- actuated-4cpu-8gb
|
||||
- actuated-4cpu-16gb
|
||||
- nscloud
|
36
.github/labeler.yml
vendored
36
.github/labeler.yml
vendored
|
@ -1,36 +0,0 @@
|
|||
modifies/docs:
|
||||
- "**/*.md"
|
||||
- "docs/**"
|
||||
|
||||
modifies/frontend:
|
||||
- "web_src/**/*"
|
||||
|
||||
modifies/templates:
|
||||
- all: ["templates/**", "!templates/swagger/v1_json.tmpl"]
|
||||
|
||||
modifies/api:
|
||||
- "routers/api/**"
|
||||
- "templates/swagger/v1_json.tmpl"
|
||||
|
||||
modifies/cli:
|
||||
- "cmd/**"
|
||||
|
||||
modifies/translation:
|
||||
- "options/locale/*.ini"
|
||||
|
||||
modifies/migrations:
|
||||
- "models/migrations/**/*"
|
||||
|
||||
modifies/internal:
|
||||
- "Makefile"
|
||||
- "Dockerfile"
|
||||
- "Dockerfile.rootless"
|
||||
- "docker/**"
|
||||
- "webpack.config.js"
|
||||
- ".eslintrc.yaml"
|
||||
- ".golangci.yml"
|
||||
- ".markdownlint.yaml"
|
||||
- ".spectral.yaml"
|
||||
- ".stylelintrc.yaml"
|
||||
- ".yamllint.yaml"
|
||||
- ".github/**"
|
9
.github/pull_request_template.md
vendored
9
.github/pull_request_template.md
vendored
|
@ -1,9 +0,0 @@
|
|||
<!-- start tips -->
|
||||
Please check the following:
|
||||
1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for backports.
|
||||
2. Make sure you have read contributing guidelines: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md .
|
||||
3. Describe what your pull request does and which issue you're targeting (if any).
|
||||
4. It is recommended to enable "Allow edits by maintainers", so maintainers can help more easily.
|
||||
5. Your input here will be included in the commit message when this PR has been merged. If you don't want some content to be included, please separate them with a line like `---`.
|
||||
6. Delete all these tips before posting.
|
||||
<!-- end tips -->
|
29
.github/workflows/cron-licenses.yml
vendored
29
.github/workflows/cron-licenses.yml
vendored
|
@ -1,29 +0,0 @@
|
|||
name: cron-licenses
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "7 0 * * 1" # every Monday at 00:07 UTC
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
cron-licenses:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'go-gitea/gitea'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- run: make generate-license generate-gitignore
|
||||
timeout-minutes: 40
|
||||
- name: push translations to repo
|
||||
uses: appleboy/git-push-action@v0.0.3
|
||||
with:
|
||||
author_email: "teabot@gitea.io"
|
||||
author_name: GiteaBot
|
||||
branch: main
|
||||
commit: true
|
||||
commit_message: "[skip ci] Updated licenses and gitignores"
|
||||
remote: "git@github.com:go-gitea/gitea.git"
|
||||
ssh_key: ${{ secrets.DEPLOY_KEY }}
|
22
.github/workflows/cron-lock.yml
vendored
22
.github/workflows/cron-lock.yml
vendored
|
@ -1,22 +0,0 @@
|
|||
name: cron-lock
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # every day at 00:00 UTC
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: lock
|
||||
|
||||
jobs:
|
||||
action:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'go-gitea/gitea'
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v5
|
||||
with:
|
||||
issue-inactive-days: 45
|
49
.github/workflows/cron-translations.yml
vendored
49
.github/workflows/cron-translations.yml
vendored
|
@ -1,49 +0,0 @@
|
|||
name: cron-translations
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "7 0 * * *" # every day at 00:07 UTC
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
crowdin-pull:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'go-gitea/gitea'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: download from crowdin
|
||||
uses: docker://jonasfranz/crowdin
|
||||
env:
|
||||
CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }}
|
||||
PLUGIN_DOWNLOAD: true
|
||||
PLUGIN_EXPORT_DIR: options/locale/
|
||||
PLUGIN_IGNORE_BRANCH: true
|
||||
PLUGIN_PROJECT_IDENTIFIER: gitea
|
||||
- name: update locales
|
||||
run: ./build/update-locales.sh
|
||||
- name: push translations to repo
|
||||
uses: appleboy/git-push-action@v0.0.3
|
||||
with:
|
||||
author_email: "teabot@gitea.io"
|
||||
author_name: GiteaBot
|
||||
branch: main
|
||||
commit: true
|
||||
commit_message: "[skip ci] Updated translations via Crowdin"
|
||||
remote: "git@github.com:go-gitea/gitea.git"
|
||||
ssh_key: ${{ secrets.DEPLOY_KEY }}
|
||||
crowdin-push:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'go-gitea/gitea'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: push translations to crowdin
|
||||
uses: docker://jonasfranz/crowdin
|
||||
env:
|
||||
CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }}
|
||||
PLUGIN_UPLOAD: true
|
||||
PLUGIN_EXPORT_DIR: options/locale/
|
||||
PLUGIN_IGNORE_BRANCH: true
|
||||
PLUGIN_PROJECT_IDENTIFIER: gitea
|
||||
PLUGIN_FILES: |
|
||||
locale_en-US.ini: options/locale/locale_en-US.ini
|
||||
PLUGIN_BRANCH: main
|
25
.github/workflows/disk-clean.yml
vendored
25
.github/workflows/disk-clean.yml
vendored
|
@ -1,25 +0,0 @@
|
|||
name: disk-clean
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
# this might remove tools that are actually needed,
|
||||
# if set to "true" but frees about 6 GB
|
||||
tool-cache: false
|
||||
|
||||
# all of these default to true, but feel free to set to
|
||||
# "false" if necessary for your workflow
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: true
|
97
.github/workflows/files-changed.yml
vendored
97
.github/workflows/files-changed.yml
vendored
|
@ -1,97 +0,0 @@
|
|||
name: files-changed
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
outputs:
|
||||
backend:
|
||||
value: ${{ jobs.detect.outputs.backend }}
|
||||
frontend:
|
||||
value: ${{ jobs.detect.outputs.frontend }}
|
||||
docs:
|
||||
value: ${{ jobs.detect.outputs.docs }}
|
||||
actions:
|
||||
value: ${{ jobs.detect.outputs.actions }}
|
||||
templates:
|
||||
value: ${{ jobs.detect.outputs.templates }}
|
||||
docker:
|
||||
value: ${{ jobs.detect.outputs.docker }}
|
||||
swagger:
|
||||
value: ${{ jobs.detect.outputs.swagger }}
|
||||
yaml:
|
||||
value: ${{ jobs.detect.outputs.yaml }}
|
||||
|
||||
jobs:
|
||||
detect:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 3
|
||||
outputs:
|
||||
backend: ${{ steps.changes.outputs.backend }}
|
||||
frontend: ${{ steps.changes.outputs.frontend }}
|
||||
docs: ${{ steps.changes.outputs.docs }}
|
||||
actions: ${{ steps.changes.outputs.actions }}
|
||||
templates: ${{ steps.changes.outputs.templates }}
|
||||
docker: ${{ steps.changes.outputs.docker }}
|
||||
swagger: ${{ steps.changes.outputs.swagger }}
|
||||
yaml: ${{ steps.changes.outputs.yaml }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
backend:
|
||||
- "**/*.go"
|
||||
- "templates/**/*.tmpl"
|
||||
- "assets/emoji.json"
|
||||
- "go.mod"
|
||||
- "go.sum"
|
||||
- "Makefile"
|
||||
- ".golangci.yml"
|
||||
- ".editorconfig"
|
||||
|
||||
frontend:
|
||||
- "**/*.js"
|
||||
- "web_src/**"
|
||||
- "assets/emoji.json"
|
||||
- "package.json"
|
||||
- "package-lock.json"
|
||||
- "Makefile"
|
||||
- ".eslintrc.yaml"
|
||||
- ".stylelintrc.yaml"
|
||||
- ".npmrc"
|
||||
|
||||
docs:
|
||||
- "**/*.md"
|
||||
- "docs/**"
|
||||
- ".markdownlint.yaml"
|
||||
- "package.json"
|
||||
- "package-lock.json"
|
||||
|
||||
actions:
|
||||
- ".github/workflows/*"
|
||||
- "Makefile"
|
||||
|
||||
templates:
|
||||
- "templates/**/*.tmpl"
|
||||
- "pyproject.toml"
|
||||
- "poetry.lock"
|
||||
|
||||
docker:
|
||||
- "Dockerfile"
|
||||
- "Dockerfile.rootless"
|
||||
- "docker/**"
|
||||
- "Makefile"
|
||||
|
||||
swagger:
|
||||
- "templates/swagger/v1_json.tmpl"
|
||||
- "Makefile"
|
||||
- "package.json"
|
||||
- "package-lock.json"
|
||||
- ".spectral.yaml"
|
||||
|
||||
yaml:
|
||||
- "**/*.yml"
|
||||
- "**/*.yaml"
|
||||
- ".yamllint.yaml"
|
||||
- "pyproject.toml"
|
||||
- "poetry.lock"
|
182
.github/workflows/pull-compliance.yml
vendored
182
.github/workflows/pull-compliance.yml
vendored
|
@ -1,182 +0,0 @@
|
|||
name: compliance
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
files-changed:
|
||||
uses: ./.github/workflows/files-changed.yml
|
||||
|
||||
lint-backend:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make lint-backend
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
|
||||
lint-templates:
|
||||
if: needs.files-changed.outputs.templates == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- run: pip install poetry
|
||||
- run: make deps-py
|
||||
- run: make lint-templates
|
||||
|
||||
lint-yaml:
|
||||
if: needs.files-changed.outputs.yaml == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- run: pip install poetry
|
||||
- run: make deps-py
|
||||
- run: make lint-yaml
|
||||
|
||||
lint-swagger:
|
||||
if: needs.files-changed.outputs.swagger == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: make deps-frontend
|
||||
- run: make lint-swagger
|
||||
|
||||
lint-go-windows:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make lint-go-windows lint-go-vet
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
GOOS: windows
|
||||
GOARCH: amd64
|
||||
|
||||
lint-go-gogit:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make lint-go
|
||||
env:
|
||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||
|
||||
checks-backend:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- run: make deps-backend deps-tools
|
||||
- run: make --always-make checks-backend # ensure the "go-licenses" make target runs
|
||||
|
||||
frontend:
|
||||
if: needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: make deps-frontend
|
||||
- run: make lint-frontend
|
||||
- run: make checks-frontend
|
||||
- run: make test-frontend
|
||||
- run: make frontend
|
||||
|
||||
backend:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
# no frontend build here as backend should be able to build
|
||||
# even without any frontend files
|
||||
- run: make deps-backend
|
||||
- run: go build -o gitea_no_gcc # test if build succeeds without the sqlite tag
|
||||
- name: build-backend-arm64
|
||||
run: make backend # test cross compile
|
||||
env:
|
||||
GOOS: linux
|
||||
GOARCH: arm64
|
||||
TAGS: bindata gogit
|
||||
- name: build-backend-windows
|
||||
run: go build -o gitea_windows
|
||||
env:
|
||||
GOOS: windows
|
||||
GOARCH: amd64
|
||||
TAGS: bindata gogit
|
||||
- name: build-backend-386
|
||||
run: go build -o gitea_linux_386 # test if compatible with 32 bit
|
||||
env:
|
||||
GOOS: linux
|
||||
GOARCH: 386
|
||||
|
||||
docs:
|
||||
if: needs.files-changed.outputs.docs == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: make deps-frontend
|
||||
- run: make lint-md
|
||||
- run: make docs
|
||||
|
||||
actions:
|
||||
if: needs.files-changed.outputs.actions == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- run: make lint-actions
|
215
.github/workflows/pull-db-tests.yml
vendored
215
.github/workflows/pull-db-tests.yml
vendored
|
@ -1,215 +0,0 @@
|
|||
name: db-tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
files-changed:
|
||||
uses: ./.github/workflows/files-changed.yml
|
||||
|
||||
test-pgsql:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
pgsql:
|
||||
image: postgres:12
|
||||
env:
|
||||
POSTGRES_DB: test
|
||||
POSTGRES_PASSWORD: postgres
|
||||
ports:
|
||||
- "5432:5432"
|
||||
ldap:
|
||||
image: gitea/test-openldap:latest
|
||||
ports:
|
||||
- "389:389"
|
||||
- "636:636"
|
||||
minio:
|
||||
# as github actions doesn't support "entrypoint", we need to use a non-official image
|
||||
# that has a custom entrypoint set to "minio server /data"
|
||||
image: bitnami/minio:2023.8.31
|
||||
env:
|
||||
MINIO_ROOT_USER: 123456
|
||||
MINIO_ROOT_PASSWORD: 12345678
|
||||
ports:
|
||||
- "9000:9000"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- name: Add hosts to /etc/hosts
|
||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 pgsql ldap minio" | sudo tee -a /etc/hosts'
|
||||
- run: make deps-backend
|
||||
- run: make backend
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: make test-pgsql-migration test-pgsql
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata gogit
|
||||
RACE_ENABLED: true
|
||||
TEST_TAGS: gogit
|
||||
TEST_LDAP: 1
|
||||
USE_REPO_TEST_DIR: 1
|
||||
|
||||
test-sqlite:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- run: make deps-backend
|
||||
- run: make backend
|
||||
env:
|
||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
||||
- run: 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
|
||||
|
||||
test-unit:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
elasticsearch:
|
||||
image: elasticsearch:7.5.0
|
||||
env:
|
||||
discovery.type: single-node
|
||||
ports:
|
||||
- "9200:9200"
|
||||
meilisearch:
|
||||
image: getmeili/meilisearch:v1.2.0
|
||||
env:
|
||||
MEILI_ENV: development # disable auth
|
||||
ports:
|
||||
- "7700:7700"
|
||||
redis:
|
||||
image: redis
|
||||
options: >- # wait until redis has started
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 5s
|
||||
--health-timeout 3s
|
||||
--health-retries 10
|
||||
ports:
|
||||
- 6379:6379
|
||||
minio:
|
||||
image: bitnami/minio:2021.3.17
|
||||
env:
|
||||
MINIO_ACCESS_KEY: 123456
|
||||
MINIO_SECRET_KEY: 12345678
|
||||
ports:
|
||||
- "9000:9000"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- name: Add hosts to /etc/hosts
|
||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch meilisearch smtpimap" | sudo tee -a /etc/hosts'
|
||||
- run: make deps-backend
|
||||
- run: make backend
|
||||
env:
|
||||
TAGS: bindata
|
||||
- name: unit-tests
|
||||
run: make unit-test-coverage test-check
|
||||
env:
|
||||
TAGS: bindata
|
||||
RACE_ENABLED: true
|
||||
GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }}
|
||||
- name: unit-tests-gogit
|
||||
run: make unit-test-coverage test-check
|
||||
env:
|
||||
TAGS: bindata gogit
|
||||
RACE_ENABLED: true
|
||||
GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }}
|
||||
|
||||
test-mysql:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
||||
MYSQL_DATABASE: testgitea
|
||||
ports:
|
||||
- "3306:3306"
|
||||
elasticsearch:
|
||||
image: elasticsearch:7.5.0
|
||||
env:
|
||||
discovery.type: single-node
|
||||
ports:
|
||||
- "9200:9200"
|
||||
smtpimap:
|
||||
image: tabascoterrier/docker-imap-devel:latest
|
||||
ports:
|
||||
- "25:25"
|
||||
- "143:143"
|
||||
- "587:587"
|
||||
- "993:993"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- name: Add hosts to /etc/hosts
|
||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch smtpimap" | sudo tee -a /etc/hosts'
|
||||
- run: make deps-backend
|
||||
- run: make backend
|
||||
env:
|
||||
TAGS: bindata
|
||||
- name: run tests
|
||||
run: make test-mysql-migration integration-test-coverage
|
||||
env:
|
||||
TAGS: bindata
|
||||
RACE_ENABLED: true
|
||||
USE_REPO_TEST_DIR: 1
|
||||
TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200"
|
||||
|
||||
test-mssql:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server:2017-latest
|
||||
env:
|
||||
ACCEPT_EULA: Y
|
||||
MSSQL_PID: Standard
|
||||
SA_PASSWORD: MwantsaSecurePassword1
|
||||
ports:
|
||||
- "1433:1433"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- name: Add hosts to /etc/hosts
|
||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mssql" | sudo tee -a /etc/hosts'
|
||||
- run: make deps-backend
|
||||
- run: make backend
|
||||
env:
|
||||
TAGS: bindata
|
||||
- run: make test-mssql-migration test-mssql
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
TAGS: bindata
|
||||
USE_REPO_TEST_DIR: 1
|
35
.github/workflows/pull-docker-dryrun.yml
vendored
35
.github/workflows/pull-docker-dryrun.yml
vendored
|
@ -1,35 +0,0 @@
|
|||
name: docker-dryrun
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
files-changed:
|
||||
uses: ./.github/workflows/files-changed.yml
|
||||
|
||||
regular:
|
||||
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: false
|
||||
tags: gitea/gitea:linux-amd64
|
||||
|
||||
rootless:
|
||||
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: false
|
||||
file: Dockerfile.rootless
|
||||
tags: gitea/gitea:linux-amd64
|
32
.github/workflows/pull-e2e-tests.yml
vendored
32
.github/workflows/pull-e2e-tests.yml
vendored
|
@ -1,32 +0,0 @@
|
|||
name: e2e-tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
files-changed:
|
||||
uses: ./.github/workflows/files-changed.yml
|
||||
|
||||
test-e2e:
|
||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
|
||||
needs: files-changed
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: make deps-frontend frontend deps-backend
|
||||
- run: npx playwright install --with-deps
|
||||
- run: make test-e2e-sqlite
|
||||
timeout-minutes: 40
|
||||
env:
|
||||
USE_REPO_TEST_DIR: 1
|
20
.github/workflows/pull-labeler.yml
vendored
20
.github/workflows/pull-labeler.yml
vendored
|
@ -1,20 +0,0 @@
|
|||
name: labeler
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
label:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
dot: true
|
134
.github/workflows/release-nightly.yml
vendored
134
.github/workflows/release-nightly.yml
vendored
|
@ -1,134 +0,0 @@
|
|||
name: release-nightly
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, release/v*]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
disk-clean:
|
||||
uses: ./.github/workflows/disk-clean.yml
|
||||
nightly-binary:
|
||||
runs-on: nscloud
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: make deps-frontend deps-backend
|
||||
# xgo build
|
||||
- run: make release
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
- name: import gpg key
|
||||
id: import_gpg
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
||||
- name: sign binaries
|
||||
run: |
|
||||
for f in dist/release/*; do
|
||||
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
|
||||
done
|
||||
# clean branch name to get the folder name in S3
|
||||
- name: Get cleaned branch name
|
||||
id: clean_name
|
||||
run: |
|
||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
||||
echo "Cleaned name is ${REF_NAME}"
|
||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
||||
- name: configure aws
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: ${{ secrets.AWS_REGION }}
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
- name: upload binaries to s3
|
||||
run: |
|
||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
||||
nightly-docker-rootful:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- name: Get cleaned branch name
|
||||
id: clean_name
|
||||
run: |
|
||||
# if main then say nightly otherwise cleanup name
|
||||
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
|
||||
echo "branch=nightly" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
||||
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: fetch go modules
|
||||
run: make vendor
|
||||
- name: build rootful docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}
|
||||
nightly-docker-rootless:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- name: Get cleaned branch name
|
||||
id: clean_name
|
||||
run: |
|
||||
# if main then say nightly otherwise cleanup name
|
||||
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
|
||||
echo "branch=nightly" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
||||
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: fetch go modules
|
||||
run: make vendor
|
||||
- name: build rootless docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
file: Dockerfile.rootless
|
||||
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}-rootless
|
132
.github/workflows/release-tag-rc.yml
vendored
132
.github/workflows/release-tag-rc.yml
vendored
|
@ -1,132 +0,0 @@
|
|||
name: release-tag-rc
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v1*-rc*"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
binary:
|
||||
runs-on: nscloud
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: make deps-frontend deps-backend
|
||||
# xgo build
|
||||
- run: make release
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
- name: import gpg key
|
||||
id: import_gpg
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
||||
- name: sign binaries
|
||||
run: |
|
||||
for f in dist/release/*; do
|
||||
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
|
||||
done
|
||||
# clean branch name to get the folder name in S3
|
||||
- name: Get cleaned branch name
|
||||
id: clean_name
|
||||
run: |
|
||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
|
||||
echo "Cleaned name is ${REF_NAME}"
|
||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
||||
- name: configure aws
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: ${{ secrets.AWS_REGION }}
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
- name: upload binaries to s3
|
||||
run: |
|
||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
||||
- name: Install GH CLI
|
||||
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
|
||||
with:
|
||||
gh-cli-version: 2.39.1
|
||||
- name: create github release
|
||||
run: |
|
||||
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --draft --notes-from-tag dist/release/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
docker-rootful:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/metadata-action@v5
|
||||
id: meta
|
||||
with:
|
||||
images: gitea/gitea
|
||||
flavor: |
|
||||
latest=false
|
||||
# 1.2.3-rc0
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: build rootful docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
docker-rootless:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/metadata-action@v5
|
||||
id: meta
|
||||
with:
|
||||
images: gitea/gitea
|
||||
# each tag below will have the suffix of -rootless
|
||||
flavor: |
|
||||
latest=false
|
||||
suffix=-rootless
|
||||
# 1.2.3-rc0
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: build rootless docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
file: Dockerfile.rootless
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
143
.github/workflows/release-tag-version.yml
vendored
143
.github/workflows/release-tag-version.yml
vendored
|
@ -1,143 +0,0 @@
|
|||
name: release-tag-version
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v1.*"
|
||||
- "!v1*-rc*"
|
||||
- "!v1*-dev"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
binary:
|
||||
runs-on: nscloud
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: make deps-frontend deps-backend
|
||||
# xgo build
|
||||
- run: make release
|
||||
env:
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
- name: import gpg key
|
||||
id: import_gpg
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
||||
- name: sign binaries
|
||||
run: |
|
||||
for f in dist/release/*; do
|
||||
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
|
||||
done
|
||||
# clean branch name to get the folder name in S3
|
||||
- name: Get cleaned branch name
|
||||
id: clean_name
|
||||
run: |
|
||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
|
||||
echo "Cleaned name is ${REF_NAME}"
|
||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
||||
- name: configure aws
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: ${{ secrets.AWS_REGION }}
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
- name: upload binaries to s3
|
||||
run: |
|
||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
||||
- name: Install GH CLI
|
||||
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
|
||||
with:
|
||||
gh-cli-version: 2.39.1
|
||||
- name: create github release
|
||||
run: |
|
||||
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --notes-from-tag dist/release/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
docker-rootful:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/metadata-action@v5
|
||||
id: meta
|
||||
with:
|
||||
images: gitea/gitea
|
||||
# this will generate tags in the following format:
|
||||
# latest
|
||||
# 1
|
||||
# 1.2
|
||||
# 1.2.3
|
||||
tags: |
|
||||
type=semver,pattern={{major}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{version}}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: build rootful docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
docker-rootless:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
||||
- run: git fetch --unshallow --quiet --tags --force
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/metadata-action@v5
|
||||
id: meta
|
||||
with:
|
||||
images: gitea/gitea
|
||||
# each tag below will have the suffix of -rootless
|
||||
flavor: |
|
||||
suffix=-rootless,onlatest=true
|
||||
# this will generate tags in the following format (with -rootless suffix added):
|
||||
# latest
|
||||
# 1
|
||||
# 1.2
|
||||
# 1.2.3
|
||||
tags: |
|
||||
type=semver,pattern={{major}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{version}}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: build rootless docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
file: Dockerfile.rootless
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
|||
# Emacs
|
||||
*~
|
||||
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
|
@ -25,6 +28,9 @@ _cgo_export.*
|
|||
|
||||
_testmain.go
|
||||
|
||||
# folder for project related local files
|
||||
/local/
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
@ -94,6 +100,7 @@ cpu.out
|
|||
/VERSION
|
||||
/.air
|
||||
/.go-licenses
|
||||
/.cur-deadcode-out
|
||||
|
||||
# Snapcraft
|
||||
/gitea_a*.txt
|
||||
|
|
32
CODEOWNERS
Normal file
32
CODEOWNERS
Normal file
|
@ -0,0 +1,32 @@
|
|||
# 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
|
|
@ -1,96 +0,0 @@
|
|||
# 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.
|
587
CONTRIBUTING.md
587
CONTRIBUTING.md
|
@ -1,579 +1,24 @@
|
|||
# Contribution Guidelines
|
||||
# Forgejo Contributor Guide
|
||||
|
||||
<details><summary>Table of Contents</summary>
|
||||
The Forgejo project is run by a community of people who are expected to follow this guide when cooperating on a simple bug fix as well as when changing the governance. For more information about the project, take a look at [the documentation explaining what Forgejo provides](README.md).
|
||||
|
||||
- [Contribution Guidelines](#contribution-guidelines)
|
||||
- [Introduction](#introduction)
|
||||
- [Issues](#issues)
|
||||
- [How to report issues](#how-to-report-issues)
|
||||
- [Types of issues](#types-of-issues)
|
||||
- [Discuss your design before the implementation](#discuss-your-design-before-the-implementation)
|
||||
- [Building Gitea](#building-gitea)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Backend](#backend)
|
||||
- [Frontend](#frontend)
|
||||
- [Design guideline](#design-guideline)
|
||||
- [Styleguide](#styleguide)
|
||||
- [Copyright](#copyright)
|
||||
- [Testing](#testing)
|
||||
- [Translation](#translation)
|
||||
- [Code review](#code-review)
|
||||
- [Pull request format](#pull-request-format)
|
||||
- [PR title and summary](#pr-title-and-summary)
|
||||
- [Milestone](#milestone)
|
||||
- [Labels](#labels)
|
||||
- [Breaking PRs](#breaking-prs)
|
||||
- [What is a breaking PR?](#what-is-a-breaking-pr)
|
||||
- [How to handle breaking PRs?](#how-to-handle-breaking-prs)
|
||||
- [Maintaining open PRs](#maintaining-open-prs)
|
||||
- [Getting PRs merged](#getting-prs-merged)
|
||||
- [Final call](#final-call)
|
||||
- [Commit messages](#commit-messages)
|
||||
- [PR Co-authors](#pr-co-authors)
|
||||
- [PRs targeting `main`](#prs-targeting-main)
|
||||
- [Backport PRs](#backport-prs)
|
||||
- [Documentation](#documentation)
|
||||
- [API v1](#api-v1)
|
||||
- [GitHub API compatibility](#github-api-compatibility)
|
||||
- [Adding/Maintaining API routes](#addingmaintaining-api-routes)
|
||||
- [When to use what HTTP method](#when-to-use-what-http-method)
|
||||
- [Requirements for API routes](#requirements-for-api-routes)
|
||||
- [Backports and Frontports](#backports-and-frontports)
|
||||
- [What is backported?](#what-is-backported)
|
||||
- [How to backport?](#how-to-backport)
|
||||
- [Format of backport PRs](#format-of-backport-prs)
|
||||
- [Frontports](#frontports)
|
||||
- [Developer Certificate of Origin (DCO)](#developer-certificate-of-origin-dco)
|
||||
- [Release Cycle](#release-cycle)
|
||||
- [Maintainers](#maintainers)
|
||||
- [Technical Oversight Committee (TOC)](#technical-oversight-committee-toc)
|
||||
- [Current TOC members](#current-toc-members)
|
||||
- [Previous TOC/owners members](#previous-tocowners-members)
|
||||
- [Governance Compensation](#governance-compensation)
|
||||
- [TOC \& Working groups](#toc--working-groups)
|
||||
- [Roadmap](#roadmap)
|
||||
- [Versions](#versions)
|
||||
- [Releasing Gitea](#releasing-gitea)
|
||||
Sensitive security-related issues should be reported to [security@forgejo.org](mailto:security@forgejo.org) using [encryption](https://keyoxide.org/security@forgejo.org).
|
||||
|
||||
</details>
|
||||
## For everyone involved
|
||||
|
||||
## Introduction
|
||||
- [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)
|
||||
|
||||
This document explains how to contribute changes to the Gitea project. \
|
||||
It assumes you have followed the [installation instructions](https://docs.gitea.com/category/installation). \
|
||||
Sensitive security-related issues should be reported to [security@gitea.io](mailto:security@gitea.io).
|
||||
## For contributors
|
||||
|
||||
For configuring IDEs for Gitea development, see the [contributed IDE configurations](contrib/ide/).
|
||||
- [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/)
|
||||
|
||||
## Issues
|
||||
## For maintainers
|
||||
|
||||
### How to report issues
|
||||
|
||||
Please search the issues on the issue tracker with a variety of related keywords to ensure that your issue has not already been reported.
|
||||
|
||||
If your issue has not been reported yet, [open an issue](https://github.com/go-gitea/gitea/issues/new)
|
||||
and answer the questions so we can understand and reproduce the problematic behavior. \
|
||||
Please write clear and concise instructions so that we can reproduce the behavior — even if it seems obvious. \
|
||||
The more detailed and specific you are, the faster we can fix the issue. \
|
||||
It is really helpful if you can reproduce your problem on a site running on the latest commits, i.e. <https://try.gitea.io>, as perhaps your problem has already been fixed on a current version. \
|
||||
Please follow the guidelines described in [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html) for your report.
|
||||
|
||||
Please be kind, remember that Gitea comes at no cost to you, and you're getting free help.
|
||||
|
||||
### Types of issues
|
||||
|
||||
Typically, issues fall in one of the following categories:
|
||||
|
||||
- `bug`: Something in the frontend or backend behaves unexpectedly
|
||||
- `security issue`: bug that has serious implications such as leaking another users data. Please do not file such issues on the public tracker and send a mail to security@gitea.io instead
|
||||
- `feature`: Completely new functionality. You should describe this feature in enough detail that anyone who reads the issue can understand how it is supposed to be implemented
|
||||
- `enhancement`: An existing feature should get an upgrade
|
||||
- `refactoring`: Parts of the code base don't conform with other parts and should be changed to improve Gitea's maintainability
|
||||
|
||||
### Discuss your design before the implementation
|
||||
|
||||
We welcome submissions. \
|
||||
If you want to change or add something, please let everyone know what you're working on — [file an issue](https://github.com/go-gitea/gitea/issues/new) or comment on an existing one before starting your work!
|
||||
|
||||
Significant changes such as new features must go through the change proposal process before they can be accepted. \
|
||||
This is mainly to save yourself the trouble of implementing it, only to find out that your proposed implementation has some potential problems. \
|
||||
Furthermore, this process gives everyone a chance to validate the design, helps prevent duplication of effort, and ensures that the idea fits inside
|
||||
the goals for the project and tools.
|
||||
|
||||
Pull requests should not be the place for architecture discussions.
|
||||
|
||||
## Building Gitea
|
||||
|
||||
See the [development setup instructions](https://docs.gitea.com/development/hacking-on-gitea).
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Backend
|
||||
|
||||
Go dependencies are managed using [Go Modules](https://golang.org/cmd/go/#hdr-Module_maintenance). \
|
||||
You can find more details in the [go mod documentation](https://go.dev/ref/mod) and the [Go Modules Wiki](https://github.com/golang/go/wiki/Modules).
|
||||
|
||||
Pull requests should only modify `go.mod` and `go.sum` where it is related to your change, be it a bugfix or a new feature. \
|
||||
Apart from that, these files should only be modified by Pull Requests whose only purpose is to update dependencies.
|
||||
|
||||
The `go.mod`, `go.sum` update needs to be justified as part of the PR description,
|
||||
and must be verified by the reviewers and/or merger to always reference
|
||||
an existing upstream commit.
|
||||
|
||||
### Frontend
|
||||
|
||||
For the frontend, we use [npm](https://www.npmjs.com/).
|
||||
|
||||
The same restrictions apply for frontend dependencies as for backend dependencies, with the exceptions that the files for it are `package.json` and `package-lock.json`, and that new versions must always reference an existing version.
|
||||
|
||||
## Design guideline
|
||||
|
||||
Depending on your change, please read the
|
||||
|
||||
- [backend development guideline](https://docs.gitea.com/contributing/guidelines-backend)
|
||||
- [frontend development guideline](https://docs.gitea.com/contributing/guidelines-frontend)
|
||||
- [refactoring guideline](https://docs.gitea.com/contributing/guidelines-refactoring)
|
||||
|
||||
## Styleguide
|
||||
|
||||
You should always run `make fmt` before committing to conform to Gitea's styleguide.
|
||||
|
||||
## Copyright
|
||||
|
||||
New code files that you contribute should use the standard copyright header:
|
||||
|
||||
```
|
||||
// Copyright <current year> The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
```
|
||||
|
||||
Afterwards, copyright should only be modified when the copyright author changes.
|
||||
|
||||
## Testing
|
||||
|
||||
Before submitting a pull request, run all tests to make sure your changes don't cause a regression elsewhere.
|
||||
|
||||
Here's how to run the test suite:
|
||||
|
||||
- code lint
|
||||
|
||||
| | |
|
||||
| :-------------------- | :---------------------------------------------------------------- |
|
||||
|``make lint`` | lint everything (not needed if you only change the front- **or** backend) |
|
||||
|``make lint-frontend`` | lint frontend files |
|
||||
|``make lint-backend`` | lint backend files |
|
||||
|
||||
- run tests (we suggest running them on Linux)
|
||||
|
||||
| Command | Action | |
|
||||
| :------------------------------------- | :----------------------------------------------- | ------------ |
|
||||
|``make test[\#SpecificTestName]`` | run unit test(s) |
|
||||
|``make test-sqlite[\#SpecificTestName]``| run [integration](tests/integration) test(s) for SQLite |[More details](tests/integration/README.md) |
|
||||
|``make test-e2e-sqlite[\#SpecificTestName]``| run [end-to-end](tests/e2e) test(s) for SQLite |[More details](tests/e2e/README.md) |
|
||||
|
||||
## Translation
|
||||
|
||||
All translation work happens on [Crowdin](https://crowdin.com/project/gitea).
|
||||
The only translation that is maintained in this repository is [the English translation](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.ini).
|
||||
It is synced regularly with Crowdin. \
|
||||
Other locales on main branch **should not** be updated manually as they will be overwritten with each sync. \
|
||||
Once a language has reached a **satisfactory percentage** of translated keys (~25%), it will be synced back into this repo and included in the next released version.
|
||||
|
||||
The tool `go run build/backport-locale.go` can be used to backport locales from the main branch to release branches that were missed.
|
||||
|
||||
## Code review
|
||||
|
||||
### Pull request format
|
||||
|
||||
Please try to make your pull request easy to review for us. \
|
||||
For that, please read the [*Best Practices for Faster Reviews*](https://github.com/kubernetes/community/blob/261cb0fd089b64002c91e8eddceebf032462ccd6/contributors/guide/pull-requests.md#best-practices-for-faster-reviews) guide. \
|
||||
It has lots of useful tips for any project you may want to contribute to. \
|
||||
Some of the key points:
|
||||
|
||||
- Make small pull requests. \
|
||||
The smaller, the faster to review and the more likely it will be merged soon.
|
||||
- Don't make changes unrelated to your PR. \
|
||||
Maybe there are typos on some comments, maybe refactoring would be welcome on a function... \
|
||||
but if that is not related to your PR, please make *another* PR for that.
|
||||
- Split big pull requests into multiple small ones. \
|
||||
An incremental change will be faster to review than a huge PR.
|
||||
- Allow edits by maintainers. This way, the maintainers will take care of merging the PR later on instead of you.
|
||||
|
||||
### PR title and summary
|
||||
|
||||
In the PR title, describe the problem you are fixing, not how you are fixing it. \
|
||||
Use the first comment as a summary of your PR. \
|
||||
In the PR summary, you can describe exactly how you are fixing this problem.
|
||||
|
||||
Keep this summary up-to-date as the PR evolves. \
|
||||
If your PR changes the UI, you must add **after** screenshots in the PR summary. \
|
||||
If you are not implementing a new feature, you should also post **before** screenshots for comparison.
|
||||
|
||||
If you are implementing a new feature, your PR will only be merged if your screenshots are up to date.\
|
||||
Furthermore, feature PRs will only be merged if their summary contains a clear usage description (understandable for users) and testing description (understandable for reviewers).
|
||||
You should strive to combine both into a single description.
|
||||
|
||||
Another requirement for merging PRs is that the PR is labeled correctly.\
|
||||
However, this is not your job as a contributor, but the job of the person merging your PR.\
|
||||
If you think that your PR was labeled incorrectly, or notice that it was merged without labels, please let us know.
|
||||
|
||||
If your PR closes some issues, you must note that in a way that both GitHub and Gitea understand, i.e. by appending a paragraph like
|
||||
|
||||
```text
|
||||
Fixes/Closes/Resolves #<ISSUE_NR_X>.
|
||||
Fixes/Closes/Resolves #<ISSUE_NR_Y>.
|
||||
```
|
||||
|
||||
to your summary. \
|
||||
Each issue that will be closed must stand on a separate line.
|
||||
|
||||
### Milestone
|
||||
|
||||
A PR should only be assigned to a milestone if it will likely be merged into the given version. \
|
||||
As a rule of thumb, assume that a PR will stay open for an additional month for every 100 added lines. \
|
||||
PRs without a milestone may not be merged.
|
||||
|
||||
### Labels
|
||||
|
||||
Almost all labels used inside Gitea can be classified as one of the following:
|
||||
|
||||
- `modifies/…`: Determines which parts of the codebase are affected. These labels will be set through the CI.
|
||||
- `topic/…`: Determines the conceptual component of Gitea that is affected, i.e. issues, projects, or authentication. At best, PRs should only target one component but there might be overlap. Must be set manually.
|
||||
- `type/…`: Determines the type of an issue or PR (feature, refactoring, docs, bug, …). If GitHub supported scoped labels, these labels would be exclusive, so you should set **exactly** one, not more or less (every PR should fall into one of the provided categories, and only one).
|
||||
- `issue/…` / `pr/…`: Labels that are specific to issues or PRs respectively and that are only necessary in a given context, i.e. `issue/not-a-bug` or `pr/need-2-approvals`
|
||||
|
||||
Every PR should be labeled correctly with every label that applies.
|
||||
|
||||
There are also some labels that will be managed automatically.\
|
||||
In particular, these are
|
||||
|
||||
- the amount of pending required approvals
|
||||
- has all `backport`s or needs a manual backport
|
||||
|
||||
### Breaking PRs
|
||||
|
||||
#### What is a breaking PR?
|
||||
|
||||
A PR is breaking if it meets one of the following criteria:
|
||||
|
||||
- It changes API output in an incompatible way for existing users
|
||||
- It removes a setting that an admin could previously set (i.e. via `app.ini`)
|
||||
- An admin must do something manually to restore the old behavior
|
||||
|
||||
In particular, this means that adding new settings is not breaking.\
|
||||
Changing the default value of a setting or replacing the setting with another one is breaking, however.
|
||||
|
||||
#### How to handle breaking PRs?
|
||||
|
||||
If your PR has a breaking change, you must add two things to the summary of your PR:
|
||||
|
||||
1. A reasoning why this breaking change is necessary
|
||||
2. A `BREAKING` section explaining in simple terms (understandable for a typical user) how this PR affects users and how to mitigate these changes. This section can look for example like
|
||||
|
||||
```md
|
||||
## :warning: BREAKING :warning:
|
||||
```
|
||||
|
||||
Breaking PRs will not be merged as long as not both of these requirements are met.
|
||||
|
||||
### Maintaining open PRs
|
||||
|
||||
The moment you create a non-draft PR or the moment you convert a draft PR to a non-draft PR is the moment code review starts for it. \
|
||||
Once that happens, do not rebase or squash your branch anymore as it makes it difficult to review the new changes. \
|
||||
Merge the base branch into your branch only when you really need to, i.e. because of conflicting changes in the mean time. \
|
||||
This reduces unnecessary CI runs. \
|
||||
Don't worry about merge commits messing up your commit history as every PR will be squash merged. \
|
||||
This means that all changes are joined into a single new commit whose message is as described below.
|
||||
|
||||
### Getting PRs merged
|
||||
|
||||
Changes to Gitea must be reviewed before they are accepted — no matter who
|
||||
makes the change, even if they are an owner or a maintainer. \
|
||||
The only exception are critical bugs that prevent Gitea from being compiled or started. \
|
||||
Specifically, we require two approvals from maintainers for every PR. \
|
||||
Once this criteria has been met, your PR receives the `lgtm/done` label. \
|
||||
From this point on, your only responsibility is to fix merge conflicts or respond to/implement requests by maintainers. \
|
||||
It is the responsibility of the maintainers from this point to get your PR merged.
|
||||
|
||||
If a PR has the `lgtm/done` label and there are no open discussions or merge conflicts anymore, any maintainer can add the `reviewed/wait-merge` label. \
|
||||
This label means that the PR is part of the merge queue and will be merged as soon as possible. \
|
||||
The merge queue will be cleared in the order of the list below:
|
||||
|
||||
<https://github.com/go-gitea/gitea/pulls?q=is%3Apr+label%3Areviewed%2Fwait-merge+sort%3Acreated-asc+is%3Aopen>
|
||||
|
||||
Gitea uses it's own tool, the <https://github.com/GiteaBot/gitea-backporter> to automate parts of the review process. \
|
||||
This tool does the things listed below automatically:
|
||||
|
||||
- create a backport PR if needed once the initial PR was merged
|
||||
- remove the PR from the merge queue after the PR merged
|
||||
- keep the oldest branch in the merge queue up to date with merges
|
||||
|
||||
### Final call
|
||||
|
||||
If a PR has been ignored for more than 7 days with no comments or reviews, and the author or any maintainer believes it will not survive a long wait (such as a refactoring PR), they can send "final call" to the TOC by mentioning them in a comment.
|
||||
|
||||
After another 7 days, if there is still zero approval, this is considered a polite refusal, and the PR will be closed to avoid wasting further time. Therefore, the "final call" has a cost, and should be used cautiously.
|
||||
|
||||
However, if there are no objections from maintainers, the PR can be merged with only one approval from the TOC (not the author).
|
||||
|
||||
### Commit messages
|
||||
|
||||
Mergers are able and required to rewrite the PR title and summary (the first comment of a PR) so that it can produce an easily understandable commit message if necessary. \
|
||||
The final commit message should no longer contain any uncertainty such as `hopefully, <x> won't happen anymore`. Replace uncertainty with certainty.
|
||||
|
||||
#### PR Co-authors
|
||||
|
||||
A person counts as a PR co-author the moment they (co-)authored a commit that is not simply a `Merge base branch into branch` commit. \
|
||||
Mergers are required to remove such "false-positive" co-authors when writing the commit message. \
|
||||
The true co-authors must remain in the commit message.
|
||||
|
||||
#### PRs targeting `main`
|
||||
|
||||
The commit message of PRs targeting `main` is always
|
||||
|
||||
```bash
|
||||
$PR_TITLE ($PR_INDEX)
|
||||
|
||||
$REWRITTEN_PR_SUMMARY
|
||||
```
|
||||
|
||||
#### Backport PRs
|
||||
|
||||
The commit message of backport PRs is always
|
||||
|
||||
```bash
|
||||
$PR_TITLE ($INITIAL_PR_INDEX) ($BACKPORT_PR_INDEX)
|
||||
|
||||
$REWRITTEN_PR_SUMMARY
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated in the same PR.
|
||||
|
||||
## API v1
|
||||
|
||||
The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [the GitHub API](https://docs.github.com/en/rest).
|
||||
|
||||
### GitHub API compatibility
|
||||
|
||||
Gitea's API should use the same endpoints and fields as the GitHub API as far as possible, unless there are good reasons to deviate. \
|
||||
If Gitea provides functionality that GitHub does not, a new endpoint can be created. \
|
||||
If information is provided by Gitea that is not provided by the GitHub API, a new field can be used that doesn't collide with any GitHub fields. \
|
||||
Updating an existing API should not remove existing fields unless there is a really good reason to do so. \
|
||||
The same applies to status responses. If you notice a problem, feel free to leave a comment in the code for future refactoring to API v2 (which is currently not planned).
|
||||
|
||||
### Adding/Maintaining API routes
|
||||
|
||||
All expected results (errors, success, fail messages) must be documented ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L319-L327)). \
|
||||
All JSON input types must be defined as a struct in [modules/structs/](modules/structs/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L76-L91)) \
|
||||
and referenced in [routers/api/v1/swagger/options.go](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/options.go). \
|
||||
They can then be used like [this example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L318). \
|
||||
All JSON responses must be defined as a struct in [modules/structs/](modules/structs/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L36-L68)) \
|
||||
and referenced in its category in [routers/api/v1/swagger/](routers/api/v1/swagger/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/issue.go#L11-L16)) \
|
||||
They can be used like [this example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L277-L279).
|
||||
|
||||
### When to use what HTTP method
|
||||
|
||||
In general, HTTP methods are chosen as follows:
|
||||
|
||||
- **GET** endpoints return the requested object(s) and status **OK (200)**
|
||||
- **DELETE** endpoints return the status **No Content (204)** and no content either
|
||||
- **POST** endpoints are used to **create** new objects (e.g. a User) and return the status **Created (201)** and the created object
|
||||
- **PUT** endpoints are used to **add/assign** existing Objects (e.g. a user to a team) and return the status **No Content (204)** and no content either
|
||||
- **PATCH** endpoints are used to **edit/change** an existing object and return the changed object and the status **OK (200)**
|
||||
|
||||
### Requirements for API routes
|
||||
|
||||
All parameters of endpoints changing/editing an object must be optional (except the ones to identify the object, which are required).
|
||||
|
||||
Endpoints returning lists must
|
||||
|
||||
- support pagination (`page` & `limit` options in query)
|
||||
- set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
|
||||
|
||||
## Backports and Frontports
|
||||
|
||||
### What is backported?
|
||||
|
||||
We backport PRs given the following circumstances:
|
||||
|
||||
1. Feature freeze is active, but `<version>-rc0` has not been released yet. Here, we backport as much as possible. <!-- TODO: Is that our definition with the new backport bot? -->
|
||||
2. `rc0` has been released. Here, we only backport bug- and security-fixes, and small enhancements. Large PRs such as refactors are not backported anymore. <!-- TODO: Is that our definition with the new backport bot? -->
|
||||
3. We never backport new features.
|
||||
4. We never backport breaking changes except when
|
||||
1. The breaking change has no effect on the vast majority of users
|
||||
2. The component triggering the breaking change is marked as experimental
|
||||
|
||||
### How to backport?
|
||||
|
||||
In the past, it was necessary to manually backport your PRs. \
|
||||
Now, that's not a requirement anymore as our [backport bot](https://github.com/GiteaBot) tries to create backports automatically once the PR is merged when the PR
|
||||
|
||||
- does not have the label `backport/manual`
|
||||
- has the label `backport/<version>`
|
||||
|
||||
The `backport/manual` label signifies either that you want to backport the change yourself, or that there were conflicts when backporting, thus you **must** do it yourself.
|
||||
|
||||
### Format of backport PRs
|
||||
|
||||
The title of backport PRs should be
|
||||
|
||||
```
|
||||
<original PR title> (#<original pr number>)
|
||||
```
|
||||
|
||||
The first two lines of the summary of the backporting PR should be
|
||||
|
||||
```
|
||||
Backport #<original pr number>
|
||||
|
||||
```
|
||||
|
||||
with the rest of the summary and labels matching the original PR.
|
||||
|
||||
### Frontports
|
||||
|
||||
Frontports behave exactly as described above for backports.
|
||||
|
||||
## Developer Certificate of Origin (DCO)
|
||||
|
||||
We consider the act of contributing to the code by submitting a Pull Request as the "Sign off" or agreement to the certifications and terms of the [DCO](DCO) and [MIT license](LICENSE). \
|
||||
No further action is required. \
|
||||
You can also decide to sign off your commits by adding the following line at the end of your commit messages:
|
||||
|
||||
```
|
||||
Signed-off-by: Joe Smith <joe.smith@email.com>
|
||||
```
|
||||
|
||||
If you set the `user.name` and `user.email` Git config options, you can add the line to the end of your commits automatically with `git commit -s`.
|
||||
|
||||
We assume in good faith that the information you provide is legally binding.
|
||||
|
||||
## Release Cycle
|
||||
|
||||
We adopted a release schedule to streamline the process of working on, finishing, and issuing releases. \
|
||||
The overall goal is to make a major release every three or four months, which breaks down into two or three months of general development followed by one month of testing and polishing known as the release freeze. \
|
||||
All the feature pull requests should be
|
||||
merged before feature freeze. And, during the frozen period, a corresponding
|
||||
release branch is open for fixes backported from main branch. Release candidates
|
||||
are made during this period for user testing to
|
||||
obtain a final version that is maintained in this branch.
|
||||
|
||||
During a development cycle, we may also publish any necessary minor releases
|
||||
for the previous version. For example, if the latest, published release is
|
||||
v1.2, then minor changes for the previous release—e.g., v1.1.0 -> v1.1.1—are
|
||||
still possible.
|
||||
|
||||
## Maintainers
|
||||
|
||||
To make sure every PR is checked, we have [maintainers](MAINTAINERS). \
|
||||
Every PR **must** be reviewed by at least two maintainers (or owners) before it can get merged. \
|
||||
For refactoring PRs after a week and documentation only PRs, the approval of only one maintainer is enough. \
|
||||
A maintainer should be a contributor of Gitea and contributed at least
|
||||
4 accepted PRs. A contributor should apply as a maintainer in the
|
||||
[Discord](https://discord.gg/Gitea) `#develop` channel. The team maintainers may invite the contributor. A maintainer
|
||||
should spend some time on code reviews. If a maintainer has no
|
||||
time to do that, they should apply to leave the maintainers team
|
||||
and we will give them the honor of being a member of the [advisors
|
||||
team](https://github.com/orgs/go-gitea/teams/advisors). Of course, if
|
||||
an advisor has time to code review, we will gladly welcome them back
|
||||
to the maintainers team. If a maintainer is inactive for more than 3
|
||||
months and forgets to leave the maintainers team, the owners may move
|
||||
him or her from the maintainers team to the advisors team.
|
||||
For security reasons, Maintainers should use 2FA for their accounts and
|
||||
if possible provide GPG signed commits.
|
||||
https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/
|
||||
https://help.github.com/articles/signing-commits-with-gpg/
|
||||
|
||||
## Technical Oversight Committee (TOC)
|
||||
|
||||
At the start of 2023, the `Owners` team was dissolved. Instead, the governance charter proposed a technical oversight committee (TOC) which expands the ownership team of the Gitea project from three elected positions to six positions. Three positions would be elected as it has been over the past years, and the other three would consist of appointed members from the Gitea company.
|
||||
https://blog.gitea.com/quarterly-23q1/
|
||||
|
||||
When the new community members have been elected, the old members will give up ownership to the newly elected members. For security reasons, TOC members or any account with write access (like a bot) must use 2FA.
|
||||
https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/
|
||||
|
||||
### Current TOC members
|
||||
|
||||
- 2023-01-01 ~ 2023-12-31 - https://blog.gitea.com/quarterly-23q1/
|
||||
- Company
|
||||
- [Jason Song](https://gitea.com/wolfogre) <i@wolfogre.com>
|
||||
- [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
|
||||
- [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
|
||||
- Community
|
||||
- [6543](https://gitea.com/6543) <6543@obermui.de>
|
||||
- [Andrew Thornton](https://gitea.com/zeripath) <art27@cantab.net>
|
||||
- [John Olheiser](https://gitea.com/jolheiser) <john.olheiser@gmail.com>
|
||||
|
||||
### Previous TOC/owners members
|
||||
|
||||
Here's the history of the owners and the time they served:
|
||||
|
||||
- [Lunny Xiao](https://gitea.com/lunny) - 2016, 2017, [2018](https://github.com/go-gitea/gitea/issues/3255), [2019](https://github.com/go-gitea/gitea/issues/5572), [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801), [2022](https://github.com/go-gitea/gitea/issues/17872)
|
||||
- [Kim Carlbäcker](https://github.com/bkcsoft) - 2016, 2017
|
||||
- [Thomas Boerger](https://gitea.com/tboerger) - 2016, 2017
|
||||
- [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) - [2018](https://github.com/go-gitea/gitea/issues/3255), [2019](https://github.com/go-gitea/gitea/issues/5572), [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801)
|
||||
- [Matti Ranta](https://gitea.com/techknowlogick) - [2019](https://github.com/go-gitea/gitea/issues/5572), [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801), [2022](https://github.com/go-gitea/gitea/issues/17872)
|
||||
- [Andrew Thornton](https://gitea.com/zeripath) - [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801), [2022](https://github.com/go-gitea/gitea/issues/17872)
|
||||
|
||||
## Governance Compensation
|
||||
|
||||
Each member of the community elected TOC will be granted $500 each month as compensation for their work.
|
||||
|
||||
Furthermore, any community release manager for a specific release or LTS will be compensated $500 for the delivery of said release.
|
||||
|
||||
These funds will come from community sources like the OpenCollective rather than directly from the company.
|
||||
Only non-company members are eligible for this compensation, and if a member of the community TOC takes the responsibility of release manager, they would only be compensated for their TOC duties.
|
||||
Gitea Ltd employees are not eligible to receive any funds from the OpenCollective unless it is reimbursement for a purchase made for the Gitea project itself.
|
||||
|
||||
## TOC & Working groups
|
||||
|
||||
With Gitea covering many projects outside of the main repository, several groups will be created to help focus on specific areas instead of requiring maintainers to be a jack-of-all-trades. Maintainers are of course more than welcome to be part of multiple groups should they wish to contribute in multiple places.
|
||||
|
||||
The currently proposed groups are:
|
||||
|
||||
- **Core Group**: maintain the primary Gitea repository
|
||||
- **Integration Group**: maintain the Gitea ecosystem's related tools, including go-sdk/tea/changelog/bots etc.
|
||||
- **Documentation Group**: maintain related documents and repositories
|
||||
- **Translation Group**: coordinate with translators and maintain translations
|
||||
- **Security Group**: managed by TOC directly, members are decided by TOC, maintains security patches/responsible for security items
|
||||
|
||||
## Roadmap
|
||||
|
||||
Each year a roadmap will be discussed with the entire Gitea maintainers team, and feedback will be solicited from various stakeholders.
|
||||
TOC members need to review the roadmap every year and work together on the direction of the project.
|
||||
|
||||
When a vote is required for a proposal or other change, the vote of community elected TOC members count slightly more than the vote of company elected TOC members. With this approach, we both avoid ties and ensure that changes align with the mission statement and community opinion.
|
||||
|
||||
You can visit our roadmap on the wiki.
|
||||
|
||||
## Versions
|
||||
|
||||
Gitea has the `main` branch as a tip branch and has version branches
|
||||
such as `release/v1.19`. `release/v1.19` is a release branch and we will
|
||||
tag `v1.19.0` for binary download. If `v1.19.0` has bugs, we will accept
|
||||
pull requests on the `release/v1.19` branch and publish a `v1.19.1` tag,
|
||||
after bringing the bug fix also to the main branch.
|
||||
|
||||
Since the `main` branch is a tip version, if you wish to use Gitea
|
||||
in production, please download the latest release tag version. All the
|
||||
branches will be protected via GitHub, all the PRs to every branch must
|
||||
be reviewed by two maintainers and must pass the automatic tests.
|
||||
|
||||
## Releasing Gitea
|
||||
|
||||
- Let $vmaj, $vmin and $vpat be Major, Minor and Patch version numbers, $vpat should be rc1, rc2, 0, 1, ...... $vmaj.$vmin will be kept the same as milestones on github or gitea in future.
|
||||
- Before releasing, confirm all the version's milestone issues or PRs has been resolved. Then discuss the release on Discord channel #maintainers and get agreed with almost all the owners and mergers. Or you can declare the version and if nobody against in about serval hours.
|
||||
- If this is a big version first you have to create PR for changelog on branch `main` with PRs with label `changelog` and after it has been merged do following steps:
|
||||
- Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`.
|
||||
- When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin`
|
||||
- If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged.
|
||||
- Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`.
|
||||
- And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically create a release and upload all the compiled binary. (But currently it doesn't add the release notes automatically. Maybe we should fix that.)
|
||||
- If needed send a frontport PR for the changelog to branch `main` and update the version in `docs/config.yaml` to refer to the new version.
|
||||
- Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release.
|
||||
- Verify all release assets were correctly published through CI on dl.gitea.com and GitHub releases. Once ACKed:
|
||||
- bump the version of https://dl.gitea.com/gitea/version.json
|
||||
- merge the blog post PR
|
||||
- announce the release in discord `#announcements`
|
||||
- [Release management](https://forgejo.org/docs/latest/developer/release/)
|
||||
- [Secrets](https://forgejo.org/docs/latest/developer/secrets/)
|
||||
|
|
45
Dockerfile
45
Dockerfile
|
@ -1,5 +1,6 @@
|
|||
# Build stage
|
||||
FROM docker.io/library/golang:1.21-alpine3.19 AS build-env
|
||||
FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
|
||||
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.21-alpine3.19 as build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
|
@ -9,24 +10,33 @@ ARG TAGS="sqlite sqlite_unlock_notify"
|
|||
ENV TAGS "bindata timetzdata $TAGS"
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
|
||||
# Build deps
|
||||
RUN apk --no-cache add \
|
||||
build-base \
|
||||
git \
|
||||
nodejs \
|
||||
npm \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
#
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
# Checkout version if set
|
||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
&& make clean-all build
|
||||
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
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
|
||||
|
||||
# Copy local files
|
||||
COPY docker/root /tmp/local
|
||||
|
@ -42,7 +52,7 @@ RUN chmod 755 /tmp/local/usr/bin/entrypoint \
|
|||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM docker.io/library/alpine:3.19
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
LABEL maintainer="contact@forgejo.org"
|
||||
|
||||
EXPOSE 22 3000
|
||||
|
||||
|
@ -81,6 +91,7 @@ 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 --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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Build stage
|
||||
FROM docker.io/library/golang:1.21-alpine3.19 AS build-env
|
||||
FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
|
||||
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.21-alpine3.19 as build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
|
@ -9,24 +10,33 @@ ARG TAGS="sqlite sqlite_unlock_notify"
|
|||
ENV TAGS "bindata timetzdata $TAGS"
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
|
||||
#Build deps
|
||||
RUN apk --no-cache add \
|
||||
build-base \
|
||||
git \
|
||||
nodejs \
|
||||
npm \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
#
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
# Checkout version if set
|
||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
&& make clean-all build
|
||||
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
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
|
||||
|
||||
# Copy local files
|
||||
COPY docker/rootless /tmp/local
|
||||
|
@ -40,7 +50,7 @@ RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
|
|||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM docker.io/library/alpine:3.19
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
LABEL maintainer="contact@forgejo.org"
|
||||
|
||||
EXPOSE 2222 3000
|
||||
|
||||
|
@ -69,18 +79,19 @@ 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 --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
|
||||
|
||||
# git:git
|
||||
#git:git
|
||||
USER 1000:1000
|
||||
ENV GITEA_WORK_DIR /var/lib/gitea
|
||||
ENV GITEA_CUSTOM /var/lib/gitea/custom
|
||||
ENV GITEA_TEMP /tmp/gitea
|
||||
ENV TMPDIR /tmp/gitea
|
||||
|
||||
# TODO add to docs the ability to define the ini to load (useful to test and revert a config)
|
||||
#TODO add to docs the ability to define the ini to load (useful to test and revert a config)
|
||||
ENV GITEA_APP_INI /etc/gitea/app.ini
|
||||
ENV HOME "/var/lib/gitea/git"
|
||||
VOLUME ["/var/lib/gitea", "/etc/gitea"]
|
||||
|
@ -88,3 +99,4 @@ WORKDIR /var/lib/gitea
|
|||
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/usr/local/bin/docker-entrypoint.sh"]
|
||||
CMD []
|
||||
|
||||
|
|
1
LICENSE
1
LICENSE
|
@ -1,3 +1,4 @@
|
|||
Copyright (c) 2022 The Forgejo Authors
|
||||
Copyright (c) 2016 The Gitea Authors
|
||||
Copyright (c) 2015 The Gogs Authors
|
||||
|
||||
|
|
102
Makefile
102
Makefile
|
@ -22,6 +22,7 @@ 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
|
||||
|
||||
|
@ -36,6 +37,7 @@ 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
|
||||
|
||||
DOCKER_IMAGE ?= gitea/gitea
|
||||
DOCKER_TAG ?= latest
|
||||
|
@ -83,38 +85,24 @@ endif
|
|||
STORED_VERSION_FILE := VERSION
|
||||
HUGO_VERSION ?= 0.111.3
|
||||
|
||||
GITHUB_REF_TYPE ?= branch
|
||||
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
ifneq ($(GITHUB_REF_TYPE),branch)
|
||||
VERSION ?= $(subst v,,$(GITHUB_REF_NAME))
|
||||
GITEA_VERSION ?= $(VERSION)
|
||||
STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null)
|
||||
ifneq ($(STORED_VERSION),)
|
||||
GITEA_VERSION ?= $(STORED_VERSION)
|
||||
else
|
||||
ifneq ($(GITHUB_REF_NAME),)
|
||||
VERSION ?= $(subst release/v,,$(GITHUB_REF_NAME))
|
||||
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
|
||||
GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
|
||||
endif
|
||||
VERSION = ${GITEA_VERSION}
|
||||
|
||||
# if version = "main" then update version to "nightly"
|
||||
ifeq ($(VERSION),main)
|
||||
VERSION := main-nightly
|
||||
endif
|
||||
# SemVer
|
||||
FORGEJO_VERSION := 7.0.0+0-gitea-1.22.0
|
||||
|
||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "main.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/...) 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/))
|
||||
|
||||
FOMANTIC_WORK_DIR := web_src/fomantic
|
||||
|
||||
|
@ -161,6 +149,8 @@ ifdef DEPS_PLAYWRIGHT
|
|||
PLAYWRIGHT_FLAGS += --with-deps
|
||||
endif
|
||||
|
||||
FORGEJO_API_SPEC := public/assets/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
|
||||
|
@ -237,6 +227,8 @@ help:
|
|||
@echo " - generate-license update license files"
|
||||
@echo " - generate-gitignore update gitignore files"
|
||||
@echo " - generate-manpage generate manpage"
|
||||
@echo " - generate-forgejo-api generate the forgejo API from spec"
|
||||
@echo " - forgejo-api-validate check if the forgejo API matches the specs"
|
||||
@echo " - generate-swagger generate the swagger spec from code comments"
|
||||
@echo " - swagger-validate check if the swagger spec is valid"
|
||||
@echo " - go-licenses regenerate go licenses"
|
||||
|
@ -321,6 +313,27 @@ ifneq "$(TAGS)" "$(shell cat $(TAGS_EVIDENCE) 2>/dev/null)"
|
|||
TAGS_PREREQ := $(TAGS_EVIDENCE)
|
||||
endif
|
||||
|
||||
OAPI_CODEGEN_PACKAGE ?= github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4
|
||||
KIN_OPENAPI_CODEGEN_PACKAGE ?= github.com/getkin/kin-openapi/cmd/validate@v0.114.0
|
||||
FORGEJO_API_SERVER = routers/api/forgejo/v1/generated.go
|
||||
|
||||
.PHONY: generate-forgejo-api
|
||||
generate-forgejo-api: $(FORGEJO_API_SPEC)
|
||||
$(GO) run $(OAPI_CODEGEN_PACKAGE) -package v1 -generate chi-server,types $< > $(FORGEJO_API_SERVER)
|
||||
|
||||
.PHONY: forgejo-api-check
|
||||
forgejo-api-check: generate-forgejo-api
|
||||
@diff=$$(git diff $(FORGEJO_API_SERVER) ; \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "Please run 'make generate-forgejo-api' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: forgejo-api-validate
|
||||
forgejo-api-validate:
|
||||
$(GO) run $(KIN_OPENAPI_CODEGEN_PACKAGE) $(FORGEJO_API_SPEC)
|
||||
|
||||
.PHONY: generate-swagger
|
||||
generate-swagger: $(SWAGGER_SPEC)
|
||||
|
||||
|
@ -351,7 +364,7 @@ checks: checks-frontend checks-backend
|
|||
checks-frontend: lockfile-check svg-check
|
||||
|
||||
.PHONY: checks-backend
|
||||
checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-validate security-check
|
||||
checks-backend: tidy-check swagger-check fmt-check misspell-check forgejo-api-validate swagger-validate security-check
|
||||
|
||||
.PHONY: lint
|
||||
lint: lint-frontend lint-backend
|
||||
|
@ -397,11 +410,18 @@ lint-md: node_modules
|
|||
|
||||
.PHONY: lint-go
|
||||
lint-go:
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
|
||||
$(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
|
||||
|
||||
.PHONY: lint-go-fix
|
||||
lint-go-fix:
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run --fix
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) --fix
|
||||
$(GO) run $(DEADCODE_PACKAGE) -generated=false -test code.gitea.io/gitea > .deadcode-out
|
||||
|
||||
# workaround step for the lint-go-windows CI task because 'go run' can not
|
||||
# have distinct GOOS/GOARCH for its build and run steps
|
||||
|
@ -413,12 +433,11 @@ lint-go-windows:
|
|||
.PHONY: lint-go-vet
|
||||
lint-go-vet:
|
||||
@echo "Running go vet..."
|
||||
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
|
||||
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
|
||||
@$(GO) vet $(GO_PACKAGES)
|
||||
|
||||
.PHONY: lint-editorconfig
|
||||
lint-editorconfig:
|
||||
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .github/workflows
|
||||
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .forgejo/workflows
|
||||
|
||||
.PHONY: lint-actions
|
||||
lint-actions:
|
||||
|
@ -702,7 +721,7 @@ 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/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
|
||||
done
|
||||
|
||||
|
@ -712,7 +731,7 @@ migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
|
|||
|
||||
.PHONY: migrations.individual.pgsql.test
|
||||
migrations.individual.pgsql.test: $(GO_SOURCES)
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
|
||||
done
|
||||
|
||||
|
@ -723,7 +742,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/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg -test.failfast; \
|
||||
done
|
||||
|
||||
|
@ -733,7 +752,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/...); do \
|
||||
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...); do \
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
|
||||
done
|
||||
|
||||
|
@ -788,8 +807,14 @@ security-check:
|
|||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||
|
||||
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-windows release-linux release-darwin release-freebsd release-copy release-compress vendor release-sources release-docs release-check
|
||||
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)
|
||||
|
@ -803,7 +828,10 @@ endif
|
|||
|
||||
.PHONY: release-linux
|
||||
release-linux: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out forgejo-$(VERSION) .
|
||||
ifeq ($(CI),true)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
|
||||
.PHONY: release-darwin
|
||||
release-darwin: | $(DIST_DIRS)
|
||||
|
@ -831,8 +859,8 @@ release-sources: | $(DIST_DIRS)
|
|||
# bsdtar needs a ^ to prevent matching subdirectories
|
||||
$(eval EXCL := --exclude=$(shell tar --help | grep -q bsdtar && echo "^")./)
|
||||
# use transform to a add a release-folder prefix; in bsdtar the transform parameter equivalent is -s
|
||||
$(eval TRANSFORM := $(shell tar --help | grep -q bsdtar && echo "-s '/^./gitea-src-$(VERSION)/'" || echo "--transform 's|^./|gitea-src-$(VERSION)/|'"))
|
||||
tar $(addprefix $(EXCL),$(TAR_EXCLUDES)) $(TRANSFORM) -czf $(DIST)/release/gitea-src-$(VERSION).tar.gz .
|
||||
$(eval TRANSFORM := $(shell tar --help | grep -q bsdtar && echo "-s '/^./forgejo-src-$(VERSION)/'" || echo "--transform 's|^./|forgejo-src-$(VERSION)/|'"))
|
||||
tar $(addprefix $(EXCL),$(TAR_EXCLUDES)) $(TRANSFORM) -czf $(DIST)/release/forgejo-src-$(VERSION).tar.gz .
|
||||
rm -f $(STORED_VERSION_FILE)
|
||||
|
||||
.PHONY: release-docs
|
||||
|
|
206
README.md
206
README.md
|
@ -1,182 +1,46 @@
|
|||
<p align="center">
|
||||
<a href="https://gitea.io/">
|
||||
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/assets/img/gitea.svg" width="220"/>
|
||||
</a>
|
||||
</p>
|
||||
<h1 align="center">Gitea - Git with a cup of tea</h1>
|
||||
<div 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>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain" title="Release Nightly">
|
||||
<img src="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main">
|
||||
</a>
|
||||
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
||||
<img src="https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2">
|
||||
</a>
|
||||
<a href="https://app.codecov.io/gh/go-gitea/gitea" title="Codecov">
|
||||
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card">
|
||||
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
||||
</a>
|
||||
<a href="https://pkg.go.dev/code.gitea.io/gitea" title="GoDoc">
|
||||
<img src="https://pkg.go.dev/badge/code.gitea.io/gitea?status.svg">
|
||||
</a>
|
||||
<a href="https://github.com/go-gitea/gitea/releases/latest" title="GitHub release">
|
||||
<img src="https://img.shields.io/github/release/go-gitea/gitea.svg">
|
||||
</a>
|
||||
<a href="https://www.codetriage.com/go-gitea/gitea" title="Help Contribute to Open Source">
|
||||
<img src="https://www.codetriage.com/go-gitea/gitea/badges/users.svg">
|
||||
</a>
|
||||
<a href="https://opencollective.com/gitea" title="Become a backer/sponsor of gitea">
|
||||
<img src="https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen">
|
||||
</a>
|
||||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</a>
|
||||
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
|
||||
<img
|
||||
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
|
||||
alt="Contribute with Gitpod"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</a>
|
||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs">
|
||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main">
|
||||
</a>
|
||||
<a href="https://app.bountysource.com/teams/gitea" title="Bountysource">
|
||||
<img src="https://img.shields.io/bountysource/team/gitea/activity">
|
||||
</a>
|
||||
</p>
|
||||
Hi there! Tired of big platforms playing monopoly?
|
||||
Providing Git hosting for your project, friends, company or community?
|
||||
**Forgejo** (/for'd͡ʒe.jo/ inspired by forĝejo – the Esperanto word for *forge*) has you covered with its intuitive interface,
|
||||
light and easy hosting and a lot of builtin functionality.
|
||||
|
||||
<p align="center">
|
||||
<a href="README_ZH.md">View this document in Chinese</a>
|
||||
</p>
|
||||
Forgejo was [created in 2022](https://forgejo.org/2022-12-15-hello-forgejo/)
|
||||
because we think that the project should be owned by an independent community.
|
||||
If you second that, then Forgejo is for you!
|
||||
Our promise: **Independent Free/Libre Software forever!**
|
||||
|
||||
## Purpose
|
||||
## What does Forgejo offer?
|
||||
|
||||
The goal of this project is to make the easiest, fastest, and most
|
||||
painless way of setting up a self-hosted Git service.
|
||||
<!-- If you want to know what Forgejo is like,
|
||||
you can check out public instances,
|
||||
e.g. [Codeberg.org](https://codeberg.org).
|
||||
-->
|
||||
|
||||
As Gitea is written in Go, it works across **all** the platforms and
|
||||
architectures that are supported by Go, including Linux, macOS, and
|
||||
Windows on x86, amd64, ARM and PowerPC architectures.
|
||||
This project has been
|
||||
[forked](https://blog.gitea.com/welcome-to-gitea/) from
|
||||
[Gogs](https://gogs.io) since November of 2016, but a lot has changed.
|
||||
If you like any of the following, Forgejo is literally meant for you:
|
||||
|
||||
For online demonstrations, you can visit [try.gitea.io](https://try.gitea.io).
|
||||
- Lightweight: Forgejo can easily be hosted on nearly **every machine**.
|
||||
Running on a Raspberry? Small cloud instance? No problem!
|
||||
- Project management: Besides Git hosting, Forgejo offers issues,
|
||||
pull requests, wikis, kanban boards and much more to **coordinate with your team**.
|
||||
- Publishing: Have something to share? Use **releases** to host your software for download,
|
||||
or use the **package registry** to publish it for docker, npm and many other package managers.
|
||||
- Customizable: Want to change your look? Change some settings?
|
||||
There are many **config switches** to make Forgejo work exactly like you want.
|
||||
- Powerful: Organizations & team permissions, CI integration, Code Search, LDAP, OAuth and much more.
|
||||
If you have **advanced needs**, Forgejo has you covered.
|
||||
- Privacy: From update checker to default settings: Forgejo is built to be **privacy first** for you and your crew.
|
||||
- Federation: (WIP) We are actively working to connect software forges with each other through **ActivityPub**,
|
||||
and create a collaborative network of personal instances.
|
||||
|
||||
For accessing free Gitea service (with a limited number of repositories), you can visit [gitea.com](https://gitea.com/user/login).
|
||||
## Learn more
|
||||
|
||||
To quickly deploy your own dedicated Gitea instance on Gitea Cloud, you can start a free trial at [cloud.gitea.com](https://cloud.gitea.com).
|
||||
Dive into the [documentation](https://forgejo.org/docs/latest/), subscribe to releases and blog post on [our website](https://forgejo.org), <a href="https://floss.social/@forgejo" rel="me">find us on the Fediverse</a> or hop into [our Matrix room](https://matrix.to/#/#forgejo-chat:matrix.org) if you have any questions or want to get involved.
|
||||
|
||||
## Building
|
||||
|
||||
From the root of the source tree, run:
|
||||
## Get involved
|
||||
|
||||
TAGS="bindata" make build
|
||||
|
||||
or if SQLite support is required:
|
||||
|
||||
TAGS="bindata sqlite sqlite_unlock_notify" make build
|
||||
|
||||
The `build` target is split into two sub-targets:
|
||||
|
||||
- `make backend` which requires [Go Stable](https://go.dev/dl/), the required version is defined in [go.mod](/go.mod).
|
||||
- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater.
|
||||
|
||||
Internet connectivity is required to download the go and npm modules. When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js.
|
||||
|
||||
Parallelism (`make -j <num>`) is not supported.
|
||||
|
||||
More info: https://docs.gitea.com/installation/install-from-source
|
||||
|
||||
## Using
|
||||
|
||||
./gitea web
|
||||
|
||||
NOTE: If you're interested in using our APIs, we have experimental
|
||||
support with [documentation](https://try.gitea.io/api/swagger).
|
||||
|
||||
## Contributing
|
||||
|
||||
Expected workflow is: Fork -> Patch -> Push -> Pull Request
|
||||
|
||||
NOTES:
|
||||
|
||||
1. **YOU MUST READ THE [CONTRIBUTORS GUIDE](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST.**
|
||||
2. If you have found a vulnerability in the project, please write privately to **security@gitea.io**. Thanks!
|
||||
|
||||
## Translating
|
||||
|
||||
Translations are done through Crowdin. If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there.
|
||||
|
||||
You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope to fill it as questions pop up.
|
||||
|
||||
https://docs.gitea.com/contributing/localization
|
||||
|
||||
[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea)
|
||||
|
||||
## Further information
|
||||
|
||||
For more information and instructions about how to install Gitea, please look at our [documentation](https://docs.gitea.com/).
|
||||
If you have questions that are not covered by the documentation, you can get in contact with us on our [Discord server](https://discord.gg/Gitea) or create a post in the [discourse forum](https://discourse.gitea.io/).
|
||||
|
||||
We maintain a list of Gitea-related projects at [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea).
|
||||
|
||||
The official Gitea CLI is developed at [gitea/tea](https://gitea.com/gitea/tea).
|
||||
|
||||
## Authors
|
||||
|
||||
- [Maintainers](https://github.com/orgs/go-gitea/people)
|
||||
- [Contributors](https://github.com/go-gitea/gitea/graphs/contributors)
|
||||
- [Translators](options/locale/TRANSLATORS)
|
||||
|
||||
## Backers
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/gitea#backer)]
|
||||
|
||||
<a href="https://opencollective.com/gitea#backers" target="_blank"><img src="https://opencollective.com/gitea/backers.svg?width=890"></a>
|
||||
|
||||
## Sponsors
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/gitea#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/gitea/sponsor/0/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/1/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/2/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/3/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/4/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/5/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/6/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
|
||||
|
||||
## FAQ
|
||||
|
||||
**How do you pronounce Gitea?**
|
||||
|
||||
Gitea is pronounced [/ɡɪ’ti:/](https://youtu.be/EM71-2uDAoY) as in "gi-tea" with a hard g.
|
||||
|
||||
**Why is this not hosted on a Gitea instance?**
|
||||
|
||||
We're [working on it](https://github.com/go-gitea/gitea/issues/1029).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License.
|
||||
See the [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) file
|
||||
for the full license text.
|
||||
|
||||
## Screenshots
|
||||
|
||||
Looking for an overview of the interface? Check it out!
|
||||
|
||||
|![Dashboard](https://dl.gitea.com/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.com/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.com/screenshots/global_issues.png)|
|
||||
|:---:|:---:|:---:|
|
||||
|![Branches](https://dl.gitea.com/screenshots/branches.png)|![Web Editor](https://dl.gitea.com/screenshots/web_editor.png)|![Activity](https://dl.gitea.com/screenshots/activity.png)|
|
||||
|![New Migration](https://dl.gitea.com/screenshots/migration.png)|![Migrating](https://dl.gitea.com/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)
|
||||
![Pull Request Dark](https://dl.gitea.com/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.com/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.com/screenshots/diff_dark.png)|
|
||||
If you are interested in making Forgejo better, either by reporting a bug or by changing the governance, please [take a look at the contribution guide](CONTRIBUTING.md).
|
||||
|
|
102
README_ZH.md
102
README_ZH.md
|
@ -1,102 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gitea.io/">
|
||||
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/assets/img/gitea.svg" width="220"/>
|
||||
</a>
|
||||
</p>
|
||||
<h1 align="center">Gitea - Git with a cup of tea</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain" title="Release Nightly">
|
||||
<img src="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main">
|
||||
</a>
|
||||
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
||||
<img src="https://img.shields.io/discord/322538954119184384.svg">
|
||||
</a>
|
||||
<a href="https://app.codecov.io/gh/go-gitea/gitea" title="Codecov">
|
||||
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card">
|
||||
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
||||
</a>
|
||||
<a href="https://pkg.go.dev/code.gitea.io/gitea" title="GoDoc">
|
||||
<img src="https://pkg.go.dev/badge/code.gitea.io/gitea?status.svg">
|
||||
</a>
|
||||
<a href="https://github.com/go-gitea/gitea/releases/latest" title="GitHub release">
|
||||
<img src="https://img.shields.io/github/release/go-gitea/gitea.svg">
|
||||
</a>
|
||||
<a href="https://www.codetriage.com/go-gitea/gitea" title="Help Contribute to Open Source">
|
||||
<img src="https://www.codetriage.com/go-gitea/gitea/badges/users.svg">
|
||||
</a>
|
||||
<a href="https://opencollective.com/gitea" title="Become a backer/sponsor of gitea">
|
||||
<img src="https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen">
|
||||
</a>
|
||||
<a href="https://opensource.org/licenses/MIT" title="License: MIT">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</a>
|
||||
<a href="https://gitpod.io/#https://github.com/go-gitea/gitea">
|
||||
<img
|
||||
src="https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod"
|
||||
alt="Contribute with Gitpod"
|
||||
/>
|
||||
</a>
|
||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</a>
|
||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs">
|
||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main">
|
||||
</a>
|
||||
<a href="https://app.bountysource.com/teams/gitea" title="Bountysource">
|
||||
<img src="https://img.shields.io/bountysource/team/gitea/activity">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="README.md">View this document in English</a>
|
||||
</p>
|
||||
|
||||
## 目标
|
||||
|
||||
Gitea 的首要目标是创建一个极易安装,运行非常快速,安装和使用体验良好的自建 Git 服务。我们采用 Go 作为后端语言,这使我们只要生成一个可执行程序即可。并且他还支持跨平台,支持 Linux, macOS 和 Windows 以及各种架构,除了 x86,amd64,还包括 ARM 和 PowerPC。
|
||||
|
||||
如果你想试用在线演示,请访问 [try.gitea.io](https://try.gitea.io/)。
|
||||
|
||||
如果你想使用免费的 Gitea 服务(有仓库数量限制),请访问 [gitea.com](https://gitea.com/user/login)。
|
||||
|
||||
如果你想在 Gitea Cloud 上快速部署你自己独享的 Gitea 实例,请访问 [cloud.gitea.com](https://cloud.gitea.com) 开始免费试用。
|
||||
|
||||
## 提示
|
||||
|
||||
1. **开始贡献代码之前请确保你已经看过了 [贡献者向导(英文)](CONTRIBUTING.md)**.
|
||||
2. 所有的安全问题,请私下发送邮件给 **security@gitea.io**。谢谢!
|
||||
3. 如果你要使用API,请参见 [API 文档](https://godoc.org/code.gitea.io/sdk/gitea).
|
||||
|
||||
## 文档
|
||||
|
||||
关于如何安装请访问我们的 [文档站](https://docs.gitea.com/zh-cn/category/installation),如果没有找到对应的文档,你也可以通过 [Discord - 英文](https://discord.gg/gitea) 和 QQ群 328432459 来和我们交流。
|
||||
|
||||
## 贡献流程
|
||||
|
||||
Fork -> Patch -> Push -> Pull Request
|
||||
|
||||
## 翻译
|
||||
|
||||
多语言翻译是基于Crowdin进行的.
|
||||
[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea)
|
||||
|
||||
## 作者
|
||||
|
||||
* [Maintainers](https://github.com/orgs/go-gitea/people)
|
||||
* [Contributors](https://github.com/go-gitea/gitea/graphs/contributors)
|
||||
* [Translators](options/locale/TRANSLATORS)
|
||||
|
||||
## 授权许可
|
||||
|
||||
本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) 文件中。
|
||||
|
||||
## 截图
|
||||
|
||||
|![Dashboard](https://dl.gitea.com/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.com/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.com/screenshots/global_issues.png)|
|
||||
|:---:|:---:|:---:|
|
||||
|![Branches](https://dl.gitea.com/screenshots/branches.png)|![Web Editor](https://dl.gitea.com/screenshots/web_editor.png)|![Activity](https://dl.gitea.com/screenshots/activity.png)|
|
||||
|![New Migration](https://dl.gitea.com/screenshots/migration.png)|![Migrating](https://dl.gitea.com/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)
|
||||
![Pull Request Dark](https://dl.gitea.com/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.com/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.com/screenshots/diff_dark.png)|
|
1602
RELEASE-NOTES.md
Normal file
1602
RELEASE-NOTES.md
Normal file
File diff suppressed because it is too large
Load diff
85
SECURITY.md
85
SECURITY.md
|
@ -1,85 +0,0 @@
|
|||
# Reporting security issues
|
||||
|
||||
The Gitea maintainers take security seriously.
|
||||
|
||||
If you discover a security issue, please bring it to their attention right away!
|
||||
|
||||
Previous vulnerabilities are listed at https://about.gitea.com/security.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please **DO NOT** file a public issue, instead send your report privately to `security@gitea.io`.
|
||||
|
||||
## Protecting Security Information
|
||||
|
||||
Due to the sensitive nature of security information, you can use the below GPG public key to encrypt your mail body.
|
||||
|
||||
The PGP key is valid until June 24, 2024.
|
||||
|
||||
```
|
||||
Key ID: 6FCD2D5B
|
||||
Key Type: RSA
|
||||
Expires: 6/24/2024
|
||||
Key Size: 4096/4096
|
||||
Fingerprint: 3DE0 3D1E 144A 7F06 9359 99DC AAFD 2381 6FCD 2D5B
|
||||
```
|
||||
|
||||
UserID: Gitea Security <security@gitea.io>
|
||||
|
||||
```
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBGK1Z/4BEADFMqXA9DeeChmSxUjF0Be5sq99ZUhgrZjcN/wOzz0wuCJZC0l8
|
||||
4uC+d6mfv7JpJYlzYzOK97/x5UguKHkYNZ6mm1G9KHaXmoIBDLKDzfPdJopVNv2r
|
||||
OajijaE0uMCnMjadlg5pbhMLRQG8a9J32yyaz7ZEAw72Ab31fvvcA53NkuqO4j2w
|
||||
k7dtFQzhbNOYV0VffQT90WDZdalYHB1JHyEQ+70U9OjVD5ggNYSzX98Eu3Hjn7V7
|
||||
kqFrcAxr5TE1elf0IXJcuBJtFzQSTUGlQldKOHtGTGgGjj9r/FFAE5ioBgVD05bV
|
||||
rEEgIMM/GqYaG/nbNpWE6P3mEc2Mnn3pZaRJL0LuF26TLjnqEcMMDp5iIhLdFzXR
|
||||
3tMdtKgQFu+Mtzs3ipwWARYgHyU09RJsI2HeBx7RmZO/Xqrec763Z7zdJ7SpCn0Z
|
||||
q+pHZl24JYR0Kf3T/ZiOC0cGd2QJqpJtg5J6S/OqfX9NH6MsCczO8pUC1N/aHH2X
|
||||
CTme2nF56izORqDWKoiICteL3GpYsCV9nyCidcCmoQsS+DKvE86YhIhVIVWGRY2F
|
||||
lzpAjnN9/KLtQroutrm+Ft0mdjDiJUeFVl1cOHDhoyfCsQh62HumoyZoZvqzQd6e
|
||||
AbN11nq6aViMe2Q3je1AbiBnRnQSHxt1Tc8X4IshO3MQK1Sk7oPI6LA5oQARAQAB
|
||||
tCJHaXRlYSBTZWN1cml0eSA8c2VjdXJpdHlAZ2l0ZWEuaW8+iQJXBBMBCABBFiEE
|
||||
PeA9HhRKfwaTWZncqv0jgW/NLVsFAmK1Z/4CGwMFCQPCZwAFCwkIBwICIgIGFQoJ
|
||||
CAsCBBYCAwECHgcCF4AACgkQqv0jgW/NLVvnyxAAhxyNnWzw/rQO2qhzqicmZM94
|
||||
njSbOg+U2qMBvCdaqCQQeC+uaMmMzkDPanUUmLcyCkWqfCjPNjeSXAkE9npepVJI
|
||||
4HtmgxZQ94OU/h3CLbft+9GVRzUkVI29TSYGdvNtV2/BkNGoFFnKWQr119um0o6A
|
||||
bgha2Uy5uY8o3ZIoiKkiHRaEoWIjjeBxJxYAojsZY4YElUmsQ3ik2joG6rhFesTa
|
||||
ofVt/bL8G2xzpOG26WGIxBbqf2qjV6OtZ0hu/vtTPHeIWMLq0Mz0V3PEDQWfkGPE
|
||||
i2RYxxYDs2xzJhSQWqTNVLSq0m5xTJnbHhQPfdCX4C2jvFKgLdfmytQq49S7jiJb
|
||||
Z03HVOZ/PsyBlQfH9xJi06R5yQCMEA8h8Z5r3/NXW09kQ6OFRe6xshoTcxZGRPTo
|
||||
srhwr3uPbmCRh+YEl7qBLU6+BC5k8IRTZXqhrj/aPJu3MxgbgwV8u3vLoFSXM2lb
|
||||
a61FgeCQ0O7lkgVswwF0RppCaH9Ul3ZDapet/vCRg4NVwm9zOI/8q/Vj0FKA1GDR
|
||||
JhRu8+Ce8zlFL65D34t+PprAzSeTlbv9um3x/ZIjCco7EEKSBylt+AZj/VyA6+e5
|
||||
kjOQwRRc6dFJWBcorsSI2dG+H+QMF7ZabzmeCcz1v9HjLOPzYHoZAHhCmSppWTvX
|
||||
AJy6+lhfW2OUTqQeYSi5Ag0EYrVn/gEQALrFLQjCR3GjuHSindz0rd3Fnx/t7Sen
|
||||
T+p07yCSSoSlmnJHCQmwh4vfg1blyz0zZ4vkIhtpHsEgc+ZAG+WQXSsJ2iRz+eSN
|
||||
GwoOQl4XC3n+QWkc1ws+btr48+6UqXIQU+F8TPQyx/PIgi2nZXJB7f5+mjCqsk46
|
||||
XvH4nTr4kJjuqMSR/++wvre2qNQRa/q/dTsK0OaN/mJsdX6Oi+aGNaQJUhIG7F+E
|
||||
ZDMkn/O6xnwWNzy/+bpg43qH/Gk0eakOmz5NmQLRkV58SZLiJvuCUtkttf6CyhnX
|
||||
03OcWaajv5W8qA39dBYQgDrrPbBWUnwfO3yMveqhwV4JjDoe8sPAyn1NwzakNYqP
|
||||
RzsWyLrLS7R7J9s3FkZXhQw/QQcsaSMcGNQO047dm1P83N8JY5aEpiRo9zSWjoiw
|
||||
qoExANj5lUTZPe8M50lI182FrcjAN7dClO3QI6pg7wy0erMxfFly3j8UQ91ysS9T
|
||||
s+GsP9I3cmWWQcKYxWHtE8xTXnNCVPFZQj2nwhJzae8ypfOtulBRA3dUKWGKuDH/
|
||||
axFENhUsT397aOU3qkP/od4a64JyNIEo4CTTSPVeWd7njsGqli2U3A4xL2CcyYvt
|
||||
D/MWcMBGEoLSNTswwKdom4FaJpn5KThnK/T0bQcmJblJhoCtppXisbexZnCpuS0x
|
||||
Zdlm2T14KJ3LABEBAAGJAjwEGAEIACYWIQQ94D0eFEp/BpNZmdyq/SOBb80tWwUC
|
||||
YrVn/gIbDAUJA8JnAAAKCRCq/SOBb80tWyTBD/9AGpW6QoDF7zYjHAozH9S5RGCA
|
||||
Y7E82dG/0xmFUwPprAG0BKmmgU6TiipyVGmKIXGYYYU92pMnbvXkYQMoa+WJNncN
|
||||
D3fY52UeXeffTf4cFpStlzi9xgYtOLhFamzYu/4xhkjOX+xhOSXscCiFRyT8cF3B
|
||||
O6c5BHU+Zj0/rGPgOyPUbx7l7B9MubB/41nNX35k08e+8T3wtWDb4XF+15HnRfva
|
||||
6fblO8wgU25Orv2Rm1jnKGa9DxJ8nE40IMrqDapENtDuL+zKJsvR0+ptWvEyL56U
|
||||
GtJJG5un6mXiLKuRQT0DEv4MdZRHDgDstDnqcbEiazVEbUuvhZZob6lRY2A19m1+
|
||||
7zfnDxkhqCA1RCnv4fdvcPdCMMFHwLpdhjgW0aI/uwgwrvsEz5+JRlnLvdQHlPAg
|
||||
q7l2fGcBSpz9U0ayyfRPjPntsNCtZl1UDxGLeciPkZhyG84zEWQbk/j52ZpRN+Ik
|
||||
ALpRLa8RBFmFSmXDUmwQrmm1EmARyQXwweKU31hf8ZGbCp2lPuRYm1LuGiirXSVP
|
||||
GysjRAJgW+VRpBKOzFQoUAUbReVWSaCwT8s17THzf71DdDb6CTj31jMLLYWwBpA/
|
||||
i73DgobDZMIGEZZC1EKqza8eh11xfyHFzGec03tbh+lIen+5IiRtWiEWkDS9ll0G
|
||||
zgS/ZdziCvdAutqnGA==
|
||||
=gZWO
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
```
|
||||
|
||||
Security reports are greatly appreciated and we will publicly thank you for it, although we keep your name confidential if you request it.
|
5
assets/go-licenses.json
generated
5
assets/go-licenses.json
generated
|
@ -359,11 +359,6 @@
|
|||
"path": "github.com/emirpasic/gods/LICENSE",
|
||||
"licenseText": "Copyright (c) 2015, Emir Pasic\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-------------------------------------------------------------------------------\n\nAVL Tree:\n\nCopyright (c) 2017 Benjamin Scher Purcell \u003cbenjapurcell@gmail.com\u003e\n\nPermission to use, copy, modify, and distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/ethantkoenig/rupture",
|
||||
"path": "github.com/ethantkoenig/rupture/LICENSE",
|
||||
"licenseText": "MIT License\n\nCopyright (c) 2018 Ethan Koenig\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/fatih/color",
|
||||
"path": "github.com/fatih/color/LICENSE.md",
|
||||
|
|
243
cmd/forgejo/actions.go
Normal file
243
cmd/forgejo/actions.go
Normal file
|
@ -0,0 +1,243 @@
|
|||
// 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.Text); 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)
|
||||
}
|
||||
}
|
147
cmd/forgejo/forgejo.go
Normal file
147
cmd/forgejo/forgejo.go
Normal file
|
@ -0,0 +1,147 @@
|
|||
// 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)
|
||||
}
|
37
cmd/main.go
37
cmd/main.go
|
@ -4,10 +4,13 @@
|
|||
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"
|
||||
|
||||
|
@ -113,6 +116,36 @@ func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context)
|
|||
}
|
||||
|
||||
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.Name = "Gitea"
|
||||
app.HelpName = "gitea"
|
||||
|
@ -137,15 +170,17 @@ func NewMainApp(version, versionExtra string) *cli.App {
|
|||
CmdMigrateStorage,
|
||||
CmdDumpRepository,
|
||||
CmdRestoreRepository,
|
||||
CmdActions,
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -482,8 +482,8 @@ INTERNAL_TOKEN=
|
|||
;;Classes include "lower,upper,digit,spec"
|
||||
;PASSWORD_COMPLEXITY = off
|
||||
;;
|
||||
;; Password Hash algorithm, either "argon2", "pbkdf2", "scrypt" or "bcrypt"
|
||||
;PASSWORD_HASH_ALGO = pbkdf2
|
||||
;; Password Hash algorithm, either "argon2", "pbkdf2"/"pbkdf2_v2", "pbkdf2_hi", "scrypt" or "bcrypt"
|
||||
;PASSWORD_HASH_ALGO = pbkdf2_hi
|
||||
;;
|
||||
;; Set false to allow JavaScript to read CSRF cookie
|
||||
;CSRF_COOKIE_HTTP_ONLY = true
|
||||
|
@ -845,12 +845,12 @@ LEVEL = Info
|
|||
;;
|
||||
;; Default map service. No external API support has been included. A service has to allow
|
||||
;; searching using URL parameters, the location will be appended to the URL as escaped query parameter.
|
||||
;; Disabled by default, some example values are:
|
||||
;; Some example values are:
|
||||
;; - OpenStreetMap: https://www.openstreetmap.org/search?query=
|
||||
;; - Google Maps: https://www.google.com/maps/place/
|
||||
;; - MapQuest: https://www.mapquest.com/search/
|
||||
;; - Bing Maps: https://www.bing.com/maps?where1=
|
||||
; USER_LOCATION_MAP_URL =
|
||||
; USER_LOCATION_MAP_URL = https://www.openstreetmap.org/search?query=
|
||||
;;
|
||||
;; Enable heatmap on users profiles.
|
||||
;ENABLE_USER_HEATMAP = true
|
||||
|
@ -2582,10 +2582,9 @@ LEVEL = Info
|
|||
; [actions]
|
||||
;; Enable/Disable actions capabilities
|
||||
;ENABLED = true
|
||||
;;
|
||||
;; Default platform to get action plugins, `github` for `https://github.com`, `self` for the current Gitea instance.
|
||||
;DEFAULT_ACTIONS_URL = github
|
||||
;; Default artifact retention time in days. Artifacts could have their own retention periods by setting the `retention-days` option in `actions/upload-artifact` step.
|
||||
;; Default address to get action plugins, e.g. the default value means downloading from "https://code.forgejo.org/actions/checkout" for "uses: actions/checkout@v3"
|
||||
;DEFAULT_ACTIONS_URL = https://code.forgejo.org
|
||||
;; Default artifact retention time in days, default is 90 days
|
||||
;ARTIFACT_RETENTION_DAYS = 90
|
||||
;; Timeout to stop the task which have running status, but haven't been updated for a long time
|
||||
;ZOMBIE_TASK_TIMEOUT = 10m
|
||||
|
|
2
go.mod
2
go.mod
|
@ -33,7 +33,6 @@ require (
|
|||
github.com/editorconfig/editorconfig-core-go/v2 v2.6.0
|
||||
github.com/emersion/go-imap v1.2.1
|
||||
github.com/emirpasic/gods v1.18.1
|
||||
github.com/ethantkoenig/rupture v1.0.1
|
||||
github.com/felixge/fgprof v0.9.3
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46
|
||||
|
@ -207,6 +206,7 @@ require (
|
|||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/go-tpm v0.9.0 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 // indirect
|
||||
github.com/gorilla/css v1.0.1 // indirect
|
||||
github.com/gorilla/handlers v1.5.2 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
|
|
60
go.sum
60
go.sum
|
@ -83,7 +83,6 @@ github.com/ClickHouse/clickhouse-go/v2 v2.16.0/go.mod h1:J7SPfIxwR+x4mQ+o8MLSe0o
|
|||
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
|
||||
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
|
@ -100,8 +99,6 @@ github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX
|
|||
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
|
||||
github.com/RoaringBitmap/roaring v1.7.0 h1:OZF303tJCER1Tj3x+aArx/S5X7hrT186ri6JjrGvG68=
|
||||
github.com/RoaringBitmap/roaring v1.7.0/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
|
||||
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
|
||||
|
@ -125,7 +122,6 @@ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsVi
|
|||
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
|
@ -134,16 +130,12 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP
|
|||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE=
|
||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bitset v1.12.0 h1:U/q1fAF7xXRhFCrhROzIfffYnu+dlS38vCZtmFVPHmA=
|
||||
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
|
||||
github.com/blevesearch/bleve/v2 v2.3.10 h1:z8V0wwGoL4rp7nG/O3qVVLYxUqCbEwskMt4iRJsPLgg=
|
||||
github.com/blevesearch/bleve/v2 v2.3.10/go.mod h1:RJzeoeHC+vNHsoLR54+crS1HmOWpnH87fL70HAUCzIA=
|
||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/bleve_index_api v1.1.4 h1:n9Ilxlb80g9DAhchR95IcVrzohamDSri0wPnkKnva50=
|
||||
github.com/blevesearch/bleve_index_api v1.1.4/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8=
|
||||
github.com/blevesearch/geo v0.1.18 h1:Np8jycHTZ5scFe7VEPLrDoHnnb9C4j636ue/CGrhtDw=
|
||||
|
@ -152,37 +144,26 @@ github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+
|
|||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
||||
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
||||
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
|
||||
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.2.5 h1:5SsNQmR8v1bojtGQ1zFhZravcMg5rdiX8AVu6LwlVtc=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.2.5/go.mod h1:8N2ytOlBCdurlxDgbqsfeR1oTKRN0ZVIKdUUP1VFZNc=
|
||||
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
||||
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
|
||||
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
|
||||
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
|
||||
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ=
|
||||
github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo=
|
||||
github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRvNBlNMrEVgY=
|
||||
github.com/blevesearch/vellum v1.0.10 h1:HGPJDT2bTva12hrHepVT3rOyIKFFF4t7Gf6yMxyMIPI=
|
||||
github.com/blevesearch/vellum v1.0.10/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k=
|
||||
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
||||
github.com/blevesearch/zapx/v11 v11.3.10 h1:hvjgj9tZ9DeIqBCxKhi70TtSZYMdcFn7gDb71Xo/fvk=
|
||||
github.com/blevesearch/zapx/v11 v11.3.10/go.mod h1:0+gW+FaE48fNxoVtMY5ugtNHHof/PxCqh7CnhYdnMzQ=
|
||||
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
||||
github.com/blevesearch/zapx/v12 v12.3.10 h1:yHfj3vXLSYmmsBleJFROXuO08mS3L1qDCdDK81jDl8s=
|
||||
github.com/blevesearch/zapx/v12 v12.3.10/go.mod h1:0yeZg6JhaGxITlsS5co73aqPtM04+ycnI6D1v0mhbCs=
|
||||
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
||||
github.com/blevesearch/zapx/v13 v13.3.10 h1:0KY9tuxg06rXxOZHg3DwPJBjniSlqEgVpxIqMGahDE8=
|
||||
github.com/blevesearch/zapx/v13 v13.3.10/go.mod h1:w2wjSDQ/WBVeEIvP0fvMJZAzDwqwIEzVPnCPrz93yAk=
|
||||
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
||||
github.com/blevesearch/zapx/v14 v14.3.10 h1:SG6xlsL+W6YjhX5N3aEiL/2tcWh3DO75Bnz77pSwwKU=
|
||||
github.com/blevesearch/zapx/v14 v14.3.10/go.mod h1:qqyuR0u230jN1yMmE4FIAuCxmahRQEOehF78m6oTgns=
|
||||
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
||||
github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ=
|
||||
github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
|
@ -218,10 +199,6 @@ github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUK
|
|||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
|
||||
github.com/couchbase/go-couchbase v0.1.1 h1:ClFXELcKj/ojyoTYbsY34QUrrYCBi/1G749sXSCkdhk=
|
||||
github.com/couchbase/go-couchbase v0.1.1/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
|
||||
|
@ -231,8 +208,6 @@ github.com/couchbase/gomemcached v0.3.0/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9Hj
|
|||
github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/couchbase/goutils v0.1.2 h1:gWr8B6XNWPIhfalHNog3qQKfGiYyh4K4VhO3P2o9BCs=
|
||||
github.com/couchbase/goutils v0.1.2/go.mod h1:h89Ek/tiOxxqjz30nPPlwZdQbdB8BwgnuBxeoUe/ViE=
|
||||
github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
@ -269,11 +244,9 @@ github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj6
|
|||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20210429054444-fca39067bc72/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.6.0 h1:5O8paxMLmi/5ONoKXzWNYxoSZU7+ITVbGcPga0IrzfE=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.6.0/go.mod h1:hdTKe+hwa3mMnMn4JUQziT+yc3pF+6EVmK2LPbLZthE=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/emersion/go-imap v1.2.1 h1:+s9ZjMEjOB8NzZMVTM3cCenz2JrQIGGo5j1df19WjTA=
|
||||
|
@ -289,8 +262,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
|||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ethantkoenig/rupture v1.0.1 h1:6aAXghmvtnngMgQzy7SMGdicMvkV86V4n9fT0meE5E4=
|
||||
github.com/ethantkoenig/rupture v1.0.1/go.mod h1:Sjqo/nbffZp1pVVXNGhpugIjsWmuS9KiIB4GtpEBur4=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
|
@ -309,8 +280,6 @@ github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADi
|
|||
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||
github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46 h1:fYiA820jw7wmAvdXrHwMItxjJkra7dT9y8yiXhtzb94=
|
||||
github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46/go.mod h1:i/TCLcdiX9Up/vs+Rp8c3yMbqp2Y4Y7Nh9uzGFCa5pM=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9 h1:j2TrkUG/NATGi/EQS+MvEoF79CxiRUmT16ErFroNcKI=
|
||||
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9/go.mod h1:cJ9Ye0ZNSMN7RzZDBRY3E+8M3Bpf/R1JX22Ir9yX6WI=
|
||||
github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 h1:I2nuhyVI/48VXoRCCZR2hYBgnSXa+EuDJf/VyX06TC0=
|
||||
|
@ -539,7 +508,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:
|
|||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q=
|
||||
|
@ -600,7 +568,6 @@ github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY
|
|||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
|
@ -625,7 +592,6 @@ github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbat
|
|||
github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
|
||||
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI=
|
||||
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0/go.mod h1:JEfTc3+2DF9Z4PXhLLvXL42zexJyh8rIq3OzUj/0rAk=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
|
@ -669,8 +635,6 @@ github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5
|
|||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
|
@ -686,7 +650,6 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
|
|||
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 h1:j2kD3MT1z4PXCiUllUJF9mWUESr9TWKS7iEKsQ/IipM=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
||||
github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE=
|
||||
|
@ -726,11 +689,9 @@ github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVn
|
|||
github.com/paulmach/orb v0.10.0 h1:guVYVqzxHE/CQ1KpfGO077TR0ATHSNjp4s6XGLn3W9s=
|
||||
github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
|
@ -756,7 +717,6 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k
|
|||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw=
|
||||
github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0=
|
||||
github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
|
@ -766,7 +726,6 @@ github.com/rhysd/actionlint v1.6.26/go.mod h1:TIj1DlCgtYLOv5CH9wCK+WJTOr1qAdnFzk
|
|||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
|
@ -777,7 +736,6 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
|
|||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
|
@ -816,25 +774,17 @@ github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbd
|
|||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
|
||||
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
|
||||
github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc=
|
||||
github.com/steveyen/gtreap v0.1.0/go.mod h1:kl/5J7XbrOmlIbYIXdRHDDE5QxHqpk0cmkT7Z4dM9/Y=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
@ -855,12 +805,10 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW
|
|||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
||||
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
||||
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
||||
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
|
||||
|
@ -878,7 +826,6 @@ github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdI
|
|||
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
|
||||
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xanzy/go-gitlab v0.95.2 h1:4p0IirHqEp5f0baK/aQqr4TR57IsD+8e4fuyAA1yi88=
|
||||
|
@ -899,7 +846,6 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
|
|||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
|
||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5 h1:3seWKGVhGoc66Ht5QlhQsr4xT2caDnFegsnh2NqvENU=
|
||||
|
@ -925,7 +871,6 @@ github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
|||
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
|
||||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
|
||||
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
|
@ -951,7 +896,6 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
|||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -1078,8 +1022,6 @@ golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
|||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1089,7 +1031,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1212,7 +1153,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
|||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
|
|
3
main.go
3
main.go
|
@ -31,8 +31,11 @@ var (
|
|||
MakeVersion = "" // "make" program version if built with make
|
||||
)
|
||||
|
||||
var ForgejoVersion = "1.0.0"
|
||||
|
||||
func init() {
|
||||
setting.AppVer = Version
|
||||
setting.ForgejoVersion = ForgejoVersion
|
||||
setting.AppBuiltWith = formatBuiltWith()
|
||||
setting.AppStartTime = time.Now().UTC()
|
||||
}
|
||||
|
|
68
models/actions/forgejo.go
Normal file
68
models/actions/forgejo.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
gouuid "github.com/google/uuid"
|
||||
)
|
||||
|
||||
func RegisterRunner(ctx context.Context, ownerID, repoID int64, token string, labels []string, name, version string) (*ActionRunner, error) {
|
||||
uuid, err := gouuid.FromBytes([]byte(token[:16]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("gouuid.FromBytes %v", err)
|
||||
}
|
||||
uuidString := uuid.String()
|
||||
|
||||
var runner ActionRunner
|
||||
|
||||
has, err := db.GetEngine(ctx).Where("uuid=?", uuidString).Get(&runner)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetRunner %v", err)
|
||||
} else if !has {
|
||||
//
|
||||
// The runner does not exist yet, create it
|
||||
//
|
||||
saltBytes, err := util.CryptoRandomBytes(16)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CryptoRandomBytes %v", err)
|
||||
}
|
||||
salt := hex.EncodeToString(saltBytes)
|
||||
|
||||
hash := auth_model.HashToken(token, salt)
|
||||
|
||||
runner = ActionRunner{
|
||||
UUID: uuidString,
|
||||
TokenHash: hash,
|
||||
TokenSalt: salt,
|
||||
}
|
||||
|
||||
if err := CreateRunner(ctx, &runner); err != nil {
|
||||
return &runner, fmt.Errorf("can't create new runner %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update the existing runner
|
||||
//
|
||||
name, _ = util.SplitStringAtByteN(name, 255)
|
||||
|
||||
runner.Name = name
|
||||
runner.OwnerID = ownerID
|
||||
runner.RepoID = repoID
|
||||
runner.Version = version
|
||||
runner.AgentLabels = labels
|
||||
|
||||
if err := UpdateRunner(ctx, &runner, "name", "owner_id", "repo_id", "version", "agent_labels"); err != nil {
|
||||
return &runner, fmt.Errorf("can't update the runner %+v %w", runner, err)
|
||||
}
|
||||
|
||||
return &runner, nil
|
||||
}
|
29
models/actions/forgejo_test.go
Normal file
29
models/actions/forgejo_test.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"testing"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestActions_RegisterRunner(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
ownerID := int64(0)
|
||||
repoID := int64(0)
|
||||
token := "0123456789012345678901234567890123456789"
|
||||
labels := []string{}
|
||||
name := "runner"
|
||||
version := "v1.2.3"
|
||||
runner, err := RegisterRunner(db.DefaultContext, ownerID, repoID, token, labels, name, version)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, name, runner.Name)
|
||||
|
||||
assert.EqualValues(t, 1, subtle.ConstantTimeCompare([]byte(runner.TokenHash), []byte(auth_model.HashToken(token, runner.TokenSalt))), "the token cannot be verified with the same method as routers/api/actions/runner/interceptor.go as of 8228751c55d6a4263f0fec2932ca16181c09c97d")
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -21,6 +22,7 @@ import (
|
|||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -595,6 +597,21 @@ func NotifyWatchers(ctx context.Context, actions ...*Action) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("get watchers: %w", err)
|
||||
}
|
||||
|
||||
// Be aware that optimizing this correctly into the `GetWatchers` SQL
|
||||
// query is for most cases less performant than doing this.
|
||||
blockedDoerUserIDs, err := user_model.ListBlockedByUsersID(ctx, act.ActUserID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user_model.ListBlockedByUsersID: %w", err)
|
||||
}
|
||||
|
||||
if len(blockedDoerUserIDs) > 0 {
|
||||
excludeWatcherIDs := make(container.Set[int64], len(blockedDoerUserIDs))
|
||||
excludeWatcherIDs.AddMultiple(blockedDoerUserIDs...)
|
||||
watchers = slices.DeleteFunc(watchers, func(v *repo_model.Watch) bool {
|
||||
return excludeWatcherIDs.Contains(v.UserID)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Add feed for actioner.
|
||||
|
|
|
@ -224,6 +224,15 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
|
|||
for _, id := range issueUnWatches {
|
||||
toNotify.Remove(id)
|
||||
}
|
||||
|
||||
// Remove users who have the notification author blocked.
|
||||
blockedAuthorIDs, err := user_model.ListBlockedByUsersID(ctx, notificationAuthorID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, id := range blockedAuthorIDs {
|
||||
toNotify.Remove(id)
|
||||
}
|
||||
}
|
||||
|
||||
err = issue.LoadRepo(ctx)
|
||||
|
|
|
@ -1,60 +1,96 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
var ErrAuthTokenNotExist = util.NewNotExistErrorf("auth token does not exist")
|
||||
// AuthorizationToken represents a authorization token to a user.
|
||||
type AuthorizationToken struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UID int64 `xorm:"INDEX"`
|
||||
LookupKey string `xorm:"INDEX UNIQUE"`
|
||||
HashedValidator string
|
||||
Expiry timeutil.TimeStamp
|
||||
}
|
||||
|
||||
type AuthToken struct { //nolint:revive
|
||||
ID string `xorm:"pk"`
|
||||
TokenHash string
|
||||
UserID int64 `xorm:"INDEX"`
|
||||
ExpiresUnix timeutil.TimeStamp `xorm:"INDEX"`
|
||||
// TableName provides the real table name.
|
||||
func (AuthorizationToken) TableName() string {
|
||||
return "forgejo_auth_token"
|
||||
}
|
||||
|
||||
func init() {
|
||||
db.RegisterModel(new(AuthToken))
|
||||
db.RegisterModel(new(AuthorizationToken))
|
||||
}
|
||||
|
||||
func InsertAuthToken(ctx context.Context, t *AuthToken) error {
|
||||
_, err := db.GetEngine(ctx).Insert(t)
|
||||
return err
|
||||
// IsExpired returns if the authorization token is expired.
|
||||
func (authToken *AuthorizationToken) IsExpired() bool {
|
||||
return authToken.Expiry.AsLocalTime().Before(time.Now())
|
||||
}
|
||||
|
||||
func GetAuthTokenByID(ctx context.Context, id string) (*AuthToken, error) {
|
||||
at := &AuthToken{}
|
||||
// GenerateAuthToken generates a new authentication token for the given user.
|
||||
// It returns the lookup key and validator values that should be passed to the
|
||||
// user via a long-term cookie.
|
||||
func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeStamp) (lookupKey, validator string, err error) {
|
||||
// Request 64 random bytes. The first 32 bytes will be used for the lookupKey
|
||||
// and the other 32 bytes will be used for the validator.
|
||||
rBytes, err := util.CryptoRandomBytes(64)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
hexEncoded := hex.EncodeToString(rBytes)
|
||||
validator, lookupKey = hexEncoded[64:], hexEncoded[:64]
|
||||
|
||||
has, err := db.GetEngine(ctx).ID(id).Get(at)
|
||||
_, err = db.GetEngine(ctx).Insert(&AuthorizationToken{
|
||||
UID: userID,
|
||||
Expiry: expiry,
|
||||
LookupKey: lookupKey,
|
||||
HashedValidator: HashValidator(rBytes[32:]),
|
||||
})
|
||||
return lookupKey, validator, err
|
||||
}
|
||||
|
||||
// FindAuthToken will find a authorization token via the lookup key.
|
||||
func FindAuthToken(ctx context.Context, lookupKey string) (*AuthorizationToken, error) {
|
||||
var authToken AuthorizationToken
|
||||
has, err := db.GetEngine(ctx).Where("lookup_key = ?", lookupKey).Get(&authToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, fmt.Errorf("lookup key %q: %w", lookupKey, util.ErrNotExist)
|
||||
}
|
||||
if !has {
|
||||
return nil, ErrAuthTokenNotExist
|
||||
return &authToken, nil
|
||||
}
|
||||
|
||||
// DeleteAuthToken will delete the authorization token.
|
||||
func DeleteAuthToken(ctx context.Context, authToken *AuthorizationToken) error {
|
||||
_, err := db.DeleteByBean(ctx, authToken)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteAuthTokenByUser will delete all authorization tokens for the user.
|
||||
func DeleteAuthTokenByUser(ctx context.Context, userID int64) error {
|
||||
if userID == 0 {
|
||||
return nil
|
||||
}
|
||||
return at, nil
|
||||
}
|
||||
|
||||
func UpdateAuthTokenByID(ctx context.Context, t *AuthToken) error {
|
||||
_, err := db.GetEngine(ctx).ID(t.ID).Cols("token_hash", "expires_unix").Update(t)
|
||||
_, err := db.DeleteByBean(ctx, &AuthorizationToken{UID: userID})
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteAuthTokenByID(ctx context.Context, id string) error {
|
||||
_, err := db.GetEngine(ctx).ID(id).Delete(&AuthToken{})
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteExpiredAuthTokens(ctx context.Context) error {
|
||||
_, err := db.GetEngine(ctx).Where(builder.Lt{"expires_unix": timeutil.TimeStampNow()}).Delete(&AuthToken{})
|
||||
return err
|
||||
// HashValidator will return a hexified hashed version of the validator.
|
||||
func HashValidator(validator []byte) string {
|
||||
h := sha256.New()
|
||||
h.Write(validator)
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
|
|
@ -292,6 +292,17 @@ func GetSourceByID(ctx context.Context, id int64) (*Source, error) {
|
|||
return source, nil
|
||||
}
|
||||
|
||||
func GetSourceByName(ctx context.Context, name string) (*Source, error) {
|
||||
source := &Source{}
|
||||
has, err := db.GetEngine(ctx).Where("name = ?", name).Get(source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrSourceNotExist{}
|
||||
}
|
||||
return source, nil
|
||||
}
|
||||
|
||||
// UpdateSource updates a Source record in DB.
|
||||
func UpdateSource(ctx context.Context, source *Source) error {
|
||||
var originalSource *Source
|
||||
|
|
|
@ -44,6 +44,7 @@ type Engine interface {
|
|||
Incr(column string, arg ...any) *xorm.Session
|
||||
Insert(...any) (int64, error)
|
||||
Iterate(any, xorm.IterFunc) error
|
||||
IsTableExist(any) (bool, error)
|
||||
Join(joinOperator string, tablename, condition any, args ...any) *xorm.Session
|
||||
SQL(any, ...any) *xorm.Session
|
||||
Where(any, ...any) *xorm.Session
|
||||
|
|
|
@ -68,6 +68,7 @@ func TestPrimaryKeys(t *testing.T) {
|
|||
|
||||
whitelist := map[string]string{
|
||||
"the_table_name_to_skip_checking": "Write a note here to explain why",
|
||||
"forgejo_sem_ver": "seriously dude",
|
||||
}
|
||||
|
||||
for _, bean := range beans {
|
||||
|
|
5
models/fixtures/forgejo_blocked_user.yml
Normal file
5
models/fixtures/forgejo_blocked_user.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
-
|
||||
id: 1
|
||||
user_id: 4
|
||||
block_id: 1
|
||||
created_unix: 1671607299
|
|
@ -37,7 +37,7 @@
|
|||
lower_name: repo2
|
||||
name: repo2
|
||||
default_branch: master
|
||||
num_watches: 0
|
||||
num_watches: 1
|
||||
num_stars: 1
|
||||
num_forks: 0
|
||||
num_issues: 2
|
||||
|
@ -83,7 +83,7 @@
|
|||
is_empty: false
|
||||
is_archived: false
|
||||
is_mirror: false
|
||||
status: 0
|
||||
status: 2
|
||||
is_fork: false
|
||||
fork_id: 0
|
||||
is_template: false
|
||||
|
|
|
@ -27,3 +27,9 @@
|
|||
user_id: 11
|
||||
repo_id: 1
|
||||
mode: 3 # auto
|
||||
|
||||
-
|
||||
id: 6
|
||||
user_id: 4
|
||||
repo_id: 2
|
||||
mode: 1 # normal
|
||||
|
|
17
models/forgejo/semver/main_test.go
Normal file
17
models/forgejo/semver/main_test.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package semver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
_ "code.gitea.io/gitea/models"
|
||||
_ "code.gitea.io/gitea/models/actions"
|
||||
_ "code.gitea.io/gitea/models/activities"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m)
|
||||
}
|
80
models/forgejo/semver/semver.go
Normal file
80
models/forgejo/semver/semver.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package semver
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
func init() {
|
||||
db.RegisterModel(new(ForgejoSemVer))
|
||||
}
|
||||
|
||||
var DefaultVersionString = "1.0.0"
|
||||
|
||||
type ForgejoSemVer struct {
|
||||
Version string
|
||||
}
|
||||
|
||||
func GetVersion(ctx context.Context) (*version.Version, error) {
|
||||
return GetVersionWithEngine(db.GetEngine(ctx))
|
||||
}
|
||||
|
||||
func GetVersionWithEngine(e db.Engine) (*version.Version, error) {
|
||||
versionString := DefaultVersionString
|
||||
|
||||
exists, err := e.IsTableExist("forgejo_sem_ver")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if exists {
|
||||
var semver ForgejoSemVer
|
||||
has, err := e.Get(&semver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if has {
|
||||
versionString = semver.Version
|
||||
}
|
||||
}
|
||||
|
||||
v, err := version.NewVersion(versionString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func SetVersionString(ctx context.Context, versionString string) error {
|
||||
return SetVersionStringWithEngine(db.GetEngine(ctx), versionString)
|
||||
}
|
||||
|
||||
func SetVersionStringWithEngine(e db.Engine, versionString string) error {
|
||||
v, err := version.NewVersion(versionString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return SetVersionWithEngine(e, v)
|
||||
}
|
||||
|
||||
func SetVersion(ctx context.Context, v *version.Version) error {
|
||||
return SetVersionWithEngine(db.GetEngine(ctx), v)
|
||||
}
|
||||
|
||||
func SetVersionWithEngine(e db.Engine, v *version.Version) error {
|
||||
var semver ForgejoSemVer
|
||||
has, err := e.Get(&semver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !has {
|
||||
_, err = e.Exec("insert into forgejo_sem_ver values (?)", v.String())
|
||||
} else {
|
||||
_, err = e.Exec("update forgejo_sem_ver set version = ?", v.String())
|
||||
}
|
||||
return err
|
||||
}
|
46
models/forgejo/semver/semver_test.go
Normal file
46
models/forgejo/semver/semver_test.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package semver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestForgejoSemVerSetGet(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
ctx := db.DefaultContext
|
||||
|
||||
newVersion, err := version.NewVersion("v1.2.3")
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, SetVersionString(ctx, newVersion.String()))
|
||||
databaseVersion, err := GetVersion(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, newVersion.String(), databaseVersion.String())
|
||||
assert.True(t, newVersion.Equal(databaseVersion))
|
||||
}
|
||||
|
||||
func TestForgejoSemVerMissing(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
ctx := db.DefaultContext
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
_, err := e.Exec("delete from forgejo_sem_ver")
|
||||
assert.NoError(t, err)
|
||||
|
||||
v, err := GetVersion(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, "1.0.0", v.String())
|
||||
|
||||
_, err = e.Exec("drop table forgejo_sem_ver")
|
||||
assert.NoError(t, err)
|
||||
|
||||
v, err = GetVersion(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, "1.0.0", v.String())
|
||||
}
|
14
models/forgejo_migrations/main_test.go
Normal file
14
models/forgejo_migrations/main_test.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo_migrations //nolint:revive
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
base.MainTest(m)
|
||||
}
|
153
models/forgejo_migrations/migrate.go
Normal file
153
models/forgejo_migrations/migrate.go
Normal file
|
@ -0,0 +1,153 @@
|
|||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo_migrations //nolint:revive
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/gitea/models/forgejo/semver"
|
||||
forgejo_v1_20 "code.gitea.io/gitea/models/forgejo_migrations/v1_20"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/names"
|
||||
)
|
||||
|
||||
// ForgejoVersion describes the Forgejo version table. Should have only one row with id = 1.
|
||||
type ForgejoVersion struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Version int64
|
||||
}
|
||||
|
||||
type Migration struct {
|
||||
description string
|
||||
migrate func(*xorm.Engine) error
|
||||
}
|
||||
|
||||
// NewMigration creates a new migration.
|
||||
func NewMigration(desc string, fn func(*xorm.Engine) error) *Migration {
|
||||
return &Migration{desc, fn}
|
||||
}
|
||||
|
||||
// This is a sequence of additional Forgejo migrations.
|
||||
// Add new migrations to the bottom of the list.
|
||||
var migrations = []*Migration{
|
||||
// v0 -> v1
|
||||
NewMigration("Add Forgejo Blocked Users table", forgejo_v1_20.AddForgejoBlockedUser),
|
||||
// v1 -> v2
|
||||
NewMigration("create the forgejo_sem_ver table", forgejo_v1_20.CreateSemVerTable),
|
||||
// v2 -> v3
|
||||
NewMigration("create the forgejo_auth_token table", forgejo_v1_20.CreateAuthorizationTokenTable),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current Forgejo database version.
|
||||
func GetCurrentDBVersion(x *xorm.Engine) (int64, error) {
|
||||
if err := x.Sync(new(ForgejoVersion)); err != nil {
|
||||
return -1, fmt.Errorf("sync: %w", err)
|
||||
}
|
||||
|
||||
currentVersion := &ForgejoVersion{ID: 1}
|
||||
has, err := x.Get(currentVersion)
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("get: %w", err)
|
||||
}
|
||||
if !has {
|
||||
return -1, nil
|
||||
}
|
||||
return currentVersion.Version, nil
|
||||
}
|
||||
|
||||
// ExpectedVersion returns the expected Forgejo database version.
|
||||
func ExpectedVersion() int64 {
|
||||
return int64(len(migrations))
|
||||
}
|
||||
|
||||
// EnsureUpToDate will check if the Forgejo database is at the correct version.
|
||||
func EnsureUpToDate(x *xorm.Engine) error {
|
||||
currentDB, err := GetCurrentDBVersion(x)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if currentDB < 0 {
|
||||
return fmt.Errorf("database has not been initialized")
|
||||
}
|
||||
|
||||
expected := ExpectedVersion()
|
||||
|
||||
if currentDB != expected {
|
||||
return fmt.Errorf(`current Forgejo database version %d is not equal to the expected version %d. Please run "forgejo [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Migrate Forgejo database to current version.
|
||||
func Migrate(x *xorm.Engine) error {
|
||||
// Set a new clean the default mapper to GonicMapper as that is the default for .
|
||||
x.SetMapper(names.GonicMapper{})
|
||||
if err := x.Sync(new(ForgejoVersion)); err != nil {
|
||||
return fmt.Errorf("sync: %w", err)
|
||||
}
|
||||
|
||||
currentVersion := &ForgejoVersion{ID: 1}
|
||||
has, err := x.Get(currentVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get: %w", err)
|
||||
} else if !has {
|
||||
// If the version record does not exist we think
|
||||
// it is a fresh installation and we can skip all migrations.
|
||||
currentVersion.ID = 0
|
||||
currentVersion.Version = ExpectedVersion()
|
||||
|
||||
if _, err = x.InsertOne(currentVersion); err != nil {
|
||||
return fmt.Errorf("insert: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
v := currentVersion.Version
|
||||
|
||||
// Downgrading Forgejo's database version not supported
|
||||
if v > ExpectedVersion() {
|
||||
msg := fmt.Sprintf("Your Forgejo database (migration version: %d) is for a newer version of Forgejo, you cannot use the newer database for this old Forgejo release (%d).", v, ExpectedVersion())
|
||||
msg += "\nForgejo will exit to keep your database safe and unchanged. Please use the correct Forgejo release, do not change the migration version manually (incorrect manual operation may cause data loss)."
|
||||
if !setting.IsProd {
|
||||
msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE forgejo_version SET version=%d WHERE id=1;", ExpectedVersion())
|
||||
}
|
||||
_, _ = fmt.Fprintln(os.Stderr, msg)
|
||||
log.Fatal(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Some migration tasks depend on the git command
|
||||
if git.DefaultContext == nil {
|
||||
if err = git.InitSimple(context.Background()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate
|
||||
for i, m := range migrations[v:] {
|
||||
log.Info("Migration[%d]: %s", v+int64(i), m.description)
|
||||
// Reset the mapper between each migration - migrations are not supposed to depend on each other
|
||||
x.SetMapper(names.GonicMapper{})
|
||||
if err = m.migrate(x); err != nil {
|
||||
return fmt.Errorf("migration[%d]: %s failed: %w", v+int64(i), m.description, err)
|
||||
}
|
||||
currentVersion.Version = v + int64(i) + 1
|
||||
if _, err = x.ID(1).Update(currentVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := x.Sync(new(semver.ForgejoSemVer)); err != nil {
|
||||
return fmt.Errorf("sync: %w", err)
|
||||
}
|
||||
|
||||
return semver.SetVersionStringWithEngine(x, setting.ForgejoVersion)
|
||||
}
|
39
models/forgejo_migrations/migrate_test.go
Normal file
39
models/forgejo_migrations/migrate_test.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo_migrations //nolint:revive
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestEnsureUpToDate tests the behavior of EnsureUpToDate.
|
||||
func TestEnsureUpToDate(t *testing.T) {
|
||||
x, deferable := base.PrepareTestEnv(t, 0, new(ForgejoVersion))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure error if there's no row in Forgejo Version.
|
||||
err := EnsureUpToDate(x)
|
||||
assert.Error(t, err)
|
||||
|
||||
// Insert 'good' Forgejo Version row.
|
||||
_, err = x.InsertOne(&ForgejoVersion{ID: 1, Version: ExpectedVersion()})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = EnsureUpToDate(x)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Modify forgejo version to have a lower version.
|
||||
_, err = x.Exec("UPDATE `forgejo_version` SET version = ? WHERE id = 1", ExpectedVersion()-1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = EnsureUpToDate(x)
|
||||
assert.Error(t, err)
|
||||
}
|
21
models/forgejo_migrations/v1_20/v1.go
Normal file
21
models/forgejo_migrations/v1_20/v1.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo_v1_20 //nolint:revive
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddForgejoBlockedUser(x *xorm.Engine) error {
|
||||
type ForgejoBlockedUser struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
BlockID int64 `xorm:"index"`
|
||||
UserID int64 `xorm:"index"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created"`
|
||||
}
|
||||
|
||||
return x.Sync(new(ForgejoBlockedUser))
|
||||
}
|
15
models/forgejo_migrations/v1_20/v2.go
Normal file
15
models/forgejo_migrations/v1_20/v2.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo_v1_20 //nolint:revive
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func CreateSemVerTable(x *xorm.Engine) error {
|
||||
type ForgejoSemVer struct {
|
||||
Version string
|
||||
}
|
||||
|
||||
return x.Sync(new(ForgejoSemVer))
|
||||
}
|
26
models/forgejo_migrations/v1_20/v3.go
Normal file
26
models/forgejo_migrations/v1_20/v3.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2023 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forgejo_v1_20 //nolint:revive
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type AuthorizationToken struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UID int64 `xorm:"INDEX"`
|
||||
LookupKey string `xorm:"INDEX UNIQUE"`
|
||||
HashedValidator string
|
||||
Expiry timeutil.TimeStamp
|
||||
}
|
||||
|
||||
func (AuthorizationToken) TableName() string {
|
||||
return "forgejo_auth_token"
|
||||
}
|
||||
|
||||
func CreateAuthorizationTokenTable(x *xorm.Engine) error {
|
||||
return x.Sync(new(AuthorizationToken))
|
||||
}
|
|
@ -824,6 +824,14 @@ func CreateComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment,
|
|||
IsForcePush: opts.IsForcePush,
|
||||
Invalidated: opts.Invalidated,
|
||||
}
|
||||
if opts.Issue.NoAutoTime {
|
||||
// Preload the comment with the Issue containing the forced update
|
||||
// date. This is needed to propagate those data in AddCrossReferences()
|
||||
comment.Issue = opts.Issue
|
||||
comment.CreatedUnix = opts.Issue.UpdatedUnix
|
||||
comment.UpdatedUnix = opts.Issue.UpdatedUnix
|
||||
e.NoAutoTime()
|
||||
}
|
||||
if _, err = e.Insert(comment); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1106,12 +1114,21 @@ func UpdateComment(ctx context.Context, c *Comment, doer *user_model.User) error
|
|||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
sess := db.GetEngine(ctx)
|
||||
|
||||
if _, err := sess.ID(c.ID).AllCols().Update(c); err != nil {
|
||||
if err := c.LoadIssue(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.LoadIssue(ctx); err != nil {
|
||||
|
||||
sess := db.GetEngine(ctx).ID(c.ID).AllCols()
|
||||
if c.Issue.NoAutoTime {
|
||||
// update the DataBase
|
||||
sess = sess.NoAutoTime().SetExpr("updated_unix", c.Issue.UpdatedUnix)
|
||||
// the UpdatedUnix value of the Comment also has to be set,
|
||||
// to return the adequate value
|
||||
// see https://codeberg.org/forgejo/forgejo/pulls/764#issuecomment-1023801
|
||||
c.UpdatedUnix = c.Issue.UpdatedUnix
|
||||
}
|
||||
if _, err := sess.Update(c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.AddCrossReferences(ctx, doer, true); err != nil {
|
||||
|
|
|
@ -126,6 +126,7 @@ type Issue struct {
|
|||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
|
||||
NoAutoTime bool `xorm:"-"`
|
||||
|
||||
Attachments []*repo_model.Attachment `xorm:"-"`
|
||||
Comments CommentList `xorm:"-"`
|
||||
|
|
|
@ -281,6 +281,8 @@ func TestIssue_ResolveMentions(t *testing.T) {
|
|||
testSuccess("user2", "repo1", "user1", []string{"nonexisting"}, []int64{})
|
||||
// Public repo, doer
|
||||
testSuccess("user2", "repo1", "user1", []string{"user1"}, []int64{})
|
||||
// Public repo, blocked user
|
||||
testSuccess("user2", "repo1", "user1", []string{"user4"}, []int64{})
|
||||
// Private repo, team member
|
||||
testSuccess("org17", "big_test_private_4", "user20", []string{"user2"}, []int64{2})
|
||||
// Private repo, not a team member
|
||||
|
|
|
@ -27,7 +27,12 @@ import (
|
|||
|
||||
// UpdateIssueCols updates cols of issue
|
||||
func UpdateIssueCols(ctx context.Context, issue *Issue, cols ...string) error {
|
||||
if _, err := db.GetEngine(ctx).ID(issue.ID).Cols(cols...).Update(issue); err != nil {
|
||||
sess := db.GetEngine(ctx).ID(issue.ID)
|
||||
if issue.NoAutoTime {
|
||||
cols = append(cols, []string{"updated_unix"}...)
|
||||
sess.NoAutoTime()
|
||||
}
|
||||
if _, err := sess.Cols(cols...).Update(issue); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -71,7 +76,11 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use
|
|||
}
|
||||
|
||||
if issue.IsClosed {
|
||||
issue.ClosedUnix = timeutil.TimeStampNow()
|
||||
if issue.NoAutoTime {
|
||||
issue.ClosedUnix = issue.UpdatedUnix
|
||||
} else {
|
||||
issue.ClosedUnix = timeutil.TimeStampNow()
|
||||
}
|
||||
} else {
|
||||
issue.ClosedUnix = 0
|
||||
}
|
||||
|
@ -92,8 +101,14 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use
|
|||
|
||||
// Update issue count of milestone
|
||||
if issue.MilestoneID > 0 {
|
||||
if err := UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil {
|
||||
return nil, err
|
||||
if issue.NoAutoTime {
|
||||
if err := UpdateMilestoneCountersWithDate(ctx, issue.MilestoneID, issue.UpdatedUnix); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,8 +274,12 @@ func ChangeIssueContent(ctx context.Context, issue *Issue, doer *user_model.User
|
|||
return fmt.Errorf("UpdateIssueCols: %w", err)
|
||||
}
|
||||
|
||||
historyDate := timeutil.TimeStampNow()
|
||||
if issue.NoAutoTime {
|
||||
historyDate = issue.UpdatedUnix
|
||||
}
|
||||
if err = SaveIssueContentHistory(ctx, doer.ID, issue.ID, 0,
|
||||
timeutil.TimeStampNow(), issue.Content, false); err != nil {
|
||||
historyDate, issue.Content, false); err != nil {
|
||||
return fmt.Errorf("SaveIssueContentHistory: %w", err)
|
||||
}
|
||||
|
||||
|
@ -449,10 +468,13 @@ func UpdateIssueByAPI(ctx context.Context, issue *Issue, doer *user_model.User)
|
|||
return nil, false, err
|
||||
}
|
||||
|
||||
if _, err := db.GetEngine(ctx).ID(issue.ID).Cols(
|
||||
"name", "content", "milestone_id", "priority",
|
||||
"deadline_unix", "updated_unix", "is_locked").
|
||||
Update(issue); err != nil {
|
||||
sess := db.GetEngine(ctx).ID(issue.ID)
|
||||
cols := []string{"name", "content", "milestone_id", "priority", "deadline_unix", "is_locked"}
|
||||
if issue.NoAutoTime {
|
||||
cols = append(cols, "updated_unix")
|
||||
sess.NoAutoTime()
|
||||
}
|
||||
if _, err := sess.Cols(cols...).Update(issue); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
|
@ -498,7 +520,7 @@ func UpdateIssueDeadline(ctx context.Context, issue *Issue, deadlineUnix timeuti
|
|||
defer committer.Close()
|
||||
|
||||
// Update the deadline
|
||||
if err = UpdateIssueCols(ctx, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix}, "deadline_unix"); err != nil {
|
||||
if err = UpdateIssueCols(ctx, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix, NoAutoTime: issue.NoAutoTime, UpdatedUnix: issue.UpdatedUnix}, "deadline_unix"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -597,9 +619,11 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
|||
teamusers := make([]*user_model.User, 0, 20)
|
||||
if err := db.GetEngine(ctx).
|
||||
Join("INNER", "team_user", "team_user.uid = `user`.id").
|
||||
Join("LEFT", "forgejo_blocked_user", "forgejo_blocked_user.user_id = `user`.id").
|
||||
In("`team_user`.team_id", checked).
|
||||
And("`user`.is_active = ?", true).
|
||||
And("`user`.prohibit_login = ?", false).
|
||||
And(builder.Or(builder.IsNull{"`forgejo_blocked_user`.block_id"}, builder.Neq{"`forgejo_blocked_user`.block_id": doer.ID})).
|
||||
Find(&teamusers); err != nil {
|
||||
return nil, fmt.Errorf("get teams users: %w", err)
|
||||
}
|
||||
|
@ -633,8 +657,10 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
|||
|
||||
unchecked := make([]*user_model.User, 0, len(mentionUsers))
|
||||
if err := db.GetEngine(ctx).
|
||||
Join("LEFT", "forgejo_blocked_user", "forgejo_blocked_user.user_id = `user`.id").
|
||||
Where("`user`.is_active = ?", true).
|
||||
And("`user`.prohibit_login = ?", false).
|
||||
And(builder.Or(builder.IsNull{"`forgejo_blocked_user`.block_id"}, builder.Neq{"`forgejo_blocked_user`.block_id": doer.ID})).
|
||||
In("`user`.lower_name", mentionUsers).
|
||||
Find(&unchecked); err != nil {
|
||||
return nil, fmt.Errorf("find mentioned users: %w", err)
|
||||
|
|
|
@ -46,11 +46,15 @@ func neuterCrossReferences(ctx context.Context, issueID, commentID int64) error
|
|||
for i, c := range active {
|
||||
ids[i] = c.ID
|
||||
}
|
||||
return neuterCrossReferencesIds(ctx, ids)
|
||||
return neuterCrossReferencesIds(ctx, nil, ids)
|
||||
}
|
||||
|
||||
func neuterCrossReferencesIds(ctx context.Context, ids []int64) error {
|
||||
_, err := db.GetEngine(ctx).In("id", ids).Cols("`ref_action`").Update(&Comment{RefAction: references.XRefActionNeutered})
|
||||
func neuterCrossReferencesIds(stdCtx context.Context, ctx *crossReferencesContext, ids []int64) error {
|
||||
sess := db.GetEngine(stdCtx).In("id", ids).Cols("`ref_action`")
|
||||
if ctx != nil && ctx.OrigIssue.NoAutoTime {
|
||||
sess.SetExpr("updated_unix", ctx.OrigIssue.UpdatedUnix).NoAutoTime()
|
||||
}
|
||||
_, err := sess.Update(&Comment{RefAction: references.XRefActionNeutered})
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -100,7 +104,7 @@ func (issue *Issue) createCrossReferences(stdCtx context.Context, ctx *crossRefe
|
|||
}
|
||||
}
|
||||
if len(ids) > 0 {
|
||||
if err = neuterCrossReferencesIds(stdCtx, ids); err != nil {
|
||||
if err = neuterCrossReferencesIds(stdCtx, ctx, ids); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +114,10 @@ func (issue *Issue) createCrossReferences(stdCtx context.Context, ctx *crossRefe
|
|||
if ctx.OrigComment != nil {
|
||||
refCommentID = ctx.OrigComment.ID
|
||||
}
|
||||
if ctx.OrigIssue.NoAutoTime {
|
||||
xref.Issue.NoAutoTime = true
|
||||
xref.Issue.UpdatedUnix = ctx.OrigIssue.UpdatedUnix
|
||||
}
|
||||
opts := &CreateCommentOptions{
|
||||
Type: ctx.Type,
|
||||
Doer: ctx.Doer,
|
||||
|
|
|
@ -187,10 +187,9 @@ func updateMilestone(ctx context.Context, m *Milestone) error {
|
|||
return UpdateMilestoneCounters(ctx, m.ID)
|
||||
}
|
||||
|
||||
// UpdateMilestoneCounters calculates NumIssues, NumClosesIssues and Completeness
|
||||
func UpdateMilestoneCounters(ctx context.Context, id int64) error {
|
||||
func updateMilestoneCounters(ctx context.Context, id int64, noAutoTime bool, updatedUnix timeutil.TimeStamp) error {
|
||||
e := db.GetEngine(ctx)
|
||||
_, err := e.ID(id).
|
||||
sess := e.ID(id).
|
||||
SetExpr("num_issues", builder.Select("count(*)").From("issue").Where(
|
||||
builder.Eq{"milestone_id": id},
|
||||
)).
|
||||
|
@ -199,8 +198,11 @@ func UpdateMilestoneCounters(ctx context.Context, id int64) error {
|
|||
"milestone_id": id,
|
||||
"is_closed": true,
|
||||
},
|
||||
)).
|
||||
Update(&Milestone{})
|
||||
))
|
||||
if noAutoTime {
|
||||
sess.SetExpr("updated_unix", updatedUnix).NoAutoTime()
|
||||
}
|
||||
_, err := sess.Update(&Milestone{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -210,6 +212,16 @@ func UpdateMilestoneCounters(ctx context.Context, id int64) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// UpdateMilestoneCounters calculates NumIssues, NumClosesIssues and Completeness
|
||||
func UpdateMilestoneCounters(ctx context.Context, id int64) error {
|
||||
return updateMilestoneCounters(ctx, id, false, 0)
|
||||
}
|
||||
|
||||
// UpdateMilestoneCountersWithDate calculates NumIssues, NumClosesIssues and Completeness and set the UpdatedUnix date
|
||||
func UpdateMilestoneCountersWithDate(ctx context.Context, id int64, updatedUnix timeutil.TimeStamp) error {
|
||||
return updateMilestoneCounters(ctx, id, true, updatedUnix)
|
||||
}
|
||||
|
||||
// ChangeMilestoneStatusByRepoIDAndID changes a milestone open/closed status if the milestone ID is in the repo.
|
||||
func ChangeMilestoneStatusByRepoIDAndID(ctx context.Context, repoID, milestoneID int64, isClosed bool) error {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
|
|
|
@ -240,25 +240,6 @@ func CreateReaction(ctx context.Context, opts *ReactionOptions) (*Reaction, erro
|
|||
return reaction, nil
|
||||
}
|
||||
|
||||
// CreateIssueReaction creates a reaction on issue.
|
||||
func CreateIssueReaction(ctx context.Context, doerID, issueID int64, content string) (*Reaction, error) {
|
||||
return CreateReaction(ctx, &ReactionOptions{
|
||||
Type: content,
|
||||
DoerID: doerID,
|
||||
IssueID: issueID,
|
||||
})
|
||||
}
|
||||
|
||||
// CreateCommentReaction creates a reaction on comment.
|
||||
func CreateCommentReaction(ctx context.Context, doerID, issueID, commentID int64, content string) (*Reaction, error) {
|
||||
return CreateReaction(ctx, &ReactionOptions{
|
||||
Type: content,
|
||||
DoerID: doerID,
|
||||
IssueID: issueID,
|
||||
CommentID: commentID,
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteReaction deletes reaction for issue or comment.
|
||||
func DeleteReaction(ctx context.Context, opts *ReactionOptions) error {
|
||||
reaction := &Reaction{
|
||||
|
|
|
@ -19,11 +19,14 @@ import (
|
|||
func addReaction(t *testing.T, doerID, issueID, commentID int64, content string) {
|
||||
var reaction *issues_model.Reaction
|
||||
var err error
|
||||
if commentID == 0 {
|
||||
reaction, err = issues_model.CreateIssueReaction(db.DefaultContext, doerID, issueID, content)
|
||||
} else {
|
||||
reaction, err = issues_model.CreateCommentReaction(db.DefaultContext, doerID, issueID, commentID, content)
|
||||
}
|
||||
// NOTE: This doesn't do user blocking checking.
|
||||
reaction, err = issues_model.CreateReaction(db.DefaultContext, &issues_model.ReactionOptions{
|
||||
DoerID: doerID,
|
||||
IssueID: issueID,
|
||||
CommentID: commentID,
|
||||
Type: content,
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, reaction)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/forgejo_migrations"
|
||||
"code.gitea.io/gitea/models/migrations/v1_10"
|
||||
"code.gitea.io/gitea/models/migrations/v1_11"
|
||||
"code.gitea.io/gitea/models/migrations/v1_12"
|
||||
|
@ -28,6 +29,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
forgejo_services "code.gitea.io/gitea/services/forgejo"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/names"
|
||||
|
@ -603,7 +605,7 @@ func EnsureUpToDate(x *xorm.Engine) error {
|
|||
return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "gitea [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected)
|
||||
}
|
||||
|
||||
return nil
|
||||
return forgejo_migrations.EnsureUpToDate(x)
|
||||
}
|
||||
|
||||
// Migrate database to current version
|
||||
|
@ -614,6 +616,7 @@ func Migrate(x *xorm.Engine) error {
|
|||
return fmt.Errorf("sync: %w", err)
|
||||
}
|
||||
|
||||
var previousVersion int64
|
||||
currentVersion := &Version{ID: 1}
|
||||
has, err := x.Get(currentVersion)
|
||||
if err != nil {
|
||||
|
@ -627,6 +630,8 @@ func Migrate(x *xorm.Engine) error {
|
|||
if _, err = x.InsertOne(currentVersion); err != nil {
|
||||
return fmt.Errorf("insert: %w", err)
|
||||
}
|
||||
} else {
|
||||
previousVersion = currentVersion.Version
|
||||
}
|
||||
|
||||
v := currentVersion.Version
|
||||
|
@ -654,6 +659,10 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t
|
|||
}
|
||||
}
|
||||
|
||||
if err := forgejo_services.PreMigrationSanityChecks(x, previousVersion, setting.CfgProvider); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Migrate
|
||||
for i, m := range migrations[v-minDBVersion:] {
|
||||
log.Info("Migration[%d]: %s", v+int64(i), m.Description())
|
||||
|
@ -667,5 +676,7 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t
|
|||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
// Execute Forgejo specific migrations.
|
||||
return forgejo_migrations.Migrate(x)
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ type Attachment struct {
|
|||
Name string
|
||||
DownloadCount int64 `xorm:"DEFAULT 0"`
|
||||
Size int64 `xorm:"DEFAULT 0"`
|
||||
NoAutoTime bool `xorm:"-"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created"`
|
||||
CustomDownloadURL string `xorm:"-"`
|
||||
}
|
||||
|
|
|
@ -136,6 +136,19 @@ func ChangeCollaborationAccessMode(ctx context.Context, repo *Repository, uid in
|
|||
})
|
||||
}
|
||||
|
||||
// GetCollaboratorWithUser returns all collaborator IDs of collabUserID on
|
||||
// repositories of ownerID.
|
||||
func GetCollaboratorWithUser(ctx context.Context, ownerID, collabUserID int64) ([]int64, error) {
|
||||
collabsID := make([]int64, 0, 8)
|
||||
err := db.GetEngine(ctx).Table("collaboration").Select("collaboration.`id`").
|
||||
Join("INNER", "repository", "repository.id = collaboration.repo_id").
|
||||
Where("repository.`owner_id` = ?", ownerID).
|
||||
And("collaboration.`user_id` = ?", collabUserID).
|
||||
Find(&collabsID)
|
||||
|
||||
return collabsID, err
|
||||
}
|
||||
|
||||
// IsOwnerMemberCollaborator checks if a provided user is the owner, a collaborator or a member of a team in a repository
|
||||
func IsOwnerMemberCollaborator(ctx context.Context, repo *Repository, userID int64) (bool, error) {
|
||||
if repo.OwnerID == userID {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -162,3 +163,23 @@ func TestRepo_GetCollaboration(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Nil(t, collab)
|
||||
}
|
||||
|
||||
func TestGetCollaboratorWithUser(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
user16 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16})
|
||||
user15 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
|
||||
user18 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 18})
|
||||
|
||||
collabs, err := repo_model.GetCollaboratorWithUser(db.DefaultContext, user16.ID, user15.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, collabs, 2)
|
||||
assert.EqualValues(t, 5, collabs[0])
|
||||
assert.EqualValues(t, 7, collabs[1])
|
||||
|
||||
collabs, err = repo_model.GetCollaboratorWithUser(db.DefaultContext, user16.ID, user18.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, collabs, 2)
|
||||
assert.EqualValues(t, 6, collabs[0])
|
||||
assert.EqualValues(t, 8, collabs[1])
|
||||
}
|
||||
|
|
|
@ -177,3 +177,16 @@ func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull boo
|
|||
Limit(30).
|
||||
Find(&users)
|
||||
}
|
||||
|
||||
// GetWatchedRepoIDsOwnedBy returns the repos owned by a particular user watched by a particular user
|
||||
func GetWatchedRepoIDsOwnedBy(ctx context.Context, userID, ownedByUserID int64) ([]int64, error) {
|
||||
repoIDs := make([]int64, 0, 10)
|
||||
err := db.GetEngine(ctx).
|
||||
Table("repository").
|
||||
Select("`repository`.id").
|
||||
Join("LEFT", "watch", "`repository`.id=`watch`.repo_id").
|
||||
Where("`watch`.user_id=?", userID).
|
||||
And("`watch`.mode<>?", WatchModeDont).
|
||||
And("`repository`.owner_id=?", ownedByUserID).Find(&repoIDs)
|
||||
return repoIDs, err
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -71,3 +72,15 @@ func TestRepoGetReviewers(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Len(t, reviewers, 1)
|
||||
}
|
||||
|
||||
func GetWatchedRepoIDsOwnedBy(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 9})
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
|
||||
repoIDs, err := repo_model.GetWatchedRepoIDsOwnedBy(db.DefaultContext, user1.ID, user2.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, repoIDs, 1)
|
||||
assert.EqualValues(t, 1, repoIDs[0])
|
||||
}
|
||||
|
|
|
@ -182,3 +182,9 @@ func WatchIfAuto(ctx context.Context, userID, repoID int64, isWrite bool) error
|
|||
}
|
||||
return watchRepoMode(ctx, watch, WatchModeAuto)
|
||||
}
|
||||
|
||||
// UnwatchRepos will unwatch the user from all given repositories.
|
||||
func UnwatchRepos(ctx context.Context, userID int64, repoIDs []int64) error {
|
||||
_, err := db.GetEngine(ctx).Where("user_id=?", userID).In("repo_id", repoIDs).Delete(&Watch{})
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -137,3 +137,16 @@ func TestWatchRepoMode(t *testing.T) {
|
|||
assert.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeNone))
|
||||
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1}, 0)
|
||||
}
|
||||
|
||||
func TestUnwatchRepos(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: 4, RepoID: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: 4, RepoID: 2})
|
||||
|
||||
err := repo_model.UnwatchRepos(db.DefaultContext, 4, []int64{1, 2})
|
||||
assert.NoError(t, err)
|
||||
|
||||
unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 4, RepoID: 1})
|
||||
unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 4, RepoID: 2})
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue