github.com/mistwind/reviewdog@v0.0.0-20230322024206-9cfa11856d58/service/github/githubutils/comment_writer.go (about) 1 package githubutils 2 3 import ( 4 "context" 5 "fmt" 6 "sync" 7 8 "github.com/haya14busa/go-actions-toolkit/core" 9 10 "github.com/mistwind/reviewdog" 11 "github.com/mistwind/reviewdog/proto/rdf" 12 ) 13 14 const MaxLoggingAnnotationsPerStep = 10 15 16 var _ reviewdog.CommentService = &GitHubActionLogWriter{} 17 18 // GitHubActionLogWriter reports results via logging command to create 19 // annotations. 20 // https://help.github.com/en/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions#example-5 21 type GitHubActionLogWriter struct { 22 level string 23 reportNum int 24 } 25 26 // NewGitHubActionLogWriter returns new GitHubActionLogWriter. 27 func NewGitHubActionLogWriter(level string) *GitHubActionLogWriter { 28 return &GitHubActionLogWriter{level: level} 29 } 30 31 func (lw *GitHubActionLogWriter) Post(_ context.Context, c *reviewdog.Comment) error { 32 lw.reportNum++ 33 if lw.reportNum == MaxLoggingAnnotationsPerStep { 34 WarnTooManyAnnotationOnce() 35 } 36 ReportAsGitHubActionsLog(c.ToolName, lw.level, c.Result.Diagnostic) 37 return nil 38 } 39 40 // Flush checks overall error at last. 41 func (lw *GitHubActionLogWriter) Flush(_ context.Context) error { 42 if lw.reportNum > 9 { 43 return fmt.Errorf("GitHubActionLogWriter: reported too many annotation (N=%d)", lw.reportNum) 44 } 45 return nil 46 } 47 48 // ReportAsGitHubActionsLog reports results via logging command to create 49 // annotations. 50 // https://help.github.com/en/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions#example-5 51 func ReportAsGitHubActionsLog(toolName, defaultLevel string, d *rdf.Diagnostic) { 52 mes := fmt.Sprintf("[%s] reported by reviewdog 🐶\n%s\n\nRaw Output:\n%s", 53 toolName, d.GetMessage(), d.GetOriginalOutput()) 54 loc := d.GetLocation() 55 start := loc.GetRange().GetStart() 56 opt := &core.LogOption{ 57 File: d.GetLocation().GetPath(), 58 Line: int(start.GetLine()), 59 Col: int(start.GetColumn()), 60 } 61 62 level := defaultLevel 63 switch d.Severity { 64 case rdf.Severity_ERROR: 65 level = "error" 66 case rdf.Severity_INFO, rdf.Severity_WARNING: 67 level = "warning" 68 } 69 70 switch level { 71 // no info command with location data. 72 case "warning", "info": 73 core.Warning(mes, opt) 74 case "error", "": 75 core.Error(mes, opt) 76 default: 77 core.Error(fmt.Sprintf("Unknown level: %s", level), nil) 78 core.Error(mes, opt) 79 } 80 } 81 82 func WarnTooManyAnnotationOnce() { 83 warnTooManyAnnotationOnce.Do(warnTooManyAnnotation) 84 } 85 86 var warnTooManyAnnotationOnce sync.Once 87 88 func warnTooManyAnnotation() { 89 core.Error(`reviewdog: Too many results (annotations) in diff. 90 You may miss some annotations due to GitHub limitation for annotation created by logging command. 91 Please check GitHub Actions log console to see all results. 92 93 Limitation: 94 - 10 warning annotations and 10 error annotations per step 95 - 50 annotations per job (sum of annotations from all the steps) 96 - 50 annotations per run (separate from the job annotations, these annotations aren't created by users) 97 98 Source: https://github.community/t5/GitHub-Actions/Maximum-number-of-annotations-that-can-be-created-using-GitHub/m-p/39085`, nil) 99 }