Jenkins Learn
03. Jobs & cấu hình build

Build Triggers

Kích hoạt build bằng webhook, lịch hoặc dependency.

Build trigger đưa một job vào hàng đợi; nó không bảo đảm build sẽ chạy ngay, checkout được revision nào, hay được quyền triển khai. Một trigger tốt phải trả lời được ba câu hỏi: sự kiện nào được phép tạo build, một thay đổi tạo bao nhiêu build, và làm sao truy được nguyên nhân của build đó.

Mục lục

Mục tiêu

Sau bài này, người học có thể:

  • phân biệt webhook, Poll SCM, lịch cron và dependency trigger; chọn cơ chế theo nguồn sự kiện thay vì bật mọi lựa chọn;
  • viết và đọc lịch Jenkins cron, dùng H để phân tán tải, đồng thời dự kiến queue delay và timezone;
  • cấu hình quan hệ upstream/downstream có điều kiện kết quả, không tạo vòng lặp hay side effect lặp;
  • giảm build trùng bằng lọc event, quiet period và chính sách concurrency phù hợp;
  • kiểm tra endpoint webhook, quyền của SCM/plugin và bằng chứng cause/revision trước khi tin kết quả build.

Chọn trigger theo loại công việc

Các khái niệm cần tách biệt

Một trigger quyết định lúc Jenkins tạo một queue item. SCM checkout quyết định revision mà build thực sự lấy. Executor/agent quyết định lúc queue item được chạy. Ba việc này có thể cách nhau nhiều phút; một commit mới xuất hiện trong khoảng đó có thể làm kết quả checkout khác với điều người gửi webhook mong đợi nếu job/plugin không pin revision theo event.

Poll SCM không phải lệnh build định kỳ. Đến lịch poll, Jenkins hỏi SCM/plugin xem có thay đổi liên quan đến job hay không; chỉ có thay đổi thì mới enqueue build. Build periodically hoặc cron(...) enqueue build theo lịch dù source không đổi. Một downstream trigger lại dựa vào kết quả của job khác, không dựa trực tiếp vào SCM.

Bảng chọn nhanh

Nhu cầuCơ chế ưu tiênKhi không phù hợpBằng chứng cần xem
Chạy CI nhanh sau push/PRWebhook của SCM source/pluginJenkins không có endpoint HTTPS đáng tin hoặc SCM không gửi được eventDelivery/event log ở SCM, cause của build, revision checkout
Có CI khi webhook không dùng đượcPoll SCM với lịch thưaNhiều repository lớn, rate limit chặt hoặc cần phản hồi gần thời gian thựcPoll log, request/rate limit SCM, revision đã phát hiện
Quét, report hoặc kiểm tra định kỳcron(...) / Build periodicallyChỉ muốn chạy khi source đổiLịch hiệu lực, timezone, cause TimerTrigger, queue delay
Chạy job sau quality gate khácUpstream trigger hoặc build stepDependency không rõ, có thể tạo chu trình, hoặc cần dữ liệu/revision cụ thểUpstream build URL/number/result, parameters, artifact/checksum

Mỗi job nên có một trigger chính được owner giải thích được. Có thể dùng webhook làm đường chính và Poll SCM làm phương án dự phòng, nhưng phải chủ động dedupe; bật cả webhook, poll và cron cho cùng một CI mà không có policy sẽ tạo queue noise và làm khó truy vết.

Webhook: sự kiện từ SCM

Webhook là HTTP request do dịch vụ SCM gửi tới endpoint của Jenkins hoặc SCM plugin khi có sự kiện như push, pull request hay merge request. Nó thường nhanh hơn Poll SCM vì Jenkins không phải liên tục hỏi SCM. Tuy nhiên, Jenkins chỉ nên tin một request sau khi endpoint/plugin đã xác thực nguồn và job/plugin đã áp dụng đúng policy event.

Luồng sự kiện và revision

