Skip to content

github-custom-actions

Python package for creating custom GitHub Actions.

How to Create Your Own GitHub Action in 5 Minutes.

The package works with Python 3.8 and up, so even those dusty old self-hosted action runners can handle it like champs.

Quick start

from github_custom_actions import ActionBase


class MyAction(ActionBase):
    def main(self):
        self.outputs["runner-os"] = self.env.runner_os
        self.summary.text += (
            self.render(
                "### {{ inputs['my-input'] }}.\n"
                "Have a nice day!"
            )
        )


if __name__ == "__main__":
    MyAction().run()

This example uses the runner_os variable from GitHub environment variables. All variables from the GitHub environment are available in the env, with descriptions shown in your IDE on mouse hover: var_ide_hover_docstring.jpg

The action gets a value from the my-input action input and renders it in the action step summary on the GitHub build summary.

It also returns a value to the runner-os action output.

The run() in the main block runs the main() that implements your action.

Explicitly defined inputs and outputs

With explicitly defined inputs and outputs, you can use typo-checked code autocompletion:

from pathlib import Path

from github_custom_actions import ActionBase, ActionInputs, ActionOutputs


class MyInputs(ActionInputs):
    my_input: str
    """My input description"""

    my_path: Path
    """My path description"""


class MyOutputs(ActionOutputs):
    runner_os: str
    """Runner OS description"""


class MyAction(ActionBase):
    inputs: MyInputs
    outputs: MyOutputs

    def main(self):
        if self.inputs.my_path is None:
            raise ValueError("my-path is required")
        self.inputs.my_path.mkdir(exist_ok=True)
        self.outputs.runner_os = self.env.runner_os
        self.summary.text += (
            self.render(
                "### {{ inputs.my_input }}.\n"
                "Have a nice day, {{ inputs['name'] }}!"
            )
        )


if __name__ == "__main__":
    MyAction().run()

Note that you only define the types of inputs and outputs, and instances are created automatically upon ActionBase initialization.

Now you can utilize the attributes defined in the inputs and outputs classes of the action. All attributes names are converted to kebab-case, allowing dot notation like inputs.my_input to replace the inputs['my-input'].

Inputs defined as Path will be converted to Path objects.

But still can use the inputs['my-input'] style if you prefer.

Example of usage

Allure Test Report Action