Chapter 05Lesson 01~95 minutes

Freestyle Projects, Build Steps, Post-Build Actions, Parameters, Triggers, and Legacy Job Maintenance: Concepts, Architecture, and Mental Model

Understand a Freestyle job as persisted controller configuration that becomes a queue item, executes on an agent workspace, invokes post-build actions, and leaves build evidence.

FreestyleJobs & buildsParametersTriggersLegacy automation

Learning objectives

  • Explain the Freestyle lifecycle from saved job configuration through trigger, queue, agent, workspace, build steps, publishers, and retained history.
  • Distinguish controller-side job configuration, build records, agent workspace state, archived evidence, and external side effects.
  • Explain why parameters and trigger metadata must be treated as input rather than trusted truth.
  • Use read-only UI/API evidence to inventory a legacy job before changing it.
  • Decide when a Freestyle job should be maintained, migrated, or retired.

1. Why Freestyle still matters

Freestyle projects are one of Jenkins' oldest and simplest job types. Their configuration is primarily stored by the controller, edited through the classic UI, and interpreted by Jenkins when a build is scheduled. Many long-lived Jenkins installations still contain hundreds or thousands of these jobs, so an operator needs to understand them even when new automation is written as Pipeline-as-Code.

The practical risk is not that Freestyle is inherently unusable. The risk is that its behavior can be spread across controller-side configuration, installed plugins, build-node assumptions, parameters, triggers, shell or batch scripts, and post-build publishers. If those pieces are not inventoried, a green build can be difficult to reproduce or migrate.

Chapter 05 rule: treat a Freestyle job as a persisted controller configuration that causes a build. The configuration is not the build; the workspace is not the job definition; and a successful build is not proof that downstream publication or delivery is healthy.

2. The Freestyle execution model

A Freestyle run begins with a saved job configuration. A trigger or user action creates a queue item. Jenkins chooses an eligible node and executor, prepares a workspace, executes configured build steps in order, then invokes publishers or post-build actions. Jenkins finally records the run result and retained evidence such as logs, archived artifacts, fingerprints, and metadata.

Causal lifecycle — configuration and run state are distinct
flowchart TD
 A[Freestyle job config / config.xml] --> B[Trigger or user/API cause]
 B --> C[Queue item]
 C --> D[Eligible agent + executor]
 D --> E[Workspace]
 E --> F[Ordered build steps]
 F --> G[Publishers / post-build actions]
 G --> H[Result + logs + archived artifacts]
 H --> I[Retained job/build history]
 H --> J[External side effects, if any]

The arrows are useful during diagnosis. A correct parameter form does not prove an executor is available. A successful shell step does not prove artifact archiving found files. An archived artifact does not prove an external deployment happened. Each transition needs its own evidence.

3. Four kinds of state you must not confuse

State Where it lives Examples Operational question
Job configuration Controller / JENKINS_HOME Parameters, triggers, node restriction, builders, publishers What is Jenkins configured to do next time?
Build/run record Controller build history Build number, cause, result, console log, archived artifacts What did run N actually do?
Workspace state Agent filesystem Checked-out source, generated files, caches, temporary outputs What files existed on the executor while the build ran?
External state SCM, registry, server, ticketing or notification system Commit, uploaded package, deployment ID, message What changed outside Jenkins?

Freestyle maintenance becomes fragile when teams use workspace leftovers as hidden configuration or treat controller-local XML as though it were reviewed source code. The chapter labs therefore recreate outputs on every build and export a sanitized configuration snapshot for review.

4. Parameters are input, not trusted truth

Parameterized Freestyle projects expose values such as strings, choices, booleans, or files to the build. String values usually arrive in build steps as environment variables. That is convenient, but it also means a value supplied by a user can influence shell behavior if the build script interpolates it unsafely.

# Good: validate a small control value and quote data.
case "$TARGET_ENV" in
  dev|test) ;;
  *) echo "Unsupported TARGET_ENV" >&2; exit 2 ;;
esac
printf 'message=%s\n' "$MESSAGE"

Do not put secrets in ordinary string parameters. Do not use parameters to select arbitrary filesystem paths or commands unless the input is strongly constrained. The same principle applies when the value was supplied by a timer plugin, webhook integration, SCM metadata, or an upstream job.

5. Trigger and cause are different from job definition

A saved Freestyle job can be triggered manually, periodically, by SCM-related mechanisms, by an upstream project, or through APIs and plugins. The trigger answers why Jenkins created a queue item. The job configuration answers what Jenkins will try to execute. Preserve the build cause when comparing two runs because the same job can behave differently when its inputs or external context differ.

For periodic schedules, Jenkins supports a cron-like syntax and recommends the hash symbol H where practical to distribute load. A schedule such as H/15 * * * * means approximately every fifteen minutes at a stable hash-selected offset for that job; it is preferable to forcing many jobs to start at minute zero.

6. The job should execute on an agent, not the controller

The built-in node belongs to the controller process. Current Jenkins guidance recommends setting its executor count to zero and running builds on agents. In a Freestyle project, the Restrict where this project can be run setting lets you supply a label expression such as linux. The queue then waits until an executor on a matching online agent is available.

Security boundary: anyone able to configure a job can influence code executed by that job. If the job runs on the built-in node, that code runs with dangerous proximity to JENKINS_HOME. Controller isolation is therefore part of Freestyle maintenance, not an optional advanced topic.

7. Build steps and post-build actions prove different things

A build step usually performs work in the workspace: compile, test, package, generate a report, or run a script. A publisher or post-build action consumes the resulting state and records or forwards evidence. The core artifact archiver, for example, copies matching workspace files into Jenkins-managed build history so they remain available after the workspace changes.

Artifact patterns are evaluated relative to the workspace. If a build creates out/evidence.txt but the publisher is configured for dist/**, the step can succeed while artifact publication fails or produces nothing. That is why the lab verifies the step and publisher separately.

8. Read-only inspection before modification

Before editing a legacy job, capture enough evidence to reconstruct its current behavior. At minimum record the job full name, current build number, parameter definitions, trigger configuration, label restriction, build steps, post-build actions, plugin dependencies, last successful and last failed build, artifact list, and one representative console log.

# Read-only examples for a secured disposable Jenkins.
# Supply a synthetic lab user's API token through an environment variable.
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN"   "$JENKINS_URL/job/legacy-demo/api/json?tree=name,url,nextBuildNumber,lastBuild[number,result,url],buildable"

curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN"   "$JENKINS_URL/job/legacy-demo/config.xml" > legacy-demo.config.xml

The configuration XML is useful evidence but may contain plugin-specific fields or references that should not be published blindly. Review and sanitize it before storing it outside the disposable lab.

9. When to maintain, migrate, or retire

Situation Reasonable action Evidence needed
Simple, stable internal job with low change rate Maintain temporarily Configuration snapshot, plugin baseline, owner, recovery path
Workflow changes often or has multiple stages/approvals Migrate toward Pipeline/Jenkinsfile Behavior inventory, source identity, testable migration plan
Job only wraps an obsolete tool or duplicate process Retire after dependency review Consumers, schedules, upstream/downstream references, retained artifacts
Job depends on abandoned publisher/plugin Prioritize migration Plugin health/security status, replacement behavior, rollback

The decision is operational, not ideological. A safe legacy job with an owner and tested recovery path can be maintained while migration is scheduled. An unowned job with hidden plugin dependencies and destructive parameters deserves attention even if it is still green.

Next lesson

Guided Hands-On Workflow and Core Operations

Create a disposable parameterized Freestyle job, run it manually and by timer, archive verifiable evidence, inspect build causes, and compare its persisted configuration.

Knowledge check

A Freestyle shell step exits 0, but no artifact is visible. What has been proved?

Why is a workspace file not durable job configuration?

Why should MESSAGE be quoted as "$MESSAGE" in a shell step?

What does a build cause tell you?

What is the first action before changing an unfamiliar legacy Freestyle job?

Official references and version notes

Version and compatibility note

Rechecked on 2026-09-15. The current Jenkins LTS baseline used by this chapter is 2.568.3, tested on Java 21 and 25. Mandatory labs assume Java 21 and use only core Freestyle/parameter/timer/artifact capabilities unless your controller already requires additional dependencies. Builds must execute on a disposable agent rather than the built-in node. If a future Jenkins LTS or plugin baseline differs, revalidate behavior before copying these exact steps.

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.