migration

package
v0.18.18 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2026 License: MIT Imports: 34 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ChunkRefSpecs

func ChunkRefSpecs(items []gitconfig.RefSpec, chunkSize int) [][]gitconfig.RefSpec

ChunkRefSpecs splits a slice of RefSpecs into chunks of the specified size.

func ParseProjectSlugs

func ParseProjectSlugs(slugs []string) (gitlabPath []string, githubPath []string, err error)

ParseProjectSlugs splits a CSV row into GitLab and GitHub path components.

func Pointer

func Pointer[T any](v T) *T

Pointer returns a pointer to the given value.

func PrintSummaryToConsole

func PrintSummaryToConsole(report *MigrationReport)

PrintSummaryToConsole prints a concise summary of the migration to console.

func WriteJSONReport

func WriteJSONReport(report *MigrationReport, outputPath string) error

WriteJSONReport writes the migration report as JSON to the specified path.

func WriteMarkdownReport

func WriteMarkdownReport(report *MigrationReport, outputPath string) error

WriteMarkdownReport writes the migration report as Markdown to the specified path.

Types

type CSVRow

type CSVRow = []string

CSVRow represents one project mapping from the projects CSV.

type CommentResult

type CommentResult struct {
	GitLabNoteID    int64        `json:"gitlab_note_id"`
	GitHubCommentID *int64       `json:"github_comment_id,omitempty"`
	Status          ResultStatus `json:"status"`
	Error           string       `json:"error,omitempty"`
	AuthorUsername  string       `json:"author_username"`
	CreatedAt       time.Time    `json:"created_at"`
}

CommentResult contains results for a single comment migration.

type MRState

type MRState struct {
	Status      MRStateStatus `json:"status"`
	GitHubPRNum *int          `json:"github_pr_number,omitempty"`
	Error       string        `json:"error,omitempty"`
	SkipReason  string        `json:"skip_reason,omitempty"`
	UpdatedAt   time.Time     `json:"updated_at"`
}

MRState holds the persisted migration state for a single merge request.

type MRStateStatus

type MRStateStatus string

MRStateStatus represents the migration status of a single merge request in the state file.

const (
	MRStateSuccess MRStateStatus = "success"
	MRStateFailed  MRStateStatus = "failed"
	MRStateSkipped MRStateStatus = "skipped"
	MRStatePartial MRStateStatus = "partial"
)

type MergeRequestResult

type MergeRequestResult struct {
	GitLabMRID     int64        `json:"gitlab_mr_id"`
	GitLabMRTitle  string       `json:"gitlab_mr_title"`
	GitLabState    string       `json:"gitlab_state"`
	SourceBranch   string       `json:"source_branch"`
	TargetBranch   string       `json:"target_branch"`
	GitHubPRNumber *int         `json:"github_pr_number,omitempty"`
	Status         ResultStatus `json:"status"`
	Error          string       `json:"error,omitempty"`
	SkipReason     string       `json:"skip_reason,omitempty"`

	Comments         []CommentResult `json:"comments,omitempty"`
	TotalComments    int             `json:"total_comments"`
	MigratedComments int             `json:"migrated_comments"`
	FailedComments   int             `json:"failed_comments"`
}

MergeRequestResult contains results for a single MR migration.

type MigrationPartialError

type MigrationPartialError struct {
	FailedProjects  int
	PartialProjects int
}

MigrationPartialError is returned when migration completes but some projects had errors.

func (*MigrationPartialError) Error

func (e *MigrationPartialError) Error() string

type MigrationReport

type MigrationReport struct {
	StartTime       time.Time       `json:"start_time"`
	EndTime         time.Time       `json:"end_time"`
	Duration        time.Duration   `json:"duration"`
	TotalProjects   int             `json:"total_projects"`
	SuccessProjects int             `json:"success_projects"`
	FailedProjects  int             `json:"failed_projects"`
	PartialProjects int             `json:"partial_projects"`
	Projects        []ProjectResult `json:"projects"`
}

MigrationReport is the top-level structure containing all migration results.

type MigrationState

type MigrationState struct {
	// contains filtered or unexported fields
}

MigrationState manages the on-disk migration state for a single project pair. It is safe for concurrent use from multiple goroutines.

func LoadOrCreate

func LoadOrCreate(filePath, gitlabProject, githubRepo string, logger hclog.Logger) (*MigrationState, error)

LoadOrCreate loads an existing state file or creates a new empty one. Returns an error if the file exists but is corrupt, has an incompatible version, or belongs to a different project pair.

func (*MigrationState) Flush

func (s *MigrationState) Flush() error

Flush writes the current state to disk atomically (write to temp file, fsync, then rename). On Windows, os.Rename cannot overwrite an existing file, so we remove the old file first. The worst case on crash during the microsecond window between remove and rename is losing the state file entirely, which falls back to full API-based re-check (the status quo).

func (*MigrationState) GetState

func (s *MigrationState) GetState(mrIID int64) *MRState

GetState returns a copy of the stored state for a specific MR IID, or nil if not found.

func (*MigrationState) RecordFailure

