feat(cmd/joj3): store & log env
Some checks failed
submodules sync / sync (push) Failing after 5s
build / build (push) Successful in 1m36s
build / trigger-build-image (push) Successful in 8s

This commit is contained in:
张泊明518370910136 2024-11-15 13:46:59 -05:00
parent 79297a26f7
commit e808408170
GPG Key ID: D47306D7062CDA9D
4 changed files with 76 additions and 54 deletions

39
cmd/joj3/env/env.go vendored Normal file
View File

@ -0,0 +1,39 @@
package env
import (
"fmt"
"os"
"time"
)
type Attribute struct {
ConfName string
RunID string
Actor string
Repository string
Sha string
Ref string
Workflow string
RunNumber string
}
var Attr Attribute
func init() {
timestamp := time.Now().UnixNano()
pid := os.Getpid()
high := timestamp >> 32
low := timestamp & 0xFFFFFFFF
combined := high ^ low
combined ^= int64(pid)
combined ^= int64(timestamp >> 16)
combined ^= (combined >> 8)
combined ^= (combined << 16)
Attr.RunID = fmt.Sprintf("%08X", combined&0xFFFFFFFF)
Attr.Actor = os.Getenv("GITHUB_ACTOR")
Attr.Repository = os.Getenv("GITHUB_REPOSITORY")
Attr.Sha = os.Getenv("GITHUB_SHA")
Attr.Ref = os.Getenv("GITHUB_REF")
Attr.Workflow = os.Getenv("GITHUB_WORKFLOW")
Attr.RunNumber = os.Getenv("GITHUB_RUN_NUMBER")
}

View File

