Gitlab Pipeline – after_script – What is after_script in GitLab CI/CD?

DevOps

YOUR COSMETIC CARE STARTS HERE

Find the Best Cosmetic Hospitals

Trusted • Curated • Easy

Looking for the right place for a cosmetic procedure? Explore top cosmetic hospitals in one place and choose with confidence.

“Small steps lead to big changes — today is a perfect day to begin.”

Explore Cosmetic Hospitals Compare hospitals, services & options quickly.

✓ Shortlist providers • ✓ Review options • ✓ Take the next step with confidence

The after_script keyword in GitLab CI/CD allows you to define a list of shell commands that should be executed after the main script commands of a job. A crucial characteristic of after_script is that its commands are executed regardless of the success or failure of the job’s script or before_script sections.

This makes after_script ideal for tasks like:

  • Cleaning up temporary files or resources.
  • Logging final status or collecting diagnostic information.
  • De-authenticating from services.
  • Uploading artifacts even if the job failed.

You can define after_script at two main levels:

  1. Globally (as a default): Using default:after_script:. These commands will run after every job unless a job overrides it.
  2. Job-level: Defined within a specific job. This overrides any global after_script for that particular job.

Example .gitlab-ci.yml with after_script:

YAML

# .gitlab-ci.yml

# 1. Default after_script: Applied to all jobs unless overridden
default:
  image: alpine:latest # Using a common default image
  after_script:
    - echo "--- Default after_script (Global) ---"
    - echo "Job finished at: $(date)"
    - echo "Job status was: $CI_JOB_STATUS" # CI_JOB_STATUS reflects the script's outcome
    - echo "Cleaning up default resources..."

stages:
  - build
  - test
  - cleanup_test

# Job 1: Successful job that uses the default after_script
successful_job:
  stage: build
  before_script:
    - echo "Before script for successful_job"
  script:
    - echo "--- Main script for successful_job ---"
    - echo "This job will succeed."
    - exit 0 # Explicitly succeed

# Job 2: Failing job that also uses the default after_script
failing_job:
  stage: test
  before_script:
    - echo "Before script for failing_job"
  script:
    - echo "--- Main script for failing_job ---"
    - echo "This job will intentionally fail."
    - exit 1 # Explicitly fail

# Job 3: Job with a custom after_script (overrides the default)
job_with_custom_after_script:
  stage: cleanup_test
  after_script: # Job-level after_script overrides the default one
    - echo "--- Custom after_script for job_with_custom_after_script ---"
    - echo "Performing specific cleanup for this job."
    - echo "Job status was: $CI_JOB_STATUS"
  script:
    - echo "--- Main script for job_with_custom_after_script ---"
    - echo "This job uses its own custom after_script."

# Job 4: Job that disables after_script (even the default one)
job_without_any_after_script:
  stage: cleanup_test
  after_script: [] # Explicitly set to an empty array to disable
  # You could also use `after_script: null` in some GitLab versions.
  script:
    - echo "--- Main script for job_without_any_after_script ---"
    - echo "No after_script (neither default nor custom) will be executed for this job."

Code language: PHP (php)

Explanation:

  1. default:after_script:
    • The default: block allows setting default configurations.
    • after_script: within default: defines commands that execute after every job, regardless of whether the job passed or failed (unless the job has its own after_script or disables it).
    • In this example:
      • It prints introductory lines and the finish time.
      • It prints the CI_JOB_STATUS (a predefined variable indicating if the job’s main script succeeded, failed, etc.).
      • It simulates a default cleanup.
  2. successful_job:
    • This job completes its script section successfully (exit 0).
    • It does not have its own after_script.
    • Therefore, it inherits and executes the commands from the default:after_script: section after its script block. The CI_JOB_STATUS will likely be success.
  3. failing_job:
    • This job intentionally fails in its script section (exit 1).
    • It also does not have its own after_script.
    • Despite the failure, it will still inherit and execute the commands from the default:after_script: section. This demonstrates the key behavior of after_script. The CI_JOB_STATUS will likely be failed.
  4. job_with_custom_after_script:
    • This job defines its own after_script: block.
    • This job-level after_script completely overrides (replaces) the default:after_script:. The commands from default:after_script: will not run for this job.
    • Only the commands listed in this job’s after_script will execute after its main script, regardless of the main script’s outcome.
  5. job_without_any_after_script:
    • This job explicitly sets after_script: [] (an empty array).
    • This tells GitLab CI not to run any after_script commands for this job, not even the ones defined in the default:after_script: section.

Key Concepts and Behavior:

  • Purpose: after_script is intended for cleanup, final logging, or any actions that must occur regardless of the job’s outcome.
  • Execution Order: For any given job:
    1. before_script (if any) runs.
    2. Main script runs.
    3. after_script (if any) runs.
  • Runs on Success or Failure: This is the most important characteristic. Commands in after_script are executed even if the before_script or script sections fail.
  • Failure Handling in after_script:
    • The exit code of commands in after_script does not affect the overall job status. The job’s status is determined by the before_script and script sections.
    • However, if a command in after_script fails, you might see errors in the job log for the after_script phase.
  • Array of Commands: after_script takes an array of strings, where each string is a shell command executed sequentially.
  • Inheritance and Overriding:
    • Job-level after_script overrides default:after_script.
    • To prevent any after_script (including a global one) from running for a specific job, set after_script: [] or after_script: null.
  • Execution Context:
    • after_script commands run on the same GitLab Runner that executed the job.
    • They generally have access to the same environment variables, files in the workspace (unless cleaned up by the job’s script), and services as the main script.
    • The CI_JOB_STATUS predefined variable is particularly useful in after_script to know the outcome of the job’s main execution.
  • Timeout: after_script has its own separate timeout, which is configured by the GitLab administrator (usually shorter than the main job timeout).
  • Common Use Cases:
    • Removing temporary files or directories.
    • Stopping services started during the job.
    • Logging out from authenticated sessions.
    • Uploading test reports or logs, especially if the job failed and artifacts wouldn’t be uploaded otherwise (though artifacts:when:always is often preferred for artifact uploading).
    • Sending notifications.

Using after_script ensures that critical cleanup and finalization steps are performed consistently, contributing to a more robust and manageable CI/CD pipeline.

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x