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
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Setup golangci-lint
|
- name: Setup golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v6
|
uses: golangci/golangci-lint-action@v7
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: v2.0
|
||||||
args: --verbose
|
args: --verbose
|
||||||
|
|
||||||
- uses: hadolint/hadolint-action@v3.1.0
|
- uses: hadolint/hadolint-action@v3.1.0
|
||||||
|
|||||||
+40
-27
@@ -1,14 +1,9 @@
|
|||||||
run:
|
version: "2"
|
||||||
timeout: 5m
|
|
||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
- asciicheck
|
- asciicheck
|
||||||
- durationcheck
|
- durationcheck
|
||||||
- errcheck
|
|
||||||
- errorlint
|
- errorlint
|
||||||
- gci
|
|
||||||
- gofmt
|
|
||||||
- goimports
|
|
||||||
- gosec
|
- gosec
|
||||||
- misspell
|
- misspell
|
||||||
- nakedret
|
- nakedret
|
||||||
@@ -18,24 +13,42 @@ linters:
|
|||||||
- revive
|
- revive
|
||||||
- usestdlibvars
|
- usestdlibvars
|
||||||
- wastedassign
|
- wastedassign
|
||||||
|
settings:
|
||||||
linters-settings:
|
gosec:
|
||||||
gosec:
|
includes:
|
||||||
# To select a subset of rules to run.
|
- G102
|
||||||
# Available rules: https://github.com/securego/gosec#available-rules
|
- G106
|
||||||
# Default: [] - means include all rules
|
- G108
|
||||||
includes:
|
- G109
|
||||||
- G102
|
- G111
|
||||||
- G106
|
- G112
|
||||||
- G108
|
- G201
|
||||||
- G109
|
- G203
|
||||||
- G111
|
perfsprint:
|
||||||
- G112
|
int-conversion: true
|
||||||
- G201
|
err-error: true
|
||||||
- G203
|
errorf: true
|
||||||
perfsprint:
|
sprintf1: true
|
||||||
err-error: true
|
strconcat: true
|
||||||
errorf: true
|
exclusions:
|
||||||
int-conversion: true
|
generated: lax
|
||||||
sprintf1: true
|
presets:
|
||||||
strconcat: true
|
- 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:
|
extra_files:
|
||||||
- glob: ./**.xz
|
- glob: ./**.xz
|
||||||
|
|
||||||
|
name_template: "Drone Discord {{.Version}}"
|
||||||
|
|
||||||
changelog:
|
changelog:
|
||||||
use: github
|
use: github
|
||||||
groups:
|
groups:
|
||||||
|
|||||||
@@ -197,3 +197,31 @@ urlencode
|
|||||||
|
|
||||||
since
|
since
|
||||||
: returns a duration string between now and the given timestamp. Example `{{since build.started}}`
|
: 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
|
EXECUTABLE := drone-discord
|
||||||
GOFMT ?= gofumpt -l -s -w
|
GOFMT ?= gofumpt -l -w
|
||||||
GO ?= go
|
GO ?= go
|
||||||
GOFILES := $(shell find . -name "*.go" -type f)
|
GOFILES := $(shell find . -name "*.go" -type f)
|
||||||
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||||
@@ -43,7 +42,7 @@ all: build
|
|||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
@hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) install mvdan.cc/gofumpt; \
|
$(GO) install mvdan.cc/gofumpt@latest; \
|
||||||
fi
|
fi
|
||||||
$(GOFMT) -w $(GOFILES)
|
$(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
|
// Creates a new file upload http request with optional extra params
|
||||||
// https://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/
|
// 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) {
|
func fileUploadRequest(ctx context.Context, uri string, params map[string]string, paramName, path string) (*http.Request, error) {
|
||||||
file, err := os.Open(path)
|
// Clean and check path
|
||||||
if err != nil {
|
path = filepath.Clean(path)
|
||||||
return nil, fmt.Errorf("failed to open file: %w", err)
|
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{}
|
body := &bytes.Buffer{}
|
||||||
writer := multipart.NewWriter(body)
|
writer := multipart.NewWriter(body)
|
||||||
|
|
||||||
|
// Add file
|
||||||
part, err := writer.CreateFormFile(paramName, filepath.Base(path))
|
part, err := writer.CreateFormFile(paramName, filepath.Base(path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create form file: %w", err)
|
return nil, fmt.Errorf("failed to create form file: %w", err)
|
||||||
}
|
}
|
||||||
if _, err = io.Copy(part, file); err != nil {
|
if _, err = part.Write(content); err != nil {
|
||||||
return nil, fmt.Errorf("failed to copy file content: %w", err)
|
return nil, fmt.Errorf("failed to write file content: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add extra params
|
||||||
for key, val := range params {
|
for key, val := range params {
|
||||||
if err = writer.WriteField(key, val); err != nil {
|
if err = writer.WriteField(key, val); err != nil {
|
||||||
return nil, fmt.Errorf("failed to write field %s: %w", key, err)
|
return nil, fmt.Errorf("failed to write field %s: %w", key, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = writer.Close(); err != nil {
|
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)
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, body)
|
||||||
if err != nil {
|
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())
|
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||||
|
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,22 +416,25 @@ func (p *Plugin) Clear() {
|
|||||||
|
|
||||||
// Color code of the embed
|
// Color code of the embed
|
||||||
func (p *Plugin) Color() int {
|
func (p *Plugin) Color() int {
|
||||||
|
// Handle custom color
|
||||||
if p.Config.Color != "" {
|
if p.Config.Color != "" {
|
||||||
p.Config.Color = strings.Replace(p.Config.Color, "#", "", -1)
|
cleanColor := strings.TrimPrefix(p.Config.Color, "#")
|
||||||
if s, err := strconv.ParseInt(p.Config.Color, 16, 32); err == nil {
|
if s, err := strconv.ParseInt(cleanColor, 16, 32); err == nil {
|
||||||
return int(s)
|
return int(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.Build.Status {
|
// Predefined status colors
|
||||||
case "success":
|
statusColors := map[string]int{
|
||||||
// green
|
"success": 0x1ac600, // green
|
||||||
return 0x1ac600
|
"failure": 0xff3232, // red
|
||||||
case "failure", "error", "killed":
|
"error": 0xff3232, // red
|
||||||
// red
|
"killed": 0xff3232, // red
|
||||||
return 0xff3232
|
"default": 0xffd930, // yellow
|
||||||
default:
|
|
||||||
// yellow
|
|
||||||
return 0xffd930
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if color, exists := statusColors[p.Build.Status]; exists {
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
return statusColors["default"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user