feat(healthcheck): check actor csv for email
All checks were successful
submodules sync / sync (push) Successful in 41s
build / build (push) Successful in 2m36s
build / trigger-build-image (push) Successful in 11s

This commit is contained in:
张泊明518370910136 2025-07-01 22:05:06 -04:00
parent 3bd89e9aa5
commit e7b0a0f1fd
GPG Key ID: D47306D7062CDA9D
3 changed files with 62 additions and 10 deletions

View File

@ -46,6 +46,7 @@ var (
checkFileSumList string
metaFile []string
allowedDomainList string
actorCsvPath string
showVersion *bool
Version string
)
@ -57,6 +58,7 @@ func init() {
flag.StringVar(&checkFileNameList, "checkFileNameList", "", "comma-separated list of files to check")
flag.StringVar(&checkFileSumList, "checkFileSumList", "", "comma-separated list of expected checksums")
flag.StringVar(&allowedDomainList, "allowedDomainList", "sjtu.edu.cn", "comma-separated list of allowed domains for commit author email")
flag.StringVar(&actorCsvPath, "actorCsvPath", "/home/tt/.config/joj/students.csv", "path to actor csv file")
parseMultiValueFlag(&metaFile, "meta", "meta files to check")
}
@ -79,6 +81,7 @@ func main() {
checkFileNameList,
checkFileSumList,
allowedDomainList,
actorCsvPath,
metaFile,
repoSize,
)

View File

@ -12,7 +12,7 @@ type Result struct {
}
func All(
rootDir, checkFileNameList, checkFileSumList, allowedDomainList string,
rootDir, checkFileNameList, checkFileSumList, allowedDomainList, actorCsvPath string,
metaFile []string, repoSize float64,
) (res Result) {
var err error
@ -65,7 +65,7 @@ func All(
} else {
res.Msg += "### Repo File Check Passed\n"
}
err = AuthorEmailCheck(rootDir, strings.Split(allowedDomainList, ","))
err = AuthorEmailCheck(rootDir, strings.Split(allowedDomainList, ","), actorCsvPath)
if err != nil {
res.Msg += fmt.Sprintf("### Author Email Check Failed:\n%s\n", err.Error())
res.Failed = true

View File

@ -1,8 +1,11 @@
package healthcheck
import (
"encoding/csv"
"fmt"
"io"
"log/slog"
"os"
"strings"
"unicode"
@ -75,7 +78,7 @@ func NonASCIIMsg(root string) error {
return nil
}
func AuthorEmailCheck(root string, allowedDomains []string) error {
func AuthorEmailCheck(root string, allowedDomains []string, actorCsvPath string) error {
repo, err := git.PlainOpen(root)
if err != nil {
slog.Error("opening git repo", "err", err)
@ -94,13 +97,60 @@ func AuthorEmailCheck(root string, allowedDomains []string) error {
return fmt.Errorf("error getting latest commit: %v", err)
}
email := commit.Author.Email
for _, domain := range allowedDomains {
if strings.HasSuffix(email, "@"+domain) {
return nil
email := strings.ToLower(commit.Author.Email)
checkDomains := true
if _, err := os.Stat(actorCsvPath); err != nil {
slog.Error("checking actor CSV file stat", "err", err, "path", actorCsvPath)
} else {
f, err := os.Open(actorCsvPath)
if err != nil {
slog.Error("opening actor CSV file", "err", err, "path", actorCsvPath)
} else {
defer f.Close()
reader := csv.NewReader(f)
for {
row, err := reader.Read()
if err == io.EOF {
checkDomains = false
break
}
if err != nil {
slog.Error("reading actor CSV file", "err", err, "path", actorCsvPath)
break
}
if len(row) >= 3 {
actor := row[2]
for _, domain := range allowedDomains {
if email == actor+"@"+domain {
return nil
}
}
}
}
}
}
return fmt.Errorf("Author email %s is not in the allowed domains: `%s`\n\n"+
var msgPrefix string
if checkDomains {
for _, domain := range allowedDomains {
if strings.HasSuffix(email, "@"+domain) {
return nil
}
}
msgPrefix = fmt.Sprintf(
"Author email %s is not in the allowed domains: `%s`",
email,
strings.Join(allowedDomains, "`, `"),
)
} else {
msgPrefix = fmt.Sprintf(
"Author email %s is not stored in `%s`",
email,
actorCsvPath,
)
}
return fmt.Errorf("%s\n\n"+
"To fix it, please run the following commands:\n"+
"```bash\n"+
"git config user.email \"<your_email>\"\n"+
@ -108,7 +158,6 @@ func AuthorEmailCheck(root string, allowedDomains []string) error {
"git push --force\n"+
"```\n"+
"Replace `<your_email>` with your actual email address\n",
email,
strings.Join(allowedDomains, "`, `"),
msgPrefix,
)
}