direction: down
dev: Developer push/PR
event: SCM event + delivery ID, repo, ref, revision
endpoint: Reverse proxy / SCM plugin endpoint
queue: Jenkins queue
build: Build
checkout: Checkout revision
result: Test / policy / kết quả
metadata: Lưu cause/delivery metadata
dev -> event
event -> endpoint: HTTPS + chữ ký/token/IP policy
endpoint -> queue: Lọc event, tìm job/branch phù hợp
queue -> build: Quiet period, executor, agent
queue -> metadata
build -> checkout -> result
Developer push/PRSCM event + delivery ID, repo, ref, revisionReverse proxy / SCM plugin endpointJenkins queueBuildCheckout revisionTest / policy / kết quảLưu cause/delivery metadata HTTPS + chữ ký/token/IP policyLọc event, tìm job/branch phù hợpQuiet period, executor, agent
Developer push/PRSCM event + delivery ID, repo, ref, revisionReverse proxy / SCM plugin endpointJenkins queueBuildCheckout revisionTest / policy / kết quảLưu cause/delivery metadata HTTPS + chữ ký/token/IP policyLọc event, tìm job/branch phù hợpQuiet period, executor, agent
Luồng sự kiện và revision

Payload báo sự kiện, không phải mặc định là nguồn chân lý duy nhất cho revision. Với Multibranch Pipeline, branch source plugin thường index repository rồi chọn Jenkinsfile/revision theo discovery strategy của nó. Với Pipeline from SCM hoặc Freestyle Git job, cấu hình SCM của job quyết định ref nào được checkout. Hãy xác minh trên build page và console log: repository URL, branch/ref, commit SHA, trigger cause và thời điểm nhận event.

Không suy diễn rằng mọi event đều là push vào nhánh chính. PR/MR opened, synchronize, comment, tag và delete event có ngữ nghĩa khác nhau. Một event delete không nên cố checkout ref đã mất; một event từ fork có thể chạy Jenkinsfile/code không tin cậy. Chỉ đăng ký loại event và branch/PR discovery mà job thực sự cần.

Thiết lập có kiểm soát

  1. Xác định SCM source. Ghi rõ repository, source plugin, job/folder nhận event và owner. Trên Jenkins, xem plugin đã cài và tài liệu đúng nhà cung cấp; không đoán endpoint từ một tutorial của plugin khác.
  2. Dùng URL công khai có TLS. SCM phải đi được đến reverse proxy/Jenkins qua hostname chuẩn, certificate hợp lệ và đường dẫn endpoint do plugin công bố. Không mở port quản trị, JENKINS_HOME hay endpoint debug để “cho webhook chạy”.
  3. Tạo webhook ở repository sandbox trước. Chọn event hẹp, chẳng hạn push vào một branch lab. Dùng secret/signature verification nếu SCM và plugin hỗ trợ; secret chỉ nằm trong credential/configuration được phê duyệt, không nằm trong Jenkinsfile hay URL.
  4. Liên kết event với đúng job. Kiểm tra repository URL, branch spec/discovery strategy, credential read-only và quyền folder/job. Một endpoint nhận event không có nghĩa mọi repository được quyền kích hoạt mọi job.
  5. Gửi event thử vô hại. Push một thay đổi text vào repository sandbox hoặc dùng cơ chế test delivery của SCM nếu nó không lộ payload nhạy cảm. Đối chiếu delivery ID/thời điểm ở SCM với build cause, commit SHA và job ở Jenkins.
  6. Chỉ sau đó mới thêm production. Bật webhook cho từng repository/job theo change review, theo dõi tỷ lệ delivery fail và giữ đường rollback là disable webhook hoặc disable job — không phải tắt bảo vệ Jenkins toàn cục.

Một số plugin tự quản lý webhook khi có credential đủ quyền, số khác yêu cầu tạo webhook thủ công trong SCM. Đây là khác biệt capability của plugin và policy SCM. Cấp credential quản lý webhook riêng, scope hẹp và quyền tối thiểu; không tái sử dụng credential deploy/release chỉ để tạo hook.

Lọc sự kiện và tránh build thừa

Lọc càng sớm càng tốt nhưng đừng phụ thuộc vào một lớp duy nhất:

  • Tại SCM, chỉ chọn event cần thiết và giới hạn repository; tránh gửi cả push, tag, issue, comment và PR event đến một job không xử lý chúng.
  • Tại branch source/job, chỉ discovery branch/PR/tag theo policy. Không build tag, fork hay PR nếu không có nhu cầu và trust model tương ứng.
  • Trong Jenkinsfile, dùng when hoặc policy rõ ràng để chặn stage có side effect khi branch/revision không thuộc allowlist. Việc chặn stage không thay thế lọc webhook vì build vẫn tốn executor.
  • Đặt một quy ước: một commit trên nhánh CI có một job owner chính. Nếu Multibranch đã quản lý branch, không tạo thêm Freestyle/Pipeline poll cùng ref trừ khi mục đích khác và đã có dedupe.

