2020-04-05 01:20:50 -05:00
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2019-03-08 02:54:10 +01:00
package main
/ *
Checkout a PR and load the tests data into sqlite database
* /
import (
2019-12-15 09:51:28 +00:00
"context"
2019-03-08 02:54:10 +01:00
"flag"
"fmt"
"log"
"net/http"
"os"
"os/exec"
"os/user"
"path"
"path/filepath"
"runtime"
2019-03-15 11:18:01 -05:00
"strconv"
2019-03-08 02:54:10 +01:00
"time"
2021-09-19 19:49:59 +08:00
"code.gitea.io/gitea/models/db"
2021-11-12 22:36:47 +08:00
"code.gitea.io/gitea/models/unittest"
2021-06-26 19:28:55 +08:00
gitea_git "code.gitea.io/gitea/modules/git"
2022-08-28 10:43:25 +01:00
"code.gitea.io/gitea/modules/graceful"
2019-05-26 01:15:39 +08:00
"code.gitea.io/gitea/modules/markup"
2019-03-08 02:54:10 +01:00
"code.gitea.io/gitea/modules/markup/external"
2022-05-09 00:46:32 +08:00
repo_module "code.gitea.io/gitea/modules/repository"
2019-06-27 02:15:26 +08:00
"code.gitea.io/gitea/modules/setting"
2020-08-11 21:05:34 +01:00
"code.gitea.io/gitea/modules/util"
2019-03-08 02:54:10 +01:00
"code.gitea.io/gitea/routers"
2022-10-22 20:15:52 +03:00
markup_service "code.gitea.io/gitea/services/markup"
2019-06-27 02:15:26 +08:00
2020-03-17 18:19:58 +02:00
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
2019-10-17 17:26:49 +08:00
"xorm.io/xorm"
2019-03-08 02:54:10 +01:00
)
var codeFilePath = "contrib/pr/checkout.go"
func runPR ( ) {
log . Printf ( "[PR] Starting gitea ...\n" )
curDir , err := os . Getwd ( )
if err != nil {
log . Fatal ( err )
}
2019-05-14 16:20:35 +01:00
setting . SetCustomPathAndConf ( "" , "" , "" )
2021-12-01 15:50:01 +08:00
setting . LoadAllowEmpty ( )
2019-03-08 02:54:10 +01:00
2021-09-22 13:38:34 +08:00
setting . RepoRootPath , err = os . MkdirTemp ( os . TempDir ( ) , "repos" )
2019-03-08 02:54:10 +01:00
if err != nil {
log . Fatalf ( "TempDir: %v\n" , err )
}
2021-09-22 13:38:34 +08:00
setting . AppDataPath , err = os . MkdirTemp ( os . TempDir ( ) , "appdata" )
2019-03-08 02:54:10 +01:00
if err != nil {
log . Fatalf ( "TempDir: %v\n" , err )
}
setting . AppWorkPath = curDir
setting . StaticRootPath = curDir
2022-10-17 07:29:26 +08:00
setting . GravatarSource = "https://secure.gravatar.com/avatar/"
2019-03-08 02:54:10 +01:00
setting . AppURL = "http://localhost:8080/"
setting . HTTPPort = "8080"
setting . SSH . Domain = "localhost"
setting . SSH . Port = 3000
setting . InstallLock = true
setting . SecretKey = "9pCviYTWSb"
setting . InternalToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTI3OTU5ODN9.OQkH5UmzID2XBdwQ9TAI6Jj2t1X-wElVTjbE7aoN4I8"
curUser , err := user . Current ( )
if err != nil {
log . Fatal ( err )
}
setting . RunUser = curUser . Username
log . Printf ( "[PR] Loading fixtures data ...\n" )
//models.LoadConfigs()
/ *
2019-08-24 17:24:45 +08:00
setting . Database . Type = "sqlite3"
setting . Database . Path = ":memory:"
setting . Database . Timeout = 500
2019-03-08 02:54:10 +01:00
* /
2021-09-19 19:49:59 +08:00
dbCfg := setting . Cfg . Section ( "database" )
dbCfg . NewKey ( "DB_TYPE" , "sqlite3" )
dbCfg . NewKey ( "PATH" , ":memory:" )
2019-08-24 17:24:45 +08:00
2021-10-21 17:22:43 +08:00
routers . InitGitServices ( )
2019-08-24 17:24:45 +08:00
setting . Database . LogSQL = true
2022-01-20 18:46:10 +01:00
// x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
2019-03-08 02:54:10 +01:00
2021-10-30 22:32:11 +08:00
db . InitEngineWithMigration ( context . Background ( ) , func ( _ * xorm . Engine ) error {
2019-03-08 02:54:10 +01:00
return nil
} )
2021-09-19 19:49:59 +08:00
db . HasEngine = true
2022-01-20 18:46:10 +01:00
// x.ShowSQL(true)
2021-11-12 22:36:47 +08:00
err = unittest . InitFixtures (
unittest . FixturesOptions {
2021-09-24 19:32:56 +08:00
Dir : path . Join ( curDir , "models/fixtures/" ) ,
} ,
2019-03-08 02:54:10 +01:00
)
if err != nil {
fmt . Printf ( "Error initializing test database: %v\n" , err )
os . Exit ( 1 )
}
2021-11-12 22:36:47 +08:00
unittest . LoadFixtures ( )
2020-08-11 21:05:34 +01:00
util . RemoveAll ( setting . RepoRootPath )
2022-05-09 00:46:32 +08:00
util . RemoveAll ( repo_module . LocalCopyPath ( ) )
2022-09-02 15:18:23 -04:00
unittest . CopyDir ( path . Join ( curDir , "tests/gitea-repositories-meta" ) , setting . RepoRootPath )
2019-03-08 02:54:10 +01:00
log . Printf ( "[PR] Setting up router\n" )
2022-01-20 18:46:10 +01:00
// routers.GlobalInit()
2021-04-20 06:25:08 +08:00
external . RegisterRenderers ( )
2022-10-22 20:15:52 +03:00
markup . Init ( markup_service . ProcessorHelper ( ) )
2022-08-28 10:43:25 +01:00
c := routers . NormalRoutes ( graceful . GetManager ( ) . HammerContext ( ) )
2019-03-08 02:54:10 +01:00
log . Printf ( "[PR] Ready for testing !\n" )
log . Printf ( "[PR] Login with user1, user2, user3, ... with pass: password\n" )
/ *
log . Info ( "Listen: %v://%s%s" , setting . Protocol , listenAddr , setting . AppSubURL )
if setting . LFS . StartServer {
log . Info ( "LFS server enabled" )
}
if setting . EnablePprof {
go func ( ) {
log . Info ( "Starting pprof server on localhost:6060" )
log . Info ( "%v" , http . ListenAndServe ( "localhost:6060" , nil ) )
} ( )
}
* /
2022-01-20 18:46:10 +01:00
// Start the server
2021-11-03 00:33:54 +00:00
http . ListenAndServe ( ":8080" , c )
2019-03-08 02:54:10 +01:00
log . Printf ( "[PR] Cleaning up ...\n" )
/ *
2020-08-11 21:05:34 +01:00
if err = util . RemoveAll ( setting . Indexer . IssuePath ) ; err != nil {
fmt . Printf ( "util.RemoveAll: %v\n" , err )
2019-03-08 02:54:10 +01:00
os . Exit ( 1 )
}
2020-08-11 21:05:34 +01:00
if err = util . RemoveAll ( setting . Indexer . RepoPath ) ; err != nil {
2019-03-08 02:54:10 +01:00
fmt . Printf ( "Unable to remove repo indexer: %v\n" , err )
os . Exit ( 1 )
}
* /
2020-08-11 21:05:34 +01:00
if err = util . RemoveAll ( setting . RepoRootPath ) ; err != nil {
log . Fatalf ( "util.RemoveAll: %v\n" , err )
2019-03-08 02:54:10 +01:00
}
2020-08-11 21:05:34 +01:00
if err = util . RemoveAll ( setting . AppDataPath ) ; err != nil {
log . Fatalf ( "util.RemoveAll: %v\n" , err )
2019-03-08 02:54:10 +01:00
}
}
func main ( ) {
2022-01-20 18:46:10 +01:00
runPRFlag := flag . Bool ( "run" , false , "Run the PR code" )
2019-03-08 02:54:10 +01:00
flag . Parse ( )
if * runPRFlag {
runPR ( )
return
}
2019-03-15 11:18:01 -05:00
// To force checkout (e.g. Windows complains about unclean work tree) set env variable FORCE=true
force , err := strconv . ParseBool ( os . Getenv ( "FORCE" ) )
if err != nil {
force = false
}
2022-01-20 18:46:10 +01:00
// Otherwise checkout PR
2019-03-08 02:54:10 +01:00
if len ( os . Args ) != 2 {
log . Fatal ( "Need only one arg: the PR number" )
}
pr := os . Args [ 1 ]
2022-01-20 18:46:10 +01:00
codeFilePath = filepath . FromSlash ( codeFilePath ) // Convert to running OS
2019-03-08 02:54:10 +01:00
2022-01-20 18:46:10 +01:00
// Copy this file if it will not exist in the PR branch
2021-09-22 13:38:34 +08:00
dat , err := os . ReadFile ( codeFilePath )
2019-03-08 02:54:10 +01:00
if err != nil {
log . Fatalf ( "Failed to cache this code file : %v" , err )
}
repo , err := git . PlainOpen ( "." )
if err != nil {
log . Fatalf ( "Failed to open the repo : %v" , err )
}
2022-01-20 18:46:10 +01:00
// Find remote upstream
2019-03-08 02:54:10 +01:00
remotes , err := repo . Remotes ( )
if err != nil {
log . Fatalf ( "Failed to list remotes of repo : %v" , err )
}
2022-01-20 18:46:10 +01:00
remoteUpstream := "origin" // Default
2019-03-08 02:54:10 +01:00
for _ , r := range remotes {
2020-08-05 22:15:57 +03:00
if r . Config ( ) . URLs [ 0 ] == "https://github.com/go-gitea/gitea.git" ||
r . Config ( ) . URLs [ 0 ] == "https://github.com/go-gitea/gitea" ||
2022-01-20 18:46:10 +01:00
r . Config ( ) . URLs [ 0 ] == "git@github.com:go-gitea/gitea.git" { // fetch at index 0
2019-03-08 02:54:10 +01:00
remoteUpstream = r . Config ( ) . Name
break
}
}
branch := fmt . Sprintf ( "pr-%s-%d" , pr , time . Now ( ) . Unix ( ) )
branchRef := plumbing . NewBranchReferenceName ( branch )
log . Printf ( "Fetching PR #%s in %s\n" , pr , branch )
if runtime . GOOS == "windows" {
2022-01-20 18:46:10 +01:00
// Use git cli command for windows
2019-03-12 12:47:04 -05:00
runCmd ( "git" , "fetch" , remoteUpstream , fmt . Sprintf ( "pull/%s/head:%s" , pr , branch ) )
2019-03-08 02:54:10 +01:00
} else {
2021-12-02 20:36:50 +01:00
ref := fmt . Sprintf ( "%s%s/head:%s" , gitea_git . PullPrefix , pr , branchRef )
2019-03-08 02:54:10 +01:00
err = repo . Fetch ( & git . FetchOptions {
RemoteName : remoteUpstream ,
RefSpecs : [ ] config . RefSpec {
config . RefSpec ( ref ) ,
} ,
} )
if err != nil {
log . Fatalf ( "Failed to fetch %s from %s : %v" , ref , remoteUpstream , err )
}
}
tree , err := repo . Worktree ( )
if err != nil {
log . Fatalf ( "Failed to parse git tree : %v" , err )
}
log . Printf ( "Checkout PR #%s in %s\n" , pr , branch )
err = tree . Checkout ( & git . CheckoutOptions {
Branch : branchRef ,
2019-03-15 11:18:01 -05:00
Force : force ,
2019-03-08 02:54:10 +01:00
} )
if err != nil {
log . Fatalf ( "Failed to checkout %s : %v" , branch , err )
}
2022-01-20 18:46:10 +01:00
// Copy this file if not exist
2019-03-08 02:54:10 +01:00
if _ , err := os . Stat ( codeFilePath ) ; os . IsNotExist ( err ) {
2022-01-20 18:46:10 +01:00
err = os . MkdirAll ( filepath . Dir ( codeFilePath ) , 0 o755 )
2019-03-08 02:54:10 +01:00
if err != nil {
log . Fatalf ( "Failed to duplicate this code file in PR : %v" , err )
}
2022-01-20 18:46:10 +01:00
err = os . WriteFile ( codeFilePath , dat , 0 o644 )
2019-03-08 02:54:10 +01:00
if err != nil {
log . Fatalf ( "Failed to duplicate this code file in PR : %v" , err )
}
}
2022-01-20 18:46:10 +01:00
// Force build of js, css, bin, ...
2020-02-08 01:14:43 +01:00
runCmd ( "make" , "build" )
2022-01-20 18:46:10 +01:00
// Start with integration test
2020-02-16 17:30:09 +01:00
runCmd ( "go" , "run" , "-mod" , "vendor" , "-tags" , "sqlite sqlite_unlock_notify" , codeFilePath , "-run" )
2019-03-08 02:54:10 +01:00
}
2022-01-20 18:46:10 +01:00
2019-03-08 02:54:10 +01:00
func runCmd ( cmd ... string ) {
log . Printf ( "Executing : %s ...\n" , cmd )
c := exec . Command ( cmd [ 0 ] , cmd [ 1 : ] ... )
c . Stdout = os . Stdout
c . Stderr = os . Stderr
if err := c . Start ( ) ; err != nil {
log . Panicln ( err )
}
if err := c . Wait ( ) ; err != nil {
log . Panicln ( err )
}
}