mirror of
https://github.com/appleboy/drone-telegram.git
synced 2026-06-04 18:23:45 +08:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd7b8b4656 | |||
| 530ced4f2a | |||
| 072876987d | |||
| caaf39fc08 | |||
| d746084872 | |||
| 6379123ca3 | |||
| cff7d4e183 | |||
| 7007692d2e | |||
| 23f0958c87 | |||
| c8c37942c1 | |||
| a7daa0df80 | |||
| f3ace6f519 | |||
| 4de983b4ef | |||
| b4a51bd6b6 | |||
| 30b9c501ff | |||
| cbae1a3737 | |||
| 0bc6220388 | |||
| 8587a97ab1 |
@@ -38,11 +38,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
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.
|
||||
@@ -51,4 +51,4 @@ jobs:
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
uses: github/codeql-action/analyze@v4
|
||||
|
||||
@@ -10,16 +10,22 @@ on:
|
||||
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@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "^1"
|
||||
check-latest: true
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -29,19 +35,19 @@ jobs:
|
||||
make build_linux_arm64
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@@ -49,7 +55,7 @@ jobs:
|
||||
|
||||
- name: Docker meta
|
||||
id: docker-meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: |
|
||||
${{ github.repository }}
|
||||
@@ -60,8 +66,33 @@ jobs:
|
||||
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-telegram:scan
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@v0.36.0
|
||||
with:
|
||||
image-ref: "drone-telegram: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@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
@@ -13,17 +13,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
|
||||
+11
-10
@@ -9,21 +9,21 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
|
||||
- name: Setup golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
uses: golangci/golangci-lint-action@v9
|
||||
with:
|
||||
version: latest
|
||||
version: v2.12
|
||||
args: --verbose
|
||||
|
||||
- uses: hadolint/hadolint-action@v3.1.0
|
||||
- uses: hadolint/hadolint-action@v3.3.0
|
||||
name: hadolint for Dockerfile
|
||||
with:
|
||||
dockerfile: docker/Dockerfile
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
go: [1.22, 1.23]
|
||||
go: [1.25, 1.26]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
go-build: ~/.cache/go-build
|
||||
@@ -43,16 +43,17 @@ jobs:
|
||||
GOPROXY: https://proxy.golang.org
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go }}
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
check-latest: true
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
${{ matrix.go-build }}
|
||||
@@ -64,6 +65,6 @@ jobs:
|
||||
run: |
|
||||
make test
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
flags: ${{ matrix.os }},go-${{ matrix.go }}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
name: Trivy Security Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
# Run daily at 00:00 UTC
|
||||
- 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-telegram:scan
|
||||
|
||||
- name: Run Trivy vulnerability scanner (image)
|
||||
uses: aquasecurity/trivy-action@v0.36.0
|
||||
with:
|
||||
image-ref: "drone-telegram: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"
|
||||
+100
-23
@@ -1,37 +1,114 @@
|
||||
version: "2"
|
||||
output:
|
||||
sort-order:
|
||||
- file
|
||||
linters:
|
||||
disable-all: true
|
||||
default: none
|
||||
enable:
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- dogsled
|
||||
- depguard
|
||||
- errcheck
|
||||
- exportloopref
|
||||
- exhaustive
|
||||
- gochecknoinits
|
||||
- goconst
|
||||
- forbidigo
|
||||
- gocheckcompilerdirectives
|
||||
- gocritic
|
||||
- gofmt
|
||||
- goimports
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- mirror
|
||||
- modernize
|
||||
- nakedret
|
||||
- noctx
|
||||
- nilnil
|
||||
- nolintlint
|
||||
- perfsprint
|
||||
- revive
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- testifylint
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- whitespace
|
||||
- gofumpt
|
||||
|
||||
- usestdlibvars
|
||||
- usetesting
|
||||
- wastedassign
|
||||
settings:
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: io/ioutil
|
||||
desc: use os or io instead
|
||||
- pkg: golang.org/x/exp
|
||||
desc: it's experimental and unreliable
|
||||
- pkg: github.com/pkg/errors
|
||||
desc: use builtin errors package instead
|
||||
nolintlint:
|
||||
allow-unused: false
|
||||
require-explanation: true
|
||||
require-specific: true
|
||||
gocritic:
|
||||
enabled-checks:
|
||||
- equalFold
|
||||
disabled-checks: []
|
||||
revive:
|
||||
severity: error
|
||||
rules:
|
||||
- name: blank-imports
|
||||
- name: constant-logical-expr
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: empty-lines
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: exported
|
||||
- name: identical-branches
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: modifies-value-receiver
|
||||
- name: package-comments
|
||||
- name: redefines-builtin-id
|
||||
- name: superfluous-else
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: var-declaration
|
||||
- name: var-naming
|
||||
disabled: true
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
testifylint: {}
|
||||
usetesting:
|
||||
os-temp-dir: true
|
||||
perfsprint:
|
||||
concat-loop: false
|
||||
govet:
|
||||
enable:
|
||||
- nilness
|
||||
- unusedwrite
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
rules:
|
||||
- linters:
|
||||
- errcheck
|
||||
- staticcheck
|
||||
- unparam
|
||||
path: _test\.go
|
||||
issues:
|
||||
exclude-rules:
|
||||
# Exclude `lll` issues for long lines with `go:generate`.
|
||||
- linters:
|
||||
- lll
|
||||
source: "^//go:generate "
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- golines
|
||||
settings:
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
exclusions:
|
||||
generated: lax
|
||||
run:
|
||||
timeout: 10m
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
DIST := dist
|
||||
EXECUTABLE := drone-telegram
|
||||
GOFMT ?= gofumpt -l
|
||||
DIST := dist
|
||||
@@ -9,7 +8,7 @@ GOFILES := $(shell find . -name "*.go" -type f)
|
||||
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||
XGO_VERSION := go-1.19.x
|
||||
GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
|
||||
|
||||
LINUX_ARCHS ?= linux/amd64,linux/arm64
|
||||
DARWIN_ARCHS ?= darwin-10.12/amd64,darwin-10.12/arm64
|
||||
@@ -116,7 +115,7 @@ coverage:
|
||||
.PHONY: deps-backend
|
||||
deps-backend:
|
||||
$(GO) mod download
|
||||
$(GO) install $(GXZ_PAGAGE)
|
||||
$(GO) install $(GXZ_PACKAGE)
|
||||
$(GO) install $(XGO_PACKAGE)
|
||||
|
||||
.PHONY: release
|
||||
@@ -156,7 +155,7 @@ release-check: | $(DIST_DIRS)
|
||||
|
||||
.PHONY: release-compress
|
||||
release-compress: | $(DIST_DIRS)
|
||||
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PAGAGE) -k -9 $${file}; done;
|
||||
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PACKAGE) -k -9 $${file}; done;
|
||||
|
||||
clean:
|
||||
$(GO) clean -x -i ./...
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||