SCM có thể retry delivery sau timeout; cùng push có thể tạo push event, branch indexing và Poll SCM; người dùng cũng có thể bấm Build Now. Xem phần Dedupe sự kiện và concurrency trước khi coi mỗi request là một build cần giữ lại.

Bảo vệ endpoint webhook

Kiểm soátCách áp dụngKhông được thay thế bằng
TLS và hostname chuẩnKết thúc TLS ở reverse proxy/Jenkins theo chuẩn tổ chức; SCM xác minh certificateHTTP, certificate bỏ kiểm tra hoặc URL IP tạm thời
Xác thực nguồnBật chữ ký HMAC/shared secret, token hoặc cơ chế plugin/SCM hỗ trợ; verify trước khi tạo buildSo sánh một header tự tạo trong Jenkinsfile
Network policyChỉ cho dải IP/egress chính thức của SCM đi tới endpoint qua firewall/WAF/proxy khi tổ chức có nguồn IP đáng tinMở rộng mọi endpoint Jenkins ra Internet
Quyền JenkinsAnonymous/overall read, job build/configure và credential scope theo least privilegeCho webhook identity quyền Configure/Administer
CSRFGiữ CSRF protection của Jenkins; chỉ dùng exemption hẹp do plugin endpoint tài liệu hóaTắt CSRF protection toàn cục để sửa lỗi 403
Audit và rate limitLưu delivery ID, repository, event type, response/status và build URL; alert burst/failureLog payload, Authorization header hoặc secret

Không ghi shared secret, personal access token hay chuỗi chữ ký vào Jenkinsfile, parameter, URL query, console output hoặc artifact. Nếu nghi lộ secret webhook, rotate ở SCM và Jenkins/plugin theo quy trình, kiểm tra delivery/build gần đó và thu hẹp quyền; xóa một log không thu hồi được bản sao đã bị đọc.

Poll SCM: hỏi SCM xem có thay đổi

Poll SCM chạy một kiểm tra SCM theo lịch. Khi plugin phát hiện thay đổi phù hợp với repository/ref của job, Jenkins mới tạo build. Nó hữu ích làm fallback cho webhook hoặc cho SCM nội bộ không hỗ trợ callback, nhưng chi phí tăng theo số job, tần suất, lịch sử/ref cần kiểm tra và độ trễ SCM.

Khác với build theo lịch

Đặc điểmPoll SCMcron(...) / Build periodically
Đến lịch thì làm gì?Hỏi SCM có thay đổi khôngEnqueue build ngay
Không có commit mớiKhông tạo buildVẫn tạo build
Phù hợpCI dựa trên source changeNightly test, refresh report, kiểm tra expiry
Nguy cơ chínhSCM API/Git traffic, rate limit, nhiều poll cùng lúcThừa build, đụng tài nguyên lúc giờ cao điểm
Cause thường cần thấySCM change/polling liên quanTimer trigger

Đừng dùng cron để giả Poll SCM rồi để shell tự git pull và quyết định có chạy hay không. Jenkins sẽ vẫn chiếm queue/agent, khó ghi cause và dễ lệch checkout. Hãy dùng SCM integration của job/plugin cho thay đổi source; dùng timer cho công việc vốn cần chạy dù source không đổi.

Cấu hình và giới hạn vận hành

Trong Declarative Pipeline, trigger poll có dạng sau. H phân tán minute giữa job; lịch chỉ là ví dụ, hãy chọn khoảng dựa trên RPO CI, số repository và quota SCM.

pipeline {
  agent none

  triggers {
    pollSCM('H/15 * * * 1-5')
  }

  stages {
    stage('Check on a sandbox agent') {
      agent { label 'ci-sandbox' }
      steps {
        echo 'The job was started after SCM polling detected a change.'
      }
    }
  }
}

