Files
2026-08-01 20:32:49 +08:00

105 lines
3.1 KiB
Go

// Copyright 2023 sigma
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package source
import (
"fmt"
"log/slog"
"net/url"
"os"
"os/exec"
"path"
"strconv"
"strings"
"github.com/go-git/go-git/v6/plumbing/transport"
"github.com/go-sigma/sigma/pkg/api/enums"
"github.com/go-sigma/sigma/pkg/utils"
"github.com/go-sigma/sigma/pkg/utils/ptr"
)
const (
homeSigma = "/opt/sigma"
knownHosts = "known_hosts"
privateKey = "private_key"
workspace = "/code"
)
// GitSource 通过 git clone 准备源码
type GitSource struct {
ScmProvider *enums.ScmProvider
ScmCredentialType *enums.ScmCredentialType
ScmSshKey *string
ScmToken *string
ScmUsername *string
ScmPassword *string
ScmRepository *string
ScmBranch *string
ScmDepth *int
ScmSubmodule *bool
}
// Prepare 执行 git clone
func (s GitSource) Prepare() error {
if utils.IsDir(path.Join(workspace, ".git")) {
return nil
}
slog.Info("start to clone repository")
git, err := exec.LookPath("git")
if err != nil {
return fmt.Errorf("git not found: %v", err)
}
cmd := exec.Command(git, "clone", "--branch", ptr.To(s.ScmBranch))
if ptr.To(s.ScmDepth) != 0 {
cmd.Args = append(cmd.Args, "--depth", strconv.Itoa(ptr.To(s.ScmDepth)))
}
if ptr.To(s.ScmSubmodule) {
cmd.Args = append(cmd.Args, "--recurse-submodules")
}
if ptr.To(s.ScmCredentialType) == enums.ScmCredentialTypeSsh {
cmd.Args = append(cmd.Args, "-i", path.Join(homeSigma, privateKey))
cmd.Env = append(os.Environ(), fmt.Sprintf("SSH_KNOWN_HOSTS=%s", path.Join(homeSigma, knownHosts)))
}
repository := ptr.To(s.ScmRepository)
if ptr.To(s.ScmCredentialType) == enums.ScmCredentialTypeToken {
u, err := url.Parse(repository)
if err != nil {
return fmt.Errorf("SCM_REPOSITORY parse with url failed: %v", err)
}
repository = fmt.Sprintf("%s://%s@%s/%s", u.Scheme, ptr.To(s.ScmToken), strings.TrimSuffix(u.Host, "/"), strings.TrimPrefix(u.Path, "/"))
}
if ptr.To(s.ScmCredentialType) == enums.ScmCredentialTypeUsername {
endpoint, err := transport.ParseURL(repository)
if err != nil {
return fmt.Errorf("transport.NewEndpoint failed: %v", err)
}
endpoint.User = url.UserPassword(ptr.To(s.ScmUsername), ptr.To(s.ScmPassword))
repository = endpoint.String()
}
cmd.Args = append(cmd.Args, repository, workspace)
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Dir = workspace
slog.Info("running git clone", "command", cmd.String(), "dir", workspace, "env", cmd.Env)
err = cmd.Run()
if err != nil {
return fmt.Errorf("clone repository failed: %v", err)
}
slog.Info("finished clone repository")
return nil
}