mirror of
https://github.com/appleboy/drone-jenkins.git
synced 2026-06-26 15:52:08 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b3682366c | |||
| f88736ff6f | |||
| e1985fadc9 | |||
| 45a9d76c71 | |||
| 5ac640a972 | |||
| 24ef1dc20c |
@@ -38,7 +38,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
go-version: "^1"
|
go-version: "^1"
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
tags: drone-jenkins:scan
|
tags: drone-jenkins:scan
|
||||||
|
|
||||||
- name: Run Trivy vulnerability scanner
|
- name: Run Trivy vulnerability scanner
|
||||||
uses: aquasecurity/trivy-action@v0.35.0
|
uses: aquasecurity/trivy-action@v0.36.0
|
||||||
with:
|
with:
|
||||||
image-ref: "drone-jenkins:scan"
|
image-ref: "drone-jenkins:scan"
|
||||||
format: "sarif"
|
format: "sarif"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ jobs:
|
|||||||
go-version: "stable"
|
go-version: "stable"
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Setup golangci-lint
|
- name: Setup golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v9
|
uses: golangci/golangci-lint-action@v9
|
||||||
with:
|
with:
|
||||||
version: v2.11
|
version: v2.12
|
||||||
args: --verbose
|
args: --verbose
|
||||||
|
|
||||||
- uses: hadolint/hadolint-action@v3.3.0
|
- uses: hadolint/hadolint-action@v3.3.0
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Checkout Code
|
- name: Checkout Code
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.ref }}
|
ref: ${{ github.ref }}
|
||||||
|
|
||||||
@@ -65,6 +65,6 @@ jobs:
|
|||||||
go test -race -cover -coverprofile=coverage.out ./...
|
go test -race -cover -coverprofile=coverage.out ./...
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v7
|
||||||
with:
|
with:
|
||||||
flags: ${{ matrix.os }},go-${{ matrix.go }}
|
flags: ${{ matrix.os }},go-${{ matrix.go }}
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Run Trivy vulnerability scanner (repo)
|
- name: Run Trivy vulnerability scanner (repo)
|
||||||
uses: aquasecurity/trivy-action@v0.35.0
|
uses: aquasecurity/trivy-action@v0.36.0
|
||||||
with:
|
with:
|
||||||
scan-type: "fs"
|
scan-type: "fs"
|
||||||
scan-ref: "."
|
scan-ref: "."
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v6
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
tags: drone-jenkins:scan
|
tags: drone-jenkins:scan
|
||||||
|
|
||||||
- name: Run Trivy vulnerability scanner (image)
|
- name: Run Trivy vulnerability scanner (image)
|
||||||
uses: aquasecurity/trivy-action@v0.35.0
|
uses: aquasecurity/trivy-action@v0.36.0
|
||||||
with:
|
with:
|
||||||
image-ref: "drone-jenkins:scan"
|
image-ref: "drone-jenkins:scan"
|
||||||
format: "sarif"
|
format: "sarif"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module github.com/appleboy/drone-jenkins
|
module github.com/appleboy/drone-jenkins
|
||||||
|
|
||||||
go 1.25.9
|
go 1.25.10
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/appleboy/com v1.1.1
|
github.com/appleboy/com v1.1.1
|
||||||
|
|||||||
+6
-4
@@ -19,6 +19,8 @@ import (
|
|||||||
"github.com/yassinebenaid/godump"
|
"github.com/yassinebenaid/godump"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const tokenParam = "token"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// Auth contain username and token
|
// Auth contain username and token
|
||||||
Auth struct {
|
Auth struct {
|
||||||
@@ -233,7 +235,7 @@ func (jenkins *Jenkins) sendRequest(
|
|||||||
req.Header.Set(crumb.CrumbRequestField, crumb.Crumb)
|
req.Header.Set(crumb.CrumbRequestField, crumb.Crumb)
|
||||||
}
|
}
|
||||||
|
|
||||||
return jenkins.Client.Do(req) //nolint:gosec // user-configured Jenkins URL
|
return jenkins.Client.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jenkins *Jenkins) get(
|
func (jenkins *Jenkins) get(
|
||||||
@@ -487,14 +489,14 @@ func (jenkins *Jenkins) trigger(ctx context.Context, job string, params url.Valu
|
|||||||
if params == nil {
|
if params == nil {
|
||||||
params = url.Values{}
|
params = url.Values{}
|
||||||
}
|
}
|
||||||
params.Set("token", jenkins.Token)
|
params.Set(tokenParam, jenkins.Token)
|
||||||
}
|
}
|
||||||
|
|
||||||
var urlPath string
|
var urlPath string
|
||||||
// Check if params contains build parameters (excluding 'token')
|
// Check if params contains build parameters (excluding 'token')
|
||||||
hasBuildParams := false
|
hasBuildParams := false
|
||||||
for key := range params {
|
for key := range params {
|
||||||
if key != "token" {
|
if key != tokenParam {
|
||||||
hasBuildParams = true
|
hasBuildParams = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -524,7 +526,7 @@ func (jenkins *Jenkins) trigger(ctx context.Context, job string, params url.Valu
|
|||||||
// Create a copy of params with masked token for display
|
// Create a copy of params with masked token for display
|
||||||
displayParams := url.Values{}
|
displayParams := url.Values{}
|
||||||
for key, values := range params {
|
for key, values := range params {
|
||||||
if key == "token" {
|
if key == tokenParam {
|
||||||
// Mask token values for security
|
// Mask token values for security
|
||||||
displayParams[key] = []string{"***MASKED***"}
|
displayParams[key] = []string{"***MASKED***"}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+41
-41
@@ -22,7 +22,7 @@ func TestParseJobPath(t *testing.T) {
|
|||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
auth,
|
auth,
|
||||||
"http://example.com",
|
testExampleURL,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
@@ -38,8 +38,8 @@ func TestParseJobPath(t *testing.T) {
|
|||||||
|
|
||||||
func TestUnSupportProtocol(t *testing.T) {
|
func TestUnSupportProtocol(t *testing.T) {
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, "example.com", "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, "example.com", "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -60,8 +60,8 @@ func TestTriggerBuild(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
@@ -129,8 +129,8 @@ func TestPostAndGetLocation(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -206,8 +206,8 @@ func TestGetQueueItem(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -242,7 +242,7 @@ func TestGetBuildInfo(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "build in progress",
|
name: "build in progress",
|
||||||
jobName: "test-job",
|
jobName: testJobName,
|
||||||
buildNumber: 123,
|
buildNumber: 123,
|
||||||
responseBody: `{"number":123,"building":true,"duration":0,"result":null,` +
|
responseBody: `{"number":123,"building":true,"duration":0,"result":null,` +
|
||||||
`"url":"http://jenkins.example.com/job/test-job/123/"}`,
|
`"url":"http://jenkins.example.com/job/test-job/123/"}`,
|
||||||
@@ -253,7 +253,7 @@ func TestGetBuildInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "build completed successfully",
|
name: "build completed successfully",
|
||||||
jobName: "test-job",
|
jobName: testJobName,
|
||||||
buildNumber: 124,
|
buildNumber: 124,
|
||||||
responseBody: `{"number":124,"building":false,"duration":5000,"result":"SUCCESS",` +
|
responseBody: `{"number":124,"building":false,"duration":5000,"result":"SUCCESS",` +
|
||||||
`"url":"http://jenkins.example.com/job/test-job/124/"}`,
|
`"url":"http://jenkins.example.com/job/test-job/124/"}`,
|
||||||
@@ -264,7 +264,7 @@ func TestGetBuildInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "build failed",
|
name: "build failed",
|
||||||
jobName: "test-job",
|
jobName: testJobName,
|
||||||
buildNumber: 125,
|
buildNumber: 125,
|
||||||
responseBody: `{"number":125,"building":false,"duration":3000,"result":"FAILURE",` +
|
responseBody: `{"number":125,"building":false,"duration":3000,"result":"FAILURE",` +
|
||||||
`"url":"http://jenkins.example.com/job/test-job/125/"}`,
|
`"url":"http://jenkins.example.com/job/test-job/125/"}`,
|
||||||
@@ -275,7 +275,7 @@ func TestGetBuildInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "build not found",
|
name: "build not found",
|
||||||
jobName: "test-job",
|
jobName: testJobName,
|
||||||
buildNumber: 999,
|
buildNumber: 999,
|
||||||
responseBody: "Not Found",
|
responseBody: "Not Found",
|
||||||
responseStatus: http.StatusNotFound,
|
responseStatus: http.StatusNotFound,
|
||||||
@@ -295,8 +295,8 @@ func TestGetBuildInfo(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -358,15 +358,15 @@ func TestWaitForCompletion(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
buildInfo, err := jenkins.waitForCompletion(
|
buildInfo, err := jenkins.waitForCompletion(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
"test-job",
|
testJobName,
|
||||||
queueID,
|
queueID,
|
||||||
100*time.Millisecond,
|
100*time.Millisecond,
|
||||||
5*time.Second,
|
5*time.Second,
|
||||||
@@ -392,15 +392,15 @@ func TestWaitForCompletion(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
buildInfo, err := jenkins.waitForCompletion(
|
buildInfo, err := jenkins.waitForCompletion(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
"test-job",
|
testJobName,
|
||||||
queueID,
|
queueID,
|
||||||
50*time.Millisecond,
|
50*time.Millisecond,
|
||||||
200*time.Millisecond,
|
200*time.Millisecond,
|
||||||
@@ -434,15 +434,15 @@ func TestWaitForCompletion(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
buildInfo, err := jenkins.waitForCompletion(
|
buildInfo, err := jenkins.waitForCompletion(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
"test-job",
|
testJobName,
|
||||||
queueID,
|
queueID,
|
||||||
50*time.Millisecond,
|
50*time.Millisecond,
|
||||||
200*time.Millisecond,
|
200*time.Millisecond,
|
||||||
@@ -485,15 +485,15 @@ func TestWaitForCompletion(t *testing.T) {
|
|||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
jenkins, err := NewJenkins(context.Background(), auth, server.URL, "", false, "", false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
buildInfo, err := jenkins.waitForCompletion(
|
buildInfo, err := jenkins.waitForCompletion(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
"test-job",
|
testJobName,
|
||||||
queueID,
|
queueID,
|
||||||
50*time.Millisecond,
|
50*time.Millisecond,
|
||||||
5*time.Second,
|
5*time.Second,
|
||||||
@@ -626,8 +626,8 @@ func TestLoadCACert(t *testing.T) {
|
|||||||
func TestNewJenkinsWithCACert(t *testing.T) {
|
func TestNewJenkinsWithCACert(t *testing.T) {
|
||||||
t.Run("with valid CA certificate", func(t *testing.T) {
|
t.Run("with valid CA certificate", func(t *testing.T) {
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
@@ -650,8 +650,8 @@ func TestNewJenkinsWithCACert(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
@@ -668,8 +668,8 @@ func TestNewJenkinsWithCACert(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("with invalid CA certificate content", func(t *testing.T) {
|
t.Run("with invalid CA certificate content", func(t *testing.T) {
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
@@ -687,8 +687,8 @@ func TestNewJenkinsWithCACert(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("with invalid PEM format", func(t *testing.T) {
|
t.Run("with invalid PEM format", func(t *testing.T) {
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
invalidPEM := "-----BEGIN CERTIFICATE-----\ninvalid-base64-data\n-----END CERTIFICATE-----"
|
invalidPEM := "-----BEGIN CERTIFICATE-----\ninvalid-base64-data\n-----END CERTIFICATE-----"
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
@@ -707,8 +707,8 @@ func TestNewJenkinsWithCACert(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("with nonexistent file path", func(t *testing.T) {
|
t.Run("with nonexistent file path", func(t *testing.T) {
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
@@ -726,8 +726,8 @@ func TestNewJenkinsWithCACert(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("insecure flag takes precedence over CA cert", func(t *testing.T) {
|
t.Run("insecure flag takes precedence over CA cert", func(t *testing.T) {
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
// When insecure is true, CA cert should be ignored
|
// When insecure is true, CA cert should be ignored
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
@@ -745,8 +745,8 @@ func TestNewJenkinsWithCACert(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("without CA certificate uses default client", func(t *testing.T) {
|
t.Run("without CA certificate uses default client", func(t *testing.T) {
|
||||||
auth := &Auth{
|
auth := &Auth{
|
||||||
Username: "test",
|
Username: testUserName,
|
||||||
Token: "test",
|
Token: testUserName,
|
||||||
}
|
}
|
||||||
jenkins, err := NewJenkins(
|
jenkins, err := NewJenkins(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ func main() {
|
|||||||
EnvVars: []string{"PLUGIN_USER", "JENKINS_USER", "INPUT_USER"},
|
EnvVars: []string{"PLUGIN_USER", "JENKINS_USER", "INPUT_USER"},
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "token",
|
Name: tokenParam,
|
||||||
Aliases: []string{"t"},
|
Aliases: []string{"t"},
|
||||||
Usage: "jenkins API token for authentication",
|
Usage: "jenkins API token for authentication",
|
||||||
EnvVars: []string{"PLUGIN_TOKEN", "JENKINS_TOKEN", "INPUT_TOKEN"},
|
EnvVars: []string{"PLUGIN_TOKEN", "JENKINS_TOKEN", "INPUT_TOKEN"},
|
||||||
@@ -175,7 +175,7 @@ func run(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate authentication: either (user + token) or remote-token must be provided
|
// Validate authentication: either (user + token) or remote-token must be provided
|
||||||
hasUserAuth := c.String("user") != "" && c.String("token") != ""
|
hasUserAuth := c.String("user") != "" && c.String(tokenParam) != ""
|
||||||
hasRemoteToken := c.String("remote-token") != ""
|
hasRemoteToken := c.String("remote-token") != ""
|
||||||
|
|
||||||
if !hasUserAuth && !hasRemoteToken {
|
if !hasUserAuth && !hasRemoteToken {
|
||||||
@@ -185,7 +185,7 @@ func run(c *cli.Context) error {
|
|||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: c.String("host"),
|
BaseURL: c.String("host"),
|
||||||
Username: c.String("user"),
|
Username: c.String("user"),
|
||||||
Token: c.String("token"),
|
Token: c.String(tokenParam),
|
||||||
RemoteToken: c.String("remote-token"),
|
RemoteToken: c.String("remote-token"),
|
||||||
Job: c.StringSlice("job"),
|
Job: c.StringSlice("job"),
|
||||||
Insecure: c.Bool("insecure"),
|
Insecure: c.Bool("insecure"),
|
||||||
|
|||||||
+61
-61
@@ -34,53 +34,53 @@ func TestValidateConfig(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "missing authentication",
|
name: "missing authentication",
|
||||||
plugin: Plugin{
|
plugin: Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
},
|
},
|
||||||
wantError: true,
|
wantError: true,
|
||||||
errorMsg: "authentication required",
|
errorMsg: testAuthRequiredErr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing token (only username)",
|
name: "missing token (only username)",
|
||||||
plugin: Plugin{
|
plugin: Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
},
|
},
|
||||||
wantError: true,
|
wantError: true,
|
||||||
errorMsg: "authentication required",
|
errorMsg: testAuthRequiredErr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing username (only token)",
|
name: "missing username (only token)",
|
||||||
plugin: Plugin{
|
plugin: Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
},
|
},
|
||||||
wantError: true,
|
wantError: true,
|
||||||
errorMsg: "authentication required",
|
errorMsg: testAuthRequiredErr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "user and token auth",
|
name: "user and token auth",
|
||||||
plugin: Plugin{
|
plugin: Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
},
|
},
|
||||||
wantError: false,
|
wantError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "remote token auth",
|
name: "remote token auth",
|
||||||
plugin: Plugin{
|
plugin: Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
RemoteToken: "remote-token-123",
|
RemoteToken: testRemoteTokenValue,
|
||||||
},
|
},
|
||||||
wantError: false,
|
wantError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "both auth methods",
|
name: "both auth methods",
|
||||||
plugin: Plugin{
|
plugin: Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
RemoteToken: "remote-token-123",
|
RemoteToken: testRemoteTokenValue,
|
||||||
},
|
},
|
||||||
wantError: false,
|
wantError: false,
|
||||||
},
|
},
|
||||||
@@ -118,7 +118,7 @@ func TestTrimWhitespaceFromSlice(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "all whitespace",
|
name: "all whitespace",
|
||||||
input: []string{" ", "\t", "\n"},
|
input: []string{testWhitespaceVal, "\t", "\n"},
|
||||||
expected: []string{},
|
expected: []string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -129,12 +129,12 @@ func TestTrimWhitespaceFromSlice(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "trim surrounding whitespace",
|
name: "trim surrounding whitespace",
|
||||||
input: []string{" foo ", " bar ", "baz"},
|
input: []string{" foo ", " bar ", "baz"},
|
||||||
expected: []string{"foo", "bar", "baz"},
|
expected: []string{testUserFoo, testUserBar, "baz"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mixed empty and valid",
|
name: "mixed empty and valid",
|
||||||
input: []string{"", "valid", "", "also-valid", ""},
|
input: []string{"", testValidStr, "", "also-valid", ""},
|
||||||
expected: []string{"valid", "also-valid"},
|
expected: []string{testValidStr, "also-valid"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,29 +157,29 @@ func TestParseParameters(t *testing.T) {
|
|||||||
name: "valid parameters",
|
name: "valid parameters",
|
||||||
input: "key1=value1\nkey2=value2",
|
input: "key1=value1\nkey2=value2",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"key1": []string{"value1"},
|
testParamKey1: []string{testParamValue1},
|
||||||
"key2": []string{"value2"},
|
testParamKey2: []string{testParamValue2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "parameter with multiple equals signs",
|
name: "parameter with multiple equals signs",
|
||||||
input: "key=value=with=equals",
|
input: "key=value=with=equals",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"key": []string{"value=with=equals"},
|
testParamKey: []string{"value=with=equals"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "parameter with spaces in value",
|
name: "parameter with spaces in value",
|
||||||
input: "key=value with spaces",
|
input: "key=value with spaces",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"key": []string{"value with spaces"},
|
testParamKey: []string{"value with spaces"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "parameter with empty value",
|
name: "parameter with empty value",
|
||||||
input: "key=",
|
input: "key=",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"key": []string{""},
|
testParamKey: []string{""},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -196,15 +196,15 @@ func TestParseParameters(t *testing.T) {
|
|||||||
name: "mixed valid and invalid",
|
name: "mixed valid and invalid",
|
||||||
input: "valid=yes\ninvalid\nalso=valid",
|
input: "valid=yes\ninvalid\nalso=valid",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"valid": []string{"yes"},
|
testValidStr: []string{"yes"},
|
||||||
"also": []string{"valid"},
|
"also": []string{testValidStr},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "key with surrounding whitespace",
|
name: "key with surrounding whitespace",
|
||||||
input: " key =value",
|
input: " key =value",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"key": []string{"value"},
|
testParamKey: []string{"value"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -216,16 +216,16 @@ func TestParseParameters(t *testing.T) {
|
|||||||
name: "multiple empty lines",
|
name: "multiple empty lines",
|
||||||
input: "key1=value1\n\n\nkey2=value2",
|
input: "key1=value1\n\n\nkey2=value2",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"key1": []string{"value1"},
|
testParamKey1: []string{testParamValue1},
|
||||||
"key2": []string{"value2"},
|
testParamKey2: []string{testParamValue2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "lines with whitespace only",
|
name: "lines with whitespace only",
|
||||||
input: "key1=value1\n \n\t\nkey2=value2",
|
input: "key1=value1\n \n\t\nkey2=value2",
|
||||||
expected: url.Values{
|
expected: url.Values{
|
||||||
"key1": []string{"value1"},
|
testParamKey1: []string{testParamValue1},
|
||||||
"key2": []string{"value2"},
|
testParamKey2: []string{testParamValue2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -252,28 +252,28 @@ func TestExecMissingConfig(t *testing.T) {
|
|||||||
// TestExecMissingJenkinsUsername tests Exec with missing username
|
// TestExecMissingJenkinsUsername tests Exec with missing username
|
||||||
func TestExecMissingJenkinsUsername(t *testing.T) {
|
func TestExecMissingJenkinsUsername(t *testing.T) {
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := plugin.Exec(context.Background())
|
err := plugin.Exec(context.Background())
|
||||||
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), "configuration error")
|
assert.Contains(t, err.Error(), "configuration error")
|
||||||
assert.Contains(t, err.Error(), "authentication required")
|
assert.Contains(t, err.Error(), testAuthRequiredErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestExecMissingJenkinsToken tests Exec with missing token
|
// TestExecMissingJenkinsToken tests Exec with missing token
|
||||||
func TestExecMissingJenkinsToken(t *testing.T) {
|
func TestExecMissingJenkinsToken(t *testing.T) {
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := plugin.Exec(context.Background())
|
err := plugin.Exec(context.Background())
|
||||||
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), "configuration error")
|
assert.Contains(t, err.Error(), "configuration error")
|
||||||
assert.Contains(t, err.Error(), "authentication required")
|
assert.Contains(t, err.Error(), testAuthRequiredErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestExecMissingJenkinsJob tests Exec with missing or empty job list
|
// TestExecMissingJenkinsJob tests Exec with missing or empty job list
|
||||||
@@ -288,7 +288,7 @@ func TestExecMissingJenkinsJob(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "only whitespace jobs",
|
name: "only whitespace jobs",
|
||||||
jobs: []string{" ", "\t", "\n"},
|
jobs: []string{testWhitespaceVal, "\t", "\n"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nil jobs",
|
name: "nil jobs",
|
||||||
@@ -299,9 +299,9 @@ func TestExecMissingJenkinsJob(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: "http://example.com",
|
BaseURL: testExampleURL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
Job: tt.jobs,
|
Job: tt.jobs,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,8 +326,8 @@ func TestExecTriggerBuild(t *testing.T) {
|
|||||||
|
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: server.URL,
|
BaseURL: server.URL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
Job: []string{"drone-jenkins"},
|
Job: []string{"drone-jenkins"},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,8 +353,8 @@ func TestExecTriggerMultipleJobs(t *testing.T) {
|
|||||||
|
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: server.URL,
|
BaseURL: server.URL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
Job: []string{"job1", "job2", "job3"},
|
Job: []string{"job1", "job2", "job3"},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,8 +377,8 @@ func TestExecWithParameters(t *testing.T) {
|
|||||||
|
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: server.URL,
|
BaseURL: server.URL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
Job: []string{"parameterized-job"},
|
Job: []string{"parameterized-job"},
|
||||||
Parameters: "branch=main\nenvironment=production",
|
Parameters: "branch=main\nenvironment=production",
|
||||||
}
|
}
|
||||||
@@ -403,16 +403,16 @@ func TestExecWithRemoteToken(t *testing.T) {
|
|||||||
|
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: server.URL,
|
BaseURL: server.URL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
RemoteToken: "remote-token-123",
|
RemoteToken: testRemoteTokenValue,
|
||||||
Job: []string{"secure-job"},
|
Job: []string{"secure-job"},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := plugin.Exec(context.Background())
|
err := plugin.Exec(context.Background())
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "remote-token-123", receivedToken)
|
assert.Equal(t, testRemoteTokenValue, receivedToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestExecWithJobsContainingWhitespace tests job list with whitespace
|
// TestExecWithJobsContainingWhitespace tests job list with whitespace
|
||||||
@@ -432,9 +432,9 @@ func TestExecWithJobsContainingWhitespace(t *testing.T) {
|
|||||||
|
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: server.URL,
|
BaseURL: server.URL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
Job: []string{" job1 ", "job2", " ", "job3"},
|
Job: []string{" job1 ", "job2", testWhitespaceVal, "job3"},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := plugin.Exec(context.Background())
|
err := plugin.Exec(context.Background())
|
||||||
@@ -467,9 +467,9 @@ func TestExecWithWaitSuccess(t *testing.T) {
|
|||||||
|
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: server.URL,
|
BaseURL: server.URL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
Job: []string{"test-job"},
|
Job: []string{testJobName},
|
||||||
Wait: true,
|
Wait: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,9 +501,9 @@ func TestExecWithWaitFailure(t *testing.T) {
|
|||||||
|
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: server.URL,
|
BaseURL: server.URL,
|
||||||
Username: "foo",
|
Username: testUserFoo,
|
||||||
Token: "bar",
|
Token: testUserBar,
|
||||||
Job: []string{"test-job"},
|
Job: []string{testJobName},
|
||||||
Wait: true,
|
Wait: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
const (
|
||||||
|
testUserFoo = "foo"
|
||||||
|
testUserBar = "bar"
|
||||||
|
testUserName = "test"
|
||||||
|
testJobName = "test-job"
|
||||||
|
testExampleURL = "http://example.com"
|
||||||
|
testAuthRequiredErr = "authentication required"
|
||||||
|
testRemoteTokenValue = "remote-token-123"
|
||||||
|
testWhitespaceVal = " "
|
||||||
|
testValidStr = "valid"
|
||||||
|
testParamKey = "key"
|
||||||
|
testParamKey1 = "key1"
|
||||||
|
testParamKey2 = "key2"
|
||||||
|
testParamValue1 = "value1"
|
||||||
|
testParamValue2 = "value2"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user