Để poll có ý nghĩa, job phải có SCM definition mà Jenkins/plugin có thể kiểm tra. Với Pipeline script from SCM, cấu hình SCM của job và Jenkinsfile phải trỏ source sandbox đúng. Với Freestyle, cấu hình Git nằm ở Source Code Management và Poll SCM nằm trong Build Triggers. Multibranch Pipeline thường dùng branch source indexing/webhook; đừng thêm Poll SCM cho từng child branch chỉ vì muốn “chắc chắn” trước khi kiểm tra tài liệu plugin.

Đo trước khi rút ngắn lịch:

  • số job poll, số remote/ref, kích thước/history Git và cache mirror trên agent/controller;
  • request/authentication failures, SCM API rate limit và thời gian poll p95;
  • tỷ lệ poll không tạo build so với số build có giá trị;
  • queue delay sau khi nhiều poll cùng phát hiện thay đổi.

Bắt đầu thưa, ví dụ mỗi 15 hoặc 30 phút cho fallback, phân tán bằng H, rồi điều chỉnh bằng số liệu. Không đặt * * * * * cho nhiều job trên controller production chỉ để bù một webhook chưa được chẩn đoán. Sửa URL, DNS, TLS, signature hoặc plugin của webhook trước; nếu Poll SCM là cơ chế chính, ghi rõ quota và capacity owner.

Lịch cron: chạy theo thời điểm

Jenkins dùng cron gồm năm trường. Declarative Pipeline khai báo timer bằng triggers { cron('...') }; Freestyle dùng Build periodically trong UI. Timer đưa build vào queue bất kể source có đổi hay không.

Năm trường cron và ký tự H

MINUTE  HOUR  DAY-OF-MONTH  MONTH  DAY-OF-WEEK
  0-59   0-23      1-31      1-12      0-7 (0 và 7 là Chủ nhật)

Các toán tử thường dùng là * (mọi giá trị), , (danh sách), - (khoảng) và / (bước). Jenkins bổ sung H: một giá trị hash ổn định từ tên đầy đủ của job, dùng để không dồn tất cả job vào cùng phút/giờ. H không phải ngẫu nhiên mỗi lần chạy; đổi tên hoặc di chuyển job/folder có thể đổi thời điểm hash.

Ví dụ H 2 * * 1-5 chạy một lần trong giờ 02 theo ngày làm việc, nhưng phút thực tế khác nhau giữa các job. H H * * * phân tán cả giờ lẫn phút cho tác vụ chạy mỗi ngày. H/15 * * * * có ý nghĩa chạy theo bước 15 phút được phân tán, không phải cam kết mọi job chạy đúng phút 00, 15, 30, 45.

Ví dụ lịch an toàn

LịchÝ nghĩaDùng choLưu ý
H H * * *Mỗi ngày một lần, giờ/phút phân tánReport hoặc kiểm tra vệ sinh không có side effectKhông dùng nếu phải chạy đúng một giờ nghiệp vụ cố định.
H 2 * * 1-5Một lần trong giờ 02, thứ Hai–SáuNightly test ngày làm việcPhút là hash; ghi timezone của controller.
H/15 * * * 1-5Khoảng 15 phút ngày làm việc, lệch giữa jobFallback Poll SCM hoặc kiểm tra nhẹĐo quota SCM và tổng số job trước khi dùng.
H 6 * * 1Mỗi thứ Hai trong giờ 06Báo cáo tuầnNếu báo cáo phụ thuộc dữ liệu tháng, xử lý ngày lễ/múi giờ trong logic đã review.
0 0 1 * *Đúng 00:00 ngày đầu thángCông việc phải theo mốc lịch cố địnhCó thể tạo thundering herd; chỉ dùng khi độ chính xác thời điểm quan trọng.

Mẫu Declarative cho nightly check vô hại:

pipeline {
  agent none

  triggers {
    cron('H 2 * * 1-5')
  }

  options {
    skipDefaultCheckout(true)
    disableConcurrentBuilds()
    timeout(time: 5, unit: 'MINUTES')
  }

  stages {
    stage('Scheduled sandbox check') {
      agent { label 'ci-sandbox' }
      steps {
        echo 'Scheduled check only; no deploy, credential, network, or cleanup action.'
      }
    }
  }
}

Timezone, thời điểm bận và độ trễ

