mirror of
https://github.com/appleboy/drone-discord.git
synced 2026-06-13 18:51:38 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bce2f5f991 | |||
| 30fbdbe54d | |||
| 9f96bb575e | |||
| 1b1fb67645 | |||
| b2b10008a5 | |||
| b291372e68 | |||
| 691536f46b |
@@ -15,9 +15,9 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
uses: golangci/golangci-lint-action@v7
|
||||
with:
|
||||
version: latest
|
||||
version: v2.0
|
||||
args: --verbose
|
||||
|
||||
- uses: hadolint/hadolint-action@v3.1.0
|
||||
|
||||
+40
-27
@@ -1,14 +1,9 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
version: "2"
|
||||
linters:
|
||||
enable:
|
||||
- asciicheck
|
||||
- durationcheck
|
||||
- errcheck
|
||||
- errorlint
|
||||
- gci
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosec
|
||||
- misspell
|
||||
- nakedret
|
||||
@@ -18,24 +13,42 @@ linters:
|
||||
- revive
|
||||
- usestdlibvars
|
||||
- wastedassign
|
||||
|
||||
linters-settings:
|
||||
gosec:
|
||||
# To select a subset of rules to run.
|
||||
# Available rules: https://github.com/securego/gosec#available-rules
|
||||
# Default: [] - means include all rules
|
||||
includes:
|
||||
- G102
|
||||
- G106
|
||||
- G108
|
||||
- G109
|
||||
- G111
|
||||
- G112
|
||||
- G201
|
||||
- G203
|
||||
perfsprint:
|
||||
err-error: true
|
||||
errorf: true
|
||||
int-conversion: true
|
||||
sprintf1: true
|
||||
strconcat: true
|
||||
settings:
|
||||
gosec:
|
||||
includes:
|
||||
- G102
|
||||
- G106
|
||||
- G108
|
||||
- G109
|
||||
- G111
|
||||
- G112
|
||||
- G201
|
||||
- G203
|
||||
perfsprint:
|
||||
int-conversion: true
|
||||
err-error: true
|
||||
errorf: true
|
||||
sprintf1: true
|
||||
strconcat: true
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
|
||||
@@ -98,6 +98,8 @@ release:
|
||||
extra_files:
|
||||
- glob: ./**.xz
|
||||
|
||||
name_template: "Drone Discord {{.Version}}"
|
||||
|
||||
changelog:
|
||||
use: github
|
||||
groups:
|
||||
|
||||
@@ -197,3 +197,31 @@ urlencode
|
||||
|
||||
since
|
||||
: returns a duration string between now and the given timestamp. Example `{{since build.started}}`
|
||||
|
||||
## Note for Woodpecker 3.x Users
|
||||
|
||||
Starting with Woodpecker 3.x, the `build.status` variable is always set to `success`, which means message templates cannot correctly distinguish between success and failure. It is recommended to use the `when.status` condition to split notifications for success and failure, as shown below:
|
||||
|
||||
```yaml
|
||||
- name: discord success notification
|
||||
when:
|
||||
status: [ success ]
|
||||
image: appleboy/drone-discord
|
||||
settings:
|
||||
webhook_id: xxxxxxxxxx
|
||||
webhook_token: xxxxxxxxxx
|
||||
message: >
|
||||
build {{build.number}} succeeded. Good job.
|
||||
|
||||
- name: discord failure notification
|
||||
when:
|
||||
status: [ failure ]
|
||||
image: appleboy/drone-discord
|
||||
settings:
|
||||
webhook_id: xxxxxxxxxx
|
||||
webhook_token: xxxxxxxxxx
|
||||
message: >
|
||||
build {{build.number}} failed. Fix me please.
|
||||
```
|
||||
|
||||
This is due to a change in Woodpecker CI behavior and cannot be fixed on the plugin side. Please use the above workaround for correct notifications.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
DIST := dist
|
||||
EXECUTABLE := drone-discord
|
||||
GOFMT ?= gofumpt -l -s -w
|
||||
GOFMT ?= gofumpt -l -w
|
||||
GO ?= go
|
||||
GOFILES := $(shell find . -name "*.go" -type f)
|
||||
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||
@@ -43,7 +42,7 @@ all: build
|
||||
|
||||
fmt:
|
||||
@hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) install mvdan.cc/gofumpt; \
|
||||
$(GO) install mvdan.cc/gofumpt@latest; \
|
||||
fi
|
||||
$(GOFMT) -w $(GOFILES)
|
||||
|
||||
|
||||
@@ -176,35 +176,49 @@ func templateMessage(t string, plugin Plugin) (string, error) {
|
||||
// Creates a new file upload http request with optional extra params
|
||||
// https://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/
|
||||
func fileUploadRequest(ctx context.Context, uri string, params map[string]string, paramName, path string) (*http.Request, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file: %w", err)
|
||||
// Clean and check path
|
||||
path = filepath.Clean(path)
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
return nil, fmt.Errorf("file %s not accessible: %w", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Read file content
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read file %s: %w", path, err)
|
||||
}
|
||||
|
||||
// Create multipart form
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
// Add file
|
||||
part, err := writer.CreateFormFile(paramName, filepath.Base(path))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create form file: %w", err)
|
||||
}
|
||||
if _, err = io.Copy(part, file); err != nil {
|
||||
return nil, fmt.Errorf("failed to copy file content: %w", err)
|
||||
if _, err = part.Write(content); err != nil {
|
||||
return nil, fmt.Errorf("failed to write file content: %w", err)
|
||||
}
|
||||
|
||||
// Add extra params
|
||||
for key, val := range params {
|
||||
if err = writer.WriteField(key, val); err != nil {
|
||||
return nil, fmt.Errorf("failed to write field %s: %w", key, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = writer.Close(); err != nil {
|
||||
return nil, fmt.Errorf("failed to close writer: %w", err)
|
||||
return nil, fmt.Errorf("failed to close multipart writer: %w", err)
|
||||
}
|
||||
|
||||
// Create request
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new request: %w", err)
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
@@ -402,22 +416,25 @@ func (p *Plugin) Clear() {
|
||||
|
||||
// Color code of the embed
|
||||
func (p *Plugin) Color() int {
|
||||
// Handle custom color
|
||||
if p.Config.Color != "" {
|
||||
p.Config.Color = strings.Replace(p.Config.Color, "#", "", -1)
|
||||
if s, err := strconv.ParseInt(p.Config.Color, 16, 32); err == nil {
|
||||
cleanColor := strings.TrimPrefix(p.Config.Color, "#")
|
||||
if s, err := strconv.ParseInt(cleanColor, 16, 32); err == nil {
|
||||
return int(s)
|
||||
}
|
||||
}
|
||||
|
||||
switch p.Build.Status {
|
||||
case "success":
|
||||
// green
|
||||
return 0x1ac600
|
||||
case "failure", "error", "killed":
|
||||
// red
|
||||
return 0xff3232
|
||||
default:
|
||||
// yellow
|
||||
return 0xffd930
|
||||
// Predefined status colors
|
||||
statusColors := map[string]int{
|
||||
"success": 0x1ac600, // green
|
||||
"failure": 0xff3232, // red
|
||||
"error": 0xff3232, // red
|
||||
"killed": 0xff3232, // red
|
||||
"default": 0xffd930, // yellow
|
||||
}
|
||||
|
||||
if color, exists := statusColors[p.Build.Status]; exists {
|
||||
return color
|
||||
}
|
||||
return statusColors["default"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user