# Deployment Pipelines

Source: https://www.jawsdeploy.net/features/deployment-pipelines

Define the ordered work a release has to do, attach it to environments and targets, and run the same flow whether you are pushing to one box or a fleet.

## What a Jaws Deploy pipeline actually is

A pipeline in Jaws Deploy is a **project's deployment process**: an ordered list of steps attached to environments and targets. It is not a YAML file in a repo, and it is not a free-form script. It is a structured deployment definition that the platform owns, versions through releases, and executes against the targets it knows about.

The shape matters. CI pipelines describe **how to build**. Jaws Deploy pipelines describe **how to deploy a thing that is already built** to a specific environment, with the right configuration, in the right order, with logs and history attached.

> **// Mental model - Build once. Deploy many times. Re-execute the same plan.**
> 
> Your CI tool produces an artifact and hands it off. Jaws Deploy locks the deployment plan into a release and runs that same plan every time the release is deployed - to dev, to staging, to production, to that one weird customer environment - without rewriting the pipeline for each.

## How a pipeline executes

Every step has a place in the order, a target scope, and either a built-in template or a custom script. When you deploy a release, Jaws Deploy walks the steps top-to-bottom and runs each one against the targets that match its scope.

If a step targets multiple machines, Jaws Deploy runs the work on each of them in parallel, then waits for the slowest one before moving on. That gives you a predictable per-environment shape: fan out across a tier, gate on the slowest target, continue.

## The four kinds of steps you actually write

- **Package deployments**: Extract a package onto a target, run pre/post hooks, apply config transforms, and clean up old versions.
- **PowerShell scripts**: Run inline or modular PowerShell against targets with full access to scoped variables and script modules.
- **Windows service & IIS**: Install, restart, or reconfigure Windows services and IIS sites without writing the plumbing every time.
- **Custom step templates**: Encapsulate a pattern once - input fields, defaults, validation - and reuse it across projects and teams.

## Built-in templates vs. your own steps

Most teams start by chaining built-in step templates: deploy a package, run a script, swap an IIS binding. That covers the boring 80%. The interesting 20% - your domain-specific deployment dance - usually lives in either a custom step template (so it gets a UI form) or a script module (so it gets shared as a function library).

The rule of thumb evaluators tend to land on:

## Templates, scripts, modules - pick the right tool

- Use a **built-in template** when the platform already knows the shape (package, service, IIS, etc.).
- Promote repeated PowerShell into a **custom step template** the moment two projects need the same form.
- Use a **script module** for pure functions that several scripts call - it stays out of the deployment-step UI.
- Drop down to **inline PowerShell** only for one-off, project-specific glue. If it survives a sprint, refactor it.

## A step is just a function with structured inputs

Steps receive scoped variables as parameters and write to the live deployment log. No special framework, no DSL.

```
param(
    [string]$ConnectionString,   # resolved from Variables for this env+target
    [string]$ReleaseVersion      # provided by Jaws Deploy
)

Write-Host "Migrating database to $ReleaseVersion ..."
& "$PSScriptRoot\tools\migrate.exe" `
    --connection $ConnectionString `
    --target-version $ReleaseVersion

if ($LASTEXITCODE -ne 0) {
    throw "Migration failed with exit code $LASTEXITCODE"
}
```

> **// Sharp edge - Order is policy, not decoration.**
> 
> Step order in a Jaws Deploy pipeline is the deployment policy. Putting the database migration before the package extract or after the service restart will change what 'works' looks like during a partial failure. Treat re-ordering steps with the same care as touching a deployment script.

## Scoping a step to targets and environments

Steps are not just "run this everywhere." Each step has a scope: which environments it applies to, which target roles, which tags. That is how a single pipeline serves multiple environments without forking.

A realistic project might have one pipeline where the migration step is scoped to a `role:db` tag, the package deploy step is scoped to `role:app`, and the cache-warmup step only runs in Production. Same pipeline. Different work in different places.

**Build and test the artifact**

Compile, unit-test, package. CI is good at this. Keep it there. Stop teaching Jenkins how to ssh into production.

**Run the deployment plan**

Take the artifact, resolve variables, walk steps in order, fan out across targets, and stream logs back. That is the platform's whole job.

## Why this shape beats hand-rolled scripts

A pile of CI scripts can deploy a release. We have all written one. The cost is not the first deployment - it is the tenth environment, the third client, the rollback at 2am when someone needs to know **which release went to which environment and what exactly it did**.

A Jaws Deploy pipeline is structured enough that the platform can answer those questions for you. Every step is a known unit. Every run is a known release. Every change to the deployment process is a change to the project, not a silent edit in a YAML file nobody reviewed.