@ -2,10 +2,10 @@ package main
import ( import (
"context" "context"
"fmt"
"log/slog" "log/slog"
"os" "os"
"time"
"github.com/joint-online-judge/JOJ3/cmd/joj3/env"
) )
var runningTest bool var runningTest bool
@ -14,21 +14,6 @@ type multiHandler struct {
handlers []slog.Handler handlers []slog.Handler
} }
var runID string
func init() {
timestamp := time.Now().UnixNano()
pid := os.Getpid()
high := timestamp >> 32
low := timestamp & 0xFFFFFFFF
combined := high ^ low
combined ^= int64(pid)
combined ^= int64(timestamp >> 16)
combined ^= (combined >> 8)
combined ^= (combined << 16)
runID = fmt.Sprintf("%08X", combined&0xFFFFFFFF)
}
func (h *multiHandler) Enabled(ctx context.Context, level slog.Level) bool { func (h *multiHandler) Enabled(ctx context.Context, level slog.Level) bool {
for _, handler := range h.handlers { for _, handler := range h.handlers {
if handler.Enabled(ctx, level) { if handler.Enabled(ctx, level) {
@ -65,6 +50,14 @@ func (h *multiHandler) WithGroup(name string) slog.Handler {
return &multiHandler{handlers: handlers} return &multiHandler{handlers: handlers}
} }
func getSlogAttrs() []slog.Attr {
return []slog.Attr{
slog.String("runID", env.Attr.RunID),
slog.String("confName", env.Attr.ConfName),
slog.String("actor", env.Attr.Actor),
}
}
func setupSlog(logPath string) error { func setupSlog(logPath string) error {
handlers := []slog.Handler{} handlers := []slog.Handler{}
if logPath != "" { if logPath != "" {
@ -104,8 +97,7 @@ func setupSlog(logPath string) error {
} }
// Create a multi-handler // Create a multi-handler
multiHandler := &multiHandler{handlers: handlers} multiHandler := &multiHandler{handlers: handlers}
multiHandlerWithAttrs := multiHandler.WithAttrs( multiHandlerWithAttrs := multiHandler.WithAttrs(getSlogAttrs())
[]slog.Attr{slog.String("runID", runID)})
// Set the default logger // Set the default logger
logger := slog.New(multiHandlerWithAttrs) logger := slog.New(multiHandlerWithAttrs)
slog.SetDefault(logger) slog.SetDefault(logger)

View File

@ -13,9 +13,9 @@ import (
) )
var ( var (
confRoot string confFileRoot string
confName string confFileName string
fallbackConfName string fallbackConfFileName string
tag string tag string
msg string msg string
showVersion *bool showVersion *bool
@ -23,9 +23,9 @@ var (
) )
func init() { func init() {
flag.StringVar(&confRoot, "conf-root", ".", "root path for all config files") flag.StringVar(&confFileRoot, "conf-root", ".", "root path for all config files")
flag.StringVar(&confName, "conf-name", "conf.json", "filename for config files") flag.StringVar(&confFileName, "conf-name", "conf.json", "filename for config files")
flag.StringVar(&fallbackConfName, "fallback-conf-name", "", "filename for the fallback config file in conf-root, leave empty to use conf-name") flag.StringVar(&fallbackConfFileName, "fallback-conf-name", "", "filename for the fallback config file in conf-root, leave empty to use conf-name")
flag.StringVar(&tag, "tag", "", "tag to trigger the running, when non-empty, should equal to the scope in msg") flag.StringVar(&tag, "tag", "", "tag to trigger the running, when non-empty, should equal to the scope in msg")
// TODO: remove this flag // TODO: remove this flag
flag.StringVar(&msg, "msg", "", "[DEPRECATED] will be ignored") flag.StringVar(&msg, "msg", "", "[DEPRECATED] will be ignored")
@ -38,10 +38,6 @@ func mainImpl() (err error) {
var forceQuitStageName string var forceQuitStageName string
var teapotResult teapot.TeapotResult var teapotResult teapot.TeapotResult
defer func() { defer func() {
actor := os.Getenv("GITHUB_ACTOR")
repository := os.Getenv("GITHUB_REPOSITORY")
ref := os.Getenv("GITHUB_REF")
workflow := os.Getenv("GITHUB_WORKFLOW")
totalScore := 0 totalScore := 0
for _, stageResult := range stageResults { for _, stageResult := range stageResults {
for _, result := range stageResult.Results { for _, result := range stageResult.Results {
@ -50,14 +46,9 @@ func mainImpl() (err error) {
} }
slog.Info( slog.Info(
"joj3 summary", "joj3 summary",
"name", confObj.Name,
"totalScore", totalScore, "totalScore", totalScore,
"forceQuit", forceQuitStageName != "", "forceQuit", forceQuitStageName != "",
"forceQuitStageName", forceQuitStageName, "forceQuitStageName", forceQuitStageName,
"actor", actor,
"repository", repository,
"ref", ref,
"workflow", workflow,
"issue", teapotResult.Issue, "issue", teapotResult.Issue,
"action", teapotResult.Action, "action", teapotResult.Action,
"sha", teapotResult.Sha, "sha", teapotResult.Sha,
@ -73,8 +64,8 @@ func mainImpl() (err error) {
fmt.Println(Version) fmt.Println(Version)
return nil return nil
} }
if fallbackConfName == "" { if fallbackConfFileName == "" {
fallbackConfName = confName fallbackConfFileName = confFileName
} }
slog.Info("start joj3", "version", Version) slog.Info("start joj3", "version", Version)
msg, err := conf.GetCommitMsg() msg, err := conf.GetCommitMsg()
@ -83,7 +74,7 @@ func mainImpl() (err error) {
return err return err
} }
confPath, confStat, conventionalCommit, err := conf.GetConfPath( confPath, confStat, conventionalCommit, err := conf.GetConfPath(
confRoot, confName, fallbackConfName, msg, tag) confFileRoot, confFileName, fallbackConfFileName, msg, tag)
if err != nil { if err != nil {
slog.Error("get conf path", "error", err) slog.Error("get conf path", "error", err)
return err return err
@ -119,7 +110,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, runID) teapotResult, err = teapot.Run(confObj)
if err != nil { if err != nil {
slog.Error("teapot run", "error", err) slog.Error("teapot run", "error", err)
return err return err

View File

@ -14,6 +14,7 @@ import (
"sync" "sync"
"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/env"
) )
type TeapotResult struct { type TeapotResult struct {
@ -22,20 +23,18 @@ type TeapotResult struct {
Sha string `json:"sha"` Sha string `json:"sha"`
} }
func Run(conf *conf.Conf, runID string) (teapotResult TeapotResult, err error) { func Run(conf *conf.Conf) (teapotResult TeapotResult, 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")
sha := os.Getenv("GITHUB_SHA") if env.Attr.Actor == "" ||
actor := os.Getenv("GITHUB_ACTOR") env.Attr.Repository == "" ||
repository := os.Getenv("GITHUB_REPOSITORY") strings.Count(env.Attr.Repository, "/") != 1 ||
runNumber := os.Getenv("GITHUB_RUN_NUMBER") env.Attr.RunNumber == "" {
if actor == "" || repository == "" || strings.Count(repository, "/") != 1 ||
runNumber == "" {
slog.Error("teapot env not set") slog.Error("teapot env not set")
err = fmt.Errorf("teapot env not set") err = fmt.Errorf("teapot env not set")
return return
} }
repoParts := strings.Split(repository, "/") repoParts := strings.Split(env.Attr.Repository, "/")
repoName := repoParts[1] repoName := repoParts[1]
skipIssueArg := "--no-skip-result-issue" skipIssueArg := "--no-skip-result-issue"
if conf.Teapot.SkipIssue { if conf.Teapot.SkipIssue {
@ -55,10 +54,11 @@ func Run(conf *conf.Conf, runID string) (teapotResult TeapotResult, err error) {
} }
re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`) re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
cmd := exec.Command("joint-teapot", cmd := exec.Command("joint-teapot",
"joj3-all", conf.Teapot.EnvFilePath, conf.Stage.OutputPath, actor, "joj3-all", conf.Teapot.EnvFilePath, conf.Stage.OutputPath,
conf.Teapot.GradingRepoName, repoName, runNumber, env.Attr.Actor, conf.Teapot.GradingRepoName, repoName,
conf.Teapot.ScoreboardPath, conf.Teapot.FailedTablePath, env.Attr.RunNumber, conf.Teapot.ScoreboardPath,
conf.Name, sha, runID, conf.Teapot.FailedTablePath,
conf.Name, env.Attr.Sha, env.Attr.RunID,
"--max-total-score", strconv.Itoa(conf.Teapot.MaxTotalScore), "--max-total-score", strconv.Itoa(conf.Teapot.MaxTotalScore),
skipIssueArg, skipScoreboardArg, skipIssueArg, skipScoreboardArg,
skipFailedTableArg, submitterInIssueTitleArg, skipFailedTableArg, submitterInIssueTitleArg,