mirror of
https://github.com/appleboy/drone-jenkins.git
synced 2026-06-16 14:49:16 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fbf3e5cd6 | |||
| 95a5eb125f |
@@ -10,11 +10,6 @@ on:
|
||||
branches:
|
||||
- "master"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
build-docker:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -23,7 +18,6 @@ jobs:
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "^1"
|
||||
check-latest: true
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
@@ -35,13 +29,13 @@ jobs:
|
||||
make build_linux_arm64
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v4
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v4
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@@ -49,7 +43,7 @@ jobs:
|
||||
|
||||
- name: Docker meta
|
||||
id: docker-meta
|
||||
uses: docker/metadata-action@v6
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/${{ github.repository }}
|
||||
@@ -59,33 +53,8 @@ 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-jenkins:scan
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@v0.35.0
|
||||
with:
|
||||
image-ref: "drone-jenkins: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
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
check-latest: true
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
|
||||
@@ -12,14 +12,13 @@ jobs:
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "stable"
|
||||
check-latest: true
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup golangci-lint
|
||||
uses: golangci/golangci-lint-action@v9
|
||||
with:
|
||||
version: v2.11
|
||||
version: v2.6
|
||||
args: --verbose
|
||||
|
||||
- uses: hadolint/hadolint-action@v3.3.0
|
||||
@@ -31,7 +30,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
go: ["1.25", "1.26"]
|
||||
go: ["1.25"]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
go-build: ~/.cache/go-build
|
||||
@@ -45,7 +44,6 @@ jobs:
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
check-latest: true
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
+24
-53
@@ -10,76 +10,47 @@ on:
|
||||
schedule:
|
||||
# Run daily at 00:00 UTC
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
workflow_dispatch: # Allow manual trigger
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
security-events: write # Required for uploading SARIF results
|
||||
|
||||
jobs:
|
||||
trivy-repo-scan:
|
||||
name: Trivy Repository Scan
|
||||
trivy-scan:
|
||||
name: Trivy Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run Trivy vulnerability scanner (repo)
|
||||
uses: aquasecurity/trivy-action@v0.35.0
|
||||
- name: Run Trivy vulnerability scanner (source code)
|
||||
uses: aquasecurity/trivy-action@0.33.1
|
||||
with:
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
scanners: "vuln,secret,misconfig"
|
||||
format: "sarif"
|
||||
output: "trivy-repo-results.sarif"
|
||||
severity: "CRITICAL,HIGH"
|
||||
output: "trivy-results.sarif"
|
||||
severity: "CRITICAL,HIGH,MEDIUM"
|
||||
ignore-unfixed: true
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
- name: Upload Trivy results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: "trivy-repo-results.sarif"
|
||||
sarif_file: "trivy-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-jenkins:scan
|
||||
|
||||
- name: Run Trivy vulnerability scanner (image)
|
||||
uses: aquasecurity/trivy-action@v0.35.0
|
||||
with:
|
||||
image-ref: "drone-jenkins: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
|
||||
- name: Run Trivy scanner (table output for logs)
|
||||
uses: aquasecurity/trivy-action@0.33.1
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: "trivy-image-results.sarif"
|
||||
category: "trivy-image"
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
scanners: "vuln,secret,misconfig"
|
||||
format: "table"
|
||||
severity: "CRITICAL,HIGH,MEDIUM"
|
||||
ignore-unfixed: true
|
||||
exit-code: "1"
|
||||
|
||||
@@ -46,16 +46,10 @@ Whether you're managing a hybrid CI/CD environment or orchestrating complex mult
|
||||
- [Configuration](#configuration)
|
||||
- [Jenkins Server Setup](#jenkins-server-setup)
|
||||
- [Authentication](#authentication)
|
||||
- [Understanding Jenkins Authentication](#understanding-jenkins-authentication)
|
||||
- [CSRF Protection Notice](#csrf-protection-notice)
|
||||
- [Parameters Reference](#parameters-reference)
|
||||
- [Usage](#usage)
|
||||
- [Command Line](#command-line)
|
||||
- [Docker](#docker)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Error: 403 No valid crumb was included in the request](#error-403-no-valid-crumb-was-included-in-the-request)
|
||||
- [Error: 401 Unauthorized](#error-401-unauthorized)
|
||||
- [Remote Token Not Working](#remote-token-not-working)
|
||||
- [Development](#development)
|
||||
- [Building](#building)
|
||||
- [Testing](#testing)
|
||||
@@ -131,20 +125,7 @@ docker run -d -v jenkins_home:/var/jenkins_home -p 8080:8080 -p 50000:50000 --re
|
||||
|
||||
### Authentication
|
||||
|
||||
#### Understanding Jenkins Authentication
|
||||
|
||||
Jenkins supports multiple authentication methods for triggering builds. This tool supports two approaches:
|
||||
|
||||
**1. API Token Authentication (Recommended)**
|
||||
|
||||
Use Jenkins user credentials with an API token. This method:
|
||||
|
||||
- ✅ Works with all Jenkins configurations
|
||||
- ✅ Supports CSRF protection (enabled by default in modern Jenkins)
|
||||
- ✅ Supports wait mode to monitor build completion
|
||||
- ✅ Provides full access to Jenkins API features
|
||||
|
||||
To create an API token:
|
||||
Jenkins API tokens are recommended for authentication. To create an API token:
|
||||
|
||||
1. Log into Jenkins
|
||||
2. Click on your username (top right)
|
||||
@@ -155,42 +136,7 @@ To create an API token:
|
||||
|
||||

|
||||
|
||||
**2. Remote Trigger Token Authentication**
|
||||
|
||||
Use a remote trigger token configured in your Jenkins job. **Important limitations**:
|
||||
|
||||
- ⚠️ **Does not work** with Jenkins CSRF protection enabled (default in modern Jenkins)
|
||||
- ⚠️ Requires anonymous users to have read access to the job, OR
|
||||
- ⚠️ Must be combined with API token authentication (see Combined Authentication below)
|
||||
|
||||
**3. Combined Authentication (Recommended for Remote Tokens)**
|
||||
|
||||
Use both API token and remote trigger token together:
|
||||
|
||||
- ✅ Works with CSRF protection enabled
|
||||
- ✅ Provides double authentication security
|
||||
- ✅ Supports all features including wait mode
|
||||
|
||||
```bash
|
||||
drone-jenkins \
|
||||
--host http://jenkins.example.com/ \
|
||||
--user YOUR_USERNAME \
|
||||
--token YOUR_API_TOKEN \
|
||||
--remote-token YOUR_REMOTE_TOKEN \
|
||||
--job my-jenkins-job
|
||||
```
|
||||
|
||||
#### CSRF Protection Notice
|
||||
|
||||
Modern Jenkins installations have CSRF protection enabled by default. If you encounter errors like:
|
||||
|
||||
```txt
|
||||
Error 403 No valid crumb was included in the request
|
||||
```
|
||||
|
||||
This means your Jenkins has CSRF protection enabled. You **must** use API token authentication (option 1 or 3 above). Remote trigger token alone will not work.
|
||||
|
||||
For more information about Jenkins CSRF protection, see the [official Jenkins documentation](https://www.jenkins.io/doc/book/security/csrf-protection/).
|
||||
Alternatively, you can use a remote trigger token configured in your Jenkins job settings.
|
||||
|
||||
### Parameters Reference
|
||||
|
||||
@@ -209,19 +155,10 @@ For more information about Jenkins CSRF protection, see the [official Jenkins do
|
||||
| Timeout | `--timeout` | `PLUGIN_TIMEOUT`, `JENKINS_TIMEOUT` | No | Maximum time to wait for job completion (default: 30m) |
|
||||
| Debug | `--debug` | `PLUGIN_DEBUG`, `JENKINS_DEBUG` | No | Enable debug mode to show detailed parameter information (default: false) |
|
||||
|
||||
**Authentication Requirements**:
|
||||
**Authentication Requirements**: You must provide either:
|
||||
|
||||
For Jenkins with **CSRF protection enabled** (default in modern Jenkins):
|
||||
|
||||
- **Required**: `user` + `token` (API token authentication)
|
||||
- **Optional**: `remote-token` (for additional security)
|
||||
|
||||
For Jenkins with **CSRF protection disabled** (not recommended):
|
||||
|
||||
- **Option 1**: `user` + `token` (API token authentication)
|
||||
- **Option 2**: `remote-token` only (requires anonymous read access to job)
|
||||
|
||||
**Important**: If you encounter "403 No valid crumb" errors, you must use API token authentication (`user` + `token`).
|
||||
- `user` + `token` (API token authentication), OR
|
||||
- `remote-token` (remote trigger token authentication)
|
||||
|
||||
**Parameters Format**: The `parameters` field accepts a multi-line string where each line contains one `key=value` pair:
|
||||
|
||||
@@ -283,22 +220,9 @@ drone-jenkins \
|
||||
--job my-jenkins-job
|
||||
```
|
||||
|
||||
**Using combined authentication (API token + remote token - Recommended):**
|
||||
**Using remote token authentication:**
|
||||
|
||||
```bash
|
||||
drone-jenkins \
|
||||
--host http://jenkins.example.com/ \
|
||||
--user appleboy \
|
||||
--token XXXXXXXX \
|
||||
--remote-token REMOTE_TOKEN_HERE \
|
||||
--job my-jenkins-job
|
||||
```
|
||||
|
||||
**Using remote token only (only works without CSRF protection):**
|
||||
|
||||
```bash
|
||||
# Note: This will fail if Jenkins has CSRF protection enabled
|
||||
# You will get "403 No valid crumb" error
|
||||
drone-jenkins \
|
||||
--host http://jenkins.example.com/ \
|
||||
--remote-token REMOTE_TOKEN_HERE \
|
||||
@@ -385,18 +309,6 @@ docker run --rm \
|
||||
ghcr.io/appleboy/drone-jenkins
|
||||
```
|
||||
|
||||
**With combined authentication (API token + remote token):**
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-e JENKINS_URL=http://jenkins.example.com/ \
|
||||
-e JENKINS_USER=appleboy \
|
||||
-e JENKINS_TOKEN=xxxxxxx \
|
||||
-e JENKINS_REMOTE_TOKEN=your_remote_token \
|
||||
-e JENKINS_JOB=my-jenkins-job \
|
||||
ghcr.io/appleboy/drone-jenkins
|
||||
```
|
||||
|
||||
**Wait for job completion:**
|
||||
|
||||
```bash
|
||||
@@ -448,57 +360,6 @@ docker run --rm \
|
||||
|
||||
For more detailed examples and advanced configurations, see [DOCS.md](DOCS.md).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: 403 No valid crumb was included in the request
|
||||
|
||||
**Cause**: Your Jenkins server has CSRF protection enabled (this is the default in modern Jenkins). Learn more at the [Jenkins CSRF Protection documentation](https://www.jenkins.io/doc/book/security/csrf-protection/).
|
||||
|
||||
**Solution**: Use API token authentication instead of remote token only:
|
||||
|
||||
```bash
|
||||
# ❌ This will fail with CSRF protection enabled
|
||||
drone-jenkins \
|
||||
--host http://jenkins.example.com/ \
|
||||
--remote-token YOUR_REMOTE_TOKEN \
|
||||
--job my-jenkins-job
|
||||
|
||||
# ✅ Use this instead
|
||||
drone-jenkins \
|
||||
--host http://jenkins.example.com/ \
|
||||
--user YOUR_USERNAME \
|
||||
--token YOUR_API_TOKEN \
|
||||
--job my-jenkins-job
|
||||
|
||||
# ✅ Or combine both for additional security
|
||||
drone-jenkins \
|
||||
--host http://jenkins.example.com/ \
|
||||
--user YOUR_USERNAME \
|
||||
--token YOUR_API_TOKEN \
|
||||
--remote-token YOUR_REMOTE_TOKEN \
|
||||
--job my-jenkins-job
|
||||
```
|
||||
|
||||
### Error: 401 Unauthorized
|
||||
|
||||
**Cause**: Invalid credentials or incorrect authentication method.
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. Verify your username and API token are correct
|
||||
2. Ensure you're using an API token, not your Jenkins password
|
||||
3. Check if you have permission to trigger the job
|
||||
4. Make sure both `--user` and `--token` are provided together
|
||||
|
||||
### Remote Token Not Working
|
||||
|
||||
**Cause**: Remote trigger tokens alone only work in specific scenarios:
|
||||
|
||||
- Jenkins has CSRF protection disabled (not recommended), AND
|
||||
- Anonymous users have read access to the job
|
||||
|
||||
**Solution**: Use combined authentication (API token + remote token) as shown in the examples above.
|
||||
|
||||
## Development
|
||||
|
||||
### Building
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
- [配置](#配置)
|
||||
- [Jenkins 服务器设置](#jenkins-服务器设置)
|
||||
- [认证](#认证)
|
||||
- [CSRF 保护注意事项](#csrf-保护注意事项)
|
||||
- [参数参考](#参数参考)
|
||||
- [使用方式](#使用方式)
|
||||
- [命令行](#命令行)
|
||||
@@ -139,18 +138,6 @@ docker run -d -v jenkins_home:/var/jenkins_home -p 8080:8080 -p 50000:50000 --re
|
||||
|
||||
或者,您可以使用在 Jenkins 任务设置中配置的远程触发令牌。
|
||||
|
||||
#### CSRF 保护注意事项
|
||||
|
||||
现代 Jenkins 安装默认启用 CSRF 保护。如果您遇到以下错误:
|
||||
|
||||
```
|
||||
Error 403 No valid crumb was included in the request
|
||||
```
|
||||
|
||||
这表示您的 Jenkins 已启用 CSRF 保护。您**必须**使用 API 令牌认证(user + token)。单独使用远程触发令牌将无法工作。
|
||||
|
||||
如需更多关于 Jenkins CSRF 保护的信息,请参阅 [Jenkins 官方文档](https://www.jenkins.io/doc/book/security/csrf-protection/)。
|
||||
|
||||
### 参数参考
|
||||
|
||||
| 参数 | CLI 标志 | 环境变量 | 必需 | 说明 |
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
- [設定](#設定)
|
||||
- [Jenkins 伺服器設定](#jenkins-伺服器設定)
|
||||
- [認證](#認證)
|
||||
- [CSRF 保護注意事項](#csrf-保護注意事項)
|
||||
- [參數參考](#參數參考)
|
||||
- [使用方式](#使用方式)
|
||||
- [命令列](#命令列)
|
||||
@@ -139,18 +138,6 @@ docker run -d -v jenkins_home:/var/jenkins_home -p 8080:8080 -p 50000:50000 --re
|
||||
|
||||
或者,您可以使用在 Jenkins 任務設定中配置的遠端觸發令牌。
|
||||
|
||||
#### CSRF 保護注意事項
|
||||
|
||||
現代 Jenkins 安裝預設啟用 CSRF 保護。如果您遇到以下錯誤:
|
||||
|
||||
```
|
||||
Error 403 No valid crumb was included in the request
|
||||
```
|
||||
|
||||
這表示您的 Jenkins 已啟用 CSRF 保護。您**必須**使用 API 令牌認證(user + token)。單獨使用遠端觸發令牌將無法運作。
|
||||
|
||||
如需更多關於 Jenkins CSRF 保護的資訊,請參閱 [Jenkins 官方文件](https://www.jenkins.io/doc/book/security/csrf-protection/)。
|
||||
|
||||
### 參數參考
|
||||
|
||||
| 參數 | CLI 旗標 | 環境變數 | 必要 | 說明 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/appleboy/drone-jenkins
|
||||
|
||||
go 1.25.9
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/appleboy/com v1.1.1
|
||||
|
||||
+1
-1
@@ -233,7 +233,7 @@ func (jenkins *Jenkins) sendRequest(
|
||||
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(
|
||||
|
||||
+2
-10
@@ -347,11 +347,7 @@ func TestWaitForCompletion(t *testing.T) {
|
||||
[]byte(`{"number":456,"building":true,"duration":0,"result":null}`),
|
||||
)
|
||||
} else {
|
||||
_, _ = w.Write(
|
||||
[]byte(
|
||||
`{"number":456,"building":false,"duration":5000,"result":"SUCCESS"}`,
|
||||
),
|
||||
)
|
||||
_, _ = w.Write([]byte(`{"number":456,"building":false,"duration":5000,"result":"SUCCESS"}`))
|
||||
}
|
||||
}
|
||||
}))
|
||||
@@ -474,11 +470,7 @@ func TestWaitForCompletion(t *testing.T) {
|
||||
[]byte(`{"number":456,"building":true,"duration":0,"result":null}`),
|
||||
)
|
||||
} else {
|
||||
_, _ = w.Write(
|
||||
[]byte(
|
||||
`{"number":456,"building":false,"duration":3000,"result":"FAILURE"}`,
|
||||
),
|
||||
)
|
||||
_, _ = w.Write([]byte(`{"number":456,"building":false,"duration":3000,"result":"FAILURE"}`))
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user