Chapter 10Lesson 05~165 minutes

Checkpoint Lab — Declarative Pipeline Syntax, agent, stages, steps, options, parameters, environment, tools, and post

Author, validate, execute, intentionally break, repair, and evidence a multi-stage Declarative Jenkinsfile using agents, options, parameters, environment, tools, when/input behavior, and post conditions.

CheckpointDeclarative JenkinsfileValidationEvidenceFailure injectionRollback

Learning objectives

  • Predict controller, queue, agent, workspace, parameter, stage, and artifact state before execution.
  • Run a multi-stage SCM-backed Declarative Pipeline using stage agents and configured tools.
  • Validate non-secret parameter/environment/tool scope with retained evidence.
  • Introduce and preserve one structural validation failure, then repair only the failing layer.
  • Produce an evidence packet that proves source identity, stage/build state, toolchain, artifacts, and cleanup boundaries.

1. Scenario and success criteria

You are creating a synthetic “package and promote” Pipeline. There is no production deployment. The build reads a text payload, records toolchain evidence, optionally runs tests, waits for approval without occupying an agent, then writes a local promotion record. You will deliberately break one Declarative directive, preserve the failure evidence, repair it in a new commit, and prove the final build state.

Success means the evidence chain is complete—not merely that the final build is green.

2. Reproducibility assumptions and preflight

Layer Lab assumption Preflight evidence
Controller Jenkins 2.568.3 LTS or documented newer current LTS Core/Java version output and controller URL
Pipeline Pipeline 608.v67378e9d3db_1; Declarative 2.2293.v6e7193cec599 reference baseline Installed plugin inventory
Agent Disposable online node labeled lab-linux; built-in node not used Node name/label/executors
Tools jdk21-build, maven-3.9 from Chapter 08 Configured names plus observed binary versions
Source Synthetic Git repository only Repository URL and immutable SHA
Credentials None required for mandatory path State explicitly that no real credential is used
External side effect Local text file only Promotion artifact in build record

3. Write predictions before execution

Create predictions.md and state at least these predictions:

  1. With top-level agent none, the approval stage will not hold an executor while waiting at its stage-level input.
  2. The Build stage will run on lab-linux, expose a workspace only for that stage, and resolve the configured JDK/Maven tools.
  3. If RUN_TESTS=false, the Test stage will be skipped rather than failed.
  4. The intentionally misplaced directive will fail at Declarative model validation before shell execution.
  5. The repaired revision will archive evidence tied to the same source SHA printed from the workspace checkout.

4. Create the synthetic repository

mkdir jenkins-ch10-checkpoint && cd jenkins-ch10-checkpoint
git init
git config user.name "Jenkins Chapter 10 Checkpoint"
git config user.email "jenkins-ch10-checkpoint@example.invalid"
printf 'payload=chapter10\n' > payload.txt
git add payload.txt
git commit -m 'ch10: checkpoint payload'

5. Author the complete Declarative Jenkinsfile

pipeline {
  agent none

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

  parameters {
    choice(name: 'TARGET', choices: ['sandbox', 'qa'], description: 'Synthetic target only')
    booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Run synthetic tests')
  }

  environment {
    APP_NAME = 'ch10-checkpoint'
  }

  stages {
    stage('Build') {
      agent { label 'lab-linux' }
      tools {
        jdk 'jdk21-build'
        maven 'maven-3.9'
      }
      options {
        timeout(time: 5, unit: 'MINUTES')
      }
      steps {
        sh '''
          set -eu
          case "$TARGET" in sandbox|qa) ;; *) exit 2 ;; esac
          mkdir -p evidence
          {
            printf 'app=%s\n' "$APP_NAME"
            printf 'job=%s\n' "$JOB_NAME"
            printf 'build=%s\n' "$BUILD_NUMBER"
            printf 'build_url=%s\n' "$BUILD_URL"
            printf 'node=%s\n' "$NODE_NAME"
            printf 'workspace=%s\n' "$WORKSPACE"
            printf 'target=%s\n' "$TARGET"
            printf 'source_sha=%s\n' "$(git rev-parse HEAD)"
            java -version 2>&1
            mvn -version
          } > evidence/build.txt
          sha256sum payload.txt > evidence/payload.sha256
        '''
      }
      post {
        always {
          archiveArtifacts artifacts: 'evidence/*', fingerprint: true
        }
      }
    }

    stage('Test') {
      when {
        expression { return params.RUN_TESTS }
      }
      agent { label 'lab-linux' }
      steps {
        sh '''
          set -eu
          grep -q 'payload=chapter10' payload.txt
          printf 'test=passed\n' > test.txt
        '''
      }
      post {
        always {
          archiveArtifacts artifacts: 'test.txt', allowEmptyArchive: true
        }
      }
    }

    stage('Approve promotion simulation') {
      input {
        message 'Write the synthetic promotion record?'
        ok 'Continue'
      }
      agent { label 'lab-linux' }
      environment {
        PROMOTION_KIND = 'local-file-only'
      }
      steps {
        sh '''
          set -eu
          case "$TARGET" in sandbox|qa) ;; *) exit 2 ;; esac
          printf 'kind=%s target=%s build=%s\n' \
            "$PROMOTION_KIND" "$TARGET" "$BUILD_NUMBER" > promotion.txt
        '''
        archiveArtifacts artifacts: 'promotion.txt', fingerprint: true
      }
    }
  }

  post {
    always {
      echo "finalResult=${currentBuild.currentResult} build=${env.BUILD_NUMBER}"
    }
    unsuccessful {
      echo 'Preserve the original failure evidence before rerun.'
    }
    cleanup {
      echo 'Mandatory lab created no external deployment resource.'
    }
  }
}

