with actual push

This commit is contained in:
Kasper Juul Hermansen 2022-09-12 22:05:06 +02:00
parent 56bfba5c17
commit b1094294b5
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
4 changed files with 164 additions and 35 deletions

View File

@ -78,6 +78,13 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) er
return
}
err = pr.git.CreateBranch(ctx, repo)
if err != nil {
pr.logger.Error("could not create branch", zap.Error(err))
errChan <- err
return
}
err = pr.action.Run(
ctx,
area,
@ -116,13 +123,19 @@ func (pr *ProcessRepos) Process(ctx context.Context, repositoryUrls []string) er
return nil
}, false)
if err != nil {
pr.logger.Error("could not run action", zap.Error(err))
errChan <- err
return
}
err = pr.git.Push(ctx, repo)
if err != nil {
pr.logger.Error("could not push to repo", zap.Error(err))
errChan <- err
return
}
pr.logger.Debug("processing done", zap.String("path", area.Path), zap.String("repoUrl", repoUrl))
}(ctx, repoUrl)
}

View File

@ -38,8 +38,9 @@ func NewServerDeps(logger *zap.Logger) *ServerDeps {
}
openPGPConfig := &signer.OpenPgpConfig{
PrivateKeyFilePath: "./examples/private.pgp",
PrivateKeyFilePath: "./example/testkey.private.pgp",
PrivateKeyPassword: "somepassword",
PrivateKeyIdentity: "kraken@kasperhermansen.com",
}
deps.openPGP = signer.NewOpenPGP(logger.With(zap.Namespace("openpgp")), openPGPConfig)
@ -51,7 +52,7 @@ func (deps *ServerDeps) GetStorageService() *storage.Service {
}
func (deps *ServerDeps) GetGitProvider() *providers.Git {
return providers.NewGit(deps.logger.With(zap.Namespace("gitProvider")), deps.gitCfg)
return providers.NewGit(deps.logger.With(zap.Namespace("gitProvider")), deps.gitCfg, deps.openPGP)
}
func (deps *ServerDeps) GetAction() *actions.Action {

View File

@ -2,11 +2,14 @@ package providers
import (
"context"
"fmt"
"time"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/signer"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/http"
@ -20,6 +23,7 @@ import (
type Git struct {
logger *zap.Logger
gitConfig *GitConfig
openPGP *signer.OpenPGP
}
type GitRepo struct {
@ -45,8 +49,8 @@ type GitConfig struct {
SshPrivateKeyPassword string
}
func NewGit(logger *zap.Logger, gitConfig *GitConfig) *Git {
return &Git{logger: logger, gitConfig: gitConfig}
func NewGit(logger *zap.Logger, gitConfig *GitConfig, openPGP *signer.OpenPGP) *Git {
return &Git{logger: logger, gitConfig: gitConfig, openPGP: openPGP}
}
func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl string) (*GitRepo, error) {
@ -70,13 +74,10 @@ func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl stri
NoCheckout: false,
Depth: 1,
RecurseSubmodules: 1,
Progress: &zapio.Writer{
Log: g.logger.With(zap.String("process", "go-git")),
Level: zap.DebugLevel,
},
Tags: 0,
InsecureSkipTLS: false,
CABundle: []byte{},
Progress: g.getProgressWriter(),
Tags: 0,
InsecureSkipTLS: false,
CABundle: []byte{},
}
repo, err := git.PlainCloneContext(ctx, storageArea.Path, false, &cloneOptions)
@ -89,6 +90,13 @@ func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl stri
return &GitRepo{repo: repo}, nil
}
func (g *Git) getProgressWriter() *zapio.Writer {
return &zapio.Writer{
Log: g.logger.With(zap.String("process", "go-git")),
Level: zap.DebugLevel,
}
}
func (g *Git) Add(ctx context.Context, storageArea *storage.Area, gitRepo *GitRepo) (*git.Worktree, error) {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
@ -107,11 +115,71 @@ func (g *Git) Add(ctx context.Context, storageArea *storage.Area, gitRepo *GitRe
return nil, err
}
g.logger.Info("git status", zap.String("status", status.String()))
g.logger.Debug("git status", zap.String("status", status.String()))
return worktree, nil
}
func (g *Git) CreateBranch(ctx context.Context, gitRepo *GitRepo) error {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
return err
}
refSpec := plumbing.NewBranchReferenceName("kraken-apply")
err = gitRepo.repo.CreateBranch(&config.Branch{
Name: "kraken-apply",
Remote: "origin",
Merge: refSpec,
Rebase: "",
})
if err != nil {
return fmt.Errorf("could not create branch: %w", err)
}
err = worktree.Checkout(&git.CheckoutOptions{
Branch: plumbing.ReferenceName(refSpec.String()),
Create: true,
Force: false,
Keep: false,
})
if err != nil {
return fmt.Errorf("could not checkout branch: %w", err)
}
remoteRef := plumbing.NewRemoteReferenceName("origin", "kraken-apply")
ref := plumbing.NewSymbolicReference(refSpec, remoteRef)
err = gitRepo.repo.Storer.SetReference(ref)
if err != nil {
return fmt.Errorf("could not set reference: %w", err)
}
auth, err := g.GetAuth()
if err != nil {
return err
}
err = worktree.PullContext(ctx, &git.PullOptions{
RemoteName: "origin",
ReferenceName: "refs/heads/main",
SingleBranch: true,
Depth: 1,
Auth: auth,
RecurseSubmodules: 1,
Progress: g.getProgressWriter(),
Force: true,
InsecureSkipTLS: false,
CABundle: []byte{},
})
if err != nil {
return fmt.Errorf("could not pull from origin: %w", err)
}
g.logger.Debug("done creating branches")
return nil
}
func (g *Git) Commit(ctx context.Context, gitRepo *GitRepo) error {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
@ -122,12 +190,41 @@ func (g *Git) Commit(ctx context.Context, gitRepo *GitRepo) error {
All: true,
Author: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()},
Committer: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()},
SignKey: &openpgp.Entity{},
SignKey: g.openPGP.SigningKey,
})
if err != nil {
return err
}
g.logger.Debug("done commiting objects")
return nil
}
func (g *Git) Push(ctx context.Context, gitRepo *GitRepo) error {
auth, err := g.GetAuth()
if err != nil {
return err
}
err = gitRepo.repo.PushContext(ctx, &git.PushOptions{
RemoteName: "origin",
RefSpecs: []config.RefSpec{},
Auth: auth,
Progress: g.getProgressWriter(),
Prune: false,
Force: false,
InsecureSkipTLS: false,
CABundle: []byte{},
RequireRemoteRefs: []config.RefSpec{},
})
if err != nil {
return err
}
g.logger.Debug("done pushing branch")
return nil
}

