github.com/smartcontractkit/chainlink-testing-framework/libs@v0.0.0-20240227141906-ec710b4eb1a3/testreporters/slack_notification.go (about) 1 // Package testreporters holds all the tools necessary to report on tests that are run utilizing the testsetups package 2 package testreporters 3 4 import ( 5 "errors" 6 "fmt" 7 "os" 8 9 "github.com/rs/zerolog/log" 10 "github.com/slack-go/slack" 11 12 "github.com/smartcontractkit/chainlink-testing-framework/libs/k8s/config" 13 ) 14 15 // Common Slack Notification Helpers 16 17 // Values for reporters to use slack to notify user of test end 18 var ( 19 SlackAPIKey = os.Getenv(config.EnvVarSlackKey) 20 SlackChannel = os.Getenv(config.EnvVarSlackChannel) 21 SlackUserID = os.Getenv(config.EnvVarSlackUser) 22 ) 23 24 // Uploads a slack file to the designated channel using the API key 25 func UploadSlackFile(slackClient *slack.Client, uploadParams slack.FileUploadParameters) error { 26 log.Info(). 27 Str("Slack API Key", SlackAPIKey). 28 Str("Slack Channel", SlackChannel). 29 Str("User Id to Notify", SlackUserID). 30 Str("File", uploadParams.File). 31 Msg("Attempting to upload file") 32 if SlackAPIKey == "" { 33 return fmt.Errorf("unable to upload file without a Slack API Key") 34 } 35 if SlackChannel == "" { 36 return fmt.Errorf("unable to upload file without a Slack Channel") 37 } 38 if uploadParams.Channels == nil || uploadParams.Channels[0] == "" { 39 uploadParams.Channels = []string{SlackChannel} 40 } 41 if uploadParams.File != "" { 42 if _, err := os.Stat(uploadParams.File); errors.Is(err, os.ErrNotExist) { 43 return fmt.Errorf("unable to upload file as it does not exist: %w", err) 44 } else if err != nil { 45 return err 46 } 47 } 48 _, err := slackClient.UploadFile(uploadParams) 49 return err 50 } 51 52 // Sends a slack message, and returns an error and the message timestamp 53 func SendSlackMessage(slackClient *slack.Client, msgOptions ...slack.MsgOption) (string, error) { 54 log.Info(). 55 Str("Slack API Key", SlackAPIKey). 56 Str("Slack Channel", SlackChannel). 57 Msg("Attempting to send message") 58 if SlackAPIKey == "" { 59 return "", fmt.Errorf("unable to send message without a Slack API Key") 60 } 61 if SlackChannel == "" { 62 return "", fmt.Errorf("unable to send message without a Slack Channel") 63 } 64 msgOptions = append(msgOptions, slack.MsgOptionAsUser(true)) 65 _, timeStamp, err := slackClient.PostMessage(SlackChannel, msgOptions...) 66 return timeStamp, err 67 } 68 69 // creates a directory if it doesn't already exist 70 func MkdirIfNotExists(dirName string) error { 71 if _, err := os.Stat(dirName); os.IsNotExist(err) { 72 if err = os.MkdirAll(dirName, os.ModePerm); err != nil { 73 return fmt.Errorf("failed to create directory: %s err: %w", dirName, err) 74 } 75 } 76 return nil 77 } 78 79 func CommonSlackNotificationBlocks( 80 headerText, namespace, 81 reportCsvLocation string, 82 ) []slack.Block { 83 return SlackNotifyBlocks(headerText, namespace, []string{ 84 fmt.Sprintf("Summary CSV created on _remote-test-runner_ at _%s_\nNotifying <@%s>", 85 reportCsvLocation, SlackUserID)}) 86 } 87 88 // SlackNotifyBlocks creates a slack payload and writes into the specified json 89 func SlackNotifyBlocks(headerText, namespace string, msgtext []string) []slack.Block { 90 var notificationBlocks slack.Blocks 91 notificationBlocks.BlockSet = append(notificationBlocks.BlockSet, 92 slack.NewHeaderBlock(slack.NewTextBlockObject("plain_text", headerText, true, false))) 93 notificationBlocks.BlockSet = append(notificationBlocks.BlockSet, 94 slack.NewContextBlock("context_block", slack.NewTextBlockObject("plain_text", namespace, false, false))) 95 notificationBlocks.BlockSet = append(notificationBlocks.BlockSet, slack.NewDividerBlock()) 96 msgtexts := "" 97 for _, text := range msgtext { 98 msgtexts = fmt.Sprintf("%s%s\n", msgtexts, text) 99 } 100 notificationBlocks.BlockSet = append(notificationBlocks.BlockSet, slack.NewSectionBlock(slack.NewTextBlockObject("mrkdwn", 101 msgtexts, false, true), nil, nil)) 102 return notificationBlocks.BlockSet 103 }