Run Python in a composite GitHub Action
To pass output from a Python script within a step of a GitHub Actions workflow, you will be able to write the variable using GitHub's specified GITHUB_OUTPUT environment variable using Python's open function with the a (append) mode.
A single line variable¶
An example is available in this comment in GitHub discussions, which states:
Do the same thing as with the shell, append to the file specified in the
GITHUB_OUTPUTenvironment variable:import os name = 'my_name' value = 'my_value' with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: print(f'{name}={value}', file=fh)Mind that for values with multiple lines you now have to use the same format as for multiline environment variables, instead of URL encoding them.
A multiline variable¶
An example is available in this comment in GitHub discussions, which states:
For those struggling to do the multiline output work, I made a small method that set its up for you:
import uuid def set_multiline_output(name, value): with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: delimiter = uuid.uuid1() print(f'{name}<<{delimiter}', file=fh) print(value, file=fh) print(delimiter, file=fh)Just call it with:
Configuring a composite GitHub Action¶
In a composite GitHub Action, you will need to configure the action.yml metadata file properly.
When running the Python script within the GitHub Action, be sure to define the step id as well as declare the proper outputs, here is an example:
# [ ... trimmed action.yml config ... ]
outputs:
json-output:
description: "a JSON object created by the python script"
value: ${{ steps.inline-python-script.outputs.MY_OUTPUT_CUSTOM_JSON }}
var-output:
description: "a variable created by the python script"
value: ${{ steps.inline-python-script.outputs.MY_OUTPUT_CUSTOM_VAR }}
runs:
using: composite
steps:
- name: Run inline Python script
id: inline-python-script
env:
MY_CUSTOM_VAR_1: ${{ inputs.custom-input-1 }}
MY_CUSTOM_VAR_2: ${{ inputs.custom-input-2 }}
run: |
"""
This is a custom python script that is part of a composite GitHub Action
"""
#
import os
import requests
import json
import uuid
#
# [ ... trimmed script ... ]
#
# function to send single-line variable to github output
def set_output(name, value):
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'{name}={value}', file=fh)
#
# function to send multi-line variable to github output
def set_multiline_output(name, value):
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
delimiter = uuid.uuid1()
print(f'{name}<<{delimiter}', file=fh)
print(value, file=fh)
print(delimiter, file=fh)
# functions to send to github output are from
# https://github.com/orgs/community/discussions/28146#discussioncomment-5638023
# https://github.com/orgs/community/discussions/28146#discussioncomment-5638014
# Example usage above
# [ ... trimmed script ... ]
#
if __name__ == "__main__":
# Get parameters from environment variables set by the action
my_custom_var1 = os.getenv('MY_CUSTOM_VAR_1')
my_custom_var2 = os.getenv('MY_CUSTOM_VAR_2')
combined_vars = my_custom_var1 + " " + my_custom_var2
#
# [ ... trimmed script ... ]
#
# Export to GitHub output
## Single line Example
set_output("MY_OUTPUT_CUSTOM_VAR", combined_vars)
#
## Multiline Example
set_multiline_output("MY_OUTPUT_CUSTOM_JSON", json.dumps(all_json_details))
# [ ... trimmed script ... ]
# [ ... trimmed script ... ]
shell: python
- name: Print the output from the Python script
id: print-python-output
run: |
echo "going to print the variable output..."
echo "$PYTHON_VAR_OUTPUT"
echo ""
echo "going to print the JSON output and pipe it to jq..."
echo "$PYTHON_JSON_OUTPUT" | jq '.'
env:
PYTHON_VAR_OUTPUT: ${{ steps.inline-python-script.outputs.MY_OUTPUT_CUSTOM_VAR }}
PYTHON_JSON_OUTPUT: ${{ steps.inline-python-script.outputs.MY_OUTPUT_CUSTOM_JSON }}
shell: bash
# [ ... trimmed action.yml config ... ]
branding:
# Ref: https://haya14busa.github.io/github-action-brandings/
# fork: https://github.com/rwaight/github-action-brandings
icon: download
color: blue
References¶
- GitHub Docs
- GitHub
actions/runner - GitHub Community Discussions
#133693How to pass output from a GitHub Action step that is in python?#28146How to set-output from a python script in Github workflow step.#40515Setting output using python file working on ubuntu-latest runner, but not working on windows-latest runner#58980How to accessoutputfrom a custom action?
- Stackoverflow
- Others