Compare commits

..

86 Commits

Author SHA1 Message Date
Bo-Yi Wu 6a809efc79 ci(actions): bump codecov-action from v6 to v7
- Update codecov/codecov-action from v6 to v7
2026-06-13 15:46:29 +08:00
Bo-Yi Wu 2f461525af chore: bump go directive to 1.25.10
- Update go.mod go directive from 1.25.9 to 1.25.10
2026-05-08 21:19:20 +08:00
Bo-Yi Wu 5f9d683257 ci: bump golangci-lint to v2.12
- Upgrade golangci-lint version from v2.11 to v2.12
2026-05-08 20:13:39 +08:00
Bo-Yi Wu 66afccb389 ci(actions): bump trivy-action to v0.36.0 and codecov-action to v6 2026-04-25 16:51:02 +08:00
Bo-Yi Wu 8c87ebd4ef docs(readme): add Trivy security scan badge 2026-04-16 23:23:44 +08:00
Bo-Yi Wu 156f3c6cb1 fix(deps): bump golang.org/x/crypto to v0.50.0 to fix CVE-2025-58181 and CVE-2025-47914 2026-04-16 23:18:55 +08:00
Bo-Yi Wu 8c8da8b643 fix(docker): bump alpine to 3.23 to clear HIGH CVEs 2026-04-16 23:15:42 +08:00
Bo-Yi Wu d7493e77f5 ci: add trivy workflow and gate docker push on image scan 2026-04-16 23:00:58 +08:00
Bo-Yi Wu 1917781d94 ci: enable check-latest in docker and goreleaser workflows 2026-04-16 22:42:42 +08:00
Bo-Yi Wu c08c2995d2 ci: enable check-latest for setup-go to fetch newest patch 2026-04-16 21:15:35 +08:00
Bo-Yi Wu 55f880d64f ci: pin golangci-lint to v2.11 2026-04-16 21:11:11 +08:00
Bo-Yi Wu 983705ffd7 ci: bump GitHub Actions and add Go 1.25/1.26 to test matrix 2026-04-16 21:03:21 +08:00
Bo-Yi Wu 523c4bb724 chore: bump go directive to 1.25.9 2026-04-16 20:57:50 +08:00
appleboy 2cbd8efffa test: update color conversion tests for new calculation logic
- Update expected output values in color conversion tests to reflect new color calculation logic

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-07-05 22:46:25 +08:00
Bo-Yi Wu f2b9ede051 refactor: refactor messaging and file upload with improved error handling (#66)
- Refactor message and file sending logic into separate handleMessages and handleFiles methods
- Stream file uploads via io.Copy rather than loading the entire content into memory
- Add centralized http.Client with timeout for all requests
- Enhance error handling throughout by returning more descriptive and wrapped errors
- Improve response validation for file and message uploads, checking HTTP status and parsing error details
- Update tests to cover plain text messages, embed messages, file uploads, color conversion, and combined features
- Add tests using assert.Error/assert.NoError and checking specific error messages
- Simplify and clarify configuration validation logic

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-07-05 21:02:30 +08:00
appleboy 1bdf20515c ci: update golangci-lint workflow to use latest action and linter
- Update golangci-lint GitHub Action from v7 to v8 and set linter version to v2.1

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-07-05 20:28:04 +08:00
appleboy 7678d611f9 chore: update and streamline dependency management
- Bump github.com/urfave/cli/v2 to v2.27.7
- Update indirect dependencies: github.com/Masterminds/semver/v3, github.com/Masterminds/sprig/v3, github.com/cpuguy83/go-md2man/v2, github.com/spf13/cast, golang.org/x/crypto, and golang.org/x/sys to newer versions
- Replace github.com/imdario/mergo with dario.cat/mergo as an indirect dependency

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-07-05 20:27:24 +08:00
Bo-Yi Wu 0e20c42ccd docs: update notification docs for Woodpecker 3.x status changes (#65)
* docs: update notification docs for Woodpecker 3.x status changes

- Add documentation note explaining that in Woodpecker 3.x, build.status is always "success", which affects message templates
- Recommend using the when.status condition to separate success and failure notifications, with example YAML provided
- Clarify that this issue results from upstream Woodpecker CI changes and is not fixable in the plugin

Signed-off-by: appleboy <appleboy.tw@gmail.com>

* Update DOCS.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Signed-off-by: appleboy <appleboy.tw@gmail.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-07-05 20:26:09 +08:00
appleboy 9f96bb575e build: update Go formatting and GitHub actions configuration
- Remove `DIST` variable definition
- Update the `GOFMT` definition by removing the `-s` flag
- Install `gofumpt` latest version instead of an unspecified version

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-04-12 09:37:03 +08:00
appleboy 1b1fb67645 build: improve release management and Discord integration
- Add name_template to release section for Drone Discord version representation

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-04-12 09:35:09 +08:00
appleboy b2b10008a5 refactor: refactor file handling for improved readability and performance
- Clean path and check accessibility before reading file
- Replace file reading with `os.ReadFile` for simpler code
- Remove deferred file closing as file is read into `content`
- Write file content directly to multipart form
- Add comments for clearer code sections

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-04-11 23:40:58 +08:00
appleboy b291372e68 refactor: refactor and streamline status color handling
- Handle custom color by trimming the prefix '#'
- Refactor predefined status colors into a map
- Simplify status color handling code

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-04-11 23:38:09 +08:00
appleboy 691536f46b ci: revise golangci-lint configuration and update versioning
- Update golangci-lint-action used version from `v6` to `v7`
- Set specific golangci-lint version to `v2.0` instead of latest
- Remove `run` section with timeout setting in `.golangci.yaml`
- Eliminate multiple linters (`errcheck`, `gci`, `gofmt`, `goimports`) from `.golangci.yaml`
- Change `linters-settings` to `settings` in `.golangci.yaml`
- Add `int-conversion: true` to `perfsprint` settings
- Add new exclusion settings for generated code, preset rules, and specific paths under `exclusions` in `.golangci.yaml`
- Incorporate formatter settings with enabled formatters and exclusions for certain paths in `.golangci.yaml`

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-04-11 23:35:39 +08:00
appleboy 2173b97920 feat: filter out empty messages in configuration processing
- Add a check for empty messages in the configuration
- Replace the original message handling with a filtered list of non-empty messages
- Update the logic to process messages only if the filtered list is not empty

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 22:45:36 +08:00
appleboy d661b29efe feat: add debug mode for plugin configuration dumping
- Add a new dependency for godump in go.mod
- Import godump in main.go
- Introduce a debug flag in the CLI options
- Update the run function to include the debug flag
- Add logic to dump the plugin configuration if debug mode is enabled
- Extend the plugin struct to include a debug field

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 22:37:30 +08:00
appleboy 3e0f7cf5df fix: enhance error handling and reporting for API responses
- Replace direct reading of response body with error handling for reading
- Add JSON unmarshalling of the response body for better error reporting
- Improve error message format to include details from the JSON response

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 20:57:02 +08:00
appleboy 464bf4772f fix: improve error reporting for message sending failures
- Enhance error reporting by including the response body in the error message when message sending fails.
- Remove the previous error message that only included the status code.

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 17:42:58 +08:00
appleboy c84a5276cb ci: rename lint workflow to testing for clarity and consistency
- Rename the lint workflow file to testing.

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 17:16:18 +08:00
appleboy e344b3ec67 ci: add webhook environment variables to lint workflow
- Add environment variables for `WEBHOOK_ID` and `WEBHOOK_TOKEN` in the lint workflow.

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 17:16:02 +08:00
appleboy 8533df8e0b refactor: enhance file upload functionality with context and error handling
- Rename the function `newfileUploadRequest` to `fileUploadRequest`
- Add context parameter to the `fileUploadRequest` function
- Improve error handling by wrapping errors with descriptive messages
- Update the `Exec` method to pass context when calling `SendFile`
- Rename the `SendFile` method to accept context as a parameter

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 17:10:53 +08:00
appleboy 217a6b17eb docs: clarify usage descriptions for webhook and build parameters
- Update usage descriptions for various webhook parameters to provide clearer context.
- Improve clarity in usage statements for Discord webhook configurations.
- Enhance descriptions for build-related parameters to better explain their purpose.
- Revise usage text for GitHub Actions parameters to ensure consistency and clarity.

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 17:07:21 +08:00
appleboy a58131af2a feat: add support for Discord webhook URL configuration and validation
- Add a new command-line flag for the Discord webhook URL
- Update the configuration structure to include the webhook URL
- Implement validation for the webhook URL format
- Introduce a method to retrieve the webhook URL from the configuration
- Refactor the code to use the new method for generating the webhook URL in multiple places

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 17:03:50 +08:00
appleboy 3721fc313d feat: validate configuration fields in Exec method
- Remove the import of the errors package
- Add a validate method to the Config type to check for missing fields
- Update the Exec method to use the new validate method for configuration validation

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:56:57 +08:00
appleboy cea35a9ac9 fix: fix error handling for empty HTTP responses
- Change the condition to check for `http.StatusNoContent` instead of `http.StatusOK` before returning an error.

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:53:12 +08:00
appleboy e80db3da6a chore: update base image to Alpine 3.21
- Update the base image from alpine version 3.17 to 3.21

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:44:54 +08:00
appleboy 6c782afaae feat: add context support to Exec and SendMessage functions
- Update the `Exec` function to accept a context parameter.
- Modify the `SendMessage` function to also accept a context parameter.
- Add context import to the necessary files.
- Update test cases to pass a context when calling `Exec`.

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:43:06 +08:00
appleboy ffa230b880 docs: refine API documentation and improve grammatical consistency
- Correct grammatical errors in descriptions, changing "message" to "messages" and "Webhook" to "Webhooks."
- Update "API document information" to "API documentation."
- Change "Sending discord message" to "Send Discord messages."
- Clarify the list of supported OS types in the binaries section.
- Improve phrasing for building the binary and sending notifications.
- Capitalize "Binary," "Docker," and "Drone CI" for consistency.

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:38:35 +08:00
appleboy f2bd7836ef refactor: refactor HTTP request handling and improve linter settings
- Remove the `exportloopref` linter from the golangci configuration
- Add the `strconv` package import in `main.go`
- Replace the `fmt.Sprintf` for the year with `strconv.Itoa` to convert the year to a string
- Update the HTTP request method to use `http.MethodPost` instead of a string literal in `plugin.go`

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:36:43 +08:00
appleboy 4d1d86d8c2 docs: clean up documentation by removing unnecessary comments
- Remove a commented-out line from the documentation file

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:35:19 +08:00
appleboy 53d0f6ec67 chore: configure golangci-lint with multiple linters and settings
- Add a new configuration file for golangci-lint
- Set a timeout of 5 minutes for linting
- Enable multiple linters including asciicheck, errcheck, and gofmt
- Configure settings for the gosec linter with specific rule inclusions
- Add settings for the perfsprint linter to check various error handling practices

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:30:04 +08:00
appleboy 91c0d241df refactor: refactor GitHub event handling in Template function
- Refactor the handling of GitHub events in the Template function
- Replace the message construction with a switch statement for better clarity
- Simplify the logic for determining the branch in pull requests
- Update the case structure for handling different build events

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:29:54 +08:00
appleboy 223b0aa14f chore: upgrade Go version and dependencies in workflow settings
- Update Go version from 1.20 to 1.23.0
- Change Go versions in the workflow from 1.21, 1.22, 1.23 to 1.23, 1.24
- Upgrade Codecov action from version 4 to version 5
- Update indirect dependencies for golang.org/x/crypto and golang.org/x/sys to newer versions

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:22:17 +08:00
appleboy 5e71b59c72 chore: upgrade dependencies and refine CLI configuration
- Update `github.com/stretchr/testify` from version `1.9.0` to `1.10.0`
- Update `github.com/urfave/cli` to version `v2.27.6` and change import path to include `/v2`
- Update `github.com/cpuguy83/go-md2man/v2` from version `2.0.4` to `2.0.5`
- Add `github.com/xrash/smetrics` as a new indirect dependency
- Change `cli.Author` to use a pointer type
- Update environment variable fields in multiple `cli.StringFlag` definitions to use `EnvVars` instead of `EnvVar`

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-03-08 16:20:27 +08:00
appleboy 01518e5a92 style: refactor codebase for consistency and performance improvements
- Change single quotes to double quotes in the custom funding URL

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2024-10-10 02:22:19 +08:00
appleboy 7478381b56 ci: refactor and optimize backend API handling
- Update Docker login action to use version 3 instead of version 2

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2024-10-10 02:21:59 +08:00
appleboy c96089116d chore: simplify and clean up build and release processes
- Update `GOFMT` command to include `-s` and `-w` flags
- Remove redundant `DIST` and `DIST_DIRS` definitions
- Remove unused variables and dependencies
- Remove `.PHONY` targets and associated release tasks
- Simplify `clean` target by removing `$(DIST)` directory from the removal list

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2024-10-06 10:08:58 +08:00
appleboy e17a1e9920 ci: streamline build process for multi-architecture support
- Remove `build_linux_arm` target from Makefile
- Remove `make build_linux_arm` step from Docker workflow
- Update Docker workflow to build for `linux/amd64` and `linux/arm64` platforms only

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2024-10-06 09:46:49 +08:00
appleboy 51f0b338c5 ci: enhance CI pipeline for Go projects
- Rename job from `testing` to `test`
- Add matrix strategy to test on multiple Go versions (1.21, 1.22, 1.23)
- Set up Go environment variables `GO111MODULE` and `GOPROXY`
- Replace `actions/checkout@v4` with `actions/setup-go@v5` for setting up Go
- Add caching for Go build and module directories using `actions/cache@v4`
- Change test command from `make test` to `go test -v -covermode=atomic -coverprofile=coverage.out`
- Add flags to `codecov/codecov-action@v4` for matrix OS and Go version

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2024-10-04 21:06:18 +08:00
appleboy 2e8d61dcf2 chore: update dependencies to latest versions
- Update `github.com/huandu/xstrings` from v1.4.0 to v1.5.0
- Update `golang.org/x/crypto` from v0.22.0 to v0.24.0
- Update `golang.org/x/sys` from v0.19.0 to v0.21.0

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2024-06-28 22:03:48 +08:00
appleboy d80fc1adb6 chore: update CI workflows and dependencies
- Update `docker/build-push-action` to version 6
- Update `goreleaser/goreleaser-action` to version 6

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2024-06-28 21:55:35 +08:00
Bo-Yi Wu 1b92a095c1 ci: update GitHub Actions lint workflow configuration
- Update the golangci-lint-action version from `v5` to `v6` in the GitHub Actions lint workflow

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-05-16 16:14:33 +08:00
qwerty287 8a872ab32f fix: icon URL (#60) 2024-05-16 16:10:54 +08:00
Bo-Yi Wu 17f7e18d78 chore: refine Docker setup and configuration
- Add a new `.hadolint.yaml` configuration file with specific rule ignores
- Update the Dockerfile to install `ca-certificates` without a fixed version

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-04-29 15:42:37 +08:00
Bo-Yi Wu 59b6fbbaf2 ci: enhance CI workflows and test robustness
- Update the Codecov action version from `v3` to `v4` in the lint workflow

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-04-29 15:24:01 +08:00
qwerty287 2000a2e484 Add Woodpecker support to docs (#57)
* Update README.md

* Add files via upload

* Update DOCS.md

* Update main.go
2024-04-29 15:23:23 +08:00
Bo-Yi Wu 6dc40cfa7f chore: update build and linting configurations
- Update CodeQL GitHub Actions from v2 to v3 in codeql.yml
- Change goreleaser argument from `--rm-dist` to `--clean` in goreleaser.yml
- Update golangci-lint GitHub Action from v3 to v5 in lint.yml
- Update the Docker container for linting from golang:1.19-alpine to golang:1.22-alpine in lint.yml
- Standardize quotes around `checksums.txt` in .goreleaser.yaml
- Add changelog configuration with groups for features, bug fixes, enhancements, refactor, build process updates, documentation updates, and others in .goreleaser.yaml

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-04-29 15:21:46 +08:00
Bo-Yi Wu 7e5539d30c chore: update dependencies to latest versions
- Update `github.com/stretchr/testify` to version `1.9.0`
- Update `github.com/urfave/cli` to version `1.22.15`
- Update `github.com/cpuguy83/go-md2man/v2` to version `2.0.4`
- Update `github.com/google/uuid` to version `1.6.0`
- Update `github.com/shopspring/decimal` to version `1.4.0`
- Update `golang.org/x/crypto` to version `0.22.0`
- Update `golang.org/x/sys` to version `0.19.0`

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-04-29 15:20:48 +08:00
appleboy 3f344cdf2e chore: update version of actions/setup-go in GitHub workflows
- Update the version of `actions/setup-go` from `v4` to `v5` in the `.github/workflows/docker.yml` file
- Update the version of `actions/setup-go` from `v4` to `v5` in the `.github/workflows/goreleaser.yml` file
- Update the version of `actions/setup-go` from `v4` to `v5` in the `.github/workflows/lint.yml` file

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-12-24 19:12:48 +08:00
appleboy 692f7ff6dd feat: add support for specifying source branch in build configuration
- Add a new flag `source.branch` with default value `develop` and usage description "git source branch"
- Add a new struct `Source` with a `Branch` field
- Add a new field `Source` to the existing struct `Build`
- Add a new test case with `Source.Branch` set to "feature/awesome-feature"

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-12-24 19:09:34 +08:00
appleboy 881339ea8f chore: refactor project configuration files
- Delete the `.editorconfig` file
- Add the `.gitignore` file

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-12-24 19:06:07 +08:00
appleboy af8276f8fa chore: update dependencies to latest versions
- Update the version of `github.com/cpuguy83/go-md2man/v2` from `v2.0.2` to `v2.0.3`
- Update the version of `github.com/google/uuid` from `v1.3.1` to `v1.5.0`
- Update the version of `github.com/sirupsen/logrus` from `v1.8.1` to `v1.9.3`
- Update the version of `github.com/spf13/cast` from `v1.5.1` to `v1.6.0`
- Update the version of `golang.org/x/crypto` from `v0.13.0` to `v0.17.0`
- Update the version of `golang.org/x/sys` from `v0.12.0` to `v0.15.0`

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-12-24 19:03:27 +08:00
appleboy 2586433815 chore: update dependency
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 21:55:01 +08:00
appleboy 69a9056c05 chore(makefile): remove unused build command
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 20:02:43 +08:00
appleboy 17058ff053 docs: remove unused badge
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:50:53 +08:00
appleboy 242a4e9588 chore: discordapp.com is deprecated
fix https://github.com/appleboy/drone-discord/issues/41

ref: https://github.com/discordjs/discord.js/pull/4160

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:48:11 +08:00
more-pepsi 4bb2c902ad docs: add config example to usage. (#37) 2023-09-24 19:39:51 +08:00
appleboy 22c00bf3c3 fix: binary name
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:39:19 +08:00
appleboy f3724e17a2 chore(CI): setup tool
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:33:42 +08:00
appleboy 9d765d231b chore(go): bump dependency version
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:30:56 +08:00
appleboy 26bd0641dc chore(CI): update lint
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:29:59 +08:00
appleboy cb38b0a194 chore(CI): bump version
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:28:05 +08:00
appleboy 5144ba01a7 chore(CI): add goreleaser
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:25:10 +08:00
appleboy a1c6d30b44 chore(docker): update dockerfile
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:24:23 +08:00
appleboy bf68bcb2b9 chore: update makefile
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 19:22:20 +08:00
appleboy 6d07c7dd06 chore: add github actions
Signed-off-by: appleboy <appleboy.tw@gmail.com>
2023-09-24 18:59:04 +08:00
Bo-Yi Wu e282060e04 chore: update Go version and dependencies
- Update Go version from 1.13 to 1.20
- Update dependencies: godotenv to v1.5.1, testify to v1.8.2, and urfave/cli to v1.22.13
- Add several new indirect dependencies

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2023-05-24 08:57:46 +08:00
Bo-Yi Wu f760d3a7a8 ci: refactor CI/CD pipeline and remove unused configs
- Remove .appveyor.yml file
- Delete .drone.jsonnet file
- Remove .drone.yml file
- Update build and deployment steps in the pipeline
- Add notifications and manifest steps in the pipeline

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2023-05-24 08:56:14 +08:00
Nils 7ac022b650 allow not setting a username for messages (closes #38) (#39) 2023-05-13 23:04:59 +08:00
Bo-Yi Wu 2830e39260 chore: update go module
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2021-07-04 15:12:06 +08:00
Bo-Yi Wu d4b1c86367 chore: update drone-template-lib module
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2021-07-04 15:06:56 +08:00
Bo-Yi Wu e1e8532e04 chore: update
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2021-07-04 15:05:47 +08:00
Bo-Yi Wu 52b70e4a89 chore: updae drone template library
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2021-07-03 10:59:33 +08:00
Bo-Yi Wu f6c3df01ff chore: update go module
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2021-06-18 08:51:38 +08:00
Bo-Yi Wu 78124dd591 chore: upgrade to go.16
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2021-06-18 08:51:09 +08:00
Laurant Marijnissen 61e5d95ddb Small spelling correction (#34) 2020-12-16 15:54:36 +08:00
Bo-Yi Wu a451d9e0a5 chore: upgrade to go1.15
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2020-09-26 12:19:09 +08:00
34 changed files with 1309 additions and 1434 deletions
-61
View File
@@ -1,61 +0,0 @@
version: '{build}'
image: 'Visual Studio 2017'
platform: x64
max_jobs: 1
environment:
GOPATH: c:\go
docker_username:
secure: em/TNLUXxG19O/HvbvfJuQ==
docker_password:
secure: Yo9FJJqihaNz5q8T4Jz8tQ==
branches:
only:
- master
install:
- ps: |
docker version
go version
go env
build_script:
- ps: |
if ( $env:APPVEYOR_REPO_TAG -eq 'false' ) {
$version = $env:APPVEYOR_REPO_COMMIT
} else {
$version = $env:APPVEYOR_REPO_TAG_NAME
}
go build -ldflags "-X main.Version=$version" -a -o release/drone-discord.exe .
docker pull microsoft/nanoserver:10.0.14393.1884
docker build -f docker/Dockerfile.windows.amd64 -t appleboy/drone-discord:windows-amd64 .
test_script:
- ps: |
docker run --rm appleboy/drone-discord:windows-amd64 --version
deploy_script:
- ps: |
$ErrorActionPreference = 'Stop';
if ( $env:APPVEYOR_PULL_REQUEST_NUMBER ) {
Write-Host Nothing to deploy.
} else {
echo $env:DOCKER_PASSWORD | docker login --username $env:DOCKER_USERNAME --password-stdin
if ( $env:APPVEYOR_REPO_TAG -eq 'true' ) {
$major,$minor,$patch = $env:APPVEYOR_REPO_TAG_NAME.split('.')
docker push appleboy/drone-discord:windows-amd64
docker tag appleboy/drone-discord:windows-amd64 appleboy/drone-discord:$major.$minor.$patch-windows-amd64
docker push appleboy/drone-discord:$major.$minor.$patch-windows-amd64
docker tag appleboy/drone-discord:windows-amd64 appleboy/drone-discord:$major.$minor-windows-amd64
docker push appleboy/drone-discord:$major.$minor-windows-amd64
docker tag appleboy/drone-discord:windows-amd64 appleboy/drone-discord:$major-windows-amd64
docker push appleboy/drone-discord:$major-windows-amd64
} else {
if ( $env:APPVEYOR_REPO_BRANCH -eq 'master' ) {
docker push appleboy/drone-discord:windows-amd64
}
}
}
-16
View File
@@ -1,16 +0,0 @@
local pipeline = import 'pipeline.libsonnet';
local name = 'drone-discord';
[
pipeline.test,
pipeline.build(name, 'linux', 'amd64'),
pipeline.build(name, 'linux', 'arm64'),
pipeline.build(name, 'linux', 'arm'),
pipeline.release,
pipeline.notifications(depends_on=[
'linux-amd64',
'linux-arm64',
'linux-arm',
'release-binary',
]),
]
-76
View File
@@ -1,76 +0,0 @@
---
kind: pipeline
name: windows-amd64
platform:
os: windows
arch: amd64
steps:
- name: build-push
pull: always
image: golang:1.11
commands:
- 'go build -v -ldflags "-X main.build=${DRONE_BUILD_NUMBER}" -a -o release/windows/amd64/drone-discord'
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- push
- pull_request
- name: build-tag
pull: always
image: golang:1.11
commands:
- 'go build -v -ldflags "-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}" -a -o release/windows/amd64/drone-discord'
environment:
CGO_ENABLED: 0
GO111MODULE: on
when:
event:
- tag
- name: executable
pull: always
image: golang:1.11
commands:
- ./release/windows/amd64/drone-discord --help
- name: dryrun
pull: always
image: plugins/docker:windows-amd64
settings:
dockerfile: docker/Dockerfile.windows.amd64
dry_run: true
password:
from_secret: docker_password
repo: appleboy/drone-discord
tags: windows-amd64
username:
from_secret: docker_username
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker:windows-amd64
settings:
auto_tag: true
auto_tag_suffix: windows-amd64
dockerfile: docker/Dockerfile.windows.amd64
password:
from_secret: docker_password
repo: appleboy/drone-discord
username:
from_secret: docker_username
when:
event:
- push
- tag
trigger:
branch:
- master
-378
View File
@@ -1,378 +0,0 @@
---
kind: pipeline
name: testing
platform:
os: linux
arch: amd64
steps:
- name: vet
pull: always
image: golang:1.14
commands:
- make vet
volumes:
- name: gopath
path: /go
- name: lint
pull: always
image: golang:1.14
commands:
- make lint
volumes:
- name: gopath
path: /go
- name: misspell
pull: always
image: golang:1.14
commands:
- make misspell-check
volumes:
- name: gopath
path: /go
- name: test
pull: always
image: golang:1.14
commands:
- make test
- make coverage
environment:
WEBHOOK_ID:
from_secret: webhook_id
WEBHOOK_TOKEN:
from_secret: webhook_token
volumes:
- name: gopath
path: /go
- name: codecov
pull: always
image: robertstettner/drone-codecov
settings:
token:
from_secret: codecov_token
volumes:
- name: gopath
temp: {}
---
kind: pipeline
name: linux-amd64
platform:
os: linux
arch: amd64
steps:
- name: build-push
pull: always
image: golang:1.14
commands:
- go build -v -ldflags '-X main.build=${DRONE_BUILD_NUMBER}' -a -o release/linux/amd64/drone-discord
environment:
CGO_ENABLED: 0
when:
event:
exclude:
- tag
- name: build-tag
pull: always
image: golang:1.14
commands:
- go build -v -ldflags '-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -a -o release/linux/amd64/drone-discord
environment:
CGO_ENABLED: 0
when:
event:
- tag
- name: executable
pull: always
image: golang:1.14
commands:
- ./release/linux/amd64/drone-discord --help
- name: dryrun
pull: always
image: plugins/docker:linux-amd64
settings:
cache_from: appleboy/drone-discord
dockerfile: docker/Dockerfile.linux.amd64
dry_run: true
repo: appleboy/drone-discord
tags: linux-amd64
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker:linux-amd64
settings:
auto_tag: true
auto_tag_suffix: linux-amd64
cache_from: appleboy/drone-discord
daemon_off: false
dockerfile: docker/Dockerfile.linux.amd64
password:
from_secret: docker_password
repo: appleboy/drone-discord
username:
from_secret: docker_username
when:
event:
exclude:
- pull_request
trigger:
ref:
- refs/heads/master
- refs/pull/**
- refs/tags/**
depends_on:
- testing
---
kind: pipeline
name: linux-arm64
platform:
os: linux
arch: arm64
steps:
- name: build-push
pull: always
image: golang:1.14
commands:
- go build -v -ldflags '-X main.build=${DRONE_BUILD_NUMBER}' -a -o release/linux/arm64/drone-discord
environment:
CGO_ENABLED: 0
when:
event:
exclude:
- tag
- name: build-tag
pull: always
image: golang:1.14
commands:
- go build -v -ldflags '-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -a -o release/linux/arm64/drone-discord
environment:
CGO_ENABLED: 0
when:
event:
- tag
- name: executable
pull: always
image: golang:1.14
commands:
- ./release/linux/arm64/drone-discord --help
- name: dryrun
pull: always
image: plugins/docker:linux-arm64
settings:
cache_from: appleboy/drone-discord
dockerfile: docker/Dockerfile.linux.arm64
dry_run: true
repo: appleboy/drone-discord
tags: linux-arm64
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker:linux-arm64
settings:
auto_tag: true
auto_tag_suffix: linux-arm64
cache_from: appleboy/drone-discord
daemon_off: false
dockerfile: docker/Dockerfile.linux.arm64
password:
from_secret: docker_password
repo: appleboy/drone-discord
username:
from_secret: docker_username
when:
event:
exclude:
- pull_request
trigger:
ref:
- refs/heads/master
- refs/pull/**
- refs/tags/**
depends_on:
- testing
---
kind: pipeline
name: linux-arm
platform:
os: linux
arch: arm
steps:
- name: build-push
pull: always
image: golang:1.14
commands:
- go build -v -ldflags '-X main.build=${DRONE_BUILD_NUMBER}' -a -o release/linux/arm/drone-discord
environment:
CGO_ENABLED: 0
when:
event:
exclude:
- tag
- name: build-tag
pull: always
image: golang:1.14
commands:
- go build -v -ldflags '-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -a -o release/linux/arm/drone-discord
environment:
CGO_ENABLED: 0
when:
event:
- tag
- name: executable
pull: always
image: golang:1.14
commands:
- ./release/linux/arm/drone-discord --help
- name: dryrun
pull: always
image: plugins/docker:linux-arm
settings:
cache_from: appleboy/drone-discord
dockerfile: docker/Dockerfile.linux.arm
dry_run: true
repo: appleboy/drone-discord
tags: linux-arm
when:
event:
- pull_request
- name: publish
pull: always
image: plugins/docker:linux-arm
settings:
auto_tag: true
auto_tag_suffix: linux-arm
cache_from: appleboy/drone-discord
daemon_off: false
dockerfile: docker/Dockerfile.linux.arm
password:
from_secret: docker_password
repo: appleboy/drone-discord
username:
from_secret: docker_username
when:
event:
exclude:
- pull_request
trigger:
ref:
- refs/heads/master
- refs/pull/**
- refs/tags/**
depends_on:
- testing
---
kind: pipeline
name: release-binary
platform:
os: linux
arch: amd64
steps:
- name: build-all-binary
pull: always
image: golang:1.14
commands:
- make release
when:
event:
- tag
- name: deploy-all-binary
pull: always
image: plugins/github-release
settings:
api_key:
from_secret: github_release_api_key
files:
- dist/release/*
when:
event:
- tag
trigger:
ref:
- refs/tags/**
depends_on:
- testing
---
kind: pipeline
name: notifications
platform:
os: linux
arch: amd64
steps:
- name: discord
pull: always
image: appleboy/drone-discord
settings:
message: "{{#success build.status}} ✅ Build #{{build.number}} of `{{repo.name}}` succeeded.\n\n📝 Commit by {{commit.author}} on `{{commit.branch}}`:\n``` {{commit.message}} ```\n🌐 {{ build.link }}\n\n ✅ duration: {{duration build.started build.finished}} \n\n ✅ started: {{datetime build.started \"2006/01/02 15:04\" \"Asia/Taipei\"}} \n\n ✅ finished: {{datetime build.finished \"2006/01/02 15:04\" \"Asia/Taipei\"}} {{else}} ❌ Build #{{build.number}} of `{{repo.name}}` failed.\n\n📝 Commit by {{commit.author}} on `{{commit.branch}}`:\n``` {{commit.message}} ```\n🌐 {{ build.link }}\n\n ✅ duration: {{duration build.started build.finished}} \n\n ✅ started: {{datetime build.started \"2006/01/02 15:04\" \"Asia/Taipei\"}} \n\n ✅ finished: {{datetime build.finished \"2006/01/02 15:04\" \"Asia/Taipei\"}}{{/success}}\n"
webhook_id:
from_secret: webhook_id
webhook_token:
from_secret: webhook_token
- name: manifest
pull: always
image: plugins/manifest
settings:
ignore_missing: true
password:
from_secret: docker_password
spec: docker/manifest.tmpl
username:
from_secret: docker_username
trigger:
ref:
- refs/heads/master
- refs/tags/**
depends_on:
- linux-amd64
- linux-arm64
- linux-arm
- release-binary
...
-42
View File
@@ -1,42 +0,0 @@
# unifying the coding style for different editors and IDEs => editorconfig.org
; indicate this is the root of the project
root = true
###########################################################
; common
###########################################################
[*]
charset = utf-8
end_of_line = LF
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
###########################################################
; make
###########################################################
[Makefile]
indent_style = tab
[makefile]
indent_style = tab
###########################################################
; markdown
###########################################################
[*.md]
trim_trailing_whitespace = false
###########################################################
; golang
###########################################################
[*.go]
indent_style = tab
+13
View File
@@ -0,0 +1,13 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ["https://www.paypal.me/appleboy46"]
+10
View File
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly
+54
View File
@@ -0,0 +1,54 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
schedule:
- cron: "41 23 * * 6"
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["go"]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
+102
View File
@@ -0,0 +1,102 @@
name: Docker Image
on:
push:
branches:
- master
tags:
- "v*"
pull_request:
branches:
- "master"
permissions:
contents: read
packages: write
security-events: write
jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- name: Setup go
uses: actions/setup-go@v6
with:
go-version: "^1"
check-latest: true
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Build binary
run: |
make build_linux_amd64
make build_linux_arm64
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: docker-meta
uses: docker/metadata-action@v6
with:
images: |
${{ github.repository }}
ghcr.io/${{ github.repository }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Build image for scanning
uses: docker/build-push-action@v7
with:
context: .
file: docker/Dockerfile
platforms: linux/amd64
push: false
load: true
tags: drone-discord:scan
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: "drone-discord:scan"
format: "sarif"
output: "trivy-image-results.sarif"
severity: "CRITICAL,HIGH"
exit-code: '1'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: "trivy-image-results.sarif"
category: "trivy-docker-image"
- name: Build and push
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64
file: docker/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
+33
View File
@@ -0,0 +1,33 @@
name: Goreleaser
on:
push:
tags:
- "*"
permissions:
contents: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup go
uses: actions/setup-go@v6
with:
go-version: "^1"
check-latest: true
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+72
View File
@@ -0,0 +1,72 @@
name: Lint and Testing
on:
push:
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Setup go
uses: actions/setup-go@v6
with:
go-version: "^1"
check-latest: true
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.12
args: --verbose
- uses: hadolint/hadolint-action@v3.3.0
name: hadolint for Dockerfile
with:
dockerfile: docker/Dockerfile
test:
strategy:
matrix:
os: [ubuntu-latest]
go: [1.25, 1.26]
include:
- os: ubuntu-latest
go-build: ~/.cache/go-build
name: ${{ matrix.os }} @ Go ${{ matrix.go }}
runs-on: ${{ matrix.os }}
env:
GO111MODULE: on
GOPROXY: https://proxy.golang.org
steps:
- name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}
check-latest: true
- name: Checkout Code
uses: actions/checkout@v6
with:
ref: ${{ github.ref }}
- uses: actions/cache@v5
with:
path: |
${{ matrix.go-build }}
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run Tests
env:
WEBHOOK_ID: ${{ secrets.WEBHOOK_ID }}
WEBHOOK_TOKEN: ${{ secrets.WEBHOOK_TOKEN }}
run: |
go test -v -covermode=atomic -coverprofile=coverage.out
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v7
with:
flags: ${{ matrix.os }},go-${{ matrix.go }}
+84
View File
@@ -0,0 +1,84 @@
name: Trivy Security Scan
on:
push:
branches:
- master
pull_request:
branches:
- master
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
permissions:
contents: read
security-events: write
jobs:
trivy-repo-scan:
name: Trivy Repository Scan
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Run Trivy vulnerability scanner (repo)
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: "fs"
scan-ref: "."
format: "sarif"
output: "trivy-repo-results.sarif"
severity: "CRITICAL,HIGH"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: "trivy-repo-results.sarif"
trivy-image-scan:
name: Trivy Image Scan
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- name: Build binary
run: |
make build_linux_amd64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build Docker image for scanning
uses: docker/build-push-action@v7
with:
context: .
file: docker/Dockerfile
platforms: linux/amd64
push: false
load: true
tags: drone-discord:scan
- name: Run Trivy vulnerability scanner (image)
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: "drone-discord:scan"
format: "sarif"
output: "trivy-image-results.sarif"
severity: "CRITICAL,HIGH"
- name: Upload Trivy image scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: "trivy-image-results.sarif"
category: "trivy-image"
+1
View File
@@ -18,3 +18,4 @@ drone-discord
coverage.txt
release/
dist/
bin/
+54
View File
@@ -0,0 +1,54 @@
version: "2"
linters:
enable:
- asciicheck
- durationcheck
- errorlint
- gosec
- misspell
- nakedret
- nilerr
- nolintlint
- perfsprint
- revive
- usestdlibvars
- wastedassign
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$
+125
View File
@@ -0,0 +1,125 @@
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- darwin
- linux
- windows
- freebsd
goarch:
- amd64
- arm
- arm64
goarm:
- "5"
- "6"
- "7"
ignore:
- goos: darwin
goarch: arm
- goos: darwin
goarch: ppc64le
- goos: darwin
goarch: s390x
- goos: windows
goarch: ppc64le
- goos: windows
goarch: s390x
- goos: windows
goarch: arm
goarm: "5"
- goos: windows
goarch: arm
goarm: "6"
- goos: windows
goarch: arm
goarm: "7"
- goos: windows
goarch: arm64
- goos: freebsd
goarch: ppc64le
- goos: freebsd
goarch: s390x
- goos: freebsd
goarch: arm
goarm: "5"
- goos: freebsd
goarch: arm
goarm: "6"
- goos: freebsd
goarch: arm
goarm: "7"
- goos: freebsd
goarch: arm64
flags:
- -trimpath
ldflags:
- -s -w
- -X main.Version={{.Version}}
binary: >-
{{ .ProjectName }}-
{{- if .IsSnapshot }}{{ .Branch }}-
{{- else }}{{- .Version }}-{{ end }}
{{- .Os }}-
{{- if eq .Arch "amd64" }}amd64
{{- else if eq .Arch "amd64_v1" }}amd64
{{- else if eq .Arch "386" }}386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}-{{ .Arm }}{{ end }}
no_unique_dist_dir: true
hooks:
post:
- cmd: xz -k -9 {{ .Path }}
dir: ./dist/
archives:
- format: binary
name_template: "{{ .Binary }}"
allow_different_binary_count: true
checksum:
name_template: "checksums.txt"
extra_files:
- glob: ./**.xz
snapshot:
name_template: "{{ incpatch .Version }}"
release:
# You can add extra pre-existing files to the release.
# The filename on the release will be the last part of the path (base).
# If another file with the same name exists, the last one found will be used.
#
# Templates: allowed
extra_files:
- glob: ./**.xz
name_template: "Drone Discord {{.Version}}"
changelog:
use: github
groups:
- title: Features
regexp: "^.*feat[(\\w)]*:+.*$"
order: 0
- title: "Bug fixes"
regexp: "^.*fix[(\\w)]*:+.*$"
order: 1
- title: "Enhancements"
regexp: "^.*chore[(\\w)]*:+.*$"
order: 2
- title: "Refactor"
regexp: "^.*refactor[(\\w)]*:+.*$"
order: 3
- title: "Build process updates"
regexp: ^.*?(build|ci)(\(.+\))??!?:.+$
order: 4
- title: "Documentation updates"
regexp: ^.*?docs?(\(.+\))??!?:.+$
order: 4
- title: Others
order: 999
+3
View File
@@ -0,0 +1,3 @@
ignored:
- DL3018
- DL3008
-25
View File
@@ -1,25 +0,0 @@
ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 1
warningCode = 1
[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
[rule.error-return]
[rule.error-strings]
[rule.error-naming]
[rule.exported]
[rule.if-return]
[rule.increment-decrement]
[rule.var-naming]
[rule.var-declaration]
[rule.package-comments]
[rule.range]
[rule.receiver-naming]
[rule.time-naming]
[rule.unexported-return]
[rule.indent-error-flow]
[rule.errorf]
+36 -3
View File
@@ -1,20 +1,25 @@
---
date: 2017-06-10T00:00:00+00:00
title: Discord
name: Discord
description: Send message to Discord channel using Webhook
author: appleboy
tags: [ notifications, chat ]
repo: appleboy/drone-discord
logo: discord.svg
repo: appleboy/drone-discord
icon: https://raw.githubusercontent.com/appleboy/drone-discord/master/images/discord-mark-blue.svg
image: appleboy/drone-discord
containerImage: appleboy/drone-discord
containerImageUrl: https://hub.docker.com/r/appleboy/drone-discord
url: https://github.com/appleboy/drone-discord
---
Webhooks are a low-effort way to post messages to channels in Discord. They do not require a bot user or authentication to use.
The webhook provided by discord is a single URL which contains the webhook_id and the webhook_token. The URL follows the following pattern:
The webhook provided by discord is a single URL which contains the webhook_id and the webhook_token. The URL follows the following pattern.
```sh
https://discord.com/ap/webhooks/<webhook_id>/<webhook_token>
https://discord.com/api/webhooks/<webhook_id>/<webhook_token>
```
The discord plugin posts build status messages to discord channel. The below pipeline configuration demonstrates simple usage:
@@ -192,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.
+38 -79
View File
@@ -1,17 +1,8 @@
DIST := dist
EXECUTABLE := drone-discord
GOFMT ?= gofmt "-s"
GOFMT ?= gofumpt -l -w
GO ?= go
# for dockerhub
DEPLOY_ACCOUNT := appleboy
DEPLOY_IMAGE := $(EXECUTABLE)
TARGETS ?= linux darwin windows
SOURCES ?= $(shell find . -name "*.go" -type f)
TAGS ?=
LDFLAGS ?= -X 'main.Version=$(VERSION)'
TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'tempdir')
GOFILES := $(shell find . -name "*.go" -type f)
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
ifneq ($(shell uname), Darwin)
EXTLDFLAGS = -extldflags "-static" $(null)
@@ -19,109 +10,77 @@ else
EXTLDFLAGS =
endif
ifeq ($(HAS_GO), GO)
GOPATH ?= $(shell $(GO) env GOPATH)
export PATH := $(GOPATH)/bin:$(PATH)
CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766
CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS)
endif
ifeq ($(OS), Windows_NT)
GOFLAGS := -v -buildmode=exe
EXECUTABLE ?= $(EXECUTABLE).exe
else ifeq ($(OS), Windows)
GOFLAGS := -v -buildmode=exe
EXECUTABLE ?= $(EXECUTABLE).exe
else
GOFLAGS := -v
EXECUTABLE ?= $(EXECUTABLE)
endif
ifneq ($(DRONE_TAG),)
VERSION ?= $(DRONE_TAG)
else
VERSION ?= $(shell git describe --tags --always || git rev-parse --short HEAD)
endif
TAGS ?=
LDFLAGS ?= -X 'main.Version=$(VERSION)'
all: build
fmt:
$(GOFMT) -w $(SOURCES)
@hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install mvdan.cc/gofumpt@latest; \
fi
$(GOFMT) -w $(GOFILES)
vet:
$(GO) vet ./...
lint:
@hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/mgechev/revive; \
fi
revive -config .revive.toml ./... || exit 1
.PHONY: misspell-check
misspell-check:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
misspell -error $(SOURCES)
.PHONY: misspell
misspell:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
misspell -w $(SOURCES)
.PHONY: fmt-check
fmt-check:
@diff=$$($(GOFMT) -d $(SOURCES)); \
@hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) install mvdan.cc/gofumpt; \
fi
@diff=$$($(GOFMT) -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;
test: fmt-check
test:
@$(GO) test -v -cover -coverprofile coverage.txt ./... && echo "\n==>\033[32m Ok\033[m\n" || exit 1
install: $(SOURCES)
install: $(GOFILES)
$(GO) install -v -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)'
build: $(EXECUTABLE)
$(EXECUTABLE): $(SOURCES)
$(GO) build -v -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o $@
release: release-dirs release-build release-copy release-check
release-dirs:
mkdir -p $(DIST)/binaries $(DIST)/release
release-build:
@which gox > /dev/null; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/mitchellh/gox; \
fi
gox -os="$(TARGETS)" -arch="amd64 386" -tags="$(TAGS)" -ldflags="-s -w $(LDFLAGS)" -output="$(DIST)/binaries/$(EXECUTABLE)-$(VERSION)-{{.OS}}-{{.Arch}}"
release-copy:
$(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));)
release-check:
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
$(EXECUTABLE): $(GOFILES)
$(GO) build -v -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o bin/$@
build_linux_amd64:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build -a -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o release/linux/amd64/$(DEPLOY_IMAGE)
build_linux_i386:
CGO_ENABLED=0 GOOS=linux GOARCH=386 $(GO) build -a -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o release/linux/i386/$(DEPLOY_IMAGE)
build_linux_arm64:
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GO) build -a -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o release/linux/arm64/$(DEPLOY_IMAGE)
build_linux_arm:
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 $(GO) build -a -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o release/linux/arm/$(DEPLOY_IMAGE)
docker_image:
docker build -t $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE) .
docker: docker_image
docker_deploy:
ifeq ($(tag),)
@echo "Usage: make $@ tag=<tag>"
@exit 1
endif
# deploy image
docker tag $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):latest $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag)
docker push $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag)
coverage:
sed -i '/main.go/d' coverage.txt
clean:
$(GO) clean -x -i ./...
rm -rf coverage.txt $(EXECUTABLE) $(DIST)
rm -rf coverage.txt $(EXECUTABLE)
version:
@echo $(VERSION)
+40 -19
View File
@@ -2,40 +2,38 @@
![logo](images/discord-logo.png)
Drone plugin for sending message to Discord channel using Webhook.
[Drone](https://www.drone.io/) / [Woodpecker](https://woodpecker-ci.org/) plugin for sending messages to Discord channels using Webhooks.
[![GoDoc](https://godoc.org/github.com/appleboy/drone-discord?status.svg)](https://godoc.org/github.com/appleboy/drone-discord)
[![Build Status](https://cloud.drone.io/api/badges/appleboy/drone-discord/status.svg)](https://cloud.drone.io/appleboy/drone-discord)
[![Build status](https://ci.appveyor.com/api/projects/status/xj24ye9lu68a9sqm?svg=true)](https://ci.appveyor.com/project/appleboy/drone-discord-bne7m)
[![Trivy Security Scan](https://github.com/appleboy/drone-discord/actions/workflows/trivy.yml/badge.svg?branch=master)](https://github.com/appleboy/drone-discord/actions/workflows/trivy.yml)
[![codecov](https://codecov.io/gh/appleboy/drone-discord/branch/master/graph/badge.svg)](https://codecov.io/gh/appleboy/drone-discord)
[![Go Report Card](https://goreportcard.com/badge/github.com/appleboy/drone-discord)](https://goreportcard.com/report/github.com/appleboy/drone-discord)
[![Docker Pulls](https://img.shields.io/docker/pulls/appleboy/drone-discord.svg)](https://hub.docker.com/r/appleboy/drone-discord/)
[![microbadger](https://images.microbadger.com/badges/image/appleboy/drone-discord:linux-amd64.svg)](https://microbadger.com/images/appleboy/drone-discord:linux-amd64 "Get your own image badge on microbadger.com")
Webhooks are a low-effort way to post messages to channels in Discord. They do not require a bot user or authentication to use. See more [api document information](https://discordapp.com/developers/docs/resources/webhook). For the usage information and a listing of the available options please take a look at [the docs](http://plugins.drone.io/appleboy/drone-discord/).
Webhooks are a low-effort way to post messages to channels in Discord. They do not require a bot user or authentication to use. See more [API documentation](https://discordapp.com/developers/docs/resources/webhook). For usage information and a list of available options, please refer to [the documentation](http://plugins.drone.io/appleboy/drone-discord/).
Sending discord message using a binary, docker or [Drone CI](http://docs.drone.io/).
Send Discord messages using a binary, Docker, or [Drone CI](http://docs.drone.io/).
## Features
* [x] Send Multiple Messages
* [x] Send Multiple Files
- [x] Send Multiple Messages
- [x] Send Multiple Files
## Build or Download a binary
The pre-compiled binaries can be downloaded from [release page](https://github.com/appleboy/drone-discord/releases). Support the following OS type.
The pre-compiled binaries can be downloaded from the [release page](https://github.com/appleboy/drone-discord/releases). The following OS types are supported:
* Windows amd64/386
* Linux arm/amd64/386
* Darwin amd64/386
- Windows amd64/386
- Linux arm/amd64/386
- Darwin amd64/386
With `Go` installed
With `Go` installed:
```sh
go get -u -v github.com/appleboy/drone-discord
```
or build the binary with the following command:
Or build the binary with the following command:
```sh
export GOOS=linux
@@ -50,9 +48,9 @@ go build -v -a -tags netgo -o release/linux/amd64/drone-discord
## Usage
There are three ways to send notification.
There are three ways to send notifications:
### Usage from binary
### Usage from Binary
```bash
drone-discord \
@@ -61,7 +59,7 @@ drone-discord \
--message "Test Message"
```
### Usage from docker
### Usage from Docker
```bash
docker run --rm \
@@ -75,7 +73,7 @@ docker run --rm \
appleboy/drone-discord
```
### Usage from drone ci
### Usage from Drone CI
#### Send Notification
@@ -107,7 +105,30 @@ docker run --rm \
appleboy/drone-discord
```
You can get more [information](DOCS.md) about how to use this plugin in drone.
## Declarative Environment Config Usage
You can get more [information](DOCS.md) about how to use this plugin in Drone.
```yml
- name: msg status
image: appleboy/drone-discord
settings:
webhook_id:
from_secret: discord_id
webhook_token:
from_secret: discord_token
message: "{{#success build.status}}✅{{else}}❌{{/success}} Repository `[{{repo.name}}/{{commit.branch}}]` triggered by event `[{{uppercase build.event}}]` for build.\n - Commit [[{{commit.sha}}]({{commit.link}})]\n - Author `[{{commit.author}} / {{commit.email}}]`\n - Message: {{commit.message}} - Drone build [[#{{build.number}}]({{build.link}})] reported `[{{uppercase build.status}}]` at `[{{datetime build.finished \"2006.01.02 15:04\" \"\"}}]`\n"
when:
status: [success, failure, changed]
```
```yml
- name: multi line msg status
...
message: >
Line one
Line two
```
## Testing
+7 -8
View File
@@ -2,19 +2,18 @@
//
// Details about the drone-discord project are found in github page:
//
// https://github.com/appleboy/drone-discord
// https://github.com/appleboy/drone-discord
//
// The pre-compiled binaries can be downloaded from release page.
//
// Send Notification
//
// drone-discord \
// --webhook-id xxxx \
// --webhook-token xxxx \
// --username value \
// --avatar-url value \
// --message "Test Message"
// drone-discord \
// --webhook-id xxxx \
// --webhook-token xxxx \
// --username value \
// --avatar-url value \
// --message "Test Message"
//
// For more details, see the documentation and example.
//
package main
+20
View File
@@ -0,0 +1,20 @@
FROM alpine:3.23
ARG TARGETOS
ARG TARGETARCH
LABEL maintainer="Bo-Yi Wu <appleboy.tw@gmail.com>" \
org.label-schema.name="Drone Discord Plugin" \
org.label-schema.vendor="Bo-Yi Wu" \
org.label-schema.schema-version="1.0"
LABEL org.opencontainers.image.source=https://github.com/appleboy/drone-discord
LABEL org.opencontainers.image.description="Drone Discord"
LABEL org.opencontainers.image.licenses=MIT
RUN apk add --no-cache ca-certificates && \
rm -rf /var/cache/apk/*
COPY release/${TARGETOS}/${TARGETARCH}/drone-discord /bin/
ENTRYPOINT ["/bin/drone-discord"]
-10
View File
@@ -1,10 +0,0 @@
FROM plugins/base:linux-amd64
LABEL maintainer="Bo-Yi Wu <appleboy.tw@gmail.com>" \
org.label-schema.name="Drone Discord" \
org.label-schema.vendor="Bo-Yi Wu" \
org.label-schema.schema-version="1.0"
COPY release/linux/amd64/drone-discord /bin/
ENTRYPOINT ["/bin/drone-discord"]
-10
View File
@@ -1,10 +0,0 @@
FROM plugins/base:linux-arm
LABEL maintainer="Bo-Yi Wu <appleboy.tw@gmail.com>" \
org.label-schema.name="Drone Discord" \
org.label-schema.vendor="Bo-Yi Wu" \
org.label-schema.schema-version="1.0"
COPY release/linux/arm/drone-discord /bin/
ENTRYPOINT ["/bin/drone-discord"]
-10
View File
@@ -1,10 +0,0 @@
FROM plugins/base:linux-arm64
LABEL maintainer="Bo-Yi Wu <appleboy.tw@gmail.com>" \
org.label-schema.name="Drone Discord" \
org.label-schema.vendor="Bo-Yi Wu" \
org.label-schema.schema-version="1.0"
COPY release/linux/arm64/drone-discord /bin/
ENTRYPOINT ["/bin/drone-discord"]
-10
View File
@@ -1,10 +0,0 @@
FROM microsoft/nanoserver:10.0.14393.1884
LABEL maintainer="Bo-Yi Wu <appleboy.tw@gmail.com>" \
org.label-schema.name="Drone Discord" \
org.label-schema.vendor="Bo-Yi Wu" \
org.label-schema.schema-version="1.0"
COPY release/drone-discord.exe C:/bin/drone-discord.exe
ENTRYPOINT [ "C:\\bin\\drone-discord.exe" ]
-25
View File
@@ -1,25 +0,0 @@
image: appleboy/drone-discord:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: appleboy/drone-discord:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
platform:
architecture: amd64
os: linux
-
image: appleboy/drone-discord:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64
platform:
architecture: arm64
os: linux
variant: v8
-
image: appleboy/drone-discord:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm
platform:
architecture: arm
os: linux
variant: v7
+29 -9
View File
@@ -1,14 +1,34 @@
module github.com/appleboy/drone-discord
go 1.13
go 1.25.10
require (
github.com/bouk/monkey v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/drone/drone-template-lib v1.0.1-0.20200720062915-8efa917a1fee
github.com/joho/godotenv v1.3.0
github.com/stretchr/testify v1.6.1
github.com/tkuchiki/faketime v0.0.0-20170607100027-a4500a4f4643 // indirect
github.com/urfave/cli v1.22.3
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 // indirect
github.com/appleboy/drone-template-lib v1.3.0
github.com/joho/godotenv v1.5.1
github.com/stretchr/testify v1.10.0
github.com/urfave/cli/v2 v2.27.7
github.com/yassinebenaid/godump v0.11.1
)
require (
dario.cat/mergo v1.0.2 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/mailgun/raymond/v2 v2.0.48 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cast v1.9.2 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/sys v0.43.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+63 -57
View File
@@ -1,66 +1,72 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.18.0+incompatible h1:QoGhlbC6pter1jxKnjMFxT8EqsLuDE6FEcNbWEpw+lI=
github.com/Masterminds/sprig v2.18.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Masterminds/sprig v2.20.0+incompatible h1:dJTKKuUkYW3RMFdQFXPU/s6hg10RgctmTjRcbZ98Ap8=
github.com/Masterminds/sprig v2.20.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/bouk/monkey v1.0.0 h1:k6z8fLlPhETfn5l9rlWVE7Q6B23DoaqosTdArvNQRdc=
github.com/bouk/monkey v1.0.0/go.mod h1:PG/63f4XEUlVyW1ttIeOJmJhhe1+t9EC/je3eTjvFhE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/appleboy/drone-template-lib v1.3.0 h1:aX36/1za3v8JsEyBeMY1Bp/VNRtZa8qPYkfkjBszW+A=
github.com/appleboy/drone-template-lib v1.3.0/go.mod h1:edlmXkFMKYAVypff8r2oN7aFlHfOZE5sLyPEnRHONeA=
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/drone/drone-template-lib v1.0.0 h1:PNBBfUhifRnrPCoWBlTitk3jipXdv8u8WLbIf7h7j00=
github.com/drone/drone-template-lib v1.0.0/go.mod h1:Hqy1tgqPH5mtbFOZmow19l4jOkZvp+WZ00cB4W3MJhg=
github.com/drone/drone-template-lib v1.0.1-0.20200720062915-8efa917a1fee h1:7c1Wn9p2BTx0XWKIokjEglZBIt9Nsusvy3QzpvCWfO8=
github.com/drone/drone-template-lib v1.0.1-0.20200720062915-8efa917a1fee/go.mod h1:EqmSrA3bzQ479NUEWDw3Vb0EZ27mLkz+81EEG22bWr0=
github.com/google/uuid v1.1.0 h1:Jf4mxPC/ziBnoPIdpQdPJ9OeiomAUHLvxmPRSPH9m4s=
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw=
github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tkuchiki/faketime v0.0.0-20170607100027-a4500a4f4643 h1:ii/sHfgFMByozryLeiDmn1ClZ/Pena4NgpJ4P7UuX9o=
github.com/tkuchiki/faketime v0.0.0-20170607100027-a4500a4f4643/go.mod h1:RXY/TXAwGGL36IKDjrHFMcjpUrEiyWSEtLhFPw3UWF0=
github.com/urfave/cli v1.22.3 h1:FpNT6zq26xNpHZy08emi755QwzLPs6Pukqjlc7RfOMU=
github.com/urfave/cli v1.22.3/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yassinebenaid/godump v0.11.1 h1:SPujx/XaYqGDfmNh7JI3dOyCUVrG0bG2duhO3Eh2EhI=
github.com/yassinebenaid/godump v0.11.1/go.mod h1:dc/0w8wmg6kVIvNGAzbKH1Oa54dXQx8SNKh4dPRyW44=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><path fill="#5865f2" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></svg>

After

Width:  |  Height:  |  Size: 764 B

+186 -156
View File
@@ -1,13 +1,14 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
"time"
"github.com/joho/godotenv"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/yassinebenaid/godump"
)
// Version set at compile-time
@@ -16,19 +17,18 @@ var Version string
func main() {
// Load env-file if it exists first
if filename, found := os.LookupEnv("PLUGIN_ENV_FILE"); found {
godotenv.Load(filename)
_ = godotenv.Load(filename)
}
if _, err := os.Stat("/run/drone/env"); err == nil {
godotenv.Overload("/run/drone/env")
_ = godotenv.Overload("/run/drone/env")
}
year := fmt.Sprintf("%v", time.Now().Year())
app := cli.NewApp()
app.Name = "Drone Discord"
app.Usage = "Sending message to Discord channel using Webhook"
app.Copyright = "Copyright (c) " + year + " Bo-Yi Wu"
app.Authors = []cli.Author{
app.Copyright = "Copyright (c) " + strconv.Itoa(time.Now().Year()) + " Bo-Yi Wu"
app.Authors = []*cli.Author{
{
Name: "Bo-Yi Wu",
Email: "appleboy.tw@gmail.com",
@@ -37,188 +37,209 @@ func main() {
app.Action = run
app.Version = Version
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "webhook-id",
Usage: "discord webhook id",
EnvVar: "PLUGIN_WEBHOOK_ID,WEBHOOK_ID,DISCORD_WEBHOOK_ID,INPUT_WEBHOOK_ID",
&cli.StringFlag{
Name: "webhook-url",
Usage: "The Discord webhook URL to send messages to.",
EnvVars: []string{"PLUGIN_WEBHOOK_URL", "WEBHOOK_URL", "DISCORD_WEBHOOK_URL", "INPUT_WEBHOOK_URL"},
},
cli.StringFlag{
Name: "webhook-token",
Usage: "discord webhook token",
EnvVar: "PLUGIN_WEBHOOK_TOKEN,WEBHOOK_TOKEN,DISCORD_WEBHOOK_TOKEN,INPUT_WEBHOOK_TOKEN",
&cli.StringFlag{
Name: "webhook-id",
Usage: "The Discord webhook ID.",
EnvVars: []string{"PLUGIN_WEBHOOK_ID", "WEBHOOK_ID", "DISCORD_WEBHOOK_ID", "INPUT_WEBHOOK_ID"},
},
cli.StringSliceFlag{
Name: "message",
Usage: "the message contents (up to 2000 characters)",
EnvVar: "PLUGIN_MESSAGE,DISCORD_MESSAGE,MESSAGE,INPUT_MESSAGE",
&cli.StringFlag{
Name: "webhook-token",
Usage: "The Discord webhook token.",
EnvVars: []string{"PLUGIN_WEBHOOK_TOKEN", "WEBHOOK_TOKEN", "DISCORD_WEBHOOK_TOKEN", "INPUT_WEBHOOK_TOKEN"},
},
cli.StringSliceFlag{
Name: "file",
Usage: "the contents of the file being sent",
EnvVar: "PLUGIN_FILE,DISCORD_FILE,FILE,INPUT_FILE",
&cli.StringSliceFlag{
Name: "message",
Usage: "The message contents to send to the Discord channel (up to 2000 characters).",
EnvVars: []string{"PLUGIN_MESSAGE", "DISCORD_MESSAGE", "MESSAGE", "INPUT_MESSAGE"},
},
cli.StringFlag{
Name: "color",
Usage: "color code of the embed",
EnvVar: "PLUGIN_COLOR,COLOR,INPUT_COLOR",
&cli.StringSliceFlag{
Name: "file",
Usage: "The contents of the file being sent to the Discord channel.",
EnvVars: []string{"PLUGIN_FILE", "DISCORD_FILE", "FILE", "INPUT_FILE"},
},
cli.BoolFlag{
Name: "wait",
Usage: "waits for server confirmation of message send before response, and returns the created message body",
EnvVar: "PLUGIN_WAIT,WAIT,INPUT_WAIT",
&cli.StringFlag{
Name: "color",
Usage: "The color code of the embed message.",
EnvVars: []string{"PLUGIN_COLOR", "COLOR", "INPUT_COLOR"},
},
cli.BoolFlag{
Name: "tts",
Usage: "true if this is a TTS message",
EnvVar: "PLUGIN_TTS,TTS,INPUT_TTS",
&cli.BoolFlag{
Name: "wait",
Usage: "Wait for server confirmation of message send before response, and return the created message body.",
EnvVars: []string{"PLUGIN_WAIT", "WAIT", "INPUT_WAIT"},
},
cli.StringFlag{
Name: "username",
Usage: "override the default username of the webhook",
EnvVar: "PLUGIN_USERNAME,USERNAME,INPUT_USERNAME",
&cli.BoolFlag{
Name: "tts",
Usage: "Set to true if this is a Text-to-Speech (TTS) message.",
EnvVars: []string{"PLUGIN_TTS", "TTS", "INPUT_TTS"},
},
cli.StringFlag{
Name: "avatar-url",
Usage: "override the default avatar of the webhook",
EnvVar: "PLUGIN_AVATAR_URL,AVATAR_URL,INPUT_AVATAR_URL",
&cli.StringFlag{
Name: "username",
Usage: "Override the default username of the webhook.",
EnvVars: []string{"PLUGIN_USERNAME", "USERNAME", "INPUT_USERNAME"},
},
cli.BoolFlag{
Name: "drone",
Usage: "environment is drone",
EnvVar: "DRONE",
&cli.StringFlag{
Name: "avatar-url",
Usage: "Override the default avatar of the webhook.",
EnvVars: []string{"PLUGIN_AVATAR_URL", "AVATAR_URL", "INPUT_AVATAR_URL"},
},
cli.StringFlag{
Name: "repo",
Usage: "repository owner and repository name",
EnvVar: "DRONE_REPO,GITHUB_REPOSITORY",
&cli.BoolFlag{
Name: "drone",
Usage: "Indicate if the environment is Drone CI.",
EnvVars: []string{"DRONE"},
},
cli.StringFlag{
Name: "repo.namespace",
Usage: "repository namespace",
EnvVar: "DRONE_REPO_OWNER,DRONE_REPO_NAMESPACE,GITHUB_ACTOR",
&cli.StringFlag{
Name: "ci.environment",
Usage: "The name of the CI environment.",
EnvVars: []string{"CI"},
},
cli.StringFlag{
Name: "repo.name",
Usage: "repository name",
EnvVar: "DRONE_REPO_NAME",
&cli.StringFlag{
Name: "repo",
Usage: "The repository owner and repository name.",
EnvVars: []string{"DRONE_REPO", "CI_REPO", "GITHUB_REPOSITORY"},
},
cli.StringFlag{
Name: "commit.sha",
Usage: "git commit sha",
EnvVar: "DRONE_COMMIT_SHA,GITHUB_SHA",
&cli.StringFlag{
Name: "repo.namespace",
Usage: "The repository namespace.",
EnvVars: []string{"DRONE_REPO_OWNER", "DRONE_REPO_NAMESPACE", "CI_REPO_OWNER", "GITHUB_ACTOR"},
},
cli.StringFlag{
Name: "commit.ref",
Usage: "git commit ref",
EnvVar: "DRONE_COMMIT_REF,GITHUB_REF",
&cli.StringFlag{
Name: "repo.name",
Usage: "The repository name.",
EnvVars: []string{"DRONE_REPO_NAME", "CI_REPO_NAME"},
},
cli.StringFlag{
Name: "commit.branch",
Value: "master",
Usage: "git commit branch",
EnvVar: "DRONE_COMMIT_BRANCH",
&cli.StringFlag{
Name: "commit.sha",
Usage: "The Git commit SHA.",
EnvVars: []string{"DRONE_COMMIT_SHA", "CI_COMMIT_SHA", "GITHUB_SHA"},
},
cli.StringFlag{
Name: "commit.link",
Usage: "git commit link",
EnvVar: "DRONE_COMMIT_LINK",
&cli.StringFlag{
Name: "commit.ref",
Usage: "The Git commit reference.",
EnvVars: []string{"DRONE_COMMIT_REF", "CI_COMMIT_REF", "GITHUB_REF"},
},
cli.StringFlag{
Name: "commit.author",
Usage: "git author name",
EnvVar: "DRONE_COMMIT_AUTHOR",
&cli.StringFlag{
Name: "commit.branch",
Value: "master",
Usage: "The Git commit branch.",
EnvVars: []string{"DRONE_COMMIT_BRANCH", "CI_COMMIT_BRANCH"},
},
cli.StringFlag{
Name: "commit.author.email",
Usage: "git author email",
EnvVar: "DRONE_COMMIT_AUTHOR_EMAIL",
&cli.StringFlag{
Name: "commit.link",
Usage: "The link to the Git commit.",
EnvVars: []string{"DRONE_COMMIT_LINK", "CI_PIPELINE_FORGE_URL"},
},
cli.StringFlag{
Name: "commit.author.avatar",
Usage: "git author avatar",
EnvVar: "DRONE_COMMIT_AUTHOR_AVATAR",
&cli.StringFlag{
Name: "commit.author",
Usage: "The name of the Git commit author.",
EnvVars: []string{"DRONE_COMMIT_AUTHOR", "CI_COMMIT_AUTHOR"},
},
cli.StringFlag{
Name: "commit.message",
Usage: "commit message",
EnvVar: "DRONE_COMMIT_MESSAGE",
&cli.StringFlag{
Name: "commit.author.email",
Usage: "The email of the Git commit author.",
EnvVars: []string{"DRONE_COMMIT_AUTHOR_EMAIL", "CI_COMMIT_AUTHOR_EMAIL"},
},
cli.StringFlag{
Name: "build.event",
Value: "push",
Usage: "build event",
EnvVar: "DRONE_BUILD_EVENT",
&cli.StringFlag{
Name: "commit.author.avatar",
Usage: "The avatar URL of the Git commit author.",
EnvVars: []string{"DRONE_COMMIT_AUTHOR_AVATAR", "CI_COMMIT_AUTHOR_AVATAR"},
},
cli.IntFlag{
Name: "build.number",
Usage: "build number",
EnvVar: "DRONE_BUILD_NUMBER",
&cli.StringFlag{
Name: "commit.message",
Usage: "The Git commit message.",
EnvVars: []string{"DRONE_COMMIT_MESSAGE", "CI_COMMIT_MESSAGE"},
},
cli.StringFlag{
Name: "build.status",
Usage: "build status",
Value: "success",
EnvVar: "DRONE_BUILD_STATUS",
&cli.StringFlag{
Name: "source.branch",
Value: "develop",
Usage: "The Git source branch.",
EnvVars: []string{"DRONE_SOURCE_BRANCH", "CI_COMMIT_SOURCE_BRANCH"},
},
cli.StringFlag{
Name: "build.link",
Usage: "build link",
EnvVar: "DRONE_BUILD_LINK",
&cli.StringFlag{
Name: "build.event",
Value: "push",
Usage: "The build event type.",
EnvVars: []string{"DRONE_BUILD_EVENT", "CI_PIPELINE_EVENT"},
},
cli.StringFlag{
Name: "build.tag",
Usage: "build tag",
EnvVar: "DRONE_TAG",
&cli.IntFlag{
Name: "build.number",
Usage: "The build number.",
EnvVars: []string{"DRONE_BUILD_NUMBER", "CI_PIPELINE_NUMBER"},
},
cli.StringFlag{
Name: "pull.request",
Usage: "pull request",
EnvVar: "DRONE_PULL_REQUEST",
&cli.StringFlag{
Name: "build.status",
Usage: "The build status.",
Value: "success",
EnvVars: []string{"DRONE_BUILD_STATUS", "CI_PIPELINE_STATUS"},
},
cli.Int64Flag{
Name: "build.started",
Usage: "build started",
EnvVar: "DRONE_BUILD_STARTED",
&cli.StringFlag{
Name: "build.link",
Usage: "The link to the build.",
EnvVars: []string{"DRONE_BUILD_LINK", "CI_PIPELINE_URL"},
},
cli.Int64Flag{
Name: "build.finished",
Usage: "build finished",
EnvVar: "DRONE_BUILD_FINISHED",
&cli.StringFlag{
Name: "build.tag",
Usage: "The build tag.",
EnvVars: []string{"DRONE_TAG", "CI_COMMIT_TAG"},
},
cli.BoolFlag{
Name: "github",
Usage: "Boolean value, indicates the runtime environment is GitHub Action.",
EnvVar: "PLUGIN_GITHUB,GITHUB",
&cli.StringFlag{
Name: "pull.request",
Usage: "The pull request number.",
EnvVars: []string{"DRONE_PULL_REQUEST", "CI_COMMIT_PULL_REQUEST"},
},
cli.StringFlag{
Name: "github.workflow",
Usage: "The name of the workflow.",
EnvVar: "GITHUB_WORKFLOW",
&cli.Int64Flag{
Name: "build.started",
Usage: "The timestamp when the build started.",
EnvVars: []string{"DRONE_BUILD_STARTED", "CI_PIPELINE_STARTED"},
},
cli.StringFlag{
Name: "github.action",
Usage: "The name of the action.",
EnvVar: "GITHUB_ACTION",
&cli.Int64Flag{
Name: "build.finished",
Usage: "The timestamp when the build finished.",
EnvVars: []string{"DRONE_BUILD_FINISHED", "CI_PIPELINE_FINISHED"},
},
cli.StringFlag{
Name: "github.event.name",
Usage: "The webhook name of the event that triggered the workflow.",
EnvVar: "GITHUB_EVENT_NAME",
&cli.BoolFlag{
Name: "github",
Usage: "Indicate if the runtime environment is GitHub Actions.",
EnvVars: []string{"PLUGIN_GITHUB", "GITHUB"},
},
cli.StringFlag{
Name: "github.event.path",
Usage: "The path to a file that contains the payload of the event that triggered the workflow. Value: /github/workflow/event.json.",
EnvVar: "GITHUB_EVENT_PATH",
&cli.StringFlag{
Name: "github.workflow",
Usage: "The name of the GitHub Actions workflow.",
EnvVars: []string{"GITHUB_WORKFLOW"},
},
cli.StringFlag{
Name: "github.workspace",
Usage: "The GitHub workspace path. Value: /github/workspace.",
EnvVar: "GITHUB_WORKSPACE",
&cli.StringFlag{
Name: "github.action",
Usage: "The name of the GitHub Actions action.",
EnvVars: []string{"GITHUB_ACTION"},
},
cli.StringFlag{
Name: "deploy.to",
Usage: "Provides the target deployment environment for the running build. This value is only available to promotion and rollback pipelines.",
EnvVar: "DRONE_DEPLOY_TO",
&cli.StringFlag{
Name: "github.event.name",
Usage: "The name of the GitHub event that triggered the workflow.",
EnvVars: []string{"GITHUB_EVENT_NAME"},
},
&cli.StringFlag{
Name: "github.event.path",
Usage: "The path to the file containing the payload of the event that triggered the workflow. Default: /github/workflow/event.json",
EnvVars: []string{"GITHUB_EVENT_PATH"},
},
&cli.StringFlag{
Name: "github.workspace",
Usage: "The GitHub workspace path. Default: /github/workspace",
EnvVars: []string{"GITHUB_WORKSPACE"},
},
&cli.StringFlag{
Name: "deploy.to",
Usage: "The target deployment environment for the running build. This value is only available to promotion and rollback pipelines.",
EnvVars: []string{"DRONE_DEPLOY_TO", "CI_PIPELINE_DEPLOY_TARGET"},
},
&cli.BoolFlag{
Name: "debug",
Usage: "Enable debug mode.",
EnvVars: []string{"PLUGIN_DEBUG", "INPUT_DEBUG", "DEBUG"},
},
}
@@ -251,6 +272,9 @@ func run(c *cli.Context) error {
Avatar: c.String("commit.author.avatar"),
Message: c.String("commit.message"),
},
Source: Source{
Branch: c.String("source.branch"),
},
Build: Build{
Tag: c.String("build.tag"),
Number: c.Int("build.number"),
@@ -263,13 +287,15 @@ func run(c *cli.Context) error {
DeployTo: c.String("deploy.to"),
},
Config: Config{
webhookURL: c.String("webhook-url"),
WebhookID: c.String("webhook-id"),
WebhookToken: c.String("webhook-token"),
Message: c.StringSlice("message"),
File: c.StringSlice("file"),
Color: c.String("color"),
Drone: c.Bool("drone"),
Drone: c.Bool("drone") || c.String("ci.environment") == "woodpecker",
GitHub: c.Bool("github"),
Debug: c.Bool("debug"),
},
Payload: Payload{
Wait: c.Bool("wait"),
@@ -279,5 +305,9 @@ func run(c *cli.Context) error {
},
}
return plugin.Exec()
if plugin.Config.Debug {
_ = godump.Dump(plugin)
}
return plugin.Exec(c.Context)
}
-268
View File
@@ -1,268 +0,0 @@
{
test:: {
kind: 'pipeline',
name: 'testing',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'vet',
image: 'golang:1.14',
pull: 'always',
commands: [
'make vet',
],
volumes: [
{
name: 'gopath',
path: '/go',
},
],
},
{
name: 'lint',
image: 'golang:1.14',
pull: 'always',
commands: [
'make lint',
],
volumes: [
{
name: 'gopath',
path: '/go',
},
],
},
{
name: 'misspell',
image: 'golang:1.14',
pull: 'always',
commands: [
'make misspell-check',
],
volumes: [
{
name: 'gopath',
path: '/go',
},
],
},
{
name: 'test',
image: 'golang:1.14',
pull: 'always',
environment: {
WEBHOOK_ID: { 'from_secret': 'webhook_id' },
WEBHOOK_TOKEN: { 'from_secret': 'webhook_token' },
},
commands: [
'make test',
'make coverage',
],
volumes: [
{
name: 'gopath',
path: '/go',
},
],
},
{
name: 'codecov',
image: 'robertstettner/drone-codecov',
pull: 'always',
settings: {
token: { 'from_secret': 'codecov_token' },
},
},
],
volumes: [
{
name: 'gopath',
temp: {},
},
],
},
build(name, os='linux', arch='amd64'):: {
kind: 'pipeline',
name: os + '-' + arch,
platform: {
os: os,
arch: arch,
},
steps: [
{
name: 'build-push',
image: 'golang:1.14',
pull: 'always',
environment: {
CGO_ENABLED: '0',
},
commands: [
'go build -v -ldflags \'-X main.build=${DRONE_BUILD_NUMBER}\' -a -o release/' + os + '/' + arch + '/' + name,
],
when: {
event: {
exclude: [ 'tag' ],
},
},
},
{
name: 'build-tag',
image: 'golang:1.14',
pull: 'always',
environment: {
CGO_ENABLED: '0',
},
commands: [
'go build -v -ldflags \'-X main.version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}\' -a -o release/' + os + '/' + arch + '/' + name,
],
when: {
event: [ 'tag' ],
},
},
{
name: 'executable',
image: 'golang:1.14',
pull: 'always',
commands: [
'./release/' + os + '/' + arch + '/' + name + ' --help',
],
},
{
name: 'dryrun',
image: 'plugins/docker:' + os + '-' + arch,
pull: 'always',
settings: {
daemon_off: false,
dry_run: true,
tags: os + '-' + arch,
dockerfile: 'docker/Dockerfile.' + os + '.' + arch,
repo: 'appleboy/' + name,
cache_from: 'appleboy/' + name,
},
when: {
event: [ 'pull_request' ],
},
},
{
name: 'publish',
image: 'plugins/docker:' + os + '-' + arch,
pull: 'always',
settings: {
daemon_off: 'false',
auto_tag: true,
auto_tag_suffix: os + '-' + arch,
dockerfile: 'docker/Dockerfile.' + os + '.' + arch,
repo: 'appleboy/' + name,
cache_from: 'appleboy/' + name,
username: { 'from_secret': 'docker_username' },
password: { 'from_secret': 'docker_password' },
},
when: {
event: {
exclude: [ 'pull_request' ],
},
},
},
],
depends_on: [
'testing',
],
trigger: {
ref: [
'refs/heads/master',
'refs/pull/**',
'refs/tags/**',
],
},
},
release:: {
kind: 'pipeline',
name: 'release-binary',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'build-all-binary',
image: 'golang:1.14',
pull: 'always',
commands: [
'make release'
],
when: {
event: [ 'tag' ],
},
},
{
name: 'deploy-all-binary',
image: 'plugins/github-release',
pull: 'always',
settings: {
files: [ 'dist/release/*' ],
api_key: { 'from_secret': 'github_release_api_key' },
},
when: {
event: [ 'tag' ],
},
},
],
depends_on: [
'testing',
],
trigger: {
ref: [
'refs/tags/**',
],
},
},
notifications(os='linux', arch='amd64', depends_on=[]):: {
kind: 'pipeline',
name: 'notifications',
platform: {
os: os,
arch: arch,
},
steps: [
{
name: 'discord',
image: 'appleboy/drone-discord',
pull: 'always',
settings: {
webhook_id: { from_secret: 'webhook_id' },
webhook_token: { from_secret: 'webhook_token' },
message: '{{#success build.status}} Build #{{build.number}} of `{{repo.name}}` succeeded.\n\n📝 Commit by {{commit.author}} on `{{commit.branch}}`:\n``` {{commit.message}} ```\n🌐 {{ build.link }}\n\n duration: {{duration build.started build.finished}} \n\n started: {{datetime build.started "2006/01/02 15:04" "Asia/Taipei"}} \n\n finished: {{datetime build.finished "2006/01/02 15:04" "Asia/Taipei"}} {{else}} Build #{{build.number}} of `{{repo.name}}` failed.\n\n📝 Commit by {{commit.author}} on `{{commit.branch}}`:\n``` {{commit.message}} ```\n🌐 {{ build.link }}\n\n duration: {{duration build.started build.finished}} \n\n started: {{datetime build.started "2006/01/02 15:04" "Asia/Taipei"}} \n\n finished: {{datetime build.finished "2006/01/02 15:04" "Asia/Taipei"}}{{/success}}\n',
},
},
{
name: 'manifest',
image: 'plugins/manifest',
pull: 'always',
settings: {
username: { from_secret: 'docker_username' },
password: { from_secret: 'docker_password' },
spec: 'docker/manifest.tmpl',
ignore_missing: true,
},
},
],
depends_on: depends_on,
trigger: {
ref: [
'refs/heads/master',
'refs/tags/**',
],
},
},
signature(key):: {
kind: 'signature',
hmac: key,
}
}
+210 -103
View File
@@ -2,18 +2,20 @@ package main
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/drone/drone-template-lib/template"
"github.com/appleboy/drone-template-lib/template"
)
const (
@@ -52,6 +54,10 @@ type (
Message string
}
Source struct {
Branch string
}
// Build information.
Build struct {
Tag string
@@ -67,6 +73,7 @@ type (
// Config for the plugin.
Config struct {
webhookURL string
WebhookID string
WebhookToken string
Color string
@@ -74,6 +81,7 @@ type (
File []string
Drone bool
GitHub bool
Debug bool
}
// EmbedFooterObject for Embed Footer Structure.
@@ -110,7 +118,7 @@ type (
Payload struct {
Wait bool `json:"wait"`
Content string `json:"content"`
Username string `json:"username"`
Username string `json:"username,omitempty"`
AvatarURL string `json:"avatar_url"`
TTS bool `json:"tts"`
Embeds []EmbedObject `json:"embeds"`
@@ -118,107 +126,182 @@ type (
// Plugin values.
Plugin struct {
GitHub GitHub
Repo Repo
Build Build
Config Config
Payload Payload
Commit Commit
GitHub GitHub
Repo Repo
Build Build
Source Source
Config Config
Payload Payload
Commit Commit
httpClient *http.Client
}
)
func (c *Config) validate() error {
if c.webhookURL != "" {
if _, err := url.Parse(c.webhookURL); err != nil {
return fmt.Errorf("invalid webhook url: %w", err)
}
return nil
}
var missingFields []string
if c.WebhookID == "" {
missingFields = append(missingFields, "WebhookID")
}
if c.WebhookToken == "" {
missingFields = append(missingFields, "WebhookToken")
}
if len(missingFields) > 0 {
return fmt.Errorf("missing discord config: %s", strings.Join(missingFields, ", "))
}
return nil
}
// Get WebhookURL
func (c *Config) GetWebhookURL() string {
if c.webhookURL != "" {
return c.webhookURL
}
return fmt.Sprintf("https://discord.com/api/webhooks/%s/%s", c.WebhookID, c.WebhookToken)
}
func templateMessage(t string, plugin Plugin) (string, error) {
return template.RenderTrim(t, plugin)
}
// 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 newfileUploadRequest(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) {
// Clean and check path
path = filepath.Clean(path)
file, err := os.Open(path)
if err != nil {
return nil, err
return nil, fmt.Errorf("file %s not accessible: %w", path, err)
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// Add file
part, err := writer.CreateFormFile(paramName, filepath.Base(path))
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to create form file: %w", err)
}
_, err = io.Copy(part, file)
// Stream file content
if _, err = io.Copy(part, file); err != nil {
return nil, fmt.Errorf("failed to write file content: %w", err)
}
// Add extra params
for key, val := range params {
_ = writer.WriteField(key, val)
}
err = writer.Close()
if err != nil {
return nil, err
if err = writer.WriteField(key, val); err != nil {
return nil, fmt.Errorf("failed to write field %s: %w", key, err)
}
}
req, err := http.NewRequest("POST", uri, body)
if err = writer.Close(); err != nil {
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 request: %w", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
return req, err
return req, nil
}
// Exec executes the plugin.
func (p *Plugin) Exec() error {
if p.Config.WebhookID == "" || p.Config.WebhookToken == "" {
return errors.New("missing discord config")
func (p *Plugin) Exec(ctx context.Context) error {
// init http client
p.httpClient = &http.Client{
Timeout: 15 * time.Second,
}
if err := p.Config.validate(); err != nil {
return fmt.Errorf("failed to validate config: %w", err)
}
if err := p.handleMessages(ctx); err != nil {
return err
}
if err := p.handleFiles(ctx); err != nil {
return err
}
return nil
}
// handleMessages sends all configured messages.
func (p *Plugin) handleMessages(ctx context.Context) error {
// 1. Handle empty message (default template)
if len(p.Config.Message) == 0 {
object := p.Template()
p.Payload.Embeds = []EmbedObject{object}
err := p.SendMessage()
if err != nil {
return err
if err := p.SendMessage(ctx); err != nil {
return fmt.Errorf("failed to send default message: %w", err)
}
return nil
}
if len(p.Config.Message) > 0 {
for _, m := range p.Config.Message {
txt, err := templateMessage(m, *p)
if err != nil {
return err
}
if len(p.Config.Color) != 0 {
object := p.DefaultTemplate(txt)
p.Payload.Embeds = append(p.Payload.Embeds, object)
} else {
p.Payload.Content = txt
err = p.SendMessage()
if err != nil {
return err
}
}
}
if len(p.Payload.Embeds) > 0 {
err := p.SendMessage()
if err != nil {
return err
}
}
}
for _, f := range p.Config.File {
if f == "" {
// 2. Handle custom messages
for _, m := range p.Config.Message {
if m == "" {
continue
}
err := p.SendFile(f)
txt, err := templateMessage(m, *p)
if err != nil {
return err
return fmt.Errorf("failed to render template: %w", err)
}
// With color, messages are grouped as embeds
if p.Config.Color != "" {
object := p.DefaultTemplate(txt)
p.Payload.Embeds = append(p.Payload.Embeds, object)
} else {
// Without color, send as plain text immediately
p.Payload.Content = txt
if err := p.SendMessage(ctx); err != nil {
return fmt.Errorf("failed to send plain text message: %w", err)
}
// Reset for next message
p.Clear()
}
}
// 3. Send grouped embeds if any
if len(p.Payload.Embeds) > 0 {
if err := p.SendMessage(ctx); err != nil {
return fmt.Errorf("failed to send embed messages: %w", err)
}
}
return nil
}
// handleFiles sends all configured files.
func (p *Plugin) handleFiles(ctx context.Context) error {
for _, f := range p.Config.File {
if f == "" {
continue
}
if err := p.SendFile(ctx, f); err != nil {
return fmt.Errorf("failed to send file %s: %w", f, err)
}
}
return nil
}
// SendFile upload file to discord
func (p *Plugin) SendFile(file string) error {
webhookURL := fmt.Sprintf("https://discordapp.com/api/webhooks/%s/%s", p.Config.WebhookID, p.Config.WebhookToken)
func (p *Plugin) SendFile(ctx context.Context, file string) error {
webhookURL := p.Config.GetWebhookURL()
extraParams := map[string]string{}
if p.Payload.Username != "" {
@@ -233,35 +316,69 @@ func (p *Plugin) SendFile(file string) error {
extraParams["tts"] = "true"
}
request, err := newfileUploadRequest(
request, err := fileUploadRequest(
ctx,
webhookURL,
extraParams,
"file",
file,
)
if err != nil {
return err
return fmt.Errorf("failed to create file upload request: %w", err)
}
client := &http.Client{}
_, err = client.Do(request)
resp, err := p.httpClient.Do(request)
if err != nil {
return err
return fmt.Errorf("failed to send file: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode >= http.StatusBadRequest {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %w", err)
}
var jsonResponse map[string]interface{}
if err := json.Unmarshal(bodyBytes, &jsonResponse); err != nil {
return fmt.Errorf("failed to send file, status code: %d, body: %s", resp.StatusCode, string(bodyBytes))
}
return fmt.Errorf("failed to send file, status code: %d, error: %s, code: %v", resp.StatusCode, jsonResponse["message"], jsonResponse["code"])
}
return nil
}
// SendMessage to send discord message.
func (p *Plugin) SendMessage() error {
webhookURL := fmt.Sprintf("https://discordapp.com/api/webhooks/%s/%s", p.Config.WebhookID, p.Config.WebhookToken)
func (p *Plugin) SendMessage(ctx context.Context) error {
webhookURL := p.Config.GetWebhookURL()
b := new(bytes.Buffer)
if err := json.NewEncoder(b).Encode(p.Payload); err != nil {
return err
return fmt.Errorf("failed to encode payload: %w", err)
}
_, err := http.Post(webhookURL, "application/json; charset=utf-8", b)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, webhookURL, b)
if err != nil {
return err
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
resp, err := p.httpClient.Do(req)
if err != nil {
return fmt.Errorf("failed to send message: %w", err)
}
defer resp.Body.Close()
// 200 and 204 are both valid status codes for webhooks.
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %w", err)
}
var jsonResponse map[string]interface{}
if err := json.Unmarshal(bodyBytes, &jsonResponse); err != nil {
return fmt.Errorf("failed to unmarshal response body: %w", err)
}
return fmt.Errorf("failed to send message, status code: %d, error: %s, code: %v", resp.StatusCode, jsonResponse["message"], jsonResponse["code"])
}
return nil
@@ -277,37 +394,24 @@ func (p *Plugin) DefaultTemplate(title string) EmbedObject {
// Template is plugin default template for Drone CI or GitHub Action.
func (p *Plugin) Template() EmbedObject {
if p.Config.GitHub {
message := fmt.Sprintf("%s/%s triggered by %s (%s)",
var description string
switch {
case p.Config.GitHub:
description = fmt.Sprintf("%s/%s triggered by %s (%s)",
p.Repo.FullName,
p.GitHub.Workflow,
p.Repo.Namespace,
p.GitHub.EventName,
)
return EmbedObject{
Title: message,
Color: p.Color(),
Footer: EmbedFooterObject{
Text: DroneDesc,
IconURL: DroneIconURL,
},
}
}
description := ""
switch p.Build.Event {
case "push":
case p.Build.Event == "push":
description = fmt.Sprintf("%s pushed to %s", p.Commit.Author, p.Commit.Branch)
case "pull_request":
branch := ""
if p.Commit.Ref != "" {
branch = p.Commit.Ref
} else {
case p.Build.Event == "pull_request":
branch := p.Commit.Ref
if branch == "" {
branch = p.Commit.Branch
}
description = fmt.Sprintf("%s updated pull request %s", p.Commit.Author, branch)
case "tag":
case p.Build.Event == "tag":
description = fmt.Sprintf("%s pushed tag %s", p.Commit.Author, p.Commit.Branch)
}
@@ -336,22 +440,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"]
}
+128 -69
View File
@@ -1,6 +1,7 @@
package main
import (
"context"
"os"
"testing"
"time"
@@ -9,14 +10,48 @@ import (
)
func TestMissingConfig(t *testing.T) {
var plugin Plugin
plugin := Plugin{}
err := plugin.Exec()
err := plugin.Exec(context.Background())
assert.NotNil(t, err)
assert.Error(t, err)
assert.Contains(t, err.Error(), "missing discord config")
}
func TestTemplate(t *testing.T) {
func TestSendPlainTextMessage(t *testing.T) {
plugin := Plugin{
Config: Config{
WebhookID: os.Getenv("WEBHOOK_ID"),
WebhookToken: os.Getenv("WEBHOOK_TOKEN"),
Message: []string{"Hello, world!", "This is a test."},
},
Payload: Payload{
Username: "test-bot",
},
}
err := plugin.Exec(context.Background())
assert.NoError(t, err)
}
func TestSendEmbedMessage(t *testing.T) {
plugin := Plugin{
Config: Config{
WebhookID: os.Getenv("WEBHOOK_ID"),
WebhookToken: os.Getenv("WEBHOOK_TOKEN"),
Message: []string{"This is an embed message."},
Color: "#48f442",
},
Payload: Payload{
Username: "embed-bot",
},
}
err := plugin.Exec(context.Background())
assert.NoError(t, err)
}
func TestSendDefaultMessage(t *testing.T) {
plugin := Plugin{
Repo: Repo{
Name: "go-hello",
@@ -25,96 +60,120 @@ func TestTemplate(t *testing.T) {
Commit: Commit{
Author: "appleboy",
Branch: "master",
Message: "update by drone discord plugin. \r\n update by drone discord plugin.",
Message: "feat: new feature",
Avatar: "https://avatars0.githubusercontent.com/u/21979?v=3&s=100",
},
Build: Build{
Number: 101,
Status: "success",
Link: "https://github.com/appleboy/go-hello",
Event: "tag",
Event: "push",
},
Config: Config{
WebhookID: os.Getenv("WEBHOOK_ID"),
WebhookToken: os.Getenv("WEBHOOK_TOKEN"),
Message: []string{"test one message from drone testing", "test two message from drone testing"},
File: []string{"./images/discord-logo.png"},
Drone: true,
},
Payload: Payload{
Username: "drone",
TTS: false,
Wait: false,
Username: "default-bot",
},
}
err := plugin.Exec()
assert.Nil(t, err)
plugin.Clear()
plugin.Config.Message = []string{"I am appleboy"}
plugin.Payload.TTS = true
plugin.Payload.Wait = true
err = plugin.Exec()
assert.Nil(t, err)
// send success embed message
plugin.Config.Message = []string{}
plugin.Payload.TTS = false
plugin.Payload.Wait = false
plugin.Clear()
err = plugin.Exec()
assert.Nil(t, err)
// send success embed message
plugin.Build.Status = "failure"
plugin.Commit.Message = "send failure embed message"
plugin.Clear()
err = plugin.Exec()
assert.Nil(t, err)
time.Sleep(1 * time.Second)
// send default embed message
plugin.Build.Status = "test"
plugin.Commit.Message = "send default embed message"
plugin.Clear()
err = plugin.Exec()
assert.Nil(t, err)
//change color for embed message
plugin.Config.Color = "#4842f4"
plugin.Commit.Message = "Change embed color to #4842f4"
plugin.Clear()
err = plugin.Exec()
assert.Nil(t, err)
err := plugin.Exec(context.Background())
assert.NoError(t, err)
}
func TestDefaultTemplate(t *testing.T) {
func TestSendFile(t *testing.T) {
// Create a dummy file for testing
dummyFile, err := os.Create("test_file.txt")
assert.NoError(t, err)
_, err = dummyFile.WriteString("This is a test file.")
assert.NoError(t, err)
dummyFile.Close()
defer os.Remove("test_file.txt")
plugin := Plugin{
Config: Config{
WebhookID: os.Getenv("WEBHOOK_ID"),
WebhookToken: os.Getenv("WEBHOOK_TOKEN"),
Message: []string{"default message 1", "default message 2"},
Color: "#48f442",
File: []string{"test_file.txt"},
},
Payload: Payload{
Username: "drone-ci",
TTS: false,
Wait: false,
Username: "file-bot",
},
}
time.Sleep(1 * time.Second)
plugin.Clear()
err := plugin.Exec()
assert.Nil(t, err)
plugin.Config.Color = "#f4be41"
time.Sleep(1 * time.Second)
plugin.Clear()
err = plugin.Exec()
assert.Nil(t, err)
err = plugin.Exec(context.Background())
assert.NoError(t, err)
}
func TestColorConversion(t *testing.T) {
tests := []struct {
name string
colorHex string
expectedInt int
buildStatus string
expectedFall int
}{
{"valid hex", "#ffaa00", 16755200, "success", 1752220},
{"invalid hex", "not-a-hex", 16724530, "failure", 16724530},
{"status success", "", 0, "success", 1754624},
{"status failure", "", 0, "failure", 16724530},
{"status killed", "", 0, "killed", 16724530},
{"status default", "", 0, "running", 16767280},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := Plugin{
Config: Config{Color: tt.colorHex},
Build: Build{Status: tt.buildStatus},
}
if tt.colorHex != "" {
assert.Equal(t, tt.expectedInt, p.Color())
} else {
assert.Equal(t, tt.expectedFall, p.Color())
}
})
}
}
func TestExecWithAllFeatures(t *testing.T) {
time.Sleep(1 * time.Second)
// Create a dummy file for testing
dummyFile, err := os.Create("test_all.txt")
assert.NoError(t, err)
_, err = dummyFile.WriteString("This is a test file for a combined test.")
assert.NoError(t, err)
dummyFile.Close()
defer os.Remove("test_all.txt")
plugin := Plugin{
Repo: Repo{
Name: "go-hello",
Namespace: "appleboy",
},
Commit: Commit{
Author: "appleboy",
Message: "Combined test with multiple features",
},
Build: Build{
Status: "success",
Link: "http://example.com",
},
Config: Config{
WebhookID: os.Getenv("WEBHOOK_ID"),
WebhookToken: os.Getenv("WEBHOOK_TOKEN"),
Message: []string{"First line of embed.", "Second line."},
File: []string{"test_all.txt"},
Color: "#32a852",
Drone: true,
},
Payload: Payload{
Username: "super-bot",
},
}
err = plugin.Exec(context.Background())
assert.NoError(t, err)
}