|
| 1 | +### pygithubactions/core |
| 2 | +> Core functions for setting results, logging, registering secrets and exporting variables across actions |
| 3 | +
|
| 4 | +### Usage |
| 5 | + |
| 6 | +### Import the package |
| 7 | + |
| 8 | +```python |
| 9 | +from pygithubactions import core |
| 10 | +``` |
| 11 | + |
| 12 | +### Inputs/Outputs |
| 13 | + |
| 14 | +Action inputs can be read with `get_input` which returns a `str` or `get_boolean_input` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` set to be false, the input should have a default value in `action.yml`. |
| 15 | + |
| 16 | +Outputs can be set with `set_output` which makes them available to be mapped into inputs of other actions to ensure they are decoupled. |
| 17 | + |
| 18 | +```python |
| 19 | +from pygithubactions import core |
| 20 | + |
| 21 | +my_input = core.get_input('inputName', required=True) |
| 22 | +boolean_input = core.get_boolean_input('booleanInputName', required=True) |
| 23 | +multiline_input = core.get_multiline_input('multilineInputName', required=True) |
| 24 | + |
| 25 | +core.set_output('outputkey', 'outputval') |
| 26 | +``` |
| 27 | + |
| 28 | +### Exporting variables |
| 29 | + |
| 30 | +Since each step runs in a separate process, you can use `export_variable` to add it to this step and future steps environment blocks. |
| 31 | + |
| 32 | +```python |
| 33 | +from pygithubactions import core |
| 34 | + |
| 35 | +core.export_variable('envvar', 'val') |
| 36 | +``` |
| 37 | + |
| 38 | +### Setting a secret |
| 39 | + |
| 40 | +Setting a secret registers the secret with the runner to ensure it is masked in logs. |
| 41 | + |
| 42 | +```python |
| 43 | +from pygithubactions import core |
| 44 | + |
| 45 | +core.set_secret('mypassword') |
| 46 | +``` |
| 47 | + |
| 48 | +### PATH Manipulation |
| 49 | + |
| 50 | +To make a tool's path available in the path for the remainder of the job (without altering the machine or containers state), use `add_path`. The runner will prepend the path given to the jobs PATH. |
| 51 | + |
| 52 | +```python |
| 53 | +from pygithubactions import core |
| 54 | + |
| 55 | +core.add_path('/path/to/mytool') |
| 56 | +``` |
| 57 | + |
| 58 | +### Exit codes |
| 59 | + |
| 60 | +You should use this library to set the failing exit code for your action. If status is not set and the script runs to completion, that will lead to a success. |
| 61 | + |
| 62 | +```python |
| 63 | +from pygithubactions import core |
| 64 | + |
| 65 | +try: |
| 66 | + # Do stuff |
| 67 | + # ... |
| 68 | + |
| 69 | +except Exception as e: |
| 70 | + # set_failed logs the message and sets a failing exit code |
| 71 | + core.set_failed(f'Action failed with error {e}') |
| 72 | +``` |
| 73 | + |
| 74 | +### Logging |
| 75 | + |
| 76 | +Finally, this library provides some utilities for logging. Note that debug logging is hidden from the logs by default. This behavior can be toggled by enabling the [Step Debug Logs](../../docs/action-debugging.md#step-debug-logs). |
| 77 | + |
| 78 | +```python |
| 79 | +from pygithubactions import core |
| 80 | + |
| 81 | + |
| 82 | +my_input = core.get_input('input') |
| 83 | + |
| 84 | +try: |
| 85 | + core.debug('Inside try block') |
| 86 | + |
| 87 | + if not my_input: |
| 88 | + core.warning('my_input was not set') |
| 89 | + |
| 90 | + if core.is_debug(): |
| 91 | + # do something |
| 92 | + else: |
| 93 | + # do something |
| 94 | + |
| 95 | + # Do stuff |
| 96 | + core.info('Output to the actions build log') |
| 97 | + core.notice('This is a message that will also emit an annotation') |
| 98 | + |
| 99 | +except Exception as e: |
| 100 | + core.error(f'Error: {e}, action may still succeed though') |
| 101 | +``` |
| 102 | + |
| 103 | +This library can also wrap chunks of output in foldable groups. |
| 104 | + |
| 105 | +```python |
| 106 | +from pygithubactions import core |
| 107 | + |
| 108 | +# Manually wrap output |
| 109 | +core.start_group('Do some function') |
| 110 | +do_some_job() |
| 111 | +core.end_group() |
| 112 | + |
| 113 | +# Wrap a function call |
| 114 | +def do_some_job(): |
| 115 | + ... |
| 116 | + return result |
| 117 | + |
| 118 | +result = core.group('Do something async', do_some_job) |
| 119 | +``` |
| 120 | + |
| 121 | +#### Annotations |
| 122 | + |
| 123 | +This library has 3 methods that will produce [annotations](https://docs.github.com/en/rest/reference/checks#create-a-check-run). |
| 124 | +```python |
| 125 | +from pygithubactions import core |
| 126 | + |
| 127 | +core.error('This is a bad error, action may still succeed though.') |
| 128 | +core.warning('Something went wrong, but it\'s not bad enough to fail the build.') |
| 129 | +core.notice('Something happened that you might want to know about.') |
| 130 | +``` |
| 131 | + |
| 132 | +These will surface to the UI in the Actions page and on Pull Requests. They look something like this: |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | +These annotations can also be attached to particular lines and columns of your source files to show exactly where a problem is occuring. |
| 137 | + |
| 138 | +These options are: |
| 139 | +```python |
| 140 | +@dataclass |
| 141 | +class AnnotationProperties: |
| 142 | + # A title for the annotation. |
| 143 | + title: str = '' |
| 144 | + |
| 145 | + # The path of the file for which the annotation should be created. |
| 146 | + file: str = '' |
| 147 | + |
| 148 | + # The start line for the annotation. |
| 149 | + startLine: int = 0 |
| 150 | + |
| 151 | + # The end line for the annotation. Defaults to `startLine` |
| 152 | + # when `startLine` is provided. |
| 153 | + endLine: int = 0 |
| 154 | + |
| 155 | + # The start column for the annotation. Cannot be sent when |
| 156 | + # `startLine` and `endLine` are different values. |
| 157 | + startColumn: int = 0 |
| 158 | + |
| 159 | + # The end column for the annotation. Cannot be sent when |
| 160 | + # `startLine` and `endLine` are different values. |
| 161 | + # Defaults to `startColumn` when `startColumn` is provided. |
| 162 | + endColumn: int = 0 |
| 163 | +``` |
| 164 | + |
| 165 | +#### Styling output |
| 166 | + |
| 167 | +Colored output is supported in the Action logs via standard [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code). 3/4 bit, 8 bit and 24 bit colors are all supported. |
| 168 | + |
| 169 | +Foreground colors: |
| 170 | +```python |
| 171 | +# 3/4 bit |
| 172 | +core.info('\u001b[35mThis foreground will be magenta') |
| 173 | + |
| 174 | +# 8 bit |
| 175 | +core.info('\u001b[38;5;6mThis foreground will be cyan') |
| 176 | + |
| 177 | +# 24 bit |
| 178 | +core.info('\u001b[38;2;255;0;0mThis foreground will be bright red') |
| 179 | +``` |
| 180 | + |
| 181 | +Background colors: |
| 182 | +```python |
| 183 | +# 3/4 bit |
| 184 | +core.info('\u001b[43mThis background will be yellow') |
| 185 | + |
| 186 | +# 8 bit |
| 187 | +core.info('\u001b[48;5;6mThis background will be cyan') |
| 188 | + |
| 189 | +# 24 bit |
| 190 | +core.info('\u001b[48;2;255;0;0mThis background will be bright red') |
| 191 | +``` |
| 192 | + |
| 193 | +Special styles: |
| 194 | +```python |
| 195 | +core.info('\u001b[1mBold text') |
| 196 | +core.info('\u001b[3mItalic text') |
| 197 | +core.info('\u001b[4mUnderlined text') |
| 198 | +``` |
| 199 | + |
| 200 | +ANSI escape codes can be combined with one another: |
| 201 | +```python |
| 202 | +core.info('\u001b[31;46mRed foreground with a cyan background and \u001b[1mbold text at the end') |
| 203 | +``` |
| 204 | + |
| 205 | +> Note: Escape codes reset at the start of each line |
| 206 | +
|
| 207 | +```python |
| 208 | +core.info('\u001b[35mThis foreground will be magenta') |
| 209 | +core.info('This foreground will reset to the default') |
| 210 | +``` |
| 211 | + |
| 212 | +#### Action state |
| 213 | + |
| 214 | +You can use this library to save state and get state for sharing information between a given wrapper action: |
| 215 | +In action's `main.py`: |
| 216 | + |
| 217 | +```python |
| 218 | +core.save_state("pidToKill", 12345) |
| 219 | + |
| 220 | +pid = core.get_state("pidToKill") |
| 221 | +``` |
| 222 | + |
| 223 | +#### Filesystem path helpers |
| 224 | + |
| 225 | +You can use these methods to manipulate file paths across operating systems. |
| 226 | + |
| 227 | +The `to_posix_path` function converts input paths to Posix-style (Linux) paths. |
| 228 | +The `to_win32_path` function converts input paths to Windows-style paths. These |
| 229 | +functions work independently of the underlying runner operating system. |
| 230 | + |
| 231 | +```python |
| 232 | +to_posix_path('\\foo\\bar') // => /foo/bar |
| 233 | +to_win32_path('/foo/bar') // => \foo\bar |
| 234 | +``` |
| 235 | + |
| 236 | +The `to_platform_path` function converts input paths to the expected value on the runner's operating system. |
| 237 | + |
| 238 | +```python |
| 239 | +// On a Windows runner. |
| 240 | +to_platform_path('/foo/bar') // => \foo\bar |
| 241 | + |
| 242 | +// On a Linux runner. |
| 243 | +to_platform_path('\\foo\\bar') // => /foo/bar |
| 244 | +``` |
0 commit comments