feat(cmd/joj3): show teapot check result in issue
All checks were successful
submodules sync / sync (push) Successful in 47s
build / build (push) Successful in 1m39s
build / trigger-build-image (push) Successful in 8s

This commit is contained in:
张泊明518370910136 2024-11-26 00:25:24 -05:00
parent aa0b33d1e7
commit c41031c2c3
GPG Key ID: D47306D7062CDA9D
4 changed files with 83 additions and 22 deletions

View File

@ -33,7 +33,8 @@ func mainImpl() (err error) {
confObj := new(conf.Conf) confObj := new(conf.Conf)
var stageResults []internalStage.StageResult var stageResults []internalStage.StageResult
var forceQuitStageName string var forceQuitStageName string
var teapotResult teapot.TeapotResult var teapotCheckResults []teapot.CheckResult
var teapotRunResult teapot.RunResult
var commitMsg string var commitMsg string
defer func() { defer func() {
totalScore := 0 totalScore := 0
@ -52,9 +53,9 @@ func mainImpl() (err error) {
"cappedTotalScore", cappedTotalScore, "cappedTotalScore", cappedTotalScore,
"forceQuit", forceQuitStageName != "", "forceQuit", forceQuitStageName != "",
"forceQuitStageName", forceQuitStageName, "forceQuitStageName", forceQuitStageName,
"issue", teapotResult.Issue, "issue", teapotRunResult.Issue,
"action", teapotResult.Action, "action", teapotRunResult.Action,
"sha", teapotResult.Sha, "sha", teapotRunResult.Sha,
"commitMsg", commitMsg, "commitMsg", commitMsg,
"error", err, "error", err,
) )
@ -107,14 +108,16 @@ func mainImpl() (err error) {
} }
groups := conf.MatchGroups(confObj, conventionalCommit) groups := conf.MatchGroups(confObj, conventionalCommit)
if len(confObj.Teapot.Groups) != 0 { if len(confObj.Teapot.Groups) != 0 {
if err = teapot.Check(confObj); err != nil { teapotCheckResults, err = teapot.Check(confObj)
if err != nil {
slog.Error("teapot check", "error", err) slog.Error("teapot check", "error", err)
return err
} }
} else { } else {
slog.Info("teapot check disabled") slog.Info("teapot check disabled")
} }
stageResults, forceQuitStageName, err = stage.Run(confObj, groups) stageResults, forceQuitStageName, err = stage.Run(
confObj, groups, teapotCheckResults,
)
if err != nil { if err != nil {
slog.Error("stage run", "error", err) slog.Error("stage run", "error", err)
} }
@ -122,7 +125,7 @@ func mainImpl() (err error) {
slog.Error("stage write", "error", err) slog.Error("stage write", "error", err)
return err return err
} }
teapotResult, err = teapot.Run(confObj, groups) teapotRunResult, err = teapot.Run(confObj, groups)
if err != nil { if err != nil {
slog.Error("teapot run", "error", err) slog.Error("teapot run", "error", err)
return err return err

View File

@ -6,6 +6,7 @@ import (
"strings" "strings"
"github.com/joint-online-judge/JOJ3/cmd/joj3/conf" "github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
"github.com/joint-online-judge/JOJ3/cmd/joj3/teapot"
executors "github.com/joint-online-judge/JOJ3/internal/executor" executors "github.com/joint-online-judge/JOJ3/internal/executor"
_ "github.com/joint-online-judge/JOJ3/internal/parser" _ "github.com/joint-online-judge/JOJ3/internal/parser"
"github.com/joint-online-judge/JOJ3/internal/stage" "github.com/joint-online-judge/JOJ3/internal/stage"
@ -116,7 +117,7 @@ func generateStages(conf *conf.Conf, groups []string) ([]stage.Stage, error) {
return stages, nil return stages, nil
} }
func newErrorStageResults(err error) []stage.StageResult { func newErrorStageResults(err error) ([]stage.StageResult, string) {
return []stage.StageResult{ return []stage.StageResult{
{ {
Name: "Internal Error", Name: "Internal Error",
@ -128,12 +129,56 @@ func newErrorStageResults(err error) []stage.StageResult {
}}, }},
ForceQuit: true, ForceQuit: true,
}, },
} }, "Internal Error"
} }
func Run(conf *conf.Conf, groups []string) ( func newTeapotCheckStageResults(
checkResults []teapot.CheckResult,
) (stageResults []stage.StageResult, forceQuitStageName string, err error) {
if len(checkResults) == 0 {
return
}
comment := ""
forceQuit := false
for _, checkResult := range checkResults {
comment += fmt.Sprintf(
"Keyword `%s` in last %d hour(s): submit count %d, max count %d\n",
checkResult.Name,
checkResult.TimePeriod,
checkResult.SubmitCount,
checkResult.MaxCount,
)
if checkResult.SubmitCount+1 > checkResult.MaxCount {
forceQuit = true
err = fmt.Errorf("submit count exceeded")
}
}
stageResults = []stage.StageResult{
{
Name: "Teapot Check",
Results: []stage.ParserResult{{
Score: 0,
Comment: comment,
}},
ForceQuit: forceQuit,
},
}
forceQuitStageName = "Teapot Check"
return
}
func Run(
conf *conf.Conf, groups []string, checkResults []teapot.CheckResult,
) (
stageResults []stage.StageResult, forceQuitStageName string, err error, stageResults []stage.StageResult, forceQuitStageName string, err error,
) { ) {
stageResults, forceQuitStageName, err = newTeapotCheckStageResults(
checkResults,
)
if err != nil {
slog.Error("teapot check", "error", err)
return
}
executors.InitWithConf( executors.InitWithConf(
conf.Stage.SandboxExecServer, conf.Stage.SandboxExecServer,
conf.Stage.SandboxToken, conf.Stage.SandboxToken,
@ -141,17 +186,16 @@ func Run(conf *conf.Conf, groups []string) (
stages, err := generateStages(conf, groups) stages, err := generateStages(conf, groups)
if err != nil { if err != nil {
slog.Error("generate stages", "error", err) slog.Error("generate stages", "error", err)
stageResults = newErrorStageResults(err) stageResults, forceQuitStageName = newErrorStageResults(err)
forceQuitStageName = "internal"
return return
} }
defer stage.Cleanup() defer stage.Cleanup()
stageResults, forceQuitStageName, err = stage.Run(stages) newStageResults, forceQuitStageName, err := stage.Run(stages)
if err != nil { if err != nil {
slog.Error("run stages", "error", err) slog.Error("run stages", "error", err)
stageResults = newErrorStageResults(err) stageResults, forceQuitStageName = newErrorStageResults(err)
forceQuitStageName = "internal"
return return
} }
stageResults = append(stageResults, newStageResults...)
return return
} }

View File

@ -1,6 +1,7 @@
package teapot package teapot
import ( import (
"encoding/json"
"fmt" "fmt"
"log/slog" "log/slog"
"os" "os"
@ -10,7 +11,14 @@ import (
"github.com/joint-online-judge/JOJ3/cmd/joj3/env" "github.com/joint-online-judge/JOJ3/cmd/joj3/env"
) )
func Check(conf *conf.Conf) (err error) { type CheckResult struct {
Name string `json:"name"`
SubmitCount int `json:"submit_count"`
MaxCount int `json:"max_count"`
TimePeriod int `json:"time_period"`
}
func Check(conf *conf.Conf) (checkResults []CheckResult, err error) {
os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath) os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath)
os.Setenv("_TYPER_STANDARD_TRACEBACK", "1") os.Setenv("_TYPER_STANDARD_TRACEBACK", "1")
if env.Attr.Actor == "" || if env.Attr.Actor == "" ||
@ -34,10 +42,16 @@ func Check(conf *conf.Conf) (err error) {
conf.Teapot.ScoreboardPath, conf.Name, conf.Teapot.ScoreboardPath, conf.Name,
"--group-config", strings.Join(formattedGroups, ","), "--group-config", strings.Join(formattedGroups, ","),
} }
_, err = runCommand(args) stdoutBuf, err := runCommand(args)
if err != nil { if err != nil {
slog.Error("teapot check exec", "error", err) slog.Error("teapot check exec", "error", err)
return return
} }
if json.Unmarshal(stdoutBuf.Bytes(), &checkResults) != nil {
slog.Error("unmarshal teapot result", "error", err,
"stdout", stdoutBuf.String())
return
}
slog.Info("teapot result", "result", checkResults)
return return
} }

View File

@ -12,14 +12,14 @@ import (
"github.com/joint-online-judge/JOJ3/cmd/joj3/env" "github.com/joint-online-judge/JOJ3/cmd/joj3/env"
) )
type TeapotResult struct { type RunResult struct {
Issue int `json:"issue"` Issue int `json:"issue"`
Action int `json:"action"` Action int `json:"action"`
Sha string `json:"sha"` Sha string `json:"sha"`
} }
func Run(conf *conf.Conf, groups []string) ( func Run(conf *conf.Conf, groups []string) (
teapotResult TeapotResult, err error, runResult RunResult, err error,
) { ) {
os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath) os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath)
os.Setenv("_TYPER_STANDARD_TRACEBACK", "1") os.Setenv("_TYPER_STANDARD_TRACEBACK", "1")
@ -65,11 +65,11 @@ func Run(conf *conf.Conf, groups []string) (
slog.Error("teapot run exec", "error", err) slog.Error("teapot run exec", "error", err)
return return
} }
if json.Unmarshal(stdoutBuf.Bytes(), &teapotResult) != nil { if json.Unmarshal(stdoutBuf.Bytes(), &runResult) != nil {
slog.Error("unmarshal teapot result", "error", err, slog.Error("unmarshal teapot result", "error", err,
"stdout", stdoutBuf.String()) "stdout", stdoutBuf.String())
return return
} }
slog.Info("teapot result", "result", teapotResult) slog.Info("teapot result", "result", runResult)
return return
} }