Add commit URL to Slack notifications with link and backtick formatting
- Add commit_url column to webhook_events and deployments tables - Extract commit URL from webhook payload (from commit object or repo URL) - Format Slack messages with backticks for branch and commit SHA - Link commit SHA to the actual commit URL on the git server - Keep plain text format for ntfy notifications
This commit is contained in:
@@ -4,6 +4,7 @@ package notify
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -73,14 +74,24 @@ func (svc *Service) NotifyBuildStart(
|
||||
deployment *models.Deployment,
|
||||
) {
|
||||
title := "Build started: " + app.Name
|
||||
message := "Building from branch " + app.Branch
|
||||
|
||||
// Plain text message for ntfy
|
||||
ntfyMessage := "Building from branch " + app.Branch
|
||||
|
||||
if deployment.CommitSHA.Valid {
|
||||
shortSHA := deployment.CommitSHA.String[:minInt(shortCommitLength, len(deployment.CommitSHA.String))]
|
||||
message += " at " + shortSHA
|
||||
shortSHA := truncateSHA(deployment.CommitSHA.String)
|
||||
ntfyMessage += " at " + shortSHA
|
||||
}
|
||||
|
||||
svc.sendNotifications(ctx, app, title, message, "info")
|
||||
// Slack message with formatting
|
||||
slackMessage := "Building from branch `" + app.Branch + "`"
|
||||
|
||||
if deployment.CommitSHA.Valid {
|
||||
shortSHA := truncateSHA(deployment.CommitSHA.String)
|
||||
slackMessage += " at " + formatCommitLink(shortSHA, deployment.CommitURL)
|
||||
}
|
||||
|
||||
svc.sendNotifications(ctx, app, title, ntfyMessage, slackMessage, "info")
|
||||
}
|
||||
|
||||
// NotifyBuildSuccess sends a build success notification.
|
||||
@@ -93,7 +104,7 @@ func (svc *Service) NotifyBuildSuccess(
|
||||
title := "Build success: " + app.Name
|
||||
message := "Image built successfully in " + formatDuration(duration)
|
||||
|
||||
svc.sendNotifications(ctx, app, title, message, "success")
|
||||
svc.sendNotifications(ctx, app, title, message, message, "success")
|
||||
}
|
||||
|
||||
// NotifyBuildFailed sends a build failed notification.
|
||||
@@ -107,7 +118,7 @@ func (svc *Service) NotifyBuildFailed(
|
||||
title := "Build failed: " + app.Name
|
||||
message := "Build failed after " + formatDuration(duration) + ": " + buildErr.Error()
|
||||
|
||||
svc.sendNotifications(ctx, app, title, message, "error")
|
||||
svc.sendNotifications(ctx, app, title, message, message, "error")
|
||||
}
|
||||
|
||||
// NotifyDeploySuccess sends a deploy success notification.
|
||||
@@ -118,14 +129,24 @@ func (svc *Service) NotifyDeploySuccess(
|
||||
) {
|
||||
duration := time.Since(deployment.StartedAt)
|
||||
title := "Deploy success: " + app.Name
|
||||
message := "Successfully deployed in " + formatDuration(duration)
|
||||
|
||||
// Plain text message for ntfy
|
||||
ntfyMessage := "Successfully deployed in " + formatDuration(duration)
|
||||
|
||||
if deployment.CommitSHA.Valid {
|
||||
shortSHA := deployment.CommitSHA.String[:minInt(shortCommitLength, len(deployment.CommitSHA.String))]
|
||||
message += " (commit " + shortSHA + ")"
|
||||
shortSHA := truncateSHA(deployment.CommitSHA.String)
|
||||
ntfyMessage += " (commit " + shortSHA + ")"
|
||||
}
|
||||
|
||||
svc.sendNotifications(ctx, app, title, message, "success")
|
||||
// Slack message with formatting
|
||||
slackMessage := "Successfully deployed in " + formatDuration(duration)
|
||||
|
||||
if deployment.CommitSHA.Valid {
|
||||
shortSHA := truncateSHA(deployment.CommitSHA.String)
|
||||
slackMessage += " (commit " + formatCommitLink(shortSHA, deployment.CommitURL) + ")"
|
||||
}
|
||||
|
||||
svc.sendNotifications(ctx, app, title, ntfyMessage, slackMessage, "success")
|
||||
}
|
||||
|
||||
// NotifyDeployFailed sends a deploy failed notification.
|
||||
@@ -139,7 +160,7 @@ func (svc *Service) NotifyDeployFailed(
|
||||
title := "Deploy failed: " + app.Name
|
||||
message := "Deployment failed after " + formatDuration(duration) + ": " + deployErr.Error()
|
||||
|
||||
svc.sendNotifications(ctx, app, title, message, "error")
|
||||
svc.sendNotifications(ctx, app, title, message, message, "error")
|
||||
}
|
||||
|
||||
// formatDuration formats a duration for display.
|
||||
@@ -154,19 +175,28 @@ func formatDuration(d time.Duration) string {
|
||||
return fmt.Sprintf("%dm %ds", minutes, seconds)
|
||||
}
|
||||
|
||||
// minInt returns the smaller of two integers.
|
||||
func minInt(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
// truncateSHA truncates a commit SHA to shortCommitLength characters.
|
||||
func truncateSHA(sha string) string {
|
||||
if len(sha) > shortCommitLength {
|
||||
return sha[:shortCommitLength]
|
||||
}
|
||||
|
||||
return b
|
||||
return sha
|
||||
}
|
||||
|
||||
// formatCommitLink formats a commit SHA as a Slack link if URL is available.
|
||||
func formatCommitLink(shortSHA string, commitURL sql.NullString) string {
|
||||
if commitURL.Valid && commitURL.String != "" {
|
||||
return "<" + commitURL.String + "|`" + shortSHA + "`>"
|
||||
}
|
||||
|
||||
return "`" + shortSHA + "`"
|
||||
}
|
||||
|
||||
func (svc *Service) sendNotifications(
|
||||
ctx context.Context,
|
||||
app *models.App,
|
||||
title, message, priority string,
|
||||
title, ntfyMessage, slackMessage, priority string,
|
||||
) {
|
||||
// Send to ntfy if configured
|
||||
if app.NtfyTopic.Valid && app.NtfyTopic.String != "" {
|
||||
@@ -178,7 +208,7 @@ func (svc *Service) sendNotifications(
|
||||
// even if the parent context is cancelled.
|
||||
notifyCtx := context.WithoutCancel(ctx)
|
||||
|
||||
ntfyErr := svc.sendNtfy(notifyCtx, ntfyTopic, title, message, priority)
|
||||
ntfyErr := svc.sendNtfy(notifyCtx, ntfyTopic, title, ntfyMessage, priority)
|
||||
if ntfyErr != nil {
|
||||
svc.log.Error(
|
||||
"failed to send ntfy notification",
|
||||
@@ -199,7 +229,7 @@ func (svc *Service) sendNotifications(
|
||||
// even if the parent context is cancelled.
|
||||
notifyCtx := context.WithoutCancel(ctx)
|
||||
|
||||
slackErr := svc.sendSlack(notifyCtx, slackWebhook, title, message, priority)
|
||||
slackErr := svc.sendSlack(notifyCtx, slackWebhook, title, slackMessage, priority)
|
||||
if slackErr != nil {
|
||||
svc.log.Error(
|
||||
"failed to send slack notification",
|
||||
|
||||
Reference in New Issue
Block a user