|
||||
|
||||
[](https://godoc.org/github.com/appleboy/drone-telegram)
|
||||
[](https://github.com/appleboy/drone-telegram/actions/workflows/trivy.yml)
|
||||
[](https://codecov.io/gh/appleboy/drone-telegram)
|
||||
[](https://goreportcard.com/report/github.com/appleboy/drone-telegram)
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.23
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/appleboy/drone-telegram
|
||||
|
||||
go 1.22
|
||||
go 1.25.10
|
||||
|
||||
require (
|
||||
github.com/appleboy/drone-template-lib v1.3.0
|
||||
@@ -28,7 +28,7 @@ require (
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -64,12 +64,12 @@ github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQ
|
||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||
github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM=
|
||||
github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
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.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"log"
|
||||
"maps"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -118,10 +117,10 @@ var icons = map[string]string{
|
||||
}
|
||||
|
||||
func trimElement(keys []string) []string {
|
||||
var newKeys []string
|
||||
newKeys := make([]string, 0, len(keys))
|
||||
|
||||
for _, value := range keys {
|
||||
value = strings.Trim(value, " ")
|
||||
value = strings.TrimSpace(value)
|
||||
if len(value) == 0 {
|
||||
continue
|
||||
}
|
||||
@@ -132,7 +131,7 @@ func trimElement(keys []string) []string {
|
||||
}
|
||||
|
||||
func escapeMarkdown(keys []string) []string {
|
||||
var newKeys []string
|
||||
newKeys := make([]string, 0, len(keys))
|
||||
|
||||
for _, value := range keys {
|
||||
value = escapeMarkdownOne(value)
|
||||
@@ -152,14 +151,20 @@ func escapeMarkdownOne(str string) string {
|
||||
return str
|
||||
}
|
||||
|
||||
func escapeMarkdownFields(fields ...*string) {
|
||||
for _, f := range fields {
|
||||
*f = escapeMarkdownOne(*f)
|
||||
}
|
||||
}
|
||||
|
||||
func globList(keys []string) []string {
|
||||
var newKeys []string
|
||||
newKeys := make([]string, 0, len(keys))
|
||||
|
||||
for _, pattern := range keys {
|
||||
pattern = strings.Trim(pattern, " ")
|
||||
pattern = strings.TrimSpace(pattern)
|
||||
matches, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
fmt.Printf("Glob error for %q: %s\n", pattern, err)
|
||||
log.Printf("Glob error for %q: %s", pattern, err)
|
||||
continue
|
||||
}
|
||||
newKeys = append(newKeys, matches...)
|
||||
@@ -183,7 +188,6 @@ func convertLocation(value string) (Location, bool) {
|
||||
}
|
||||
|
||||
if len(values) > 3 {
|
||||
title = values[2]
|
||||
address = values[3]
|
||||
}
|
||||
|
||||
@@ -208,13 +212,7 @@ func convertLocation(value string) (Location, bool) {
|
||||
}
|
||||
|
||||
func loadTextFromFile(filename string) ([]string, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
r := bufio.NewReader(f)
|
||||
content, err := io.ReadAll(r)
|
||||
content, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -258,12 +256,8 @@ func parseTo(to []string, authorEmail string, matchEmail bool) []int64 {
|
||||
return ids
|
||||
}
|
||||
|
||||
func templateMessage(t string, plugin Plugin) (string, error) {
|
||||
return template.RenderTrim(t, plugin)
|
||||
}
|
||||
|
||||
// Exec executes the plugin.
|
||||
func (p Plugin) Exec() (err error) {
|
||||
func (p *Plugin) Exec() (err error) {
|
||||
if len(p.Config.Token) == 0 || len(p.Config.To) == 0 {
|
||||
return errors.New("missing telegram token or user list")
|
||||
}
|
||||
@@ -273,7 +267,7 @@ func (p Plugin) Exec() (err error) {
|
||||
case len(p.Config.MessageFile) > 0:
|
||||
message, err = loadTextFromFile(p.Config.MessageFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error loading message file '%s': %v", p.Config.MessageFile, err)
|
||||
return fmt.Errorf("error loading message file '%s': %w", p.Config.MessageFile, err)
|
||||
}
|
||||
case len(p.Config.Message) > 0:
|
||||
message = []string{p.Config.Message}
|
||||
@@ -285,36 +279,46 @@ func (p Plugin) Exec() (err error) {
|
||||
if p.Config.TemplateVars != "" {
|
||||
p.Tpl = make(map[string]string)
|
||||
if err = json.Unmarshal([]byte(p.Config.TemplateVars), &p.Tpl); err != nil {
|
||||
return fmt.Errorf("unable to unmarshall template vars from JSON string '%s': %v", p.Config.TemplateVars, err)
|
||||
return fmt.Errorf(
|
||||
"unable to unmarshal template vars from JSON string '%s': %w",
|
||||
p.Config.TemplateVars,
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if p.Config.TemplateVarsFile != "" {
|
||||
content, err := os.ReadFile(p.Config.TemplateVarsFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read file with template vars '%s': %v", p.Config.TemplateVarsFile, err)
|
||||
return fmt.Errorf(
|
||||
"unable to read file with template vars '%s': %w",
|
||||
p.Config.TemplateVarsFile,
|
||||
err,
|
||||
)
|
||||
}
|
||||
vars := make(map[string]string)
|
||||
if err = json.Unmarshal(content, &vars); err != nil {
|
||||
return fmt.Errorf("unable to unmarshall template vars from JSON file '%s': %v", p.Config.TemplateVarsFile, err)
|
||||
return fmt.Errorf(
|
||||
"unable to unmarshal template vars from JSON file '%s': %w",
|
||||
p.Config.TemplateVarsFile,
|
||||
err,
|
||||
)
|
||||
}
|
||||
// Merging templates variables from file to the variables form plugin settings (variables from file takes precedence)
|
||||
// File variables take precedence over inline variables
|
||||
if p.Tpl == nil {
|
||||
p.Tpl = vars
|
||||
} else {
|
||||
for k, v := range vars {
|
||||
p.Tpl[k] = v
|
||||
}
|
||||
maps.Copy(p.Tpl, vars)
|
||||
}
|
||||
}
|
||||
|
||||
var proxyURL *url.URL
|
||||
if proxyURL, err = url.Parse(p.Config.Socks5); err != nil {
|
||||
return fmt.Errorf("unable to unmarshall socks5 proxy url from string '%s': %v", p.Config.Socks5, err)
|
||||
}
|
||||
|
||||
var bot *tgbotapi.BotAPI
|
||||
if len(p.Config.Socks5) > 0 {
|
||||
var proxyURL *url.URL
|
||||
proxyURL, err = url.Parse(p.Config.Socks5)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse socks5 proxy URL '%s': %w", p.Config.Socks5, err)
|
||||
}
|
||||
proxyClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)}}
|
||||
bot, err = tgbotapi.NewBotAPIWithClient(p.Config.Token, proxyClient)
|
||||
} else {
|
||||
@@ -328,12 +332,12 @@ func (p Plugin) Exec() (err error) {
|
||||
bot.Debug = p.Config.Debug
|
||||
|
||||
ids := parseTo(p.Config.To, p.Commit.Email, p.Config.MatchEmail)
|
||||
photos := globList(trimElement(p.Config.Photo))
|
||||
documents := globList(trimElement(p.Config.Document))
|
||||
stickers := globList(trimElement(p.Config.Sticker))
|
||||
audios := globList(trimElement(p.Config.Audio))
|
||||
voices := globList(trimElement(p.Config.Voice))
|
||||
videos := globList(trimElement(p.Config.Video))
|
||||
photos := globList(p.Config.Photo)
|
||||
documents := globList(p.Config.Document)
|
||||
stickers := globList(p.Config.Sticker)
|
||||
audios := globList(p.Config.Audio)
|
||||
voices := globList(p.Config.Voice)
|
||||
videos := globList(p.Config.Video)
|
||||
locations := trimElement(p.Config.Location)
|
||||
venues := trimElement(p.Config.Venue)
|
||||
|
||||
@@ -342,30 +346,43 @@ func (p Plugin) Exec() (err error) {
|
||||
if p.Config.Format == formatMarkdown {
|
||||
message = escapeMarkdown(message)
|
||||
|
||||
p.Commit.Message = escapeMarkdownOne(p.Commit.Message)
|
||||
p.Commit.Branch = escapeMarkdownOne(p.Commit.Branch)
|
||||
p.Commit.Link = escapeMarkdownOne(p.Commit.Link)
|
||||
p.Commit.Author = escapeMarkdownOne(p.Commit.Author)
|
||||
p.Commit.Email = escapeMarkdownOne(p.Commit.Email)
|
||||
|
||||
p.Build.Tag = escapeMarkdownOne(p.Build.Tag)
|
||||
p.Build.Link = escapeMarkdownOne(p.Build.Link)
|
||||
p.Build.PR = escapeMarkdownOne(p.Build.PR)
|
||||
|
||||
p.Repo.Namespace = escapeMarkdownOne(p.Repo.Namespace)
|
||||
p.Repo.Name = escapeMarkdownOne(p.Repo.Name)
|
||||
escapeMarkdownFields(
|
||||
&p.Commit.Message, &p.Commit.Branch, &p.Commit.Link,
|
||||
&p.Commit.Author, &p.Commit.Email,
|
||||
&p.Build.Tag, &p.Build.Link, &p.Build.PR,
|
||||
&p.Repo.Namespace, &p.Repo.Name,
|
||||
)
|
||||
}
|
||||
|
||||
// pre-render message templates (identical for all users)
|
||||
var renderedMessages []string
|
||||
for _, value := range message {
|
||||
txt, err := template.RenderTrim(value, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
renderedMessages = append(renderedMessages, html.UnescapeString(txt))
|
||||
}
|
||||
|
||||
// pre-parse locations and venues (identical for all users)
|
||||
var parsedLocations []Location
|
||||
for _, value := range locations {
|
||||
loc, empty := convertLocation(value)
|
||||
if !empty {
|
||||
parsedLocations = append(parsedLocations, loc)
|
||||
}
|
||||
}
|
||||
|
||||
var parsedVenues []Location
|
||||
for _, value := range venues {
|
||||
loc, empty := convertLocation(value)
|
||||
if !empty {
|
||||
parsedVenues = append(parsedVenues, loc)
|
||||
}
|
||||
}
|
||||
|
||||
// send message.
|
||||
for _, user := range ids {
|
||||
for _, value := range message {
|
||||
txt, err := templateMessage(value, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txt = html.UnescapeString(txt)
|
||||
|
||||
for _, txt := range renderedMessages {
|
||||
msg := tgbotapi.NewMessage(user, txt)
|
||||
msg.ParseMode = p.Config.Format
|
||||
msg.DisableWebPagePreview = p.Config.DisableWebPagePreview
|
||||
@@ -398,7 +415,7 @@ func (p Plugin) Exec() (err error) {
|
||||
|
||||
for _, value := range audios {
|
||||
msg := tgbotapi.NewAudioUpload(user, value)
|
||||
msg.Title = "Audio Message."
|
||||
msg.Title = "Audio Message"
|
||||
if err := p.Send(bot, msg); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -419,27 +436,21 @@ func (p Plugin) Exec() (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
for _, value := range locations {
|
||||
location, empty := convertLocation(value)
|
||||
|
||||
if empty {
|
||||
continue
|
||||
}
|
||||
|
||||
msg := tgbotapi.NewLocation(user, location.Latitude, location.Longitude)
|
||||
for _, loc := range parsedLocations {
|
||||
msg := tgbotapi.NewLocation(user, loc.Latitude, loc.Longitude)
|
||||
if err := p.Send(bot, msg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, value := range venues {
|
||||
location, empty := convertLocation(value)
|
||||
|
||||
if empty {
|
||||
continue
|
||||
}
|
||||
|
||||
msg := tgbotapi.NewVenue(user, location.Title, location.Address, location.Latitude, location.Longitude)
|
||||
for _, loc := range parsedVenues {
|
||||
msg := tgbotapi.NewVenue(
|
||||
user,
|
||||
loc.Title,
|
||||
loc.Address,
|
||||
loc.Latitude,
|
||||
loc.Longitude,
|
||||
)
|
||||
if err := p.Send(bot, msg); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -450,7 +461,7 @@ func (p Plugin) Exec() (err error) {
|
||||
}
|
||||
|
||||
// Send bot message.
|
||||
func (p Plugin) Send(bot *tgbotapi.BotAPI, msg tgbotapi.Chattable) error {
|
||||
func (p *Plugin) Send(bot *tgbotapi.BotAPI, msg tgbotapi.Chattable) error {
|
||||
message, err := bot.Send(msg)
|
||||
|
||||
if p.Config.Debug {
|
||||
@@ -467,7 +478,7 @@ func (p Plugin) Send(bot *tgbotapi.BotAPI, msg tgbotapi.Chattable) error {
|
||||
}
|
||||
|
||||
// Message is plugin default message.
|
||||
func (p Plugin) Message() []string {
|
||||
func (p *Plugin) Message() []string {
|
||||
icon := icons[strings.ToLower(p.Build.Status)]
|
||||
|
||||
if p.Config.GitHub {
|
||||
@@ -485,14 +496,16 @@ func (p Plugin) Message() []string {
|
||||
// chore: update default template
|
||||
//
|
||||
// 🌐 https://cloud.drone.io/appleboy/drone-telegram/106
|
||||
return []string{fmt.Sprintf("%s Build #%d of `%s` %s.\n\n📝 Commit by %s on `%s`:\n``` %s ```\n\n🌐 %s",
|
||||
icon,
|
||||
p.Build.Number,
|
||||
p.Repo.FullName,
|
||||
p.Build.Status,
|
||||
p.Commit.Author,
|
||||
p.Commit.Branch,
|
||||
p.Commit.Message,
|
||||
p.Build.Link,
|
||||
)}
|
||||
return []string{
|
||||
fmt.Sprintf("%s Build #%d of `%s` %s.\n\n📝 Commit by %s on `%s`:\n``` %s ```\n\n🌐 %s",
|
||||
icon,
|
||||
p.Build.Number,
|
||||
p.Repo.FullName,
|
||||
p.Build.Status,
|
||||
p.Commit.Author,
|
||||
p.Commit.Branch,
|
||||
p.Commit.Message,
|
||||
p.Build.Link,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
+66
-31
@@ -7,14 +7,22 @@ import (
|
||||
|
||||
"github.com/appleboy/drone-template-lib/template"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func skipIfNoTelegramSecrets(t *testing.T) {
|
||||
t.Helper()
|
||||
if os.Getenv("TELEGRAM_TOKEN") == "" || os.Getenv("TELEGRAM_TO") == "" {
|
||||
t.Skip("TELEGRAM_TOKEN/TELEGRAM_TO not set; skipping integration test")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissingDefaultConfig(t *testing.T) {
|
||||
var plugin Plugin
|
||||
|
||||
err := plugin.Exec()
|
||||
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestMissingUserConfig(t *testing.T) {
|
||||
@@ -26,7 +34,7 @@ func TestMissingUserConfig(t *testing.T) {
|
||||
|
||||
err := plugin.Exec()
|
||||
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDefaultMessageFormat(t *testing.T) {
|
||||
@@ -51,7 +59,13 @@ func TestDefaultMessageFormat(t *testing.T) {
|
||||
|
||||
message := plugin.Message()
|
||||
|
||||
assert.Equal(t, []string{"✅ Build #101 of `appleboy/go-hello` success.\n\n📝 Commit by Bo-Yi Wu on `master`:\n``` update travis ```\n\n🌐 https://github.com/appleboy/go-hello"}, message)
|
||||
assert.Equal(
|
||||
t,
|
||||
[]string{
|
||||
"✅ Build #101 of `appleboy/go-hello` success.\n\n📝 Commit by Bo-Yi Wu on `master`:\n``` update travis ```\n\n🌐 https://github.com/appleboy/go-hello",
|
||||
},
|
||||
message,
|
||||
)
|
||||
}
|
||||
|
||||
func TestDefaultMessageFormatFromGitHub(t *testing.T) {
|
||||
@@ -73,7 +87,11 @@ func TestDefaultMessageFormatFromGitHub(t *testing.T) {
|
||||
|
||||
message := plugin.Message()
|
||||
|
||||
assert.Equal(t, []string{"appleboy/go-hello/test-workflow triggered by appleboy (push)"}, message)
|
||||
assert.Equal(
|
||||
t,
|
||||
[]string{"appleboy/go-hello/test-workflow triggered by appleboy (push)"},
|
||||
message,
|
||||
)
|
||||
}
|
||||
|
||||
func TestSendMessage(t *testing.T) {
|
||||
@@ -97,8 +115,13 @@ func TestSendMessage(t *testing.T) {
|
||||
},
|
||||
|
||||
Config: Config{
|
||||
Token: os.Getenv("TELEGRAM_TOKEN"),
|
||||
To: []string{os.Getenv("TELEGRAM_TO"), os.Getenv("TELEGRAM_TO") + ":appleboy@gmail.com", "中文ID", "1234567890"},
|
||||
Token: os.Getenv("TELEGRAM_TOKEN"),
|
||||
To: []string{
|
||||
os.Getenv("TELEGRAM_TO"),
|
||||
os.Getenv("TELEGRAM_TO") + ":appleboy@gmail.com",
|
||||
"中文ID",
|
||||
"1234567890",
|
||||
},
|
||||
Message: "Test Telegram Chat Bot From Travis or Local, commit message: 『{{ build.message }}』",
|
||||
Photo: []string{"tests/github.png", "1234", " "},
|
||||
Document: []string{"tests/gophercolor.png", "1234", " "},
|
||||
@@ -106,27 +129,33 @@ func TestSendMessage(t *testing.T) {
|
||||
Audio: []string{"tests/audio.mp3", "1234", " "},
|
||||
Voice: []string{"tests/voice.ogg", "1234", " "},
|
||||
Location: []string{"24.9163213 121.1424972", "1", " "},
|
||||
Venue: []string{"35.661777 139.704051 竹北體育館 新竹縣竹北市", "24.9163213 121.1424972", "1", " "},
|
||||
Video: []string{"tests/video.mp4", "1234", " "},
|
||||
Debug: false,
|
||||
Venue: []string{
|
||||
"35.661777 139.704051 竹北體育館 新竹縣竹北市",
|
||||
"24.9163213 121.1424972",
|
||||
"1",
|
||||
" ",
|
||||
},
|
||||
Video: []string{"tests/video.mp4", "1234", " "},
|
||||
Debug: false,
|
||||
},
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
assert.NotNil(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
plugin.Config.Format = formatMarkdown
|
||||
plugin.Config.Message = "Test escape under_score"
|
||||
err = plugin.Exec()
|
||||
assert.NotNil(t, err)
|
||||
require.Error(t, err)
|
||||
|
||||
// disable message
|
||||
plugin.Config.Message = ""
|
||||
err = plugin.Exec()
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDisableWebPagePreviewMessage(t *testing.T) {
|
||||
skipIfNoTelegramSecrets(t)
|
||||
plugin := Plugin{
|
||||
Config: Config{
|
||||
Token: os.Getenv("TELEGRAM_TOKEN"),
|
||||
@@ -138,16 +167,17 @@ func TestDisableWebPagePreviewMessage(t *testing.T) {
|
||||
|
||||
plugin.Config.Message = "DisableWebPagePreview https://www.google.com.tw"
|
||||
err := plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// disable message
|
||||
plugin.Config.DisableWebPagePreview = false
|
||||
plugin.Config.Message = "EnableWebPagePreview https://www.google.com.tw"
|
||||
err = plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestDisableNotificationMessage(t *testing.T) {
|
||||
skipIfNoTelegramSecrets(t)
|
||||
plugin := Plugin{
|
||||
Config: Config{
|
||||
Token: os.Getenv("TELEGRAM_TOKEN"),
|
||||
@@ -159,13 +189,13 @@ func TestDisableNotificationMessage(t *testing.T) {
|
||||
|
||||
plugin.Config.Message = "DisableNotification https://www.google.com.tw"
|
||||
err := plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// disable message
|
||||
plugin.Config.DisableNotification = false
|
||||
plugin.Config.Message = "EnableNotification https://www.google.com.tw"
|
||||
err = plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestBotError(t *testing.T) {
|
||||
@@ -194,7 +224,7 @@ func TestBotError(t *testing.T) {
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestTrimElement(t *testing.T) {
|
||||
@@ -270,7 +300,7 @@ func TestParseTo(t *testing.T) {
|
||||
|
||||
// test empty ids
|
||||
ids = parseTo([]string{"", " ", " "}, "a@gmail.com", true)
|
||||
assert.Equal(t, 0, len(ids))
|
||||
assert.Empty(t, ids)
|
||||
}
|
||||
|
||||
func TestGlobList(t *testing.T) {
|
||||
@@ -294,27 +324,27 @@ func TestConvertLocation(t *testing.T) {
|
||||
input = "1"
|
||||
result, empty = convertLocation(input)
|
||||
|
||||
assert.Equal(t, true, empty)
|
||||
assert.True(t, empty)
|
||||
assert.Equal(t, Location{}, result)
|
||||
|
||||
// strconv.ParseInt: parsing "測試": invalid syntax
|
||||
input = "測試 139.704051"
|
||||
result, empty = convertLocation(input)
|
||||
|
||||
assert.Equal(t, true, empty)
|
||||
assert.True(t, empty)
|
||||
assert.Equal(t, Location{}, result)
|
||||
|
||||
// strconv.ParseInt: parsing "測試": invalid syntax
|
||||
input = "35.661777 測試"
|
||||
result, empty = convertLocation(input)
|
||||
|
||||
assert.Equal(t, true, empty)
|
||||
assert.True(t, empty)
|
||||
assert.Equal(t, Location{}, result)
|
||||
|
||||
input = "35.661777 139.704051"
|
||||
result, empty = convertLocation(input)
|
||||
|
||||
assert.Equal(t, false, empty)
|
||||
assert.False(t, empty)
|
||||
assert.Equal(t, Location{
|
||||
Latitude: float64(35.661777),
|
||||
Longitude: float64(139.704051),
|
||||
@@ -323,7 +353,7 @@ func TestConvertLocation(t *testing.T) {
|
||||
input = "35.661777 139.704051 title"
|
||||
result, empty = convertLocation(input)
|
||||
|
||||
assert.Equal(t, false, empty)
|
||||
assert.False(t, empty)
|
||||
assert.Equal(t, Location{
|
||||
Title: "title",
|
||||
Address: "",
|
||||
@@ -334,7 +364,7 @@ func TestConvertLocation(t *testing.T) {
|
||||
input = "35.661777 139.704051 title address"
|
||||
result, empty = convertLocation(input)
|
||||
|
||||
assert.Equal(t, false, empty)
|
||||
assert.False(t, empty)
|
||||
assert.Equal(t, Location{
|
||||
Title: "title",
|
||||
Address: "address",
|
||||
@@ -344,6 +374,7 @@ func TestConvertLocation(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHTMLMessage(t *testing.T) {
|
||||
skipIfNoTelegramSecrets(t)
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Name: "go-hello",
|
||||
@@ -374,13 +405,14 @@ Test HTML Format
|
||||
},
|
||||
}
|
||||
|
||||
assert.Nil(t, plugin.Exec())
|
||||
assert.NoError(t, plugin.Exec())
|
||||
|
||||
plugin.Config.MessageFile = "tests/message_html.txt"
|
||||
assert.Nil(t, plugin.Exec())
|
||||
assert.NoError(t, plugin.Exec())
|
||||
}
|
||||
|
||||
func TestMessageFile(t *testing.T) {
|
||||
skipIfNoTelegramSecrets(t)
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Name: "go-hello",
|
||||
@@ -408,10 +440,11 @@ func TestMessageFile(t *testing.T) {
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestTemplateVars(t *testing.T) {
|
||||
skipIfNoTelegramSecrets(t)
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Name: "go-hello",
|
||||
@@ -441,10 +474,11 @@ func TestTemplateVars(t *testing.T) {
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestTemplateVarsFile(t *testing.T) {
|
||||
skipIfNoTelegramSecrets(t)
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Name: "go-hello",
|
||||
@@ -472,10 +506,11 @@ func TestTemplateVarsFile(t *testing.T) {
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestProxySendMessage(t *testing.T) {
|
||||
skipIfNoTelegramSecrets(t)
|
||||
plugin := Plugin{
|
||||
Repo: Repo{
|
||||
Name: "go-hello",
|
||||
@@ -505,7 +540,7 @@ func TestProxySendMessage(t *testing.T) {
|
||||
}
|
||||
|
||||
err := plugin.Exec()
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestBuildTemplate(t *testing.T) {
|
||||
@@ -533,5 +568,5 @@ Commit msg: {{uppercasefirst commit.message}}
|
||||
|
||||
duration: {{duration build.started build.finished}}
|
||||
`, plugin)
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user