Cron được Jenkins diễn giải theo timezone đang hiệu lực trên controller trừ khi cấu hình trigger/instance của bạn quy định khác. Do daylight-saving time, một giờ địa phương có thể lặp hoặc không tồn tại ở vùng có DST. Kiểm tra timezone controller, bản Jenkins/plugin và lịch hiệu lực trên instance; ghi timezone như một phần contract vận hành, ví dụ “khoảng 02:00 UTC”, thay vì chỉ ghi “2 giờ sáng”.

Timer chỉ tạo queue item. Build thực tế có thể muộn vì quiet period, controller tải cao, agent offline, executor hết chỗ, lock, disableConcurrentBuilds() hoặc maintenance window. Do đó không dùng Jenkins timer đơn thuần cho deadline pháp lý, cutover chính xác từng phút hoặc thao tác một lần không thể lặp. Những việc đó cần owner, timezone/holiday calendar, idempotency, alert khi trễ và cơ chế xác nhận completion riêng.

Nếu hai lịch có thể chồng nhau, hãy tính thời gian chạy p95/p99 và queue delay. Chọn một trong các cách: giảm tần suất, tách resource pool, để build cũ hoàn thành rồi queue build kế tiếp, hoặc làm công việc idempotent có lock/lease ở hệ thống đích. Không giải quyết bằng cách tắt timeout hay cho phép vô hạn concurrent build.

Upstream và downstream: dependency giữa job

Dependency trigger phù hợp khi đầu ra hay quality gate của job A là điều kiện để job B bắt đầu. Nó không tự truyền artifact, commit SHA, parameter, credential hoặc ý nghĩa “đã release”. Những dữ liệu đó phải được truyền/xác minh tường minh theo contract của hai job.

Upstream trigger

Job downstream có thể khai báo trigger từ job upstream và threshold kết quả. Trong Declarative Pipeline, cú pháp tham khảo là:

pipeline {
  agent none

  triggers {
    upstream(
      upstreamProjects: 'platform/compile-and-test',
      threshold: hudson.model.Result.SUCCESS
    )
  }

  stages {
    stage('Consume verified input') {
      agent { label 'ci-sandbox' }
      steps {
        echo 'Run only after the named upstream job succeeds.'
      }
    }
  }
}

upstreamProjects là tên/path job Jenkins, không phải URL repository. Xác nhận folder path sau khi đổi tên/move job; dùng tên không mơ hồ và một owner cho cạnh dependency. SUCCESS là ngưỡng chặt cho bước tiếp theo có side effect. Nếu chọn threshold như UNSTABLE, phải ghi rõ tại sao test/cảnh báo unstable vẫn an toàn cho downstream; không dùng ngưỡng lỏng để che quality gate.

Với Freestyle, lựa chọn UI thường là Build after other projects are built. Tên và khả năng chính xác phụ thuộc core/plugin, nhưng nguyên tắc không đổi: ghi upstream cụ thể, result threshold, owner và cách khôi phục khi upstream bị rename/disable.

Kích hoạt downstream tường minh

Khi Pipeline A biết chính xác lúc nào cần gọi B, dùng build step tường minh. Mẫu dưới chỉ truyền metadata sandbox allowlist; downstream vẫn phải validate input và tự áp dụng quyền của nó.

stage('Request downstream verification') {
  steps {
    build(
      job: 'platform/downstream-verification',
      wait: true,
      propagate: false,
      parameters: [
        string(name: 'UPSTREAM_BUILD_URL', value: env.BUILD_URL ?: ''),
        string(name: 'SOURCE_REVISION', value: 'sandbox-revision')
      ]
    )
  }
}

wait: true khiến Pipeline A chờ B kết thúc. propagate: false giúp A tự kiểm tra kết quả trả về và quyết định thông điệp/rollback theo policy, thay vì tự động ném lỗi ngay; nó không biến failure của B thành success về mặt vận hành. Trong workflow thật, truyền commit SHA từ SCM metadata đã kiểm chứng, build URL/number và artifact version/checksum theo contract; không truyền free-form job name, credential ID, command, URL đích deploy hoặc secret qua parameter.

Nếu A không cần biết kết quả B ngay, wait: false chỉ enqueue B rồi tiếp tục. Cách này phù hợp notification hay tác vụ tách biệt, không phù hợp quality gate mà A phải dựa vào. Ghi correlation ID/build URL để vẫn truy được chuỗi khi B thất bại sau đó.

Thiết kế dependency không tạo vòng lặp

