Chapter 21Lesson 01190–250 min

Webhooks, Jenkins and CI Integrations, Maven Deployments, Build Promotion, and Event Automation: Concepts, Architecture, and Mental Model

Connect CI/CD to Nexus without confusing build execution with artifact governance: a build creates bytes once, Nexus persists and exposes those bytes, events describe repository changes, and downstream automation must preserve identity rather than rebuild.

WebhooksCI/CDMaven deployArtifact identityPromotion

Learning objectives

  • Distinguish build execution, repository publication, repository events, downstream consumption, and promotion as separate state transitions.
  • Define publication identity using coordinates/version plus byte-level checksum instead of a mutable job name, tag, or “latest” alias.
  • Explain repository/global webhooks, delivery IDs, shared-secret HMAC, and receiver idempotence before configuring an event action.
  • Separate Maven project deployment configuration from client-side credentials and Nexus authorization.
  • Explain why build-once promotion preserves evidence while rebuild-at-release creates a different artifact.
Version and edition baseline (27 August 2026). This chapter uses Nexus Repository 3.95.2-01 as the dated self-hosted reference line and Java 21 as the current runtime requirement. Verify the running instance and current release notes before using version-sensitive UI, plugin, webhook, or staging behavior. The mandatory path is Community/free-compatible and uses only disposable local resources.
Credential and production boundary. Never paste real CI secrets, Maven server passwords, Jenkins credentials, webhook shared secrets, Authorization headers, production repository URLs, or employer namespaces into lesson files, shell history, Git, screenshots, or evidence bundles. Use a loopback/private lab, synthetic com.example coordinates, and disposable service identities.
Promotion boundary. Sonatype currently classifies Staging & Build Promotion and component tagging as Pro features. Therefore the required Community lab teaches the invariant—promote the exact already-built bytes—by downloading/verifying/re-uploading a disposable artifact between hosted repositories. Native Staging/Move/Tag workflows are optional Pro extensions, not prerequisites.

1. The practical problem: CI can produce artifacts faster than teams can govern them

A CI runner knows how to compile and test source. Nexus Repository knows how to store, authorize, index, and serve published artifacts. A webhook receiver knows how to react to an event. None of those roles is interchangeable. The dangerous design is a pipeline that treats “job succeeded” as sufficient artifact identity, stores administrator credentials in the runner, rebuilds during release, and lets downstream jobs resolve whatever happens to be called latest.

The safe design creates one artifact, assigns a stable coordinate/version, records its checksum and source/build evidence, publishes it to the correct hosted repository with a scoped identity, and then promotes or hands off that exact artifact downstream.

2. Mental model: build → publish → event → verify → promote → consume

CI/CD and repository state boundaries
flowchart TD
  SRC[Source commit] --> CI[CI build]
  CI --> OUT[Artifact bytes + POM]
  OUT -->|publish once| HOST[Hosted repository]
  HOST --> DB[(Database metadata)]
  HOST --> BLOB[(Blob bytes)]
  HOST -->|repository event| WH[Webhook receiver]
  WH -->|validated, idempotent action| CTRL[Promotion controller]
  CTRL -->|same bytes| REL[Release repository]
  REL --> CONS[Downstream consumer]
  ID[Scoped service identity] --> HOST
  SEC[Webhook shared secret] --> WH

The arrows are deliberately different. The build creates bytes; publication writes package metadata and blob content; Nexus emits an HTTP callback; the receiver validates and deduplicates the callback; promotion moves or republishes the already-built bytes; consumers resolve the promoted coordinate. Database metadata and blob content remain separate persistent state.

3. Publication identity is more than “the build number”

Evidence What it identifies What it does not prove
Source commit The source tree input selected by CI Which exact binary bytes were ultimately published
Maven GAV + version Logical package coordinate such as com.example:learner-ch21:1.0.0 Trusted origin or vulnerability status
SHA-256 Exact artifact bytes Who built them or whether they are safe
CI build ID One execution in the CI system Immutability of a mutable repository alias
Publication timestamp When repository state changed Source identity by itself

For this chapter, the promotion invariant is: the SHA-256 of the promoted JAR must equal the SHA-256 captured immediately after the build. A different checksum means a different artifact, even if the filename and version string match.

4. Webhooks are notifications, not authorization decisions

Nexus Repository documents global and repository webhook capabilities. A repository webhook can emit asset/component events to an HTTP endpoint. When a secret is configured, Nexus supplies X-Nexus-Webhook-Signature; current Sonatype guidance uses HMAC-SHA1 over the JSON payload. Event headers also include X-Nexus-Webhook-Id and a unique X-Nexus-Webhook-Delivery UUID.

