Script & Plugin Tasks
About 953 wordsAbout 3 min
Script and Plugin Tasks compares the two task types in a pipeline to help you pick the right one.
When to use: when writing .cnb.yml and unsure whether to use a script or a plugin image — for example running a few commands, reusing an existing capability from the community, or checking whether plugin parameters can read custom environment variables.
Overview
In CNB pipelines, a Job is the smallest execution unit, mainly divided into script tasks, plugin tasks, and built-in tasks.
- Script tasks: Use an image as the execution environment and run user-specified Shell commands
- Plugin tasks: Run the
ENTRYPOINTbuilt into the plugin image, configured via parameters
Both support specifying image, which can be confusing for beginners. This document explains the differences.
Core Comparison
| Feature | Script Task | Plugin Task |
|---|---|---|
| Execution | Runs script / commands | Image's built-in ENTRYPOINT |
| Environment | Pipeline or independent container | Independent container only |
| Parameters | Via env / imports | Via settings (become PLUGIN_*) |
| Custom env vars | Supported | Not passed |
| Flexibility | High, any command | Preset by plugin developer |
| Reusability | Business-specific | Shareable via plugin marketplace |
Environment details:
- Script task: Runs in the pipeline container without
image; runs in an independent container withimage. - Plugin task: Must specify
image, always runs in an independent container.
Execution Environment & File Sharing
- Script tasks without
imagerun in the pipeline container - Script tasks with
imageand plugin tasks run in independent containers
Only the following directories are shared between tasks; other directories are not visible to each other:
CNB_BUILD_WORKSPACE(default/workspace)- Directories declared in
docker.volumes
Tips
If a file produced by a previous task cannot be found in the next task, make sure the file was written to CNB_BUILD_WORKSPACE or a declared shared volume.
Examples
The same flow that installs dependencies and publishes is implemented below with a script task and a plugin task respectively.
Script Task
main:
push:
- docker:
image: node:20
stages:
- name: install dependencies
script: npm install
env:
NODE_ENV: production
- name: build
script: npm run buildPlugin Task
main:
push:
- stages:
- name: publish to npm
image: plugins/npm:1.2.3
settings:
username: $NPM_USER
password: $NPM_PASS
registry: https://registry.npmjs.org/The settings above are injected as environment variables: PLUGIN_USERNAME, PLUGIN_PASSWORD, PLUGIN_REGISTRY.
Environment Variable Rules
Script Task
It can read the following environment variables:
- Custom env vars declared via
env - Env vars imported via
imports - CNB built-in system env vars
For custom env vars, the priority is Job env > Stage env > Pipeline env.
Plugin Task
It can read CNB built-in system env vars, and reference env vars via $VAR in settings / args:
main:
push:
- stages:
- name: publish to npm
image: plugins/npm
settings:
username: $NPM_USER
password: $NPM_PASSHowever, custom env vars from env / imports are not passed to plugins. The following does not work:
main:
push:
- stages:
- name: publish to npm
image: plugins/npm
env:
# Not passed to the plugin, so the plugin cannot read it
PLUGIN_USERNAME: $NPM_USERWhy can't plugin tasks receive env vars via env?
Plugin tasks are designed as modular components that explicitly define accepted parameters via settings. This design:
- Keeps plugin interfaces clear and avoids parameter confusion
- Lets plugins explicitly declare required parameters
- Prevents env var naming conflicts, improving maintainability
- Avoids security issues caused by environment variable injection
When to Use Which
| Scenario | Recommended | Reason |
|---|---|---|
| Code building and testing | Script task | Flexible, adapts to various build tools |
| Custom business logic | Script task | Full control over execution flow |
| Notifications (WeCom, Lark, etc.) | Plugin task | Cohesive, simple configuration |
| Common CI/CD operations | Plugin task | Mature solutions in plugin marketplace |
| Reusable generic functionality | Plugin task | Shareable via plugin marketplace |
Guiding principles:
- If an existing plugin meets your needs, or the functionality is reusable and shareable, choose a plugin task
- If you need to run custom commands flexibly, or the logic is strongly tied to your business, choose a script task
Best Practices
Version Control
Whenever image is used, it's recommended to specify the image version. Using latest means image updates may cause unexpected behavior changes.
main:
push:
- stages:
- name: publish to npm
image: plugins/npm:1.2.3
settings:
username: $NPM_USER
- name: build
image: node:20
script: npm run buildSecurity
- Use official or trusted images
- Store sensitive data in the secrets vault, never hardcode
- Regularly check images for security updates
Reusability
Plugin tasks are suitable for reusable functionality:
- Notifications (WeCom, Lark, DingTalk, etc.)
- Common CI/CD operations (publish, deploy, etc.)
- Code quality checks (lint, scanning, etc.)
These can be published to the CNB plugin marketplace for others to use.
Script tasks are suitable for business-related logic:
- Code building and testing
- Custom data processing
- Specific business workflows
FAQ
Where do script tasks run without specifying image?
In the pipeline container environment. The pipeline container is specified by Pipeline.docker.image or Stage.image. See Build Environment - Environment Scope for details.
How to use environment variables in plugin tasks?
Use variable substitution in settings or args:
main:
push:
- stages:
- name: publish to npm
image: plugins/npm
settings:
username: $NPM_USER
password: $NPM_PASSCan plugin tasks execute custom scripts?
Plugin tasks can pass script content to the plugin via settings, but only if the plugin itself supports receiving and executing scripts. The execution logic is controlled by the plugin image, not by CNB.
Script tasks are different — script or commands are natively supported by CNB syntax, and CNB directly executes them in the script task's specified image or the pipeline container environment.