Post Conditions and Result Semantics

Scenario: Cleanup placed after a failing step never runs and leaves a shared target locked.

Pipeline example

pipeline { agent any; stages { stage('Test') { steps { sh './test.sh' } } }; post { always { junit 'reports/*.xml' }; cleanup { deleteDir() } } }

Results carry distinct meanings

Jenkins records success, unstable, failure, aborted, or not-built states. A test publisher may mark a run unstable even when its shell command returned zero; an abandoned approval is not a compilation failure. Declarative post conditions include always, changed, fixed, regression, aborted, failure, success, unstable, unsuccessful, and cleanup. Which blocks run depends on the accumulated result and condition ordering.

Publish JUnit and diagnostic evidence in post-always when a failing test command would otherwise skip the publisher. Require real report matches so no-tests-run cannot masquerade as green. Cleanup is best-effort final work after other post behavior, but a workspace deletion is not a reliable unlock for an external environment. External locks and leases need explicit, idempotent release semantics.

Do not hide the causal failure

Notification or cleanup errors can obscure the original exception. Make them defensive, preserve the primary result, and report secondary failures distinctly. CatchError can assign separate stage and build results for a consciously tolerated scanner or test outcome; using it around everything paints failures green and destroys useful semantics.

Exercise every result path and verify the final badge, stage state, reports, notifications, and cleanup. Downstream consumers must choose an explicit threshold: promotion generally requires success, while diagnostic collection may accept unstable or aborted runs. A trustworthy Pipeline makes the difference between rejected quality, infrastructure failure, and human cancellation visible to both automation and operators.

Goal: Practice the concrete behavior in jenkins-artifact-promotion. Learn sections have no Jenkins terminal; the Jenkins lab opens the real shared service in a new full-screen tab inside your private folder.