fix(report): footer advertises log attachment only when actually attached
All checks were successful
release / build-and-release (push) Successful in 35s
All checks were successful
release / build-and-release (push) Successful in 35s
buildHTML ran before zipLog, so the email footer always claimed "log v priloze (<host>-Deploy.log.zip)" even when the log was unreadable and no attachment was added. Zip the log first and pass the attachment name into buildHTML; footer now names the zip only when present, otherwise points solely to the local copy. Covered by TestBuildHTMLFooterMatchesAttachment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
eabf207e3f
commit
ef56410139
2 changed files with 37 additions and 10 deletions
|
|
@ -56,7 +56,11 @@ func Send(results []StepResult, issueURL, logPath string) error {
|
|||
now := time.Now().Format("2006-01-02 15:04")
|
||||
|
||||
subject := fmt.Sprintf("xetup report %s", hostname)
|
||||
body := buildHTML(results, hostname, now, issueURL)
|
||||
|
||||
// Zip the log first (best-effort; nil attachment => plain email) so the
|
||||
// body's footer can state accurately whether the log is actually attached.
|
||||
attachName, attachData := zipLog(logPath, hostname)
|
||||
body := buildHTML(results, hostname, now, issueURL, attachName)
|
||||
|
||||
// Always save local copy so technician has a record even if SMTP fails
|
||||
_ = os.MkdirAll(filepath.Dir(localReportPath), 0755)
|
||||
|
|
@ -64,9 +68,6 @@ func Send(results []StepResult, issueURL, logPath string) error {
|
|||
fmt.Fprintf(os.Stderr, "[WARN] Failed to save local report: %v\n", err)
|
||||
}
|
||||
|
||||
// Zip the log for attachment (best-effort; nil attachment => plain email)
|
||||
attachName, attachData := zipLog(logPath, hostname)
|
||||
|
||||
// Retry SMTP up to 3 times with exponential backoff (1s, 5s, 15s)
|
||||
delays := []time.Duration{0, 1 * time.Second, 5 * time.Second}
|
||||
var lastErr error
|
||||
|
|
@ -168,7 +169,7 @@ func writeBase64(w *bytes.Buffer, data []byte) {
|
|||
w.WriteString("\r\n")
|
||||
}
|
||||
|
||||
func buildHTML(results []StepResult, hostname, dateTime, issueURL string) string {
|
||||
func buildHTML(results []StepResult, hostname, dateTime, issueURL, attachName string) string {
|
||||
var ok, errs, skipped int
|
||||
var rows strings.Builder
|
||||
|
||||
|
|
@ -235,14 +236,25 @@ func buildHTML(results []StepResult, hostname, dateTime, issueURL string) string
|
|||
%s
|
||||
</div>
|
||||
<p style="text-align:center;color:#999;font-size:12px;margin-top:16px">
|
||||
Odeslano z xetup.exe — log v priloze (%s-Deploy.log.zip) i lokalne: C:\Windows\Setup\Scripts\Deploy.log
|
||||
%s
|
||||
</p>
|
||||
</body></html>`,
|
||||
hostname, dateTime,
|
||||
rows.String(),
|
||||
summaryColor, summaryText, ok, errs, skipped,
|
||||
trackerLinks(hostname, issueURL),
|
||||
hostname)
|
||||
logFooter(attachName))
|
||||
}
|
||||
|
||||
// logFooter names the zipped log in the footer only when it is actually
|
||||
// attached; otherwise it points solely to the local copy on the machine.
|
||||
func logFooter(attachName string) string {
|
||||
if attachName != "" {
|
||||
return fmt.Sprintf("Odeslano z xetup.exe — log v priloze (%s) i lokalne: "+
|
||||
`C:\Windows\Setup\Scripts\Deploy.log`, attachName)
|
||||
}
|
||||
return "Odeslano z xetup.exe — log lokalne: " +
|
||||
`C:\Windows\Setup\Scripts\Deploy.log`
|
||||
}
|
||||
|
||||
// trackerLinks renders the tracker links block: a direct link to this run's
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ func writeLog(t *testing.T, content []byte) string {
|
|||
// buildHTML must embed the direct issue link and the per-machine tracker filter.
|
||||
func TestBuildHTMLLinks(t *testing.T) {
|
||||
issueURL := "https://git.xetup.x9.cz/x9/xetup-runs/issues/42"
|
||||
html := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", issueURL)
|
||||
html := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", issueURL, "PC-TEST-Deploy.log.zip")
|
||||
|
||||
if !strings.Contains(html, issueURL) {
|
||||
t.Errorf("html does not link the run issue %q", issueURL)
|
||||
|
|
@ -45,7 +45,7 @@ func TestBuildHTMLLinks(t *testing.T) {
|
|||
|
||||
// With no issue (clean run / post failed), only the tracker link is shown.
|
||||
func TestBuildHTMLNoIssue(t *testing.T) {
|
||||
html := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", "")
|
||||
html := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", "", "PC-TEST-Deploy.log.zip")
|
||||
if strings.Contains(html, "Chyby tohoto behu") {
|
||||
t.Error("issue-specific line shown when issueURL is empty")
|
||||
}
|
||||
|
|
@ -54,6 +54,21 @@ func TestBuildHTMLNoIssue(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// The footer must only advertise the attachment when one is actually present.
|
||||
func TestBuildHTMLFooterMatchesAttachment(t *testing.T) {
|
||||
with := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", "", "PC-TEST-Deploy.log.zip")
|
||||
if !strings.Contains(with, "v priloze (PC-TEST-Deploy.log.zip)") {
|
||||
t.Error("footer should name the attachment when one is present")
|
||||
}
|
||||
without := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", "", "")
|
||||
if strings.Contains(without, "v priloze") {
|
||||
t.Errorf("footer claims an attachment when none is attached:\n%s", without)
|
||||
}
|
||||
if !strings.Contains(without, "log lokalne") {
|
||||
t.Error("footer should still point to the local log copy")
|
||||
}
|
||||
}
|
||||
|
||||
// zipLog must produce a valid zip whose Deploy.log entry round-trips.
|
||||
func TestZipLogRoundTrip(t *testing.T) {
|
||||
content := []byte("line one\nERROR something failed\nline three\n")
|
||||
|
|
@ -90,7 +105,7 @@ func TestZipLogMissing(t *testing.T) {
|
|||
func TestBuildMessageMultipart(t *testing.T) {
|
||||
logContent := []byte("deploy log body\nERROR boom\n")
|
||||
_, zipData := zipLog(writeLog(t, logContent), "PC-TEST")
|
||||
html := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", "https://x/issues/1")
|
||||
html := buildHTML(sampleResults, "PC-TEST", "2026-07-28 10:00", "https://x/issues/1", "PC-TEST-Deploy.log.zip")
|
||||
|
||||
raw := buildMessage("xetup report PC-TEST", html, "PC-TEST-Deploy.log.zip", zipData)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue