Resolving Deprecation Errors in GitHub Actions Due to the `set-output`, `save-state`, `add-path` and the `set-env` Workflow Commands

41 minute read     Updated:

Mustapha Ahmad Ayodeji %
Mustapha Ahmad Ayodeji

This article outlines how to address deprecation errors in GitHub Actions, particularly focusing on the set-output, save-state, add-path, and set-env workflow commands. It discusses the reasons behind their deprecation and provides detailed solutions for updating workflows to use the new environment files method.

Disabled and Deprecated Workflow Commands Errors and Warnings

Have you encountered failed GitHub Actions (GA) workflow runs accompanied by the error messages above? Or perhaps you’ve come across those unsettling warnings displayed in the screenshot? If so, you are probably wondering what these errors meant, how can you resolve them, the purpose of the environment files suggested in the warnings, and why are these actions even being deprecated.

This article will address all these concerns. However, this article assumes that you are already familiar with Github Action.

The errors and warnings are shown because GitHub has deprecated and disabled the set-env and add-path workflow commands and the set-output and the save-state workflow commands are also on the deprecation list and they will soon be disabled.

Before you dive into how you can fix the errors and warnings, and the rationale behind their deprecation, let’s take a short review of what these workflow commands do.

If you like to just take the fix and move on, you can find them in this section

The save-state and set-output Workflow Command

The steps in your workflow jobs run sequentially, one after the other and your workflow jobs run in parallel, however, a job can depend on another in which the dependent job runs after the job it depends on. The save-state and set-output were previously ways to pass data across from one step to another and from one job to another in a workflow.

Despite their shared functionalities, they served different purposes and the data that they stored was available in different scopes.

The save-state Command

The save-state was used to persist data across different steps in the same job or different jobs (not necessarily depending on each other) in the same workflow file and the data persisted was available for the entire duration of the workflow run.

It had the following syntax:

echo "::save-state name=<state_name>::<state_value>"

For example, you could persist a Go version environment variable as shown below:

echo "::save-state name=build_version::$VERSION"

The build_version state would then be available throughout the workflow run.

The set-output Command

The set-output was used to set the output for a workflow job. This output would be available in the steps that follow the step that sets it and in the steps of the jobs that depend on the job that sets it, where it could be accessed with the needs context.

An example of using this command is shown below:

echo "::set-output name=<output_name>::<output_value>"

For example, you could set an output of an already defined timestamp variable as shown below:

echo "::set-output name=build_timestamp::$TIMESTAMP"

The build_timestamp would then be available in the steps that follow and the steps of other jobs that depend on the job that sets the output.

The choice of whether to use the save-state or the set-output depends on whether you want the data to persist throughout the workflow run or within a job and its dependent jobs.

The add-path and set-env Workflow Command

The set-env command was used to set environment variables that could be used in subsequent steps.

It had the following syntax:

echo ::set-env:: name="<env_name>::<env_value>

The add-path command was used to add a directory to PATH to make it available for use without the need to specify the full path when executing the command.

It had the following syntax:

echo "::add-path::/usr/local/mytool"

So, what were the problems with them and why were they deprecated?

Why Were They Deprecated ?

The save-state and the set-output command were deprecated (although not yet disabled at the time of writing this article) as part of security enhancement for GitHub action against a potential security breach.

As outlined in the changelog post that introduced this changes:

" To avoid untrusted logged data to use save-state and set-output workflow commands without the intention of the workflow author we have introduced a new set of environment files to manage state and output."

These suggested new sets of environment files will be discussed later on in the article.

Similarly, the add-path and set-env workflow commands, which have also been deprecated, and have now been disabled, due to a moderate security vulnerability that was identified in the GitHub Actions runner that could allow environment variable and path injection in workflows that log untrusted data to STDOUT. This could potentially result in the introduction or modification of environment variables without the workflow author’s intention.

All these deprecated commands are now being replaced by environment files. The following section provides a brief introduction to this newly recommended alternative.

Environment Files

Environment Files are temporary files that the action runners generate during the execution of workflows. The path to these files is exposed by default environment variables that have a naming convention of GITHUB_*. These environment variables cannot be overridden by user-defined environment variables.

These environment files offer a highly secure and user-friendly method of managing states, setting outputs, manipulating the PATH variable, and defining additional environment variables.

An example of how they can be used to set environment variables is shown below:

echo "{key}={value}" >> "$GITHUB_ENV"

They also support the use of multiline with the syntax

{name}<<{delimiter}
{value}
{delimiter}

An example of this is the step below that saves a multiline encoded data as an environment variable:

​​steps:
  - name: Set the value in bash
    id: step_one
    run: |
      # Encode some sensitive data (e.g., a secret key)
      ENCODED_DATA=$(echo "my_secret_key" | base64)

     # Generate a random delimiter
     EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)

      # Store the encoded data in a multiline environment variable
      echo "ENCODED_SECRET<<EOF" >> "$GITHUB_ENV"
      echo "$ENCODED_DATA" >> "$GITHUB_ENV"
      echo "EOF" >> "$GITHUB_ENV"

The content that will be saved in the environment file will look as shown below:

ENCODED_SECRET<<EOF
bXlfc2VjcmV0X2tleQ==
EOF

So now that you understand why you are seeing these errors and warnings, what they meant, and how to use the suggested environment files, You can now move on to fixing the warnings and the errors.

The fixes that will be discussed will be for both workflow authors and action authors.

Fix for Workflow Authors

As a workflow author, you write workflow files. A simple fix for your workflow files that uses the commands above is to make the following changes in your workflow files.

For the warning below:

The `save-state` command is deprecated and will be disabled soon. 
Please upgrade to using Environment Files. For more information see:
https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

Replace the syntax below:

- name: Save state 
  run: echo "::save-state name={state_name}::{state_value}"

With:

- name: Save state 
  run: echo "{state_name}={state_value}" >> $GITHUB_STATE

For the warning below:

The `set-output` command is deprecated and will be disabled soon. 
Please upgrade to using Environment Files. For more information see:
https://github.blog/changeloq/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

Update your workflow files to replace the syntax below:

- name: Set output
  run: echo "::set-output name={output_name}::{output_value}"

With:

- name: Set output 
  run: echo "{name}={value}" >> $GITHUB_OUTPUT

For the error below:

The `add-path` command is disabled. Please upgrade to using 
Environment Files or opt into unsecure command execution by setting the
`ACTIONS_ALLOW _UNSECURE_COMMANDS` environment variable to `true`. 
For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/

Update your workflow files by replacing the syntax below:

- name: Add Path
  run echo "::add-path::/usr/local/mytool"

With:

- name: Add Path
   run echo "{:/usr/local/mytool}" >> $GITHUB_PATH

For the error below:

The `set-env` command is disabled. Please upgrade to using 
Environment Files or opt into unsecure command execution by 
setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment 
variable to 'true. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/

Update your workflow files by replacing the syntax below:

- name: Set Env
  run echo "::set-env name={output_name}::{output_value}"

With:

- name: Set Env
  run: echo "{name}={value}" >> $GITHUB_ENV

To do a quick hands-on of making these fixes in an actual workflow file, let’s make use of the workflow file that generated the errors and warnings in the image at the beginning of this article. The workflow file is available in this GitHub repository.

The workflow is as shown below:

name: Build and Deploy
on:
  workflow_dispatch:


jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check Out
        uses: actions/checkout@v3

      - name: Setup Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.x

      - name: Build Go App
        run: go build -o dra_app main.go

      - name: Save the binary as an artifact
        uses: actions/upload-artifact@v3
        with:
          name: dra_app-binary
          path: dra_app

      - name: Save an Environment version as output
        run: |
          DRA_ENV="This is from GA"
          echo "::set-output name=draenv::$DRA_ENV"

      - name: Save Timestamp as State
        run: |
          TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
          echo "::save-state name=build_timestamp::$TIMESTAMP"

      - name: Set Go version as env value 
        run: echo "::set-env name=GO_VERSION::$(go version \
        | awk '{print $3}')"


  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: always()  # Ensure the job runs always, regardless of the \
    first job's status

    steps:
      - name: Download Artifact
        uses: actions/download-artifact@v2
        with:
          name: dra_app-binary
      
      - name: Set executable permissions
        run: chmod +x dra_app
 
      - name: Deploy Go App
        run: ./dra_app
        
      - name: Retrieve the Timestamp
        run: |
          TIMESTAMP=$
          DRA_ENV=$
          echo "Deployment completed at timestamp $TIMESTAMP and \
          environment variable $DRA_ENV was setups"

      - name: Install jq and add to PATH
        run: |
          sudo apt-get update
          sudo apt-get install jq -y
          echo "::add-path::/usr/bin"

The workflow file is designed to build and run a simple Go app. This workflow is triggered by a workflow_dispatch event and consists of two distinct jobs.

The first job, which is executed on an Ubuntu machine, performs the following steps:

Checks out the repository. Sets up the Go environment. Builds the Go app and saves the build output artifact. Utilizes the deprecated set-output command to set an output. Employs the deprecated save-state command to retain a timestamp as a state. Utilizes the deprecated and disabled set-env command to set the Go version as an environment variable.

The second job is dependent on the outcome of the first job and is also executed on an Ubuntu machine. This job runs regardless of whether the first job succeeded or encountered any failures. The primary tasks of this workflow job are as follows:

Downloads the build artifact that was preserved during the first job. Sets the downloaded file as an executable. Attempts to retrieve values from the TIMESTAMP output and the DRA_ENV environment variable. Downloads the jq command-line tool. Tries to add jq to the list of PATH variables using the add-path command.

To fix the errors and the warning that you will get from executing this workflow file, you need to change each of these deprecated commands to the new syntax.

The first one is the step below that sets a value as an output:

      - name: Save an Environment version as output
        run: |
          DRA_ENV="This is from GA"
          echo "::set-output name=draenv::$DRA_ENV"

Here, you will change the set-output command to use the new environment file for setting output:

      - name: Save an Environment version as output
        run: |
          DRA_ENV="This is from GA"
          echo "draenv=$DRA_ENV" >> $GITHUB_OUTPUT

The second one is the step that saves the timestamp as a state:

      - name: Save Timestamp as State
        run: |
          TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
          echo "::save-state name=build_timestamp::$TIMESTAMP"

You can fix this by using the new environment file for saving the state:

      - name: Save Timestamp as State
        run: |
          TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
          echo "build_timestamp=$TIMESTAMP" >> $GITHUB_STATE

The third error was from the step that sets the Go version as an environment variable with the disabled set-env command:

      - name: Set Go version as env value 
        run: echo "::set-env name=GO_VERSION::$(go version \
        | awk '{print $3}')"

This can be fixed as shown below:

      - name: Set Go version as env value 
        run: echo "GO_VERSION=$(go version \
        | awk '{print $3}')" >> $GITHUB_ENV

Finally, the last error was from the step that installed the jq command and added it to the path:

      - name: Install jq and add to PATH
        run: |
          sudo apt-get update
          sudo apt-get install jq -y
          echo "/usr/bin" >> $GITHUB_PATH

This github branch contains these changes. The highlighted changes can be found in this GitHub commit.

If you rerun this workflow file in this new branch:

Rerun build

The run will be successful without any warnings or errors:

Successful build without any warnings

In your GitHub repositories, you have probably used these commands in multiple places in a workflow file, it can be a little bit hard looking for the usage of these commands in the file. You can make use of the GitHub editor’s find and replace features to make this a little bit easier.

Searching for the Command Usage in a Single File

You can search for the instances of these deprecated commands in a single file by using the GitHub editor’s find and replace feature.

To use this, open the workflow file in edit mode and click on Command+F (Mac) or Ctrl+F (Windows/Linux). This will bring up a panel that allows you to search for the instances of these commands:

image

Using the replace feature might not be efficient here due to the dynamics of the usage of these commands. However, you can manually edit the file to effect the new changes.

The demonstration above involves fixing the usage of these deprecated commands in a single workflow file. You have probably used these commands in multiple workflow files. In the next section, you will learn how to find the usage of these commands across multiple workflow files in different repositories so that you can know where you need to change.

