This repository has been archived by the owner on Feb 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
RE: ARCHITECTURE #148
Merged
+10,154
−5,901
Merged
RE: ARCHITECTURE #148
Changes from 11 commits
Commits
Show all changes
135 commits
Select commit
Hold shift + click to select a range
51aa5d0
Add new task runner
duck8823 240d65e
Reduce instance variables
duck8823 3fd0d1d
Change type name
duck8823 53db3bb
Cleanup config
duck8823 949dd8d
Separate helper methods
duck8823 c3ef14c
DockerRunner as domain service
duck8823 f1fe4f4
Implement core modules
duck8823 8a5f2d6
Add runner builder
duck8823 b8b9a4e
Add job model
duck8823 d04040c
reduce for loop
duck8823 cda5f2c
Replace to single function
duck8823 8f8a0c7
Add target model
duck8823 a1d4d4b
Move package
duck8823 56d9943
Change import
duck8823 b702f41
Rename struct
duck8823 fb910a1
Revert: commit b702f4106b5677c5692e34f56b113720c411e653
duck8823 e431df6
Add github push target
duck8823 a6f39be
Fix to be able to checkout past commit
duck8823 186a24c
Add initialize method
duck8823 9516ecf
Add nothing to do function and set as default
duck8823 c9e9a00
Change log replace method
duck8823 cf28ead
Add target github pull request
duck8823 d07860b
Fix godoc
duck8823 bfe1e8f
Change to use model
duck8823 e7d1d29
Add function "CreateCommitStatus"
duck8823 49591aa
Fix return type
duck8823 0c56a8b
Add executor builder
duck8823 6f3fb0b
Add context to application
duck8823 b4f9d96
Add new PushHandler
duck8823 94bf764
Add new IssueCommentHandler
duck8823 0afd932
Add health handler
duck8823 d511ed4
Add job handler and service
duck8823 08c764d
Rename files
duck8823 4e7a541
Error message
duck8823 06feb3e
Fix logic to get key of store
duck8823 a59f618
Fix job modules
duck8823 45a37f0
Add service functions
duck8823 ac676a3
Change interface
duck8823 9ade4dc
Using new api
duck8823 1f81e81
Remove old apis
duck8823 318322d
Change repository api
duck8823 5a8eec3
Change type of build job
duck8823 d1a5c57
Run asynchronously
duck8823 1de7127
Add application initialize
duck8823 d15fc04
Fix print message
duck8823 4bc5090
Add duci struct
duck8823 3a954a2
Change error type to variable
duck8823 7f1efa0
Add comment to public functions and variables
duck8823 17bb89b
s/ToString/String/
duck8823 529828b
Remove To prefix
duck8823 90b0d04
Fix success
duck8823 4a47878
Fix exit code for success
duck8823 e9dc806
Change log logic
duck8823 318d957
Add test cases for git
duck8823 255afa4
Add test cases for github
duck8823 815ee77
mockgen git and github
duck8823 6eb8e22
[wip] for testable
duck8823 825f751
Add singleton container
duck8823 4288e8c
Add override function
duck8823 03982ce
Remove instance variable form git package
duck8823 af0ec67
Remove NewGithubPush
duck8823 4289921
Remove GitHubPR struct and rename GitHubPush to GitHub
duck8823 e5a3b67
Add test for models
duck8823 b6253bd
Remove package variable in job
duck8823 5f35098
Add test case
duck8823 77de961
Add test case to application context
duck8823 76e8f44
Add initialize test
duck8823 fce32bc
Add line brake
duck8823 9147ff0
Set instance to container as interface
duck8823 a513358
Separate files implementation and interface
duck8823 5a4bc82
Add test for job service
duck8823 80266bd
Generate mock_service
duck8823 9ac29e1
Add test for job service
duck8823 10420ca
Add datasource test
duck8823 5c3475c
Fix test case
duck8823 d9dade0
Add test for runner builder
duck8823 edcbc7b
Add generated mock
duck8823 a34d88f
Add test cases for runner
duck8823 3197cf2
Change to private field
duck8823 08d502d
Add pattern
duck8823 4fae994
Separate interface and implementation
duck8823 9111763
Add docker mock
duck8823 b72c814
Add runner test
duck8823 ca63afa
Fix allow unexported structure
duck8823 cd49606
Add test pattern
duck8823 e43363b
Add test case
duck8823 820eb25
Remove unused interface function
duck8823 41032e3
Use generated mock
duck8823 766d513
Move package
duck8823 0f07c07
Add handler test
duck8823 a5b8c81
Add assertion
duck8823 f34955b
Change to execute job in goroutine
duck8823 2a69e4a
Add test pattern
duck8823 b40a82c
Fix missing call func goroutine
duck8823 c60d366
Update gomock
duck8823 d4acd46
Add test cases
duck8823 09b5d70
Using gomock instead of gock
duck8823 aac1e29
Add test cases
duck8823 2cab6e3
Add router test
duck8823 3779da0
Fix panic when failed cast
duck8823 92f668d
Fix logic when error
duck8823 5144e3f
Add test for duci
duck8823 b1ca078
Return error instead of panic
duck8823 89f74ac
Add executor test
duck8823 8b8ea5c
Remove return value from job.Cleanup
duck8823 73e443d
Remove unused struct
duck8823 3006a29
Change transform func
duck8823 75cb4af
Fix unhandled error
duck8823 5d7434f
Add assertion
duck8823 ff9b4db
Remove redundant return
duck8823 28bb20b
Use raw literal for regex
duck8823 9c81f9f
For more stable
duck8823 7d5f184
Separate test case
duck8823 7a12a0c
Change context key to use pointer
duck8823 3c01661
Change return type to exported type
duck8823 113190b
Fix error messages
duck8823 d5f3ef6
Change to exported type
duck8823 7a688d0
Change package name
duck8823 b713db0
Remove dot import
duck8823 97156f2
Fix comments
duck8823 cd7a947
Fix error type name
duck8823 5a5c46d
Add comments
duck8823 e8364a9
Rename types
duck8823 c1ee4ac
Change to exported types
duck8823 1779a86
Remove dot import
duck8823 c0ef51e
Add comment
duck8823 55929e6
Change return type to exported it
duck8823 bcad5bf
Rename error variable
duck8823 8a809ce
Fix git client using ssh
duck8823 134c05d
Fix target url of commit status
duck8823 8580b25
Fix json key of log line
duck8823 2b0284b
Fix ref when push
duck8823 172fe63
Add debug print in error
duck8823 6c4af7a
Fix sha on push
duck8823 c116414
Delete http-requests-log.http
duck8823 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package executor | ||
|
||
import ( | ||
"context" | ||
"github.com/duck8823/duci/application" | ||
"github.com/duck8823/duci/application/semaphore" | ||
"github.com/duck8823/duci/domain/model/docker" | ||
"github.com/duck8823/duci/domain/service/runner" | ||
"github.com/labstack/gommon/random" | ||
) | ||
|
||
type JobExecutor struct { | ||
runner.DockerRunner | ||
StartFunc func(context.Context) | ||
EndFunc func(context.Context, error) | ||
} | ||
|
||
// Execute job | ||
func (r *JobExecutor) Execute(ctx context.Context, dir string, cmd ...string) error { | ||
r.StartFunc(ctx) | ||
|
||
errs := make(chan error, 1) | ||
|
||
timeout, cancel := context.WithTimeout(ctx, application.Config.Timeout()) | ||
defer cancel() | ||
|
||
go func() { | ||
semaphore.Acquire() | ||
errs <- r.DockerRunner.Run(timeout, dir, docker.Tag(random.String(16, random.Lowercase)), cmd) | ||
semaphore.Release() | ||
}() | ||
|
||
select { | ||
case <-timeout.Done(): | ||
r.EndFunc(ctx, timeout.Err()) | ||
return timeout.Err() | ||
case err := <-errs: | ||
r.EndFunc(ctx, err) | ||
return err | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package runner | ||
|
||
import ( | ||
"bytes" | ||
"github.com/duck8823/duci/application/service/docker" | ||
"github.com/duck8823/duci/infrastructure/archive/tar" | ||
"github.com/pkg/errors" | ||
"gopkg.in/yaml.v2" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
// createTarball creates a tar archive | ||
func createTarball(workDir string) (*os.File, error) { | ||
tarFilePath := filepath.Join(workDir, "duci.tar") | ||
writeFile, err := os.OpenFile(tarFilePath, os.O_RDWR|os.O_CREATE, 0600) | ||
if err != nil { | ||
return nil, errors.WithStack(err) | ||
} | ||
defer writeFile.Close() | ||
|
||
if err := tar.Create(workDir, writeFile); err != nil { | ||
return nil, errors.WithStack(err) | ||
} | ||
|
||
readFile, _ := os.Open(tarFilePath) | ||
return readFile, nil | ||
} | ||
|
||
// dockerfilePath returns a path to dockerfile for duci using | ||
func dockerfilePath(workDir string) docker.Dockerfile { | ||
dockerfile := "./Dockerfile" | ||
if exists(filepath.Join(workDir, ".duci/Dockerfile")) { | ||
dockerfile = ".duci/Dockerfile" | ||
} | ||
return docker.Dockerfile(dockerfile) | ||
} | ||
|
||
// exists indicates whether the file exists | ||
func exists(name string) bool { | ||
_, err := os.Stat(name) | ||
return !os.IsNotExist(err) | ||
} | ||
|
||
// runtimeOptions parses a config.yml and returns a docker runtime options | ||
func runtimeOptions(workDir string) (docker.RuntimeOptions, error) { | ||
var opts docker.RuntimeOptions | ||
|
||
if !exists(filepath.Join(workDir, ".duci/config.yml")) { | ||
return opts, nil | ||
} | ||
content, err := ioutil.ReadFile(filepath.Join(workDir, ".duci/config.yml")) | ||
if err != nil { | ||
return opts, errors.WithStack(err) | ||
} | ||
content = []byte(os.ExpandEnv(string(content))) | ||
if err := yaml.NewDecoder(bytes.NewReader(content)).Decode(&opts); err != nil { | ||
return opts, errors.WithStack(err) | ||
} | ||
return opts, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package docker | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/duck8823/duci/domain/model/job" | ||
"github.com/pkg/errors" | ||
"io" | ||
"time" | ||
) | ||
|
||
var now = time.Now | ||
|
||
type buildLogger struct { | ||
reader *bufio.Reader | ||
} | ||
|
||
// NewBuildLog return a instance of Log. | ||
func NewBuildLog(r io.Reader) *buildLogger { | ||
return &buildLogger{bufio.NewReader(r)} | ||
} | ||
|
||
// ReadLine returns LogLine. | ||
func (l *buildLogger) ReadLine() (*job.LogLine, error) { | ||
for { | ||
line, _, readErr := l.reader.ReadLine() | ||
msg := extractMessage(line) | ||
if readErr == io.EOF { | ||
return &job.LogLine{Timestamp: now(), Message: msg}, readErr | ||
} | ||
if readErr != nil { | ||
return nil, errors.WithStack(readErr) | ||
} | ||
|
||
if len(msg) == 0 { | ||
continue | ||
} | ||
|
||
return &job.LogLine{Timestamp: now(), Message: msg}, readErr | ||
} | ||
} | ||
|
||
type runLogger struct { | ||
reader *bufio.Reader | ||
} | ||
|
||
// NewRunLog returns a instance of Log | ||
func NewRunLog(r io.Reader) *runLogger { | ||
return &runLogger{bufio.NewReader(r)} | ||
} | ||
|
||
// ReadLine returns LogLine. | ||
func (l *runLogger) ReadLine() (*job.LogLine, error) { | ||
for { | ||
line, _, readErr := l.reader.ReadLine() | ||
if readErr != nil && readErr != io.EOF { | ||
return nil, errors.WithStack(readErr) | ||
} | ||
|
||
messages, err := trimPrefix(line) | ||
if err != nil { | ||
return nil, errors.WithStack(err) | ||
} | ||
|
||
// prevent to CR | ||
progress := bytes.Split(messages, []byte{'\r'}) | ||
return &job.LogLine{Timestamp: now(), Message: string(progress[0])}, readErr | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the surrounding loop is unconditionally terminated (from |
||
} | ||
} | ||
|
||
func extractMessage(line []byte) string { | ||
s := &struct { | ||
Stream string `json:"stream"` | ||
}{} | ||
json.NewDecoder(bytes.NewReader(line)).Decode(s) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error return value of |
||
return s.Stream | ||
} | ||
|
||
func trimPrefix(line []byte) ([]byte, error) { | ||
if len(line) < 8 { | ||
return []byte{}, nil | ||
} | ||
|
||
// detect logstore prefix | ||
// see https://godoc.org/github.com/docker/docker/client#Client.ContainerLogs | ||
if !((line[0] == 1 || line[0] == 2) && (line[1] == 0 && line[2] == 0 && line[3] == 0)) { | ||
return nil, fmt.Errorf("invalid logstore prefix: %+v", line[:7]) | ||
} | ||
return line[8:], nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package docker | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
// RuntimeOptions is a docker options. | ||
type RuntimeOptions struct { | ||
Environments Environments | ||
Volumes Volumes | ||
} | ||
|
||
// Environments represents a docker `-e` option. | ||
type Environments map[string]interface{} | ||
|
||
// ToArray returns string array of environments | ||
func (e Environments) ToArray() []string { | ||
var a []string | ||
for key, val := range e { | ||
a = append(a, fmt.Sprintf("%s=%v", key, val)) | ||
} | ||
return a | ||
} | ||
|
||
// Volumes represents a docker `-v` option. | ||
type Volumes []string | ||
|
||
// ToMap returns map of volumes. | ||
func (v Volumes) ToMap() map[string]struct{} { | ||
m := make(map[string]struct{}) | ||
for _, volume := range v { | ||
key := strings.Split(volume, ":")[0] | ||
m[key] = struct{}{} | ||
} | ||
return m | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package docker | ||
|
||
// Tag describes a docker tag | ||
type Tag string | ||
|
||
// ToString return string value | ||
func (t Tag) ToString() string { | ||
return string(t) | ||
} | ||
|
||
// Command describes a docker CMD | ||
type Command []string | ||
|
||
// ToSlice returns slice values | ||
func (c Command) ToSlice() []string { | ||
return []string(c) | ||
} | ||
|
||
// Dockerfile represents a path to dockerfile | ||
type Dockerfile string | ||
|
||
// ToString returns string value | ||
func (d Dockerfile) ToString() string { | ||
return string(d) | ||
} | ||
|
||
// ContainerID describes a container id of docker | ||
type ContainerID string | ||
|
||
// ToString returns string value | ||
func (c ContainerID) ToString() string { | ||
return string(c) | ||
} | ||
|
||
// ExitCode describes a exit code | ||
type ExitCode int64 | ||
|
||
// IsFailure returns whether failure code or not | ||
func (c ExitCode) IsFailure() bool { | ||
return c != 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package job | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"github.com/google/uuid" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// Job represents a task | ||
type Job struct { | ||
Finished bool `json:"finished"` | ||
Stream []LogLine `json:"stream"` | ||
} | ||
|
||
// AppendLog append log line to stream | ||
func (j *Job) AppendLog(line LogLine) { | ||
j.Stream = append(j.Stream, line) | ||
} | ||
|
||
// Finish set true to Finished | ||
func (j *Job) Finish() { | ||
j.Finished = true | ||
} | ||
|
||
// ToBytes returns marshal byte slice | ||
func (j *Job) ToBytes() ([]byte, error) { | ||
data, err := json.Marshal(j) | ||
if err != nil { | ||
return nil, errors.WithStack(err) | ||
} | ||
return data, nil | ||
} | ||
|
||
// NewJob returns unmarshal Job instance | ||
func NewJob(data []byte) (*Job, error) { | ||
job := &Job{} | ||
if err := json.NewDecoder(bytes.NewReader(data)).Decode(job); err != nil { | ||
return nil, errors.WithStack(err) | ||
} | ||
return job, nil | ||
} | ||
|
||
// ID is the identifier of job | ||
type ID uuid.UUID | ||
|
||
// ToSlice returns slice value | ||
func (i ID) ToSlice() []byte { | ||
return []byte(i[:]) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
runtimeOptions
is unused (fromdeadcode
)