Skip to content

Add pre-job and post-job execution support to BashV3 task#21876

Open
nickymunga wants to merge 2 commits intomicrosoft:masterfrom
nickymunga:user/nickykalu/improve-bash-v3
Open

Add pre-job and post-job execution support to BashV3 task#21876
nickymunga wants to merge 2 commits intomicrosoft:masterfrom
nickymunga:user/nickykalu/improve-bash-v3

Conversation

@nickymunga
Copy link

@nickymunga nickymunga commented Feb 26, 2026

Context

This PR adds pre-job and post-job script execution capabilities to the BashV3 task, enabling users to run setup and cleanup scripts alongside their main bash script execution. This addresses the need for task-level lifecycle hooks commonly used for environment setup, dependency installation, and cleanup operations.


Task Name

BashV3


Description

  • Added optional preJobScript and postJobScript inputs to BashV3 task
  • Extracted shared bash execution logic into bashrunner.ts to eliminate code duplication across entry points
  • Created prebash.ts for pre-job execution (runs before main script)
  • Created postbash.ts for post-job execution (runs after main script, never fails the pipeline)
  • Post-job scripts are resilient - they log warnings on failure but always succeed to prevent disrupting pipeline cleanup
  • All user-facing messages use proper localization via tl.loc()
  • Version bumped from 3.268.1 to 3.269.0 (minor version - backward compatible feature)

Risk Assessment (Low / Medium / High)

Low

Reasoning:

  • Fully backward compatible - all new inputs are optional
  • If pre/post job scripts are not provided, execution is skipped immediately
  • No changes to existing bash task behavior or inputs
  • Post-job failures are handled gracefully (warnings only, never fail the task)
  • Extensive test coverage (50 tests passing including 5 new tests)
  • Follows existing patterns from other tasks (InstallSSHKeyV0, AndroidSigningV3)

Change Behind Feature Flag (Yes / No)

No

This change does not require a feature flag because:

  • It's completely backward compatible (optional inputs)
  • No behavioral changes to existing functionality
  • New functionality is opt-in (only runs when inputs are provided)
  • Well-tested with comprehensive unit tests

Tech Design / Approach

  • Design Pattern: Extracted common bash execution logic to eliminate duplication

    • Created bashrunner.ts with runBashScript() function accepting BashRunnerOptions interface
    • Refactored bash.ts from 233 lines to 32 lines using shared logic
    • New prebash.ts and postbash.ts use same shared execution logic
  • Architectural Decisions:

    • Used Azure Pipelines task execution phases: prejobexecution, execution, postjobexecution
    • Pre-job uses standard error handling (fails on script failure)
    • Post-job implements resilient error handling (warnings only, always succeeds)
    • Added setResult parameter to runBashScript() to allow post-job to control result setting
    • Returns BashResult interface with exit code and result status for inspection
  • Trade-offs:

    • Pre/post job scripts are inline only (no filepath support) - simpler implementation, covers most use cases
    • Post-job scripts share common inputs (workingDirectory, failOnStderr, bashEnvValue) with main script

Documentation Changes Required (Yes/No)

Yes

  • Task.json includes help text for new inputs:
    • preJobScript: "Optional bash script to run before the job starts..."
    • postJobScript: "Optional bash script to run after the job completes..."
  • Localization strings added in resources.resjson for all new messages
  • Consider updating user-facing documentation/examples if applicable

Unit Tests Added or Updated (Yes / No)

Yes

Added 5 new test files covering all scenarios:

  1. L0PreJob.ts - Successful pre-job script execution
  2. L0PreJobSkip.ts - Skip when no pre-job script provided
  3. L0PostJob.ts - Successful post-job script execution
  4. L0PostJobSkip.ts - Skip when no post-job script provided
  5. L0PostJobFailure.ts - Post-job resilience (task succeeds with warning when post-job fails)

Updated L0.ts with test assertions for all new functionality.


Additional Testing Performed

  • All 50 unit tests passing (8 original + 5 new pre/post job + 37 env processing tests)
  • Built successfully with node make.js build --task BashV3 --BypassNpmAudit
  • Tested on Linux (development environment)
  • Code coverage: 83.84% overall
    • postbash.js: 91.3%
    • prebash.js: 94.73%
    • bash.js: 94.44%
    • bashrunner.js: 71%

Logging Added/Updated (Yes/No)

Yes

  • All user-facing messages use localization: tl.loc()
  • Pre-job logs: "Starting Pre-Job Script" banner, skip message
  • Post-job logs: "Starting Post-Job Script" banner, skip message, failure warnings with exit codes
  • Appropriate log statements added with meaningful messages
  • No sensitive data exposed in logs
  • Log levels used correctly (console.log for info, tl.warning for non-fatal errors)

Telemetry Added/Updated (Yes/No)

No

No new telemetry added. Existing telemetry in bashrunner.ts for argument validation errors is preserved from original bash.ts implementation.


Rollback Scenario and Process (Yes/No)

Yes

  • Rollback Plan: Revert to version 3.268.1 if issues arise
  • Minimal Risk: Since all new functionality is optional and backward compatible, rollback would simply remove the new pre/post job capabilities
  • No Breaking Changes: Existing pipelines using BashV3 will continue to work identically
  • Safe Deployment: Can be deployed incrementally - pipelines only use new features when explicitly configured

Dependency Impact Assessed and Regression Tested (Yes/No)

Yes

  • No new dependencies added
  • Existing dependencies unchanged: azure-pipelines-task-lib, azure-pipelines-tasks-utility-common, uuid
  • Regression tested: All 8 original BashV3 tests continue passing
  • No breaking changes: Existing bash.ts functionality preserved, only refactored to use shared logic
  • Common tests passing: 8/8 general suite tests passing

Checklist

  • Related issue linked (if applicable)
  • Task version was bumped — see versioning guide
    • Version bumped from 3.268.1 to 3.269.0 (minor version for backward compatible feature)
  • Verified the task behaves as expected
    • All 50 tests passing
    • Pre-job executes before main script
    • Post-job executes after main script and never fails the pipeline
    • Skipping works correctly when scripts not provided

nickymunga and others added 2 commits February 26, 2026 13:01
Enables users to run setup scripts before job execution and cleanup scripts after job completion. Pre-job scripts can prepare environments and download resources, while post-job scripts handle cleanup without failing the pipeline. Includes comprehensive test coverage for all execution phases.
- Use tl.loc() for skip messages in prebash.ts and postbash.ts
- Include exit code in post-job failure warning message
- Update test assertions to expect localized mock strings

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@nickymunga nickymunga marked this pull request as ready for review February 26, 2026 11:20
@nickymunga nickymunga requested review from a team and tarunramsinghani as code owners February 26, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant