Skip to content

Latest commit

 

History

History
979 lines (677 loc) · 28.5 KB

workflow-commands-for-github-actions.md

File metadata and controls

979 lines (677 loc) · 28.5 KB
title shortTitle intro defaultTool redirect_from versions
Workflow commands for GitHub Actions
Workflow commands
You can use workflow commands when running shell commands in a workflow or in an action's code.
bash
/articles/development-tools-for-github-actions
/github/automating-your-workflow-with-github-actions/development-tools-for-github-actions
/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions
/actions/reference/development-tools-for-github-actions
/actions/reference/logging-commands-for-github-actions
/actions/reference/workflow-commands-for-github-actions
/actions/learn-github-actions/workflow-commands-for-github-actions
fpt ghes ghae ghec
*
*
*
*

{% data reusables.actions.enterprise-beta %} {% data reusables.actions.enterprise-github-hosted-runners %}

About workflow commands

Actions can communicate with the runner machine to set environment variables, output values used by other actions, add debug messages to the output logs, and other tasks.

Most workflow commands use the echo command in a specific format, while others are invoked by writing to a file. For more information, see "Environment files."

Example of a workflow command

{% bash %}

echo "::workflow-command parameter1={data},parameter2={data}::{command value}"

{% endbash %}

{% powershell %}

Write-Output "::workflow-command parameter1={data},parameter2={data}::{command value}"

{% endpowershell %}

{% note %}

Note: Workflow command and parameter names are not case-sensitive.

{% endnote %}

{% warning %}

