mirror of
https://codeberg.org/woodpecker-plugins/go-plugin
synced 2026-06-16 14:49:10 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| deb8bebb75 | |||
| 715e1e0802 | |||
| c8a8fc1983 | |||
| 320f95afae | |||
| 4fba2ed06e | |||
| 64071307b1 | |||
| 00f2fd05f9 | |||
| 4cfd9035eb |
@@ -6,7 +6,7 @@ when:
|
||||
|
||||
steps:
|
||||
- name: release-helper
|
||||
image: docker.io/woodpeckerci/plugin-ready-release-go:4.0.0
|
||||
image: docker.io/woodpeckerci/plugin-ready-release-go:4.1.0
|
||||
settings:
|
||||
release_branch: ${CI_COMMIT_BRANCH}
|
||||
git_email: woodpecker-bot@obermui.de
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## [1.1.0](https://codeberg.org/woodpecker-plugins/go-plugin/releases/tag/v1.1.0) - 2026-03-30
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@OCram85
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- feat(flags): adds support for http proxy config [[#82](https://codeberg.org/woodpecker-plugins/go-plugin/pulls/82)]
|
||||
|
||||
## [1.0.3](https://codeberg.org/woodpecker-plugins/go-plugin/releases/tag/v1.0.3) - 2026-03-07
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@@ -9,12 +9,40 @@ HTTP client library.
|
||||
## Builtin settings
|
||||
|
||||
| Settings Name | Environment variable | Default | Description |
|
||||
| ------------- | -------------------- | ------- | ---------------------------------------------------------------------------- | ------------------------------------ |
|
||||
| ------------- | -------------------- | ------- | ---------------------------------------------------------------------------- |
|
||||
| `log_level` | - | `info` | Sets log level (`panic`, `fatal`, `error`, `warn`, `info`, `debug`, `trace`) |
|
||||
| `skip_verify` | - | `false` | - | Skip verification of TLS certificate |
|
||||
| `skip_verify` | - | `false` | Skip verification of TLS certificate |
|
||||
| | `SOCKS_PROXY` | _none_ | SOCKS5 proxy to use for connections |
|
||||
| | `SOCKS_PROXY_OFF` | _none_ | Do not use SOCKS5 proxy |
|
||||
|
||||
### Optional: HTTP proxy support
|
||||
|
||||
HTTP proxy support is **opt-in** and must be explicitly enabled by the plugin author via `EnableHTTPProxy: true` in `plugin.Options`. When enabled, the following settings become available:
|
||||
|
||||
| Settings Name | Environment variable | Default | Description |
|
||||
| ------------- | -------------------- | ------- | ------------------------------------------------------ |
|
||||
| `http_proxy` | `HTTP_PROXY` | _none_ | HTTP proxy URL for outgoing connections |
|
||||
| `https_proxy` | `HTTPS_PROXY` | _none_ | HTTPS proxy URL for outgoing connections |
|
||||
| `no_proxy` | `NO_PROXY` | _none_ | Comma-separated list of hosts to exclude from proxying |
|
||||
|
||||
The settings are resolved in the following order of precedence:
|
||||
|
||||
1. **Plugin settings** — `PLUGIN_HTTP_PROXY`, `PLUGIN_HTTPS_PROXY`, `PLUGIN_NO_PROXY`
|
||||
2. **Lowercase env vars** — `http_proxy`, `https_proxy`, `no_proxy`
|
||||
3. **Uppercase env vars** — `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`
|
||||
|
||||
Example Woodpecker CI pipeline configuration:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: my-plugin
|
||||
image: my-plugin:latest
|
||||
settings:
|
||||
http_proxy: http://proxy.example.com:3128
|
||||
https_proxy: http://proxy.example.com:3128
|
||||
no_proxy: "localhost,internal.example.com"
|
||||
```
|
||||
|
||||
## Creating plugin
|
||||
|
||||
```go
|
||||
@@ -62,10 +90,11 @@ func main() {
|
||||
}
|
||||
|
||||
p.Plugin = plugin.New(plugin.Options{
|
||||
Name: "sample-plugin",
|
||||
Description: "Sample plugin",
|
||||
Flags: p.Flags(),
|
||||
Execute: p.Execute,
|
||||
Name: "sample-plugin",
|
||||
Description: "Sample plugin",
|
||||
Flags: p.Flags(),
|
||||
Execute: p.Execute,
|
||||
EnableHTTPProxy: true, // opt-in to HTTP proxy support
|
||||
})
|
||||
|
||||
p.Run()
|
||||
|
||||
@@ -6,17 +6,17 @@ toolchain go1.26.1
|
||||
|
||||
require (
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/rs/zerolog v1.34.0
|
||||
github.com/rs/zerolog v1.35.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/urfave/cli/v3 v3.7.0
|
||||
golang.org/x/net v0.51.0
|
||||
github.com/urfave/cli/v3 v3.8.0
|
||||
golang.org/x/net v0.52.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
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/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||
github.com/rs/zerolog v1.35.0 h1:VD0ykx7HMiMJytqINBsKcbLS+BJ4WYjz+05us+LRTdI=
|
||||
github.com/rs/zerolog v1.35.0/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/urfave/cli/v3 v3.7.0 h1:AGSnbUyjtLiM+WJUb4dzXKldl/gL+F8OwmRDtVr6g2U=
|
||||
github.com/urfave/cli/v3 v3.7.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
|
||||
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
|
||||
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
github.com/urfave/cli/v3 v3.8.0 h1:XqKPrm0q4P0q5JpoclYoCAv0/MIvH/jZ2umzuf8pNTI=
|
||||
github.com/urfave/cli/v3 v3.8.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
|
||||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||
golang.org/x/sys v0.42.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.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"crypto/x509"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -55,13 +56,59 @@ func httpClientFlags() []cli.Flag {
|
||||
}
|
||||
}
|
||||
|
||||
func HTTPClientFromContext(c *cli.Command) *http.Client {
|
||||
// httpProxyFlags returns the optional HTTP proxy flags.
|
||||
// Only added to the app when EnableHTTPProxy is set in Options.
|
||||
func httpProxyFlags() []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "transport.http-proxy",
|
||||
Usage: "HTTP proxy URL",
|
||||
Sources: cli.EnvVars(
|
||||
"PLUGIN_HTTP_PROXY",
|
||||
),
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "transport.https-proxy",
|
||||
Usage: "HTTPS proxy URL",
|
||||
Sources: cli.EnvVars(
|
||||
"PLUGIN_HTTPS_PROXY",
|
||||
),
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "transport.no-proxy",
|
||||
Usage: "Hosts to exclude from proxy (comma-separated)",
|
||||
Sources: cli.EnvVars(
|
||||
"PLUGIN_NO_PROXY",
|
||||
),
|
||||
Hidden: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func HTTPClientFromContext(c *cli.Command, httpProxyEnabled bool) *http.Client {
|
||||
var (
|
||||
skip = c.Bool("transport.skip-verify")
|
||||
socks = c.String("transport.socks-proxy")
|
||||
socksOff = c.Bool("transport.socks-proxy-off")
|
||||
)
|
||||
|
||||
if httpProxyEnabled {
|
||||
if v := c.String("transport.http-proxy"); v != "" {
|
||||
os.Setenv("HTTP_PROXY", v)
|
||||
os.Setenv("http_proxy", v)
|
||||
}
|
||||
if v := c.String("transport.https-proxy"); v != "" {
|
||||
os.Setenv("HTTPS_PROXY", v)
|
||||
os.Setenv("https_proxy", v)
|
||||
}
|
||||
if v := c.String("transport.no-proxy"); v != "" {
|
||||
os.Setenv("NO_PROXY", v)
|
||||
os.Setenv("no_proxy", v)
|
||||
}
|
||||
}
|
||||
|
||||
certs, err := x509.SystemCertPool()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to find system CA certs")
|
||||
|
||||
@@ -38,6 +38,10 @@ type Options struct {
|
||||
Execute ExecuteFunc
|
||||
// Context the plugin will use while executing.
|
||||
Context context.Context
|
||||
// EnableHTTPProxy allows plugins to opt-in to HTTP/HTTPS proxy support.
|
||||
// When true, PLUGIN_HTTP_PROXY, PLUGIN_HTTPS_PROXY and PLUGIN_NO_PROXY
|
||||
// are accepted as settings and applied to the HTTP client.
|
||||
EnableHTTPProxy bool
|
||||
}
|
||||
|
||||
// Plugin defines the plugin instance.
|
||||
@@ -46,6 +50,8 @@ type Plugin struct {
|
||||
execute ExecuteFunc
|
||||
client *http.Client
|
||||
ctx context.Context
|
||||
// enableHTTPProxy controls whether HTTP proxy flags are registered and applied.
|
||||
enableHTTPProxy bool
|
||||
// Metadata of the current pipeline.
|
||||
Metadata Metadata
|
||||
}
|
||||
@@ -68,10 +74,16 @@ func New(opt Options) *Plugin {
|
||||
}
|
||||
|
||||
plugin := &Plugin{
|
||||
App: app,
|
||||
execute: opt.Execute,
|
||||
ctx: opt.Context,
|
||||
App: app,
|
||||
execute: opt.Execute,
|
||||
ctx: opt.Context,
|
||||
enableHTTPProxy: opt.EnableHTTPProxy,
|
||||
}
|
||||
|
||||
if opt.EnableHTTPProxy {
|
||||
app.Flags = append(app.Flags, httpProxyFlags()...)
|
||||
}
|
||||
|
||||
plugin.App.Action = plugin.action
|
||||
|
||||
if plugin.ctx == nil {
|
||||
@@ -87,7 +99,7 @@ func (p *Plugin) action(ctx context.Context, c *cli.Command) error {
|
||||
}
|
||||
|
||||
p.Metadata = MetadataFromContext(c)
|
||||
p.client = HTTPClientFromContext(c)
|
||||
p.client = HTTPClientFromContext(c, p.enableHTTPProxy)
|
||||
|
||||
if p.execute == nil {
|
||||
panic("plugin execute function is not set")
|
||||
|
||||
Reference in New Issue
Block a user