Commit this Jenkinsfile and record the SHA:

git add Jenkinsfile
git commit -m 'ch10: add declarative checkpoint'
git rev-parse HEAD

6. Configure the SCM-backed Pipeline

Create ch10-declarative-checkpoint as Pipeline script from SCM. Use the synthetic repository and Jenkinsfile path. Do not configure a credential if the repository is locally/publicly readable. Record the job full name and configured branch/ref.

7. Validate and run the known-good revision

Validate the Jenkinsfile using the controller's supported Declarative/Pipeline syntax tooling. Trigger a manual run with TARGET=sandbox and RUN_TESTS=true. While the approval stage is waiting, inspect executors: the stage-level input should occur before that stage enters its lab-linux agent.

Approve the synthetic action, let the run finish, and download the archived evidence.

8. Verify each prediction independently

Prediction Evidence Pass condition
No executor held during approval Executor/node state while input waits Approval stage has not yet allocated its stage agent
Build agent/toolchain known evidence/build.txt Node/workspace and exact JDK/Maven output recorded
Source identity exact Printed source_sha versus expected Git SHA Exact match
Test stage behavior Stage graph and test.txt Runs when true; later verify skipped when false
Promotion bounded promotion.txt Contains only local synthetic target/build metadata

9. Run once with the conditional stage skipped

Trigger a new build with RUN_TESTS=false. Predict and verify that the Test stage is skipped. This is a new run with a new build number; do not overwrite the evidence from the first run.

10. Failure injection — break the Declarative model

Create a branch or new commit that moves the top-level parameters block inside the Build stage. Do not alter agent labels, plugins, or tools at the same time.

Validate/trigger that revision. Preserve:

  • the broken Jenkinsfile SHA;
  • the exact Declarative validation error;
  • job/build URL if a build record exists;
  • proof that no shell-produced checkpoint evidence was generated for the invalid model.

11. Repair in a new source revision

Move parameters back to the top-level Pipeline, commit the repair, record the new SHA, validate, and run. The repair is accepted only if you can explain why the original failure was structural and why the later build's source identity differs.

12. Evidence packet

  • baseline.txt: Jenkins core/Java and Pipeline/Declarative/Credentials Binding versions.
  • predictions.md: pre-run predictions.
  • Job full name, build numbers/URLs, causes, source/Jenkinsfile SHAs for good/broken/repaired revisions.
  • Agent/node/label/executor/workspace evidence.
  • Configured tool names and observed JDK/Maven versions.
  • Non-secret parameter/environment values and stage results.
  • Archived build/payload/test/promotion evidence and fingerprints.
  • Exact validation error for broken revision.
  • limitations.md: no real credential, cloud, registry, or deployment service used.

13. Cleanup and rollback

Download the evidence packet first. Delete only the Chapter 10 checkpoint job/repository/branch resources. Do not delete shared agents, global tool definitions, shared credentials, or Pipeline plugins. If you changed a global setting merely to make this lab work, restore its documented prior value and record that rollback.

14. What Chapter 10 adds

You can now translate Jenkins Pipeline's durable execution model into a constrained, reviewable Declarative grammar. You can reason about directive scope, executor allocation, tool/environment ownership, validation versus runtime failure, stage/build result, and post-processing without collapsing them into one “Pipeline succeeded” state.

Chapter 11 moves into Scripted Pipeline and Groovy control flow, where flexibility increases and so does the need to understand controller-side program logic, node blocks, and dynamic orchestration boundaries.

Next lesson

Chapter 11 — Scripted Pipeline, Groovy Control Flow, node Blocks, Dynamic Logic, and When to Use Scripted Pipelines

Compare Declarative structure with Scripted Pipeline flexibility while preserving the same evidence, agent, workspace, security, and durability boundaries.

Knowledge check

What evidence proves the stage-level approval did not hold an executor?

Why run once with RUN_TESTS=false?

What should the broken revision demonstrate?

Why is the promotion action only a local file?

What is the main bridge to Chapter 11?

Official references and version notes

Version and compatibility note

Rechecked on 2026-09-16. Examples assume Jenkins 2.568.3 LTS, tested with Java 21 and 25, Pipeline aggregator 608.v67378e9d3db_1, Pipeline: Declarative 2.2293.v6e7193cec599, Credentials Binding 728.v902a_273b_8947, and optional Stage View 2.41. Declarative 2.2293 requires Jenkins 2.504.3 or newer. Labs reuse the Chapter 08 tool names jdk21-build and maven-3.9; verify what exact binaries those names resolve to on your disposable agent before running. Plugin versions and supported directives change independently, so capture the installed baseline rather than assuming these versions forever.

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
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.