如何在Jenkins声明式流水线中按触发方式执行特定阶段?
Absolutely! Declarative Pipelines are perfect for this scenario—you can easily control which stages run based on how the pipeline was triggered using built-in Jenkins features. Let me break this down for you with a concrete example.
Step 1: Define Your Triggers
First, set up both the scheduled timer and SCM (code commit) triggers in your Jenkinsfile under the triggers block. For the timer, we’ll use cron syntax to run every 4 hours. For code commits, you can use webhooks (recommended for GitHub/GitLab) or SCM polling if webhooks aren’t an option.
pipeline { agent any triggers { cron('0 */4 * * *') // Runs every 4 hours on the hour // Uncomment below if using SCM polling (skip if using webhooks): // scm('H/10 * * * *') // Checks for code changes every 10 minutes } // Rest of your pipeline logic goes here... }
Step 2: Use when Conditions to Target Stages
Declarative Pipelines include a when directive that lets you run stages only when specific conditions are met. To distinguish between trigger types, we’ll check the build cause using currentBuild.getBuildCauses(), which returns details about why the pipeline started.
Here’s a full example with stage-specific triggers:
pipeline { agent any triggers { cron('0 */4 * * *') // Scheduled every 4 hours } stages { // Stage that only runs when code is committed (e.g., GitHub webhook trigger) stage('Code Commit Validation') { when { expression { // Check if the build was triggered by an SCM event (like a git push) currentBuild.getBuildCauses().any { cause -> cause.shortDescription.contains('SCM trigger') || cause.class.simpleName == 'GitHubCause' // Adjust for your SCM } } } steps { echo 'Running code commit-specific checks: linting, unit tests...' // Add your code commit steps here (e.g., `sh 'npm run lint'`, `sh 'mvn test'`) } } // Stage that only runs for scheduled timer triggers stage('Scheduled Health Check') { when { expression { // Check if the build was triggered by the timer currentBuild.getBuildCauses().any { cause -> cause.shortDescription.contains('Timer trigger') } } } steps { echo 'Running scheduled tasks: system health check, data sync...' // Add your timer-specific steps here (e.g., `sh './scripts/health-check.sh'`) } } // Optional: Stage that runs for both triggers stage('Common Cleanup') { when { anyOf { expression { currentBuild.getBuildCauses().any { it.shortDescription.contains('SCM trigger') } } expression { currentBuild.getBuildCauses().any { it.shortDescription.contains('Timer trigger') } } } } steps { echo 'Cleaning up resources for all trigger types...' } } } }
Step 3: Debugging Tip
If you’re unsure what build cause to target, add a debug stage to print the build causes in your logs:
stage('Debug Trigger') { steps { echo "Build causes: ${currentBuild.getBuildCauses()}" } }
Run test builds via both code commit and timer, then check the logs to see the exact class names or descriptions to use in your when conditions.
Key Notes
- For webhook triggers (like GitHub), the build cause class might be
GitHubCauseinstead of the genericSCMTrigger—adjust the condition to match your setup. - The cron syntax follows standard Jenkins format:
MINUTE HOUR DOM MONTH DOW(e.g.,0 */4 * * *means every 4 hours at minute 0). - You don’t need to define
scmintriggersif using webhooks—webhooks will automatically trigger the pipeline when code is pushed.
That’s it! This setup lets you run only the stages you want for each trigger type, all within a Declarative Pipeline.
内容的提问来源于stack exchange,提问作者mson

