Exit non-zero when any errors are logged during bootstrap run

Track error count in issues.go alongside the existing issues slice.
Add hasErrors() helper. In main.go, call osExit(1) after writeRunLog()
if any [ERROR] entries were recorded, so CI steps correctly fail when
errors occur (e.g. GitHub API 403 rate-limit hits in the macOS job).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-26 13:35:05 -05:00
co-authored by Copilot
parent 4d99bba06f
commit 9093aedb66
4 changed files with 44 additions and 3 deletions
+1
View File
@@ -38,5 +38,6 @@ func resetMocks() {
issuesMu.Lock()
issues = nil
notices = nil
errorCount = 0
issuesMu.Unlock()
}
+13 -3
View File
@@ -13,9 +13,10 @@ import (
// when there's something to report.
var (
issuesMu sync.Mutex
issues []string
notices []string
issuesMu sync.Mutex
issues []string
notices []string
errorCount int
)
func logIssue(level, msg string) {
@@ -23,11 +24,20 @@ func logIssue(level, msg string) {
defer issuesMu.Unlock()
fmt.Printf(" [%s] %s\n", level, msg)
issues = append(issues, fmt.Sprintf("[%s] %s", level, msg))
if level == "ERROR" {
errorCount++
}
}
func warn(msg string) { logIssue("WARN", msg) }
func errLog(msg string) { logIssue("ERROR", msg) }
func hasErrors() bool {
issuesMu.Lock()
defer issuesMu.Unlock()
return errorCount > 0
}
func notice(msg string) {
issuesMu.Lock()
defer issuesMu.Unlock()
+25
View File
@@ -38,6 +38,7 @@ func TestIssuesLogging(t *testing.T) {
issuesMu.Lock()
issueLen := len(issues)
noticeLen := len(notices)
errCount := errorCount
issuesMu.Unlock()
if issueLen != 2 {
@@ -46,6 +47,12 @@ func TestIssuesLogging(t *testing.T) {
if noticeLen != 1 {
t.Errorf("expected 1 notice, got %d", noticeLen)
}
if errCount != 1 {
t.Errorf("expected 1 error count, got %d", errCount)
}
if !hasErrors() {
t.Error("expected hasErrors() to return true after errLog call")
}
}
func TestWriteRunLog(t *testing.T) {
@@ -83,6 +90,24 @@ func TestWriteRunLog(t *testing.T) {
}
}
func TestHasErrors(t *testing.T) {
defer resetMocks()
if hasErrors() {
t.Error("expected hasErrors() false with no errors logged")
}
warn("just a warning")
if hasErrors() {
t.Error("expected hasErrors() false after only a warning")
}
errLog("a real error")
if !hasErrors() {
t.Error("expected hasErrors() true after errLog call")
}
}
func TestPrintNotices(t *testing.T) {
defer resetMocks()
+5
View File
@@ -169,6 +169,11 @@ func runMain(args []string) {
printNotices()
fmt.Println("\nDone.")
if hasErrors() {
osExit(1)
return
}
home, _ := os.UserHomeDir()
zshrc := filepath.Join(home, ".zshrc")
if hasCmd("zsh") {