func (s *MigrationState) RecordFailure(mrIID int64, errMsg string)

RecordFailure records a failed MR migration.

func (*MigrationState) RecordPartial

func (s *MigrationState) RecordPartial(mrIID int64, githubPRNum *int, errMsg string)

RecordPartial records a partially successful MR migration (PR created but some comments failed).

func (*MigrationState) RecordSkipped

func (s *MigrationState) RecordSkipped(mrIID int64, reason string)

RecordSkipped records a skipped MR migration.

func (*MigrationState) RecordSuccess

func (s *MigrationState) RecordSuccess(mrIID int64, githubPRNum *int)

RecordSuccess records a successful MR migration.

func (*MigrationState) ShouldSkip

func (s *MigrationState) ShouldSkip(mrIID int64) bool

ShouldSkip returns true if the MR with the given IID was previously completed successfully or skipped, and does not need reprocessing. A skip because of -skip-open-merge-requests, saved by an older version, is not final: it depends on the flags of the run that saved it, and the MR can be merged or closed later. A skip of an older version because the clone lacked a commit of the MR is not final either: this version fetches the commit.

func (*MigrationState) Summary

func (s *MigrationState) Summary() (total, success, failed, skipped, partial int)

Summary returns counts of each status for logging purposes. A null entry has no status and is not counted.

type Migrator

type Migrator struct {
	// contains filtered or unexported fields
}

Migrator holds all runtime dependencies for the migration process.

func NewMigrator

func NewMigrator(
	cfg *config.Config,
	gh *gogithub.Client,
	gl *gogitlab.Client,
	ghClient clients.GitHubClient,
	glClient clients.GitLabClient,
	logger hclog.Logger,
) *Migrator

NewMigrator creates a fully initialised Migrator.

func (*Migrator) PerformMigration

func (m *Migrator) PerformMigration(ctx context.Context, projects []CSVRow, collector *ResultCollector, sessionID string) error

PerformMigration migrates all projects and writes reports.

func (*Migrator) PrintReport

func (m *Migrator) PrintReport(ctx context.Context, projects []CSVRow) error

PrintReport prints a human-readable report for the given projects to stdout. It returns an error when at least one project could not be reported.

type ProjectResult

type ProjectResult struct {
	GitLabGroup   string        `json:"gitlab_group"`
	GitLabProject string        `json:"gitlab_project"`
	GitHubOwner   string        `json:"github_owner"`
	GitHubRepo    string        `json:"github_repo"`
	Status        ResultStatus  `json:"status"`
	Error         string        `json:"error,omitempty"`
	StartTime     time.Time     `json:"start_time"`
	EndTime       time.Time     `json:"end_time"`
	Duration      time.Duration `json:"duration"`

	BranchesMigrated []string `json:"branches_migrated"`
	BranchCount      int      `json:"branch_count"`

	MergeRequests []MergeRequestResult `json:"merge_requests,omitempty"`
	TotalMRs      int                  `json:"total_mrs"`
	SuccessfulMRs int                  `json:"successful_mrs"`
	FailedMRs     int                  `json:"failed_mrs"`
	SkippedMRs    int                  `json:"skipped_mrs"`
}

ProjectResult contains results for a single project migration.

type Report

type Report struct {
	GroupName          string
	ProjectName        string
	MergeRequestsCount int
}

Report holds high-level project report data.

type ResultCollector

type ResultCollector struct {
	// contains filtered or unexported fields
}

ResultCollector is a thread-safe collector for migration results.

func NewResultCollector

func NewResultCollector() *ResultCollector

NewResultCollector creates a new ResultCollector.

func (*ResultCollector) AddProjectResult

func (rc *ResultCollector) AddProjectResult(result ProjectResult)

AddProjectResult adds a project result to the collection (thread-safe).

func (*ResultCollector) Finalize

func (rc *ResultCollector) Finalize() *MigrationReport

Finalize finalizes the report with end time and duration.

func (*ResultCollector) Snapshot added in v0.18.1

func (rc *ResultCollector) Snapshot() *MigrationReport

Snapshot returns a copy of the results collected so far, with the end time and duration set to now. Unlike Finalize, it does not change the collector, so results added later do not show up in the snapshot.

type ResultStatus

type ResultStatus string

ResultStatus represents the outcome of a migration operation.

const (
	StatusSuccess ResultStatus = "success"
	StatusFailed  ResultStatus = "failed"
	StatusSkipped ResultStatus = "skipped"
	StatusPartial ResultStatus = "partial"
)

type StateFile

type StateFile struct {
	Version       int                 `json:"version"`
	GitLabProject string              `json:"gitlab_project"`
	GitHubRepo    string              `json:"github_repo"`
	UpdatedAt     time.Time           `json:"updated_at"`
	MergeRequests map[string]*MRState `json:"merge_requests"`
}

StateFile is the top-level structure serialized to/from the state JSON file.

func (*StateFile) MarshalJSON

func (sf *StateFile) MarshalJSON() ([]byte, error)

MarshalJSON implements custom JSON marshaling to sort merge request keys numerically instead of the default lexicographic order (which produces "1","10","100","2",...).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL