forgejo/cmd/dump_repo.go
Michael Jerger aee161ff25 [gitea] week 2025-19 cherry pick (gitea/main -> forgejo) (#7909)
## Checklist

- [x] go to the last cherry-pick PR (forgejo/forgejo#7804) to figure out how far it went: [gitea@a2024953c5](a2024953c5)
- [x] cherry-pick and open PR (forgejo/forgejo#7909)
- [ ] have the PR pass the CI
- end-to-end (specially important if there are actions related changes)
  - [ ] add `run-end-to-end` label
  - [ ] check the result
- [ ] write release notes
- [ ] assign reviewers
- [ ] 48h later, last call
- merge 1 hour after the last call

## Legend

-  - No decision about the commit has been made.
- 🍒 - The commit has been cherry picked.
-  - The commit has been skipped.
- 💡 - The commit has been skipped, but should be ported to Forgejo.
- ✍️ - The commit has been skipped, and a port to Forgejo already exists.

## Commits

- 🍒 [`gitea`](e92c4f1808) -> [`forgejo`](56fa2caef3) Add missing setting load in dump-repo command ([gitea#34479](https://github.com/go-gitea/gitea/pull/34479))
- 🍒 [`gitea`](7b518bc6c7) -> [`forgejo`](6e5299606a) Change "rejected" to "changes requested" in 3rd party PR review notification ([gitea#34481](https://github.com/go-gitea/gitea/pull/34481))

## TODO

- 💡 [`gitea`](972381097c) Fix url validation in webhook add/edit API ([gitea#34492](https://github.com/go-gitea/gitea/pull/34492))
  Relevant input validation but test needs more backport.
------
- 💡 [`gitea`](59df03b554) Fix get / delete runner to use consistent http 404 and 500 status ([gitea#34480](https://github.com/go-gitea/gitea/pull/34480))
  It may be relevant to Forgejo as well
------
- 💡 [`gitea`](1e2f3514b9) Add endpoint deleting workflow run ([gitea#34337](https://github.com/go-gitea/gitea/pull/34337))
  Actions, it would be worth having in Forgejo as well.
------
- 💡 [`gitea`](5cb4cbf044) Fix repo broken check ([gitea#34444](https://github.com/go-gitea/gitea/pull/34444))
  Check wether this is relevant to us, port if yes.
------
- 💡 [`gitea`](355e9a9d54) Add a webhook push test for dev branch ([gitea#34421](https://github.com/go-gitea/gitea/pull/34421))
  Enhances webhook integration tests.
------
- 💡 [`gitea`](34281bc198) Fix bug webhook milestone is not right. ([gitea#34419](https://github.com/go-gitea/gitea/pull/34419))
  Testcode diverged, port required.
------
- 💡 [`gitea`](780e92ea99) Only git operations should update `last changed` of a repository ([gitea#34388](https://github.com/go-gitea/gitea/pull/34388))
  Port required, would benefit from additional tests.
------
- 💡 [`gitea`](b07e03956a) When updating comment, if the content is the same, just return and not update the databse ([gitea#34422](https://github.com/go-gitea/gitea/pull/34422))
  Codebase diverged, port required.
------
- 💡 [`gitea`](71a1187209) Fix incorrect divergence cache after switching default branch ([gitea#34370](https://github.com/go-gitea/gitea/pull/34370))
  Depends on previous gitea changes, port needed.
------
- 💡 [`gitea`](4c611bf280) Add a button editing action secret ([gitea#34348](https://github.com/go-gitea/gitea/pull/34348))
  This is an interesting feature and it has tests as well. Feature request covering this: https://codeberg.org/forgejo/forgejo/issues/7882
------
- 💡 [`gitea`](2fbc8f9e87) Fix LFS file not stored in LFS when uploaded/edited via API or web UI ([gitea#34367](https://github.com/go-gitea/gitea/pull/34367))
  Our code diverged - pls. check relevance & maybe port.
------
- 💡 [`gitea`](020e774b91) feat: add label 'state' to metric 'gitea_users' ([gitea#34326](https://github.com/go-gitea/gitea/pull/34326))
  Adjust our existing tests while porting this.
------

## Skipped

-  [`gitea`](ec10c6ba5a) [skip ci] Updated translations via Crowdin
------
-  [`gitea`](d89eed998f) Fix edithook api can not update package, status and workflow_job events ([gitea#34495](https://github.com/go-gitea/gitea/pull/34495))

  - gitea actions specific specific
------
-  [`gitea`](b6c0667474)  Add R-HNF to the TRANSLATORS file ([gitea#34494](https://github.com/go-gitea/gitea/pull/34494))

  - gitea translators update specific
------
-  [`gitea`](6fbf0e6738) nix flake update ([gitea#34476](https://github.com/go-gitea/gitea/pull/34476))

  - gitea dependency update specific
------
-  [`gitea`](c24f4b3d29) Add migrations tests ([gitea#34456](https://github.com/go-gitea/gitea/pull/34456))
------
-  [`gitea`](bf338bb9e2) Fix project board view ([gitea#34470](https://github.com/go-gitea/gitea/pull/34470))

  - gitea ui specific specific
------
-  [`gitea`](319d03fbc0) [skip ci] Updated translations via Crowdin
------
-  [`gitea`](dd500ce559) Fix Workflow run Not Found page ([gitea#34459](https://github.com/go-gitea/gitea/pull/34459))

  - gitea actions specific specific
------
-  [`gitea`](b6bf128f1e) [skip ci] Updated translations via Crowdin
------
-  [`gitea`](a0595add72) Fix remove org user failure on mssql ([gitea#34449](https://github.com/go-gitea/gitea/pull/34449))
------
-  [`gitea`](b5fd3e7210) Fix comment textarea scroll issue in Firefox ([gitea#34438](https://github.com/go-gitea/gitea/pull/34438))

  - gitea ui specific specific
------
-  [`gitea`](4011e2245b) Fix releases sidebar navigation link ([gitea#34436](https://github.com/go-gitea/gitea/pull/34436))

  - gitea ui specific specific
------
-  [`gitea`](0902d42fc7) [skip ci] Updated translations via Crowdin
------
-  [`gitea`](4a98ab0540) Remove legacy template helper functions ([gitea#34426](https://github.com/go-gitea/gitea/pull/34426))

  - gitea specific specific
------
-  [`gitea`](9b8609e017) Fix GetUsersByEmails ([gitea#34423](https://github.com/go-gitea/gitea/pull/34423))

  - gitea specific specific
------
-  [`gitea`](0f63a5ef48) [skip ci] Updated translations via Crowdin
------
-  [`gitea`](ad271444e9) Fix a bug when uploading file via lfs ssh command ([gitea#34408](https://github.com/go-gitea/gitea/pull/34408))
  :skiP: present with PR #7752
------
-  [`gitea`](8b16ab719c) Merge and tweak markup editor expander CSS ([gitea#34409](https://github.com/go-gitea/gitea/pull/34409))

  - gitea ui specific specific
------
-  [`gitea`](2ecd73d2e5) Bump `@github/relative-time-element` to v4.4.8 ([gitea#34413](https://github.com/go-gitea/gitea/pull/34413))

  - gitea dependency update specific
------
-  [`gitea`](179068fddb) Refactor commit message rendering and fix bugs ([gitea#34412](https://github.com/go-gitea/gitea/pull/34412))

  - gitea ui specific specific
------
-  [`gitea`](44aadc37c9) [skip ci] Updated translations via Crowdin
------
-  [`gitea`](f63822fe64) Fix autofocus behavior ([gitea#34397](https://github.com/go-gitea/gitea/pull/34397))

  - gitea ui specific specific
------
-  [`gitea`](82071ee730) [skip ci] Updated translations via Crowdin
------
-  [`gitea`](bbfc21e74f) Fix "The sidebar of the repository file list does not have a fixed height #34298" ([gitea#34321](https://github.com/go-gitea/gitea/pull/34321))

  - gitea ui specific specific
------
-  [`gitea`](dd886d729f) Update JS and PY dependencies ([gitea#34391](https://github.com/go-gitea/gitea/pull/34391))

  - gitea dependency update specific
------
-  [`gitea`](2a660b4a1b) Upgrade go-github v61 -> v71 ([gitea#34385](https://github.com/go-gitea/gitea/pull/34385))

  - gitea dependency update specific
------
-  [`gitea`](6bd8fe5353) Bump `@github/relative-time-element` to v4.4.7 ([gitea#34384](https://github.com/go-gitea/gitea/pull/34384))

  - gitea dependency update specific
------

<details>
<summary><h2>Stats</h2></summary>

<br>

Between [`gitea@a2024953c5`](a2024953c5) and [`gitea@ec10c6ba5a`](ec10c6ba5a), **41** commits have been reviewed. We picked **2**, skipped **27**, and decided to port **12**.

</details>

Co-authored-by: Sebastian Weigand <s.weigand.phy@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7909
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Michael Jerger <michael.jerger@meissa-gmbh.de>
Co-committed-by: Michael Jerger <michael.jerger@meissa-gmbh.de>
2025-06-27 13:59:07 +02:00

199 lines
5.4 KiB
Go

// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"errors"
"fmt"
"os"
"strings"
"forgejo.org/modules/git"
"forgejo.org/modules/log"
base "forgejo.org/modules/migration"
"forgejo.org/modules/setting"
"forgejo.org/modules/structs"
"forgejo.org/modules/util"
"forgejo.org/services/convert"
"forgejo.org/services/migrations"
"github.com/urfave/cli/v3"
)
// CmdDumpRepository represents the available dump repository sub-command.
func cmdDumpRepository() *cli.Command {
return &cli.Command{
Name: "dump-repo",
Usage: "Dump the repository from git/github/gitea/gitlab",
Description: "This is a command for dumping the repository data.",
Action: runDumpRepository,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "git_service",
Value: "",
Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
},
&cli.StringFlag{
Name: "repo_dir",
Aliases: []string{"r"},
Value: "./data",
Usage: "Repository dir path to store the data",
},
&cli.StringFlag{
Name: "clone_addr",
Value: "",
Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
},
&cli.StringFlag{
Name: "auth_username",
Value: "",
Usage: "The username to visit the clone_addr",
},
&cli.StringFlag{
Name: "auth_password",
Value: "",
Usage: "The password to visit the clone_addr",
},
&cli.StringFlag{
Name: "auth_token",
Value: "",
Usage: "The personal token to visit the clone_addr",
},
&cli.StringFlag{
Name: "owner_name",
Value: "",
Usage: "The data will be stored on a directory with owner name if not empty",
},
&cli.StringFlag{
Name: "repo_name",
Value: "",
Usage: "The data will be stored on a directory with repository name if not empty",
},
&cli.StringFlag{
Name: "units",
Value: "",
Usage: `Which items will be migrated, one or more units should be separated as comma.
wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
},
},
}
}
func runDumpRepository(stdCtx context.Context, ctx *cli.Command) error {
setupConsoleLogger(log.INFO, log.CanColorStderr, os.Stderr)
// setting.DisableLoggerInit()
setting.LoadSettings() // cannot access skip_tls_verify settings otherwise
stdCtx, cancel := installSignals(stdCtx)
defer cancel()
if err := initDB(stdCtx); err != nil {
return err
}
// migrations.GiteaLocalUploader depends on git module
if err := git.InitSimple(context.Background()); err != nil {
return err
}
log.Info("AppPath: %s", setting.AppPath)
log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.Log.RootPath)
log.Info("Configuration file: %s", setting.CustomConf)
var (
serviceType structs.GitServiceType
cloneAddr = ctx.String("clone_addr")
serviceStr = ctx.String("git_service")
)
if strings.HasPrefix(strings.ToLower(cloneAddr), "https://github.com/") {
serviceStr = "github"
} else if strings.HasPrefix(strings.ToLower(cloneAddr), "https://gitlab.com/") {
serviceStr = "gitlab"
} else if strings.HasPrefix(strings.ToLower(cloneAddr), "https://gitea.com/") {
serviceStr = "gitea"
}
if serviceStr == "" {
return errors.New("git_service missed or clone_addr cannot be recognized")
}
serviceType = convert.ToGitServiceType(serviceStr)
opts := base.MigrateOptions{
GitServiceType: serviceType,
CloneAddr: cloneAddr,
AuthUsername: ctx.String("auth_username"),
AuthPassword: ctx.String("auth_password"),
AuthToken: ctx.String("auth_token"),
RepoName: ctx.String("repo_name"),
}
if len(ctx.String("units")) == 0 {
opts.Wiki = true
opts.Issues = true
opts.Milestones = true
opts.Labels = true
opts.Releases = true
opts.Comments = true
opts.PullRequests = true
opts.ReleaseAssets = true
} else {
units := strings.Split(ctx.String("units"), ",")
for _, unit := range units {
switch strings.ToLower(strings.TrimSpace(unit)) {
case "":
continue
case "wiki":
opts.Wiki = true
case "issues":
opts.Issues = true
case "milestones":
opts.Milestones = true
case "labels":
opts.Labels = true
case "releases":
opts.Releases = true
case "release_assets":
opts.ReleaseAssets = true
case "comments":
opts.Comments = true
case "pull_requests":
opts.PullRequests = true
default:
return errors.New("invalid unit: " + unit)
}
}
}
// the repo_dir will be removed if error occurs in DumpRepository
// make sure the directory doesn't exist or is empty, prevent from deleting user files
repoDir := ctx.String("repo_dir")
if exists, err := util.IsExist(repoDir); err != nil {
return fmt.Errorf("unable to stat repo_dir %q: %w", repoDir, err)
} else if exists {
if isDir, _ := util.IsDir(repoDir); !isDir {
return fmt.Errorf("repo_dir %q already exists but it's not a directory", repoDir)
}
if dir, _ := os.ReadDir(repoDir); len(dir) > 0 {
return fmt.Errorf("repo_dir %q is not empty", repoDir)
}
}
if err := migrations.DumpRepository(
context.Background(),
repoDir,
ctx.String("owner_name"),
opts,
); err != nil {
log.Fatal("Failed to dump repository: %v", err)
return err
}
log.Trace("Dump finished!!!")
return nil
}