View File

@ -2,22 +2,25 @@ package signer
import (
"context"
"errors"
"os"
"strings"
"git.front.kjuulh.io/kjuulh/curre"
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/go-crypto/openpgp"
"go.uber.org/zap"
)
type OpenPGP struct {
logger *zap.Logger
PrivateKeyRing *crypto.KeyRing
config *OpenPgpConfig
logger *zap.Logger
SigningKey *openpgp.Entity
config *OpenPgpConfig
}
type OpenPgpConfig struct {
PrivateKeyFilePath string
PrivateKeyPassword string
PrivateKeyIdentity string
}
func NewOpenPGP(logger *zap.Logger, config *OpenPgpConfig) *OpenPGP {
@ -29,26 +32,14 @@ func NewOpenPGP(logger *zap.Logger, config *OpenPgpConfig) *OpenPGP {
func NewOpenPGPApp(openPGP *OpenPGP) curre.Component {
return curre.NewFunctionalComponent(&curre.FunctionalComponent{
InitFunc: func(fc *curre.FunctionalComponent, ctx context.Context) error {
content, err := os.ReadFile(openPGP.config.PrivateKeyFilePath)
if err != nil {
return err
}
privateKeyObj, err := crypto.NewKeyFromArmored(string(content))
if err != nil {
return err
}
unlockedPrivateKeyRing, err := privateKeyObj.Unlock([]byte(openPGP.config.PrivateKeyPassword))
if err != nil {
return err
}
privateKeyRing, err := crypto.NewKeyRing(unlockedPrivateKeyRing)
InitFunc: func(_ *curre.FunctionalComponent, ctx context.Context) error {
keyring, err := buildKeyring(ctx, openPGP)
if err != nil {
openPGP.logger.Panic("could not build keyring", zap.Error(err))
return err
}
openPGP.PrivateKeyRing = privateKeyRing
openPGP.SigningKey = keyring
return nil
},
@ -59,5 +50,32 @@ func NewOpenPGPApp(openPGP *OpenPGP) curre.Component {
return nil
},
})
}
func buildKeyring(_ context.Context, openPGP *OpenPGP) (*openpgp.Entity, error) {
content, err := os.ReadFile(openPGP.config.PrivateKeyFilePath)
if err != nil {
return nil, err
}
reader := strings.NewReader(string(content))
es, err := openpgp.ReadArmoredKeyRing(reader)
if err != nil {
return nil, err
}
for _, key := range es {
for k := range key.Identities {
if strings.Contains(k, openPGP.config.PrivateKeyIdentity) {
err = key.PrivateKey.Decrypt([]byte(openPGP.config.PrivateKeyPassword))
if err != nil {
return nil, err
}
return key, nil
}
}
}
return nil, errors.New("could not find key matching identity")
}