Searching for Command Usage with GitHub Code Search Syntax

To look for all the instances of the above-deprecated commands in your repositories, you can make use of the GitHub code search syntax which allows you to build search queries for these commands by using specialized code qualifiers, regular expressions, and boolean operations.

To use it, click on the search icon from anywhere in your GitHub account:

image

Add your search query in the search bar. The query below searches for the use of any of the save-state, add-path, set-env, and set-output in the file path of .github/workflows in any repository owned by DrAnonymousNet (replace with your GitHub username:

owner:DrAnonymousNet  path:/^\.github\/workflows\// save-state \
OR add-path OR set-env OR set-output

This search query returns the following result in my repository:

image

From the result, you can identify the files where these commands are used. In the next section, you will see how you can fix all the instances of these commands in a file at once with the sed command.

Fixing All Instances of the Commands Usage with the sed Command

To fix all instances of these commands in a file, you can execute this sed command in a bash-based workflow:

sed -i '' \
  -e 's/echo "::set-output name=\([^:]*\)::\([^"]*\)"/echo "\1=\2" >> $GITHUB_OUTPUT/g' \
  -e 's/echo "::set-env name=\([^:]*\)::\([^"]*\)"/echo "\1=\2" >> $GITHUB_ENV/g' \
  -e 's/echo "::save-state name=\([^:]*\)::\([^"]*\)"/echo "\1=\2" >> $GITHUB_STATE/g' \
  -e 's/echo "::add-path::\([^"]*\)"/echo "\1" >> $GITHUB_PATH/'

 file_name

The command searches all syntax that matches the deprecated syntax and replaces them with the new syntax of the environment files.

Replace the file_name placeholder with your workflow file.

After running the command, inspect the output of git diff and make any final touches that aren’t perfect.

The following is the output of executing the command on the workflow file used in this article:

Output of git diff

Another instance of this sed command is suggested by kcgen in this GitHub community discussion

Fix for Errors and Warnings Due to Workflow Dependencies

The fixes discussed above are applicable when you get these errors and warnings because you use these commands directly in your workflow files. It is also possible that you get these errors and warnings due to an action that your workflow file depends on.

Take this workflow file that uses the setup-python action pinned to an old commit sha:

name: My Workflow

on:

  workflow_dispatch:

jobs:
  my_job:
    runs-on: ubuntu-latest
    steps:
      - name: Set up Python 3.10
        uses: actions/setup-python@bdd6409dc13e625e6c1c0ad857bd591804786f7b
        with:
            python-version: "3.10"

When you dispatch this workflow, you will get the errors and warnings below due to the deprecated commands even though you don’t directly use them:

image

To fix this, you need to switch to an updated version provided by the action author where they have fixed the issue. If there is no updated version, you can raise an issue in their repository to notify them of the errors and warnings.

Fix for Action Authors

As an action author that writes custom actions that workflow files depend on, If the users of your custom actions are raising GitHub issues due to the deprecation of the commands above, you need to update the @actions/core package to the latest version. The latest version of this package provides the updated version of the code that provides the workflow commands.

Conclusion

In this tutorial, you learn about how to fix the warnings and errors in your workflow files due to the deprecation of the set-env, add-path, set-output, and the save-state command. You learn about the reasons for these deprecations, what the suggested environment files meant, and how to use the environment file.

For action authors, you have also learned about how to fix the custom action that you provide when users that depend on your action get this error.

In order to stay updated with the latest changes like deprecation or features introduction on GitHub products generally, you can always visit the changelog page.

Earthly Cloud: Consistent, Fast Builds, Any CI
Consistent, repeatable builds across all environments. Advanced caching for faster builds. Easy integration with any CI. 6,000 build minutes per month included.

Get Started Free

Mustapha Ahmad Ayodeji %
Mustapha Ahmad Ayodeji
Ahmad is a Software developer and a Technical writer with so much interest for Django related frameworks.

Updated:

Published:

Get notified about new articles!
We won't send you spam. Unsubscribe at any time.