The receiver must still make its own decision. A valid signature means the body matches what a holder of the shared secret signed; it does not mean “release this artifact.” Authorization, policy, expected repository, expected event type, immutable coordinate, and duplicate-delivery handling are separate checks.

Firewall webhook distinction. The newer Repository Firewall quarantine webhook is a separate Pro + Firewall capability (3.91.0+). Do not confuse it with the longstanding repository/global webhook model. Chapter 22–23 will cover policy intelligence; this chapter uses ordinary repository events or a faithful signed local fixture.

5. Receiver trust boundary: authenticate, deduplicate, then act

A robust receiver follows a narrow sequence: preserve raw body → verify HMAC in constant time → validate event type/repository → check the delivery UUID against a deduplication store → persist concise evidence → enqueue or perform an idempotent downstream action → return an appropriate HTTP response.

import hashlib, hmac

def verify(raw_body: bytes, provided_hex: str, secret: bytes) -> bool:
    expected = hmac.new(secret, raw_body, hashlib.sha1).hexdigest()
    return hmac.compare_digest(expected, provided_hex or "")

# Verification authenticates the payload body; authorization rules still follow.

6. Maven deployment has two configuration domains

Apache Maven defines the deployment repository in project distributionManagement. Credentials belong in a client-side settings.xml server entry whose id matches the repository ID. Nexus then authenticates that identity and evaluates repository privileges. Keeping credentials out of the POM allows the same source project to be public while CI injects a disposable/private authentication context.



  
    learner-ch21-releases
    http://127.0.0.1:8081/repository/learner-ch21-releases/
  


  
    
      learner-ch21-releases
      svc-learner-ch21
      password-FAKE_DO_NOT_USE
    
  

If those IDs do not match, Maven may have the correct password but no credentials associated with the deployment target. That is a client configuration failure, not a reason to grant nx-admin.

7. Jenkins is an optional execution environment, not the repository model

Sonatype documents a Jenkins Nexus Repository publisher for Maven 2 release repositories. Current documentation notes that snapshot publication should use the Maven Deploy Plugin, and tagging/staging-related behavior is Pro. The mandatory exercises therefore use a provider-neutral local script. Jenkins, GitHub Actions, GitLab CI, or another runner can later supply the same environment variables, temporary Maven settings, and verification steps.

8. Build once; promote evidence, not source

Native Nexus Staging can move components between repositories, but the current feature matrix marks Staging & Build Promotion as Pro. The Community exercise models the invariant without pretending the product feature exists: download the artifact from the first hosted repository, verify the captured SHA-256, then upload that same file to a second disposable hosted repository. Do not run mvn package again in the promotion stage.

Promotion preserves bytes, not build intent
flowchart TB
  BUILD[Build once] --> A1[artifact.jar SHA-256 = H]
  A1 --> DEV[Development hosted repo]
  DEV --> VERIFY{Checksum = H?}
  VERIFY -->|yes| COPY[Transfer existing bytes]
  VERIFY -->|no| STOP[Stop promotion]
  COPY --> REL[Release hosted repo]
  REL --> A2[artifact.jar SHA-256 = H]
  REBUILD[Rebuild source] -. creates new evidence .-> BAD[Do not call this promotion]

9. Read-only inspection before changing CI or Nexus

  • Record Nexus version/edition/runtime and confirm the target is disposable/private.
  • Inspect repository names, format, type, version policy, deployment policy, and blob store.
  • Inventory the intended service user's current roles/privileges.
  • Confirm whether Webhook: Repository appears in Capabilities on the pinned instance; if not, use the signed fixture path.
  • Inspect Maven version and the effective deployment repository ID without printing credentials.
  • Record current component/asset count so publication causality is observable.

10. Why this matters in DevOps

A repository-centered handoff makes releases reproducible and auditable across CI providers. The pipeline can change, but coordinate, checksum, service-account scope, webhook delivery evidence, and promotion proof remain stable interfaces. That is the repository boundary this course needs before later policy, SBOM, recovery, and production chapters.

11. Knowledge check

A webhook has a valid HMAC. Should the receiver release the component immediately?

Why does Maven repository ID matter when credentials are correct?

Two release-stage builds use the same source commit and version but have different SHA-256 values. Are they the same promoted artifact?

What does X-Nexus-Webhook-Delivery help a receiver do?

Is native Nexus Staging required for the mandatory lab?

12. Summary and next step

You now have the Chapter 21 mental model: CI creates one artifact, Nexus governs publication, webhooks carry untrusted-until-verified event evidence, service identities are scoped, Maven target IDs and credentials are separated, and promotion preserves exact bytes. Lesson 2 turns that model into a disposable workflow.

Official references and version notes

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.