Vẽ dependency theo một hướng, ví dụ compile-and-test → package → sandbox-verification. Không tạo cả “A triggers B” và “B triggers A”, cũng không để cron/webhook trên B kích hoạt lại A mà không có guard. Vòng lặp có thể tạo hàng trăm build, đặc biệt khi mỗi job lại publish commit/tag hoặc gọi webhook.

Trước khi nối hai job, trả lời rõ:

  1. Job nào là owner của checkout/revision và artifact producer?
  2. Điều kiện kết quả nào cho phép bước tiếp theo, và UNSTABLE có ý nghĩa gì?
  3. B nhận artifact/version nào, bằng đường nào, và xác minh checksum ở đâu?
  4. Khi B retry hoặc A bị chạy lại, side effect có idempotent không?
  5. Ai dừng chuỗi khi queue tăng hoặc một dependency bị disable?

Dùng tên job theo domain và ghi upstream/downstream graph trong description/runbook. Khi cần nhiều branch/PR, ưu tiên Multibranch/SCM-aware design thay vì hard-code một ma trận tên child job dễ drift.

Dedupe sự kiện và concurrency

Nguồn build trùng thường gặp

Một commit có thể tạo hơn một queue item vì webhook retry, push event chồng với Poll SCM, branch indexing, cron, upstream trigger, manual rebuild hoặc hai webhook rule cùng match. Build trùng không luôn vô hại: chúng có thể cạnh tranh workspace/cache, ghi đè cùng version, gửi notification lặp hoặc deploy hai lần.

Bắt đầu điều tra từ evidence của từng build: Build Cause, timestamp nhận event, repository/ref/SHA, queue time, agent, parameter và downstream build URL. Đừng suy ra “webhook bị lỗi” chỉ vì có hai build; một build có thể là manual hoặc timer, và SCM delivery retry có thể là hậu quả Jenkins/proxy trả timeout.

Chọn chính sách hàng đợi

Mục tiêuKiểm soátTrade-off và điều kiện
Không chạy cùng lúc hai build của một joboptions { disableConcurrentBuilds() }Build mới chờ build trước; phù hợp test/scan dùng cùng tài nguyên. Queue có thể dài khi commit dày.
Chỉ giữ thay đổi mới nhất cho CI hủy đượcdisableConcurrentBuilds(abortPrevious: true) khi bản Jenkins/plugin hỗ trợBuild cũ bị hủy. Chỉ dùng cho test/scan idempotent, không deploy/migration/publish hay cleanup có thể làm hỏng build khác.
Gom event gần nhauQuiet period ở job/trigger theo UI hoặc Pipeline option đã xác minhTăng latency và không thay delivery dedupe; chọn thời gian bằng số liệu push burst.
Không tạo event thừaLọc webhook/branch source, tắt trigger chồng chéoCần owner của mapping repository → job.
Chống side effect trùngVersion bất biến, idempotency key, lock/lease ở hệ thống đíchdisableConcurrentBuilds chỉ bảo vệ một job, không bảo vệ hai job/controller khác nhau.

Mẫu CI an toàn mặc định thường là serialize, không hủy build đang chạy:

options {
  disableConcurrentBuilds()
  timeout(time: 20, unit: 'MINUTES')
  buildDiscarder(logRotator(numToKeepStr: '30'))
}

Nếu mục tiêu là “chỉ cần trạng thái mới nhất”, dùng hủy build cũ chỉ sau khi xác nhận tất cả stage có thể bị interruption giữa chừng. Đặc biệt không để post { always { ... } } xóa một path dùng chung, revoke resource của build khác, hay publish “latest” khi build bị hủy. Mọi publish/deploy cần version bất biến và kiểm soát concurrency ở hệ thống đích, không chỉ ở Jenkins.

Lab sandbox: xác minh timer và Poll SCM

Lab này tạo console output vô hại trên agent sandbox. Nó không dùng credential, không gọi API bên ngoài, không publish/deploy và không xóa path. Cần một Jenkins lab, agent Unix có label ci-sandbox, Pipeline plugin và quyền tạo/xóa job sandbox. Không thay label bằng built-in node/controller nếu không có sandbox agent.

