feat(cmd/joj3): extra summary info from teapot [force build]
This commit is contained in:
parent
7b4d167448
commit
e4bfcfbe8d
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
|
||||
"github.com/joint-online-judge/JOJ3/cmd/joj3/stage"
|
||||
"github.com/joint-online-judge/JOJ3/cmd/joj3/teapot"
|
||||
internalStage "github.com/joint-online-judge/JOJ3/internal/stage"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -31,7 +32,37 @@ func init() {
|
|||
showVersion = flag.Bool("version", false, "print current version")
|
||||
}
|
||||
|
||||
func mainImpl() error {
|
||||
func mainImpl() (err error) {
|
||||
confObj := new(conf.Conf)
|
||||
var stageResults []internalStage.StageResult
|
||||
var stageForceQuit bool
|
||||
var teapotResult teapot.TeapotResult
|
||||
defer func() {
|
||||
actor := os.Getenv("GITHUB_ACTOR")
|
||||
repository := os.Getenv("GITHUB_REPOSITORY")
|
||||
ref := os.Getenv("GITHUB_REF")
|
||||
workflow := os.Getenv("GITHUB_WORKFLOW")
|
||||
totalScore := 0
|
||||
for _, stageResult := range stageResults {
|
||||
for _, result := range stageResult.Results {
|
||||
totalScore += result.Score
|
||||
}
|
||||
}
|
||||
slog.Info(
|
||||
"joj3 summary",
|
||||
"name", confObj.Name,
|
||||
"totalScore", totalScore,
|
||||
"forceQuit", stageForceQuit,
|
||||
"actor", actor,
|
||||
"repository", repository,
|
||||
"ref", ref,
|
||||
"workflow", workflow,
|
||||
"issue", teapotResult.Issue,
|
||||
"action", teapotResult.Action,
|
||||
"sha", teapotResult.Sha,
|
||||
"error", err,
|
||||
)
|
||||
}()
|
||||
if err := setupSlog(""); err != nil { // before conf is loaded
|
||||
slog.Error("setup slog", "error", err)
|
||||
return err
|
||||
|
@ -57,7 +88,7 @@ func mainImpl() error {
|
|||
return err
|
||||
}
|
||||
slog.Info("try to load conf", "path", confPath)
|
||||
confObj, err := conf.ParseConfFile(confPath)
|
||||
confObj, err = conf.ParseConfFile(confPath)
|
||||
if err != nil {
|
||||
slog.Error("parse conf", "error", err)
|
||||
return err
|
||||
|
@ -79,16 +110,16 @@ func mainImpl() error {
|
|||
return err
|
||||
}
|
||||
groups := conf.MatchGroups(confObj, conventionalCommit)
|
||||
stageResults, stageForceQuit, err := stage.Run(confObj, groups)
|
||||
stageResults, stageForceQuit, err = stage.Run(confObj, groups)
|
||||
if err != nil {
|
||||
slog.Error("stage run", "error", err)
|
||||
}
|
||||
stage.Summarize(confObj, stageResults, stageForceQuit)
|
||||
if err = stage.Write(confObj.Stage.OutputPath, stageResults); err != nil {
|
||||
slog.Error("stage write", "error", err)
|
||||
return err
|
||||
}
|
||||
if err := teapot.Run(confObj, runID); err != nil {
|
||||
teapotResult, err = teapot.Run(confObj, runID)
|
||||
if err != nil {
|
||||
slog.Error("teapot run", "error", err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import (
|
|||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
type StageResult stage.StageResult
|
||||
|
||||
func generateStages(conf *conf.Conf, groups []string) ([]stage.Stage, error) {
|
||||
stages := []stage.Stage{}
|
||||
existNames := map[string]bool{}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
package stage
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
|
||||
"github.com/joint-online-judge/JOJ3/internal/stage"
|
||||
)
|
||||
|
||||
func Summarize(
|
||||
conf *conf.Conf, stageResults []stage.StageResult, stageForceQuit bool,
|
||||
) {
|
||||
actor := os.Getenv("GITHUB_ACTOR")
|
||||
repository := os.Getenv("GITHUB_REPOSITORY")
|
||||
ref := os.Getenv("GITHUB_REF")
|
||||
workflow := os.Getenv("GITHUB_WORKFLOW")
|
||||
totalScore := 0
|
||||
for _, stageResult := range stageResults {
|
||||
for _, result := range stageResult.Results {
|
||||
totalScore += result.Score
|
||||
}
|
||||
}
|
||||
slog.Info(
|
||||
"stage summary",
|
||||
"name", conf.Name,
|
||||
"totalScore", totalScore,
|
||||
"forceQuit", stageForceQuit,
|
||||
"actor", actor,
|
||||
"repository", repository,
|
||||
"ref", ref,
|
||||
"workflow", workflow,
|
||||
)
|
||||
}
|
|
@ -2,6 +2,8 @@ package teapot
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
@ -14,7 +16,13 @@ import (
|
|||
"github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
|
||||
)
|
||||
|
||||
func Run(conf *conf.Conf, runID string) error {
|
||||
type TeapotResult struct {
|
||||
Issue int `json:"issue"`
|
||||
Action int `json:"action"`
|
||||
Sha string `json:"sha"`
|
||||
}
|
||||
|
||||
func Run(conf *conf.Conf, runID string) (teapotResult TeapotResult, err error) {
|
||||
os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath)
|
||||
os.Setenv("_TYPER_STANDARD_TRACEBACK", "1")
|
||||
sha := os.Getenv("GITHUB_SHA")
|
||||
|
@ -24,52 +32,11 @@ func Run(conf *conf.Conf, runID string) error {
|
|||
if actor == "" || repository == "" || strings.Count(repository, "/") != 1 ||
|
||||
runNumber == "" {
|
||||
slog.Error("teapot env not set")
|
||||
return fmt.Errorf("teapot env not set")
|
||||
err = fmt.Errorf("teapot env not set")
|
||||
return
|
||||
}
|
||||
repoParts := strings.Split(repository, "/")
|
||||
repoName := repoParts[1]
|
||||
re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
|
||||
execCommand := func(name string, cmdArgs []string) error {
|
||||
cmd := exec.Command(name, cmdArgs...) // #nosec G204
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
slog.Error("stderr pipe", "error", err)
|
||||
return err
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
go func() {
|
||||
for scanner.Scan() {
|
||||
text := re.ReplaceAllString(scanner.Text(), "")
|
||||
if text == "" {
|
||||
continue
|
||||
}
|
||||
slog.Info(name, "stderr", text)
|
||||
}
|
||||
wg.Done()
|
||||
if scanner.Err() != nil {
|
||||
slog.Error("stderr scanner", "error", scanner.Err())
|
||||
}
|
||||
}()
|
||||
if err = cmd.Start(); err != nil {
|
||||
slog.Error("cmd start", "error", err)
|
||||
return err
|
||||
}
|
||||
wg.Wait()
|
||||
if err = cmd.Wait(); err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
exitCode := exitErr.ExitCode()
|
||||
slog.Error("cmd completed with non-zero exit code",
|
||||
"error", err,
|
||||
"exitCode", exitCode)
|
||||
} else {
|
||||
slog.Error("cmd wait", "error", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
skipIssueArg := "--no-skip-result-issue"
|
||||
if conf.Teapot.SkipIssue {
|
||||
skipIssueArg = "--skip-result-issue"
|
||||
|
@ -86,7 +53,8 @@ func Run(conf *conf.Conf, runID string) error {
|
|||
if conf.Teapot.SubmitterInIssueTitle {
|
||||
submitterInIssueTitleArg = "--submitter-in-issue-title"
|
||||
}
|
||||
if err := execCommand("joint-teapot", []string{
|
||||
re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
|
||||
cmd := exec.Command("joint-teapot",
|
||||
"joj3-all", conf.Teapot.EnvFilePath, conf.Stage.OutputPath, actor,
|
||||
conf.Teapot.GradingRepoName, repoName, runNumber,
|
||||
conf.Teapot.ScoreboardPath, conf.Teapot.FailedTablePath,
|
||||
|
@ -94,9 +62,51 @@ func Run(conf *conf.Conf, runID string) error {
|
|||
"--max-total-score", strconv.Itoa(conf.Teapot.MaxTotalScore),
|
||||
skipIssueArg, skipScoreboardArg,
|
||||
skipFailedTableArg, submitterInIssueTitleArg,
|
||||
}); err != nil {
|
||||
slog.Error("teapot exit", "error", err)
|
||||
return fmt.Errorf("teapot exit")
|
||||
) // #nosec G204
|
||||
stdoutBuf := new(bytes.Buffer)
|
||||
cmd.Stdout = stdoutBuf
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
slog.Error("stderr pipe", "error", err)
|
||||
return
|
||||
}
|
||||
return nil
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
go func() {
|
||||
for scanner.Scan() {
|
||||
text := re.ReplaceAllString(scanner.Text(), "")
|
||||
if text == "" {
|
||||
continue
|
||||
}
|
||||
slog.Info("joint-teapot", "stderr", text)
|
||||
}
|
||||
wg.Done()
|
||||
if scanner.Err() != nil {
|
||||
slog.Error("stderr scanner", "error", scanner.Err())
|
||||
}
|
||||
}()
|
||||
if err = cmd.Start(); err != nil {
|
||||
slog.Error("cmd start", "error", err)
|
||||
return
|
||||
}
|
||||
wg.Wait()
|
||||
if err = cmd.Wait(); err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
exitCode := exitErr.ExitCode()
|
||||
slog.Error("cmd completed with non-zero exit code",
|
||||
"error", err,
|
||||
"exitCode", exitCode)
|
||||
} else {
|
||||
slog.Error("cmd wait", "error", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if json.Unmarshal(stdoutBuf.Bytes(), &teapotResult) != nil {
|
||||
slog.Error("unmarshal teapot result", "error", err,
|
||||
"stdout", stdoutBuf.String())
|
||||
return
|
||||
}
|
||||
slog.Info("teapot result", "result", teapotResult)
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user