Lesson 002 · Jenkins Learning Path

Create the First Jenkins Job and Read Build Evidence

· Published · 6 min read

Labelled Jenkins CI/CD path separating untrusted pull request validation from trusted immutable artifact approval deployment monitoring and rollback

The first job should teach the complete Jenkins execution loop: queue, executor, workspace, exit status, console log, artifact, test result and retention. A green ball alone does not prove that the intended revision was tested.

Start from a known controller checkpoint

Use the disposable controller from the installation lesson. Confirm the Jenkins service, controller URL, administrator access and at least one isolated build agent. Take a configuration backup before changing controller-wide state.

java -version
sudo systemctl is-active jenkins
sudo systemctl --no-pager --full status jenkins
curl -fsS http://127.0.0.1:8080/login >/dev/null

Understand the operating boundary

DecisionImplementationEvidence
Source revisionUse a local training repository firstConsole records the exact commit SHA
ExecutionRun on a labelled agent, not the controllerNode name, executor and workspace are visible
ResultUse process exit code plus published evidenceFailure is attributable to one command
OutputArchive only the intended package and test reportFingerprint and retention policy are visible

Prepare the lab

Create a tiny repository whose success and failure are deterministic. This avoids blaming GitHub, credentials or a large application while learning the Jenkins execution model.

mkdir -p ~/jenkins-first-job && cd ~/jenkins-first-job
git init
printf '#!/usr/bin/env bash\nset -euo pipefail\nmkdir -p dist reports\nprintf ok > dist/result.txt\nprintf "<testsuite tests=\"1\" failures=\"0\"><testcase name=\"smoke\"/></testsuite>" > reports/junit.xml\n' > build.sh
chmod 0755 build.sh
git add . && git commit -m 'Add deterministic first build'
git rev-parse HEAD

Implement it step by step

  1. Create a Freestyle project named training-first-job, restrict it to the lab agent label and select the repository.
  2. Add one shell step: ./build.sh.
  3. Add JUnit publication for reports/junit.xml and archive dist/result.txt with fingerprinting.
  4. Set build retention to ten builds and run it manually.
  5. Create a Pipeline item from SCM so the same behavior becomes reviewable.

Follow one run through Jenkins internally. The trigger creates a queue item. The scheduler compares its label expression with online nodes and waits for a free executor. After assignment, Jenkins allocates a workspace, performs checkout and starts each configured step as the agent identity. A non-zero process status fails the step unless Pipeline code deliberately changes that interpretation. Publishers then copy selected reports or artifacts out of disposable workspace storage into retained build records.

This separation matters during diagnosis. A long queue duration is not a slow build. A checkout failure occurs before application compilation. A missing report may mean the test command never ran, wrote elsewhere or was incorrectly optional. An archived artifact proves that Jenkins retained a file, but its fingerprint and recorded source revision are needed to identify what it represents. Read timestamps and the first causal error before the cascade of skipped stages or post-action messages.

pipeline {
  agent { label 'linux-lab' }
  options { timestamps(); timeout(time: 10, unit: 'MINUTES'); buildDiscarder(logRotator(numToKeepStr: '10')) }
  stages {
    stage('Checkout') { steps { checkout scm; sh 'git rev-parse HEAD' } }
    stage('Build') { steps { sh './build.sh' } }
  }
  post {
    always { junit testResults: 'reports/junit.xml', allowEmptyResults: false }
    success { archiveArtifacts artifacts: 'dist/result.txt', fingerprint: true }
    cleanup { deleteDir() }
  }
}

Verify the positive path

Open the build page and trace it rather than reading only the final color. Match the commit in the checkout log to the repository, locate the assigned agent, inspect stage duration, open the test result and download the fingerprinted artifact.

# On the agent while a controlled build runs
ps -ef | grep -E '[j]ava|[b]uild.sh'
df -hT
# In the repository
git show --no-patch --format='%H %cI %s' HEAD
# Jenkins API with a personal API token
curl --fail --user 'learner:API_TOKEN' 'http://jenkins.example.test/job/training-first-job/lastBuild/api/json?tree=number,result,builtOn,duration,url'
CheckExpected evidenceReject when
RevisionConsole SHA equals the intended commitA floating or unexpected revision ran
TestOne test and zero failures are publishedThe report is missing or silently optional
Artifactresult.txt downloads and has a fingerprintWorkspace is the only copy
Second buildNew build has independent evidenceOld workspace output is reused

Make one build fail on purpose

Change the script to exit with code 23 after writing a diagnostic line. Jenkins should mark the shell step and build failed, still publish the test evidence in post always, skip the success-only artifact and clean the workspace. Restore the previous commit and confirm recovery in a new build rather than changing the failed build record.

printf '\necho controlled-failure >&2\nexit 23\n' >> build.sh
git add build.sh && git commit -m 'Lab: inject exit 23'
# run the job, retain its number, then recover
git revert --no-edit HEAD
git push origin HEAD

Troubleshoot by failed layer

SymptomInspectCorrection
Queued foreverLabel expression, offline nodes and executor countBring up the intended agent or correct the capability label
Checkout failsRepository URL, ref and checkout credentialTest the same identity without weakening TLS or host keys
Shell says permission deniedExecutable bit, mount options and agent identityCommit mode 0755 or invoke the correct interpreter
Build green without testsJUnit pattern and allowEmptyResultsRequire the report and fail on absence

Unsafe shortcuts

  • Unsafe: enabling executors on the controller merely to clear a queue runs repository code in the control plane.
  • Unsafe: using a shell step that ends with || true converts real test failures into green builds.
  • Unsafe: retaining unlimited workspaces and artifacts eventually exhausts disk and can expose old data.

Operate, recover and retain evidence

Record job owner, repository, credential scope, agent label, timeout and retention. The queue explains waiting work; executor utilization explains capacity; console logs explain command flow; reports and fingerprints explain what the run produced. Do not edit history after an incident.

sudo journalctl -u jenkins --since '-15 minutes' --no-pager
# Safely cancel only the identified stuck build in the UI/API
# Preserve console, test and artifact evidence before deleting a lab job
curl --fail --user 'learner:API_TOKEN' 'http://jenkins.example.test/job/training-first-job/lastBuild/consoleText'

Worked use cases

SituationDesign choiceAcceptance
Documentation buildBuild static HTML and archive itExact commit and artifact fingerprint are recorded
Unit-test jobPublish JUnit even after test failureFailed test name and duration remain visible
Scheduled inventoryRun read-only script on a timerOwner, last success and stale-result alarm are defined

Knowledge checks

What places a run in the queue?
A trigger creates executable work that waits for a matching available executor.
What is an executor?
One concurrent work slot on a Jenkins node.
What is a workspace?
Disposable filesystem storage assigned for a job on an agent.
Why publish JUnit?
It turns report files into durable test history and failure evidence.
Why fingerprint artifacts?
It helps trace the same file across producing and consuming jobs.
Does green prove the correct code ran?
No; verify the checked-out revision and intended tests.
Freestyle or Pipeline for growing work?
Pipeline from SCM provides reviewable versioned behavior.
Why use post always?
Evidence collection must still run after a failed main stage.

Independent lab

  1. Build the repository successfully in Freestyle and identify its queue time, node and workspace.
  2. Recreate it as Pipeline from SCM and prove the exact commit.
  3. Inject exit code 23 and explain every post action.
  4. Recover through Git, rerun, download the artifact and compare fingerprints.
  5. Reduce the agent executors to zero temporarily and diagnose the queued reason before restoring them.

Official references

Advertisement