Warning: If you are using Command Prompt, omit double quote characters (") when using workflow commands.

{% endwarning %}

Using workflow commands to access toolkit functions

The actions/toolkit includes a number of functions that can be executed as workflow commands. Use the :: syntax to run the workflow commands within your YAML file; these commands are then sent to the runner over stdout.

{%- ifversion actions-save-state-set-output-envs %} For example, instead of using code to create an error annotation, as below:

core.error('Missing semicolon', {file: 'app.js', startLine: 1})

Example: Creating an annotation for an error

You can use the error command in your workflow to create the same error annotation:

{% bash %}

{% raw %}

      - name: Create annotation for build error
        run: echo "::error file=app.js,line=1::Missing semicolon"

{% endraw %}

{% endbash %}

{% powershell %}

{% raw %}

      - name: Create annotation for build error
        run: Write-Output "::error file=app.js,line=1::Missing semicolon"

{% endraw %}

{% endpowershell %} {%- else %} For example, instead of using code to set an output, as below:

core.setOutput('SELECTED_COLOR', 'green');

Example: Setting a value

You can use the set-output command in your workflow to set the same value:

{% bash %}

{% raw %}

      - name: Set selected color
        run: echo '::set-output name=SELECTED_COLOR::green'
        id: random-color-generator
      - name: Get color
        run: echo "The selected color is ${{ steps.random-color-generator.outputs.SELECTED_COLOR }}"

{% endraw %}

{% endbash %}

{% powershell %}

{% raw %}

      - name: Set selected color
        run: Write-Output "::set-output name=SELECTED_COLOR::green"
        id: random-color-generator
      - name: Get color
        run: Write-Output "The selected color is ${{ steps.random-color-generator.outputs.SELECTED_COLOR }}"

{% endraw %}

{% endpowershell %}

{% endif %}

The following table shows which toolkit functions are available within a workflow:

Toolkit function Equivalent workflow command
core.addPath Accessible using environment file GITHUB_PATH
core.debug debug
core.notice notice
core.error error
core.endGroup endgroup
core.exportVariable Accessible using environment file GITHUB_ENV
core.getInput Accessible using environment variable INPUT_{NAME}
core.getState Accessible using environment variable STATE_{NAME}
core.isDebug Accessible using environment variable RUNNER_DEBUG
{%- ifversion actions-job-summaries %}
core.summary Accessible using environment file GITHUB_STEP_SUMMARY
{%- endif %}
core.saveState {% ifversion actions-save-state-set-output-envs %}Accessible using environment file GITHUB_STATE{% else %}save-state{% endif %}
core.setCommandEcho echo
core.setFailed Used as a shortcut for ::error and exit 1
core.setOutput {% ifversion actions-save-state-set-output-envs %}Accessible using environment file GITHUB_OUTPUT{% else %}set-output{% endif %}
core.setSecret add-mask
core.startGroup group
core.warning warning

{% ifversion actions-save-state-set-output-envs %}{% else %}

Setting an output parameter

Sets an action's output parameter.

::set-output name={name}::{value}

Optionally, you can also declare output parameters in an action's metadata file. For more information, see "AUTOTITLE."

You can escape multiline strings for setting an output parameter by creating an environment variable and using it in a workflow command. For more information, see "Setting an environment variable."

Example: Setting an output parameter

{% bash %}

echo "::set-output name=action_fruit::strawberry"

{% endbash %}

{% powershell %}

Write-Output "::set-output name=action_fruit::strawberry"

{% endpowershell %} {% endif %}

Setting a debug message

Prints a debug message to the log. You must create a secret named ACTIONS_STEP_DEBUG with the value true to see the debug messages set by this command in the log. For more information, see "AUTOTITLE."

::debug::{message}

Example: Setting a debug message

{% bash %}

echo "::debug::Set the Octocat variable"

{% endbash %}

{% powershell %}

Write-Output "::debug::Set the Octocat variable"

{% endpowershell %}

Setting a notice message

Creates a notice message and prints the message to the log. {% data reusables.actions.message-annotation-explanation %}

::notice file={name},line={line},endLine={endLine},title={title}::{message}

{% data reusables.actions.message-parameters %}

Example: Setting a notice message

{% bash %}

echo "::notice file=app.js,line=1,col=5,endColumn=7::Missing semicolon"

{% endbash %}

{% powershell %}

Write-Output "::notice file=app.js,line=1,col=5,endColumn=7::Missing semicolon"

{% endpowershell %}

Setting a warning message

Creates a warning message and prints the message to the log. {% data reusables.actions.message-annotation-explanation %}

::warning file={name},line={line},endLine={endLine},title={title}::{message}

{% data reusables.actions.message-parameters %}

Example: Setting a warning message

{% bash %}

echo "::warning file=app.js,line=1,col=5,endColumn=7::Missing semicolon"

{% endbash %}

{% powershell %}

Write-Output "::warning file=app.js,line=1,col=5,endColumn=7::Missing semicolon"

{% endpowershell %}

Setting an error message

Creates an error message and prints the message to the log. {% data reusables.actions.message-annotation-explanation %}

::error file={name},line={line},endLine={endLine},title={title}::{message}

{% data reusables.actions.message-parameters %}

Example: Setting an error message

{% bash %}

echo "::error file=app.js,line=1,col=5,endColumn=7::Missing semicolon"

{% endbash %}

{% powershell %}

Write-Output "::error file=app.js,line=1,col=5,endColumn=7::Missing semicolon"

{% endpowershell %}

Grouping log lines

Creates an expandable group in the log. To create a group, use the group command and specify a title. Anything you print to the log between the group and endgroup commands is nested inside an expandable entry in the log.

::group::{title}
::endgroup::

Example: Grouping log lines

{% bash %}

jobs:
  bash-example:
    runs-on: ubuntu-latest
    steps:
      - name: Group of log lines
        run: |
            echo "::group::My title"
            echo "Inside group"
            echo "::endgroup::"

{% endbash %}

{% powershell %}

jobs:
  powershell-example:
    runs-on: windows-latest
    steps:
      - name: Group of log lines
        run: |
            Write-Output "::group::My title"
            Write-Output "Inside group"
            Write-Output "::endgroup::"

{% endpowershell %}

Foldable group in workflow run log

Masking a value in log

::add-mask::{value}

Masking a value prevents a string or variable from being printed in the log. Each masked word separated by whitespace is replaced with the * character. You can use an environment variable or string for the mask's value. When you mask a value, it is treated as a secret and will be redacted on the runner. For example, after you mask a value, you won't be able to set that value as an output.

Example: Masking a string

When you print "Mona The Octocat" in the log, you'll see "***".

{% bash %}

echo "::add-mask::Mona The Octocat"

{% endbash %}

{% powershell %}

Write-Output "::add-mask::Mona The Octocat"

{% endpowershell %}

{% warning %}

Warning: Make sure you register the secret with 'add-mask' before outputting it in the build logs or using it in any other workflow commands.

{% endwarning %}

Example: Masking an environment variable

When you print the variable MY_NAME or the value "Mona The Octocat" in the log, you'll see "***" instead of "Mona The Octocat".

{% bash %}

jobs:
  bash-example:
    runs-on: ubuntu-latest
    env:
      MY_NAME: "Mona The Octocat"
    steps:
      - name: bash-version
        run: echo "::add-mask::$MY_NAME"

{% endbash %}

{% powershell %}

jobs:
  powershell-example:
    runs-on: windows-latest
    env:
      MY_NAME: "Mona The Octocat"
    steps:
      - name: powershell-version
        run: Write-Output "::add-mask::$env:MY_NAME"

{% endpowershell %}

Stopping and starting workflow commands

Stops processing any workflow commands. This special command allows you to log anything without accidentally running a workflow command. For example, you could stop logging to output an entire script that has comments.

::stop-commands::{endtoken}

To stop the processing of workflow commands, pass a unique token to stop-commands. To resume processing workflow commands, pass the same token that you used to stop workflow commands.

{% warning %}

Warning: Make sure the token you're using is randomly generated and unique for each run.

{% endwarning %}

::{endtoken}::

Example: Stopping and starting workflow commands

{% bash %}

{% raw %}

jobs:
  workflow-command-job:
    runs-on: ubuntu-latest
    steps:
      - name: Disable workflow commands
        run: |
          echo '::warning:: This is a warning message, to demonstrate that commands are being processed.'
          stopMarker=$(uuidgen)
          echo "::stop-commands::$stopMarker"
          echo '::warning:: This will NOT be rendered as a warning, because stop-commands has been invoked.'
          echo "::$stopMarker::"
          echo '::warning:: This is a warning again, because stop-commands has been turned off.'

{% endraw %}

{% endbash %}

{% powershell %}

{% raw %}

jobs:
  workflow-command-job:
    runs-on: windows-latest
    steps:
      - name: Disable workflow commands
        run: |
          Write-Output '::warning:: This is a warning message, to demonstrate that commands are being processed.'
          $stopMarker = New-Guid
          Write-Output "::stop-commands::$stopMarker"
          Write-Output '::warning:: This will NOT be rendered as a warning, because stop-commands has been invoked.'
          Write-Output "::$stopMarker::"
          Write-Output '::warning:: This is a warning again, because stop-commands has been turned off.'

{% endraw %}

{% endpowershell %}

{% ifversion actions-save-state-set-output-envs %}{% else %}

Echoing command outputs

Enables or disables echoing of workflow commands. For example, if you use the set-output command in a workflow, it sets an output parameter but the workflow run's log does not show the command itself. If you enable command echoing, then the log shows the command, such as ::set-output name={name}::{value}.

::echo::on
::echo::off

Command echoing is disabled by default. However, a workflow command is echoed if there are any errors processing the command.

The add-mask, debug, warning, and error commands do not support echoing because their outputs are already echoed to the log.

You can also enable command echoing globally by turning on step debug logging using the ACTIONS_STEP_DEBUG secret. For more information, see "AUTOTITLE". In contrast, the echo workflow command lets you enable command echoing at a more granular level, rather than enabling it for every workflow in a repository.

Example: Toggling command echoing

{% bash %}

jobs:
  workflow-command-job:
    runs-on: ubuntu-latest
    steps:
      - name: toggle workflow command echoing
        run: |
          echo '::set-output name=action_echo::disabled'
          echo '::echo::on'
          echo '::set-output name=action_echo::enabled'
          echo '::echo::off'
          echo '::set-output name=action_echo::disabled'

{% endbash %}

{% powershell %}

jobs:
  workflow-command-job:
    runs-on: windows-latest
    steps:
      - name: toggle workflow command echoing
        run: |
          write-output "::set-output name=action_echo::disabled"
          write-output "::echo::on"
          write-output "::set-output name=action_echo::enabled"
          write-output "::echo::off"
          write-output "::set-output name=action_echo::disabled"

{% endpowershell %}

The example above prints the following lines to the log:

::set-output name=action_echo::enabled
::echo::off

Only the second set-output and echo workflow commands are included in the log because command echoing was only enabled when they were run. Even though it is not always echoed, the output parameter is set in all cases.

{% endif %}

Sending values to the pre and post actions

{% ifversion actions-save-state-set-output-envs %}You can create environment variables for sharing with your workflow's pre: or post: actions by writing to the file located at GITHUB_STATE{% else %}You can use the save-state command to create environment variables for sharing with your workflow's pre: or post: actions{% endif %}. For example, you can create a file with the pre: action, pass the file location to the main: action, and then use the post: action to delete the file. Alternatively, you could create a file with the main: action, pass the file location to the post: action, and also use the post: action to delete the file.

If you have multiple pre: or post: actions, you can only access the saved value in the action where {% ifversion actions-save-state-set-output-envs %}it was written to GITHUB_STATE{% else %}save-state was used{% endif %}. For more information on the post: action, see "AUTOTITLE."

{% ifversion actions-save-state-set-output-envs %}The GITHUB_STATE file is only available within an action{% else %}The save-state command can only be run within an action, and is not available to YAML files{% endif %}. The saved value is stored as an environment value with the STATE_ prefix.

{% ifversion actions-save-state-set-output-envs %} This example uses JavaScript to write to the GITHUB_STATE file. The resulting environment variable is named STATE_processID with the value of 12345:

import * as fs from 'fs'
import * as os from 'os'

fs.appendFileSync(process.env.GITHUB_STATE, `processID=12345${os.EOL}`, {
  encoding: 'utf8'
})

{% else %} This example uses JavaScript to run the save-state command. The resulting environment variable is named STATE_processID with the value of 12345:

console.log('::save-state name=processID::12345')

{% endif %}

The STATE_processID variable is then exclusively available to the cleanup script running under the main action. This example runs in main and uses JavaScript to display the value assigned to the STATE_processID environment variable:

console.log("The running PID from the main action is: " +  process.env.STATE_processID);

Environment files

During the execution of a workflow, the runner generates temporary files that can be used to perform certain actions. The path to these files are exposed via environment variables. You will need to use UTF-8 encoding when writing to these files to ensure proper processing of the commands. Multiple commands can be written to the same file, separated by newlines.

Most commands in the following examples use double quotes for echoing strings, which will attempt to interpolate characters like $ for shell variable names. To always use literal values in quoted strings, you can use single quotes instead.

{% powershell %}

{% note %}

Note: PowerShell versions 5.1 and below (shell: powershell) do not use UTF-8 by default, so you must specify the UTF-8 encoding. For example:

jobs:
  legacy-powershell-example:
    runs-on: windows-latest
    steps:
      - shell: powershell
        run: |
          "mypath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append

PowerShell Core versions 6 and higher (shell: pwsh) use UTF-8 by default. For example:

jobs:
  powershell-core-example:
    runs-on: windows-latest
    steps:
      - shell: pwsh
        run: |
          "mypath" >> $env:GITHUB_PATH

{% endnote %}

{% endpowershell %}

Setting an environment variable

{% bash %}

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

{% endbash %}

{% powershell %}

  • Using PowerShell version 6 and higher:

    "{environment_variable_name}={value}" >> $env:GITHUB_ENV
    
  • Using PowerShell version 5.1 and below:

    "{environment_variable_name}={value}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    

{% endpowershell %}

You can make an environment variable available to any subsequent steps in a workflow job by defining or updating the environment variable and writing this to the GITHUB_ENV environment file. The step that creates or updates the environment variable does not have access to the new value, but all subsequent steps in a job will have access. The names of environment variables are case-sensitive, and you can include punctuation. For more information, see "AUTOTITLE."

Example of writing an environment variable to GITHUB_ENV

{% bash %}

{% raw %}

steps:
  - name: Set the value
    id: step_one
    run: |
      echo "action_state=yellow" >> $GITHUB_ENV
  - name: Use the value
    id: step_two
    run: |
      echo "${{ env.action_state }}" # This will output 'yellow'

{% endraw %}

{% endbash %}

{% powershell %}

{% raw %}

steps:
  - name: Set the value
    id: step_one
    run: |
      "action_state=yellow" >> $env:GITHUB_ENV
  - name: Use the value
    id: step_two
    run: |
      Write-Output "${{ env.action_state }}" # This will output 'yellow'

{% endraw %}

{% endpowershell %}

Multiline strings

For multiline strings, you may use a delimiter with the following syntax.

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

{% warning %}

Warning: Make sure the delimiter you're using is randomly generated and unique for each run. For more information, see "AUTOTITLE".

{% endwarning %}

Example of a multiline string

This example uses EOF as a delimiter, and sets the JSON_RESPONSE environment variable to the value of the curl response.

{% bash %}

steps:
  - name: Set the value in bash
    id: step_one
    run: |
      echo 'JSON_RESPONSE<<EOF' >> $GITHUB_ENV
      curl https://example.com >> $GITHUB_ENV
      echo 'EOF' >> $GITHUB_ENV

{% endbash %}

{% powershell %}

steps:
  - name: Set the value in pwsh
    id: step_one
    run: |
      "JSON_RESPONSE<<EOF" >> $env:GITHUB_ENV
      (Invoke-WebRequest -Uri "https://example.com").Content >> $env:GITHUB_ENV
      "EOF" >> $env:GITHUB_ENV
    shell: pwsh

{% endpowershell %}

{% ifversion actions-save-state-set-output-envs %}

Setting an output parameter

Sets a step's output parameter. Note that the step will need an id to be defined to later retrieve the output value.

{% bash %}

echo "{name}={value}" >> $GITHUB_OUTPUT

{% endbash %}

{% powershell %}

"{name}=value" >> $env:GITHUB_OUTPUT

{% endpowershell %}

Example of setting an output parameter

{% bash %}

This example demonstrates how to set the SELECTED_COLOR output parameter and later retrieve it:

{% raw %}

      - name: Set color
        id: random-color-generator
        run: echo "SELECTED_COLOR=green" >> $GITHUB_OUTPUT
      - name: Get color
        run: echo "The selected color is ${{ steps.random-color-generator.outputs.SELECTED_COLOR }}"

{% endraw %}

{% endbash %}

{% powershell %}

{% raw %} This example demonstrates how to set the SELECTED_COLOR output parameter and later retrieve it:

      - name: Set color
        id: random-color-generator
        run: |
            "SELECTED_COLOR=green" >> $env:GITHUB_OUTPUT
      - name: Get color
        run: Write-Output "The selected color is ${{ steps.random-color-generator.outputs.SELECTED_COLOR }}"

{% endraw %}

{% endpowershell %}

{% note %}

Note: Multi-line output values can be set in the same way Multi-line environment variables are. For more information, see "Multiline strings."

{% endnote %}

{% endif %}

{% ifversion actions-job-summaries %}

Adding a job summary

{% bash %}

echo "{markdown content}" >> $GITHUB_STEP_SUMMARY

{% endbash %}

{% powershell %}

"{markdown content}" >> $env:GITHUB_STEP_SUMMARY

{% endpowershell %}

You can set some custom Markdown for each job so that it will be displayed on the summary page of a workflow run. You can use job summaries to display and group unique content, such as test result summaries, so that someone viewing the result of a workflow run doesn't need to go into the logs to see important information related to the run, such as failures.

Job summaries support {% data variables.product.prodname_dotcom %} flavored Markdown, and you can add your Markdown content for a step to the GITHUB_STEP_SUMMARY environment file. GITHUB_STEP_SUMMARY is unique for each step in a job. For more information about the per-step file that GITHUB_STEP_SUMMARY references, see "Environment files."

When a job finishes, the summaries for all steps in a job are grouped together into a single job summary and are shown on the workflow run summary page. If multiple jobs generate summaries, the job summaries are ordered by job completion time.

Example of adding a job summary

{% bash %}

echo "### Hello world! :rocket:" >> $GITHUB_STEP_SUMMARY

{% endbash %}

{% powershell %}

"### Hello world! :rocket:" >> $env:GITHUB_STEP_SUMMARY

{% endpowershell %}

Markdown summary example

Multiline Markdown content

For multiline Markdown content, you can use >> to continuously append content for the current step. With every append operation, a newline character is automatically added.

Example of multiline Markdown content

{% bash %}

- name: Generate list using Markdown
  run: |
    echo "This is the lead in sentence for the list" >> $GITHUB_STEP_SUMMARY
    echo "" >> $GITHUB_STEP_SUMMARY # this is a blank line
    echo "- Lets add a bullet point" >> $GITHUB_STEP_SUMMARY
    echo "- Lets add a second bullet point" >> $GITHUB_STEP_SUMMARY
    echo "- How about a third one?" >> $GITHUB_STEP_SUMMARY

{% endbash %}

{% powershell %}

- name: Generate list using Markdown
  run: |
    "This is the lead in sentence for the list" >> $env:GITHUB_STEP_SUMMARY
    "" >> $env:GITHUB_STEP_SUMMARY # this is a blank line
    "- Lets add a bullet point" >> $env:GITHUB_STEP_SUMMARY
    "- Lets add a second bullet point" >> $env:GITHUB_STEP_SUMMARY
    "- How about a third one?" >> $env:GITHUB_STEP_SUMMARY

{% endpowershell %}

Overwriting job summaries

To clear all content for the current step, you can use > to overwrite any previously added content.

Example of overwriting job summaries

{% bash %}

- name: Overwrite Markdown
  run: |
    echo "Adding some Markdown content" >> $GITHUB_STEP_SUMMARY
    echo "There was an error, we need to clear the previous Markdown with some new content." > $GITHUB_STEP_SUMMARY

{% endbash %}

{% powershell %}

- name: Overwrite Markdown
  run: |
    "Adding some Markdown content" >> $env:GITHUB_STEP_SUMMARY
    "There was an error, we need to clear the previous Markdown with some new content." > $env:GITHUB_STEP_SUMMARY

{% endpowershell %}

Removing job summaries

To completely remove a summary for the current step, the file that GITHUB_STEP_SUMMARY references can be deleted.

Example of removing job summaries

{% bash %}

- name: Delete all summary content
  run: |
    echo "Adding Markdown content that we want to remove before the step ends" >> $GITHUB_STEP_SUMMARY
    rm $GITHUB_STEP_SUMMARY

{% endbash %}

{% powershell %}

- name: Delete all summary content
  run: |
    "Adding Markdown content that we want to remove before the step ends" >> $env:GITHUB_STEP_SUMMARY
    rm $env:GITHUB_STEP_SUMMARY

{% endpowershell %}

After a step has completed, job summaries are uploaded and subsequent steps cannot modify previously uploaded Markdown content. Summaries automatically mask any secrets that might have been added accidentally. If a job summary contains sensitive information that must be deleted, you can delete the entire workflow run to remove all its job summaries. For more information see "AUTOTITLE."

Step isolation and limits

Job summaries are isolated between steps and each step is restricted to a maximum size of 1MiB. Isolation is enforced between steps so that potentially malformed Markdown from a single step cannot break Markdown rendering for subsequent steps. If more than 1MiB of content is added for a step, then the upload for the step will fail and an error annotation will be created. Upload failures for job summaries do not affect the overall status of a step or a job. A maximum of 20 job summaries from steps are displayed per job.

{% endif %}

Adding a system path

Prepends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job; the currently running action cannot access the updated path variable. To see the currently defined paths for your job, you can use echo "$PATH" in a step or an action.

{% bash %}

echo "{path}" >> $GITHUB_PATH

{% endbash %}

{% powershell %}

"{path}" >> $env:GITHUB_PATH

{% endpowershell %}

Example of adding a system path

{% bash %}

This example demonstrates how to add the user $HOME/.local/bin directory to PATH:

echo "$HOME/.local/bin" >> $GITHUB_PATH

{% endbash %}

{% powershell %}

This example demonstrates how to add the user $env:HOMEPATH/.local/bin directory to PATH:

"$env:HOMEPATH/.local/bin" >> $env:GITHUB_PATH

{% endpowershell %}