diff --git a/cmd/joj3/env/env.go b/cmd/joj3/env/env.go new file mode 100644 index 0000000..f0bc015 --- /dev/null +++ b/cmd/joj3/env/env.go @@ -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") +} diff --git a/cmd/joj3/log.go b/cmd/joj3/log.go index 09d02d2..d661281 100644 --- a/cmd/joj3/log.go +++ b/cmd/joj3/log.go @@ -2,10 +2,10 @@ package main import ( "context" - "fmt" "log/slog" "os" - "time" + + "github.com/joint-online-judge/JOJ3/cmd/joj3/env" ) var runningTest bool @@ -14,21 +14,6 @@ type multiHandler struct { 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 { for _, handler := range h.handlers { if handler.Enabled(ctx, level) { @@ -65,6 +50,14 @@ func (h *multiHandler) WithGroup(name string) slog.Handler { 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 { handlers := []slog.Handler{} if logPath != "" { @@ -104,8 +97,7 @@ func setupSlog(logPath string) error { } // Create a multi-handler multiHandler := &multiHandler{handlers: handlers} - multiHandlerWithAttrs := multiHandler.WithAttrs( - []slog.Attr{slog.String("runID", runID)}) + multiHandlerWithAttrs := multiHandler.WithAttrs(getSlogAttrs()) // Set the default logger logger := slog.New(multiHandlerWithAttrs) slog.SetDefault(logger) diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index ced57e4..d317a86 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -13,19 +13,19 @@ import ( ) var ( - confRoot string - confName string - fallbackConfName string - tag string - msg string - showVersion *bool - Version string = "debug" + confFileRoot string + confFileName string + fallbackConfFileName string + tag string + msg string + showVersion *bool + Version string = "debug" ) func init() { - flag.StringVar(&confRoot, "conf-root", ".", "root path for all config files") - flag.StringVar(&confName, "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(&confFileRoot, "conf-root", ".", "root path for all config files") + flag.StringVar(&confFileName, "conf-name", "conf.json", "filename for config files") + 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") // TODO: remove this flag flag.StringVar(&msg, "msg", "", "[DEPRECATED] will be ignored") @@ -38,10 +38,6 @@ func mainImpl() (err error) { var forceQuitStageName string 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 { @@ -50,14 +46,9 @@ func mainImpl() (err error) { } slog.Info( "joj3 summary", - "name", confObj.Name, "totalScore", totalScore, "forceQuit", forceQuitStageName != "", "forceQuitStageName", forceQuitStageName, - "actor", actor, - "repository", repository, - "ref", ref, - "workflow", workflow, "issue", teapotResult.Issue, "action", teapotResult.Action, "sha", teapotResult.Sha, @@ -73,8 +64,8 @@ func mainImpl() (err error) { fmt.Println(Version) return nil } - if fallbackConfName == "" { - fallbackConfName = confName + if fallbackConfFileName == "" { + fallbackConfFileName = confFileName } slog.Info("start joj3", "version", Version) msg, err := conf.GetCommitMsg() @@ -83,7 +74,7 @@ func mainImpl() (err error) { return err } confPath, confStat, conventionalCommit, err := conf.GetConfPath( - confRoot, confName, fallbackConfName, msg, tag) + confFileRoot, confFileName, fallbackConfFileName, msg, tag) if err != nil { slog.Error("get conf path", "error", err) return err @@ -119,7 +110,7 @@ func mainImpl() (err error) { slog.Error("stage write", "error", err) return err } - teapotResult, err = teapot.Run(confObj, runID) + teapotResult, err = teapot.Run(confObj) if err != nil { slog.Error("teapot run", "error", err) return err diff --git a/cmd/joj3/teapot/run.go b/cmd/joj3/teapot/run.go index e449382..477f7ec 100644 --- a/cmd/joj3/teapot/run.go +++ b/cmd/joj3/teapot/run.go @@ -14,6 +14,7 @@ import ( "sync" "github.com/joint-online-judge/JOJ3/cmd/joj3/conf" + "github.com/joint-online-judge/JOJ3/cmd/joj3/env" ) type TeapotResult struct { @@ -22,20 +23,18 @@ type TeapotResult struct { 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("_TYPER_STANDARD_TRACEBACK", "1") - sha := os.Getenv("GITHUB_SHA") - actor := os.Getenv("GITHUB_ACTOR") - repository := os.Getenv("GITHUB_REPOSITORY") - runNumber := os.Getenv("GITHUB_RUN_NUMBER") - if actor == "" || repository == "" || strings.Count(repository, "/") != 1 || - runNumber == "" { + if env.Attr.Actor == "" || + env.Attr.Repository == "" || + strings.Count(env.Attr.Repository, "/") != 1 || + env.Attr.RunNumber == "" { slog.Error("teapot env not set") err = fmt.Errorf("teapot env not set") return } - repoParts := strings.Split(repository, "/") + repoParts := strings.Split(env.Attr.Repository, "/") repoName := repoParts[1] skipIssueArg := "--no-skip-result-issue" 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]`) 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, - conf.Name, sha, runID, + "joj3-all", conf.Teapot.EnvFilePath, conf.Stage.OutputPath, + env.Attr.Actor, conf.Teapot.GradingRepoName, repoName, + env.Attr.RunNumber, conf.Teapot.ScoreboardPath, + conf.Teapot.FailedTablePath, + conf.Name, env.Attr.Sha, env.Attr.RunID, "--max-total-score", strconv.Itoa(conf.Teapot.MaxTotalScore), skipIssueArg, skipScoreboardArg, skipFailedTableArg, submitterInIssueTitleArg,