# Set Environment Variables for Later Steps (https://www.shipfox.io/docs/how-to/author-workflows/set-environment-variables-for-later-steps)

Description: Set an environment variable or add a PATH directory in one step, and use it in the later steps of the same job.

A step can set an environment variable for the steps that run after it in the
same job. A step can also add a directory to `PATH` for these steps. Use this
when one step installs a program or calculates a value that later steps need.

Each step runs in a new shell. When the step ends, the shell closes. The
variables that the step set with `export` are lost. The changes that the step
made to `PATH` are also lost.

To keep a value for the later steps, write the value to a file:

* Write an environment variable to the file `$SHIPFOX_ENV`.
* Write a `PATH` directory to the file `$SHIPFOX_PATH`.

When the step ends, Shipfox reads the two files. Shipfox then gives the values
to each later step of the job.

The example below installs Nix in one step and runs it in the next step. For
your own case, keep the two `echo` lines. Change the variable, the directory,
and the commands.

## Set a variable and add a PATH directory [#set-a-variable-and-add-a-path-directory]

This is a complete workflow:

```yaml
# yaml-language-server: $schema=https://www.shipfox.io/docs/workflow.schema.json
name: Set environment variables for later steps
runner: shipfox

triggers:
  manual:
    source: manual

jobs:
  test:
    steps:
      - name: Install Nix
        run: |
          curl -L https://nixos.org/nix/install | sh -s -- --no-daemon

          # Sets the variable NIX_PATH for the later steps.
          # Write one NAME=value on each line.
          echo "NIX_PATH=nixpkgs=channel:nixos-24.05" >> "$SHIPFOX_ENV"

          # Adds the directory of the nix program to PATH for the later steps.
          # Write one directory on each line.
          echo "$HOME/.nix-profile/bin" >> "$SHIPFOX_PATH"

      # This step finds the nix program and reads $NIX_PATH.
      - run: nix develop --command make test
```

These steps get the values:

* The run steps and the action steps that run later in the same job.
* The shell commands of the agent steps that run later in the same job.

The step that writes the files doesn't get the values. Other jobs don't get
them.

Shipfox reads the files when the step ends, even if the step fails. Two names
are not permitted in `$SHIPFOX_ENV`: `PATH`, and a name that starts with
`SHIPFOX_`. A step that writes one of these names fails.

> **Values in $SHIPFOX_ENV are not masked (warn)**
> Shipfox masks only the secrets it stores. A token that a command fetches and
> writes to `$SHIPFOX_ENV` appears in the logs of any later step that prints
> it. Don't print this token in a later step. If the token doesn't change
> between runs, store it as a
> [secret](https://www.shipfox.io/docs/how-to/set-up-work/secrets-and-variables) instead.

## Check which value a step gets [#check-which-value-a-step-gets]

A step can get the same variable from several places. Shipfox applies the
places in this order. A later place replaces an earlier one:

1. The environment of the runner.
2. The values that earlier steps wrote to `$SHIPFOX_ENV`. When two steps write
   the same name, the later step wins.
3. The `env` of the workflow, the job, and the step, including the secrets they
   bind.
4. The variables that Shipfox sets, such as `SHIPFOX_RUN_ID`.

Shipfox puts the directories from `$SHIPFOX_PATH` before the directories that
`PATH` already contains. The directory that was written last comes first.

## Know what a gate restart changes [#know-what-a-gate-restart-changes]

A [gate](https://www.shipfox.io/docs/understand/feedback-loops) can make earlier steps run again. Later
steps then get the values from the last time each step ran:

* A step that runs again replaces all the values it wrote before.
* A step that is skipped the second time gives no values. Shipfox removes the
  values and the directories that the step wrote before.
* A step before the restart point keeps its values.

## Adapt it to your workflow [#adapt-it-to-your-workflow]

| To...                                 | Change this                                                                                                                                 |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Set a value that has several lines    | Write a `NAME<<DELIMITER` line, the value, then a line with only the delimiter. The format is the same as for `$SHIPFOX_OUTPUT`.            |
| Add a directory inside the repository | Write a relative path to `$SHIPFOX_PATH`. Shipfox resolves it against the working directory of the step.                                    |
| Use another value in one step only    | Set the variable in the `env` of that step. See [Environment variables](https://www.shipfox.io/docs/reference/workflow-schema#environment-variables).                  |
| Send a value to another job           | Use an output. See [Pass values between jobs](https://www.shipfox.io/docs/how-to/author-workflows/pass-outputs).                                                       |
| Use a credential                      | Bind a secret in `env` instead of writing it to `$SHIPFOX_ENV`. See [Add secrets and variables](https://www.shipfox.io/docs/how-to/set-up-work/secrets-and-variables). |

## Verify the values [#verify-the-values]

### Start the workflow

Select **Run**, then open the new run.

### Inspect the later step

Open a step that runs after the step that writes the files. Confirm that
it read the variable and found the program.

In the example, the second step runs `nix`. The log doesn't contain a
"command not found" error.

See [Step environment](https://www.shipfox.io/docs/reference/runner#step-environment) for every variable
that Shipfox sets on a step.