Chuẩn bị

  1. Tạo một Pipeline job tạm tên trigger-timer-lab; chọn Pipeline script và dán Jenkinsfile ở phần kế tiếp.
  2. Xác nhận ci-sandbox là pool tách biệt, online và có executor. Đặt built-in node/controller là 0 executor trong môi trường production theo policy quản trị.
  3. Lưu job, dùng Build Now một lần để kiểm tra cú pháp, label và output. Manual build là baseline; nó không chứng minh timer đã chạy.
  4. Ghi tên job đầy đủ, timezone controller và thời điểm lưu. Jenkins dùng tên job để tính H, nên không đổi tên job trong lúc quan sát lịch.

Jenkinsfile timer vô hại

pipeline {
  agent none

  triggers {
    cron('H/5 * * * *')
  }

  options {
    skipDefaultCheckout(true)
    disableConcurrentBuilds()
    timeout(time: 3, unit: 'MINUTES')
    buildDiscarder(logRotator(numToKeepStr: '10'))
  }

  stages {
    stage('Record trigger safely') {
      agent { label 'ci-sandbox' }
      steps {
        echo "Sandbox timer build number: ${env.BUILD_NUMBER}"
        echo 'No checkout, credential, network, artifact, deploy, or filesystem cleanup was requested.'
      }
    }
  }
}

H/5 giúp lab không đợi quá lâu nhưng vẫn không ép mọi job chạy đúng cùng phút. Chỉ dùng tần suất này cho một job lab ngắn hạn; sau bài thực hành, disable/xóa job để không để timer test chạy mãi.

Thử Poll SCM và webhook

Để kiểm tra Poll SCM, tạo một job sandbox riêng thay vì đổi job timer. Cấu hình job đó với repository Git sandbox do bạn được phép sửa; dùng credential read-only nếu repository private. Với Freestyle, bật Poll SCM và dùng H/15 * * * 1-5. Với Pipeline from SCM, xác nhận SCM definition của job và khai báo pollSCM('H/15 * * * 1-5') trong Jenkinsfile sau khi kiểm tra syntax trên controller.

Thực hiện theo thứ tự:

  1. Đợi một chu kỳ poll khi repository không đổi. Kết quả đúng là không có build mới từ Poll SCM.
  2. Commit/push một thay đổi text vô hại vào branch sandbox đã cấu hình. Không dùng secret, tag release hay branch production.
  3. Đợi chu kỳ tiếp theo. Mở build mới, ghi cause và commit SHA checkout. Kết quả đúng là có đúng một build do SCM change/poll, trừ khi job còn trigger khác đã được ghi nhận.
  4. Nếu đã có endpoint webhook được quản trị, thêm webhook chỉ cho repository/branch sandbox và event push hẹp. Gửi một thay đổi text khác, rồi đối chiếu delivery ID ở SCM với build cause, SHA và thời điểm ở Jenkins.
  5. Khi webhook đã chứng minh hoạt động, tắt Poll SCM trong job webhook thử nghiệm hoặc giữ fallback theo policy dedupe đã viết. Không để cả hai chạy mơ hồ rồi suy đoán từ số build.

Không dùng nút “test webhook” để paste payload/secret vào Jenkins console. Delivery history của SCM và log plugin/proxy đã kiểm soát là nơi phù hợp để điều tra status HTTP; chỉ lưu metadata cần thiết, không lưu header xác thực hay payload nhạy cảm.

Kết quả mong đợi và dọn dẹp

Thử nghiệmKết quả mong đợiBằng chứng
Manual baselineMột build SUCCESS, hai dòng console vô hạiBuild number, agent ci-sandbox, không checkout/credential/network
TimerMột build mới sau thời điểm hash của job; có timer causeThời điểm queue/build và cause trên build page
Poll không đổi sourceKhông có build Poll SCM mớiPoll log/timestamp và build history không tăng từ poll
Poll sau push sandboxMột build checkout đúng SHA sandboxCause, repository/ref/SHA và console checkout
Webhook sandboxDelivery thành công liên kết với build đúng job/SHADelivery ID/status ở SCM, build URL/cause/timestamp

Khi xong, disable hoặc xóa hai job sandbox theo policy đội ngũ, xóa webhook sandbox ở SCM nếu bạn có quyền và không còn cần evidence, rồi kiểm tra không còn timer/poll hoạt động. Không xóa workspace bằng shell, không xóa build history/job production và không thu hồi credential không thuộc lab.

Troubleshooting

Triệu chứngNguyên nhân thường gặpCách chẩn đoán và xử lý an toàn
SCM báo webhook 404Sai endpoint/path, reverse proxy route sai hoặc plugin chưa cung cấp endpoint đóLấy endpoint từ tài liệu plugin đang cài, kiểm reverse-proxy route/TLS; không mở thêm endpoint hay đoán URL.
SCM báo 401/403Signature/token sai, permission/policy endpoint hoặc CSRF/plugin mismatchĐối chiếu cấu hình plugin và SCM, rotate secret nếu cần; không tắt CSRF hay cấp Administer để thử.
SCM timeout nhưng Jenkins có buildProxy/controller phản hồi chậm nên SCM retry deliverySo sánh delivery ID/timestamps, HTTP access log đã được bảo vệ và cause; thêm dedupe/quiet period, xử lý latency.
Có hai hoặc nhiều build cho một commitWebhook + poll/indexing/manual/upstream cùng hoạt động, hoặc SCM retryPhân loại cause từng build, tắt trigger chồng hoặc serialize; không chỉ xóa build record để che triệu chứng.
Poll SCM luôn build dù không có commit mớiSai SCM/ref, plugin behavior/configuration hoặc workspace/SCM metadata không ổn địnhKiểm SCM definition và poll log trên job sandbox, cập nhật/fix plugin theo change process; đừng thay bằng cron.
Poll SCM không bao giờ buildKhông có SCM definition có thể poll, sai credential/ref, lịch chưa đến hoặc SCM không truy cập đượcKiểm trigger schedule, repo/ref/credential read-only và log; test một commit sandbox rồi chờ chu kỳ.
Timer không chạy đúng phút kỳ vọngH phân tán lịch, timezone controller, DST hoặc queue delayXem full job name, timezone và cause/queue time; chỉ dùng giờ/phút cố định khi requirement thực sự cần.
Build nằm trong queueAgent/label/executor thiếu, concurrency/lock hoặc quiet periodĐọc queue reason và node status; tăng capacity đúng pool hoặc điều chỉnh lịch, không route source code sang controller.
Downstream không chạySai job path, upstream threshold chưa đạt, job disabled hoặc thiếu quyền buildKiểm exact full name/result/cause và quyền; không nới threshold hoặc quyền trước khi hiểu dependency.
Vòng lặp buildA/B trigger lẫn nhau hoặc publish tạo event quay lạiDisable một cạnh trong sandbox, vẽ graph, thêm guard/idempotency và chỉ bật lại sau review.

Checklist xác minh trước khi bật production

  • Mỗi job có owner, mục đích trigger, repository/branch hoặc upstream rõ ràng; trigger thừa đã được tắt hoặc có lý do được ghi lại.
  • Tôi phân biệt trigger, SCM checkout và thời điểm executor chạy; build evidence có cause, repository/ref và commit SHA.
  • Webhook dùng endpoint do source plugin tài liệu hóa, HTTPS/certificate hợp lệ, xác thực nguồn, quyền tối thiểu và audit/rate-limit phù hợp.
  • CSRF protection vẫn bật; không có secret trong URL, Jenkinsfile, parameter, console, artifact hoặc delivery evidence.
  • Event webhook chỉ gồm loại event/repository/branch cần thiết; PR/fork không tin cậy không nhận credential hay agent có đường production.
  • Poll SCM chỉ dùng khi có SCM definition hợp lệ và capacity/quota đã đo; lịch dùng H và không poll mỗi phút không có bằng chứng.
  • Timer được phân biệt với Poll SCM; timezone, DST, queue delay và hành vi khi trễ đã được ghi thành contract vận hành.
  • Upstream/downstream có exact job path, threshold, revision/artifact contract, owner và không có chu trình.
  • Chính sách dedupe/concurrency đã chọn: lọc event, quiet period khi cần, serialize hoặc chỉ hủy build cũ cho công việc interruptible.
  • Publish/deploy có idempotency/version bất biến và lock/lease ở hệ thống đích; không chỉ dựa vào disableConcurrentBuilds().
  • Lab sandbox đã đối chiếu manual, timer, Poll SCM hoặc webhook bằng cause, timestamp và SHA; timer/poll/webhook lab đã được dọn hoặc disable.

Nguồn Jenkins chính thức

Đọc tiếp

On this page