1 | # `@actions/core`
|
2 |
|
3 | > Core functions for setting results, logging, registering secrets and exporting variables across actions
|
4 |
|
5 | ## Usage
|
6 |
|
7 | ### Import the package
|
8 |
|
9 | ```js
|
10 | // javascript
|
11 | const core = require('@actions/core');
|
12 |
|
13 | // typescript
|
14 | import * as core from '@actions/core';
|
15 | ```
|
16 |
|
17 | #### Inputs/Outputs
|
18 |
|
19 | Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` 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`.
|
20 |
|
21 | Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled.
|
22 |
|
23 | ```js
|
24 | const myInput = core.getInput('inputName', { required: true });
|
25 | const myBooleanInput = core.getBooleanInput('booleanInputName', { required: true });
|
26 | const myMultilineInput = core.getMultilineInput('multilineInputName', { required: true });
|
27 | core.setOutput('outputKey', 'outputVal');
|
28 | ```
|
29 |
|
30 | #### Exporting variables
|
31 |
|
32 | Since each step runs in a separate process, you can use `exportVariable` to add it to this step and future steps environment blocks.
|
33 |
|
34 | ```js
|
35 | core.exportVariable('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 | ```js
|
43 | core.setSecret('myPassword');
|
44 | ```
|
45 |
|
46 | #### PATH Manipulation
|
47 |
|
48 | To make a tool's path available in the path for the remainder of the job (without altering the machine or containers state), use `addPath`. The runner will prepend the path given to the jobs PATH.
|
49 |
|
50 | ```js
|
51 | core.addPath('/path/to/mytool');
|
52 | ```
|
53 |
|
54 | #### Exit codes
|
55 |
|
56 | 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.
|
57 |
|
58 | ```js
|
59 | const core = require('@actions/core');
|
60 |
|
61 | try {
|
62 | // Do stuff
|
63 | }
|
64 | catch (err) {
|
65 | // setFailed logs the message and sets a failing exit code
|
66 | core.setFailed(`Action failed with error ${err}`);
|
67 | }
|
68 | ```
|
69 |
|
70 | Note that `setNeutral` is not yet implemented in actions V2 but equivalent functionality is being planned.
|
71 |
|
72 | #### Logging
|
73 |
|
74 | 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).
|
75 |
|
76 | ```js
|
77 | const core = require('@actions/core');
|
78 |
|
79 | const myInput = core.getInput('input');
|
80 | try {
|
81 | core.debug('Inside try block');
|
82 |
|
83 | if (!myInput) {
|
84 | core.warning('myInput was not set');
|
85 | }
|
86 |
|
87 | if (core.isDebug()) {
|
88 | // curl -v https://github.com
|
89 | } else {
|
90 | // curl https://github.com
|
91 | }
|
92 |
|
93 | // Do stuff
|
94 | core.info('Output to the actions build log')
|
95 |
|
96 | core.notice('This is a message that will also emit an annotation')
|
97 | }
|
98 | catch (err) {
|
99 | core.error(`Error ${err}, action may still succeed though`);
|
100 | }
|
101 | ```
|
102 |
|
103 | This library can also wrap chunks of output in foldable groups.
|
104 |
|
105 | ```js
|
106 | const core = require('@actions/core')
|
107 |
|
108 | // Manually wrap output
|
109 | core.startGroup('Do some function')
|
110 | doSomeFunction()
|
111 | core.endGroup()
|
112 |
|
113 | // Wrap an asynchronous function call
|
114 | const result = await core.group('Do something async', async () => {
|
115 | const response = await doSomeHTTPRequest()
|
116 | return response
|
117 | })
|
118 | ```
|
119 |
|
120 | #### Annotations
|
121 |
|
122 | This library has 3 methods that will produce [annotations](https://docs.github.com/en/rest/reference/checks#create-a-check-run).
|
123 | ```js
|
124 | core.error('This is a bad error, action may still succeed though.')
|
125 |
|
126 | core.warning('Something went wrong, but it\'s not bad enough to fail the build.')
|
127 |
|
128 | core.notice('Something happened that you might want to know about.')
|
129 | ```
|
130 |
|
131 | These will surface to the UI in the Actions page and on Pull Requests. They look something like this:
|
132 |
|
133 | ![Annotations Image](../../docs/assets/annotations.png)
|
134 |
|
135 | These annotations can also be attached to particular lines and columns of your source files to show exactly where a problem is occuring.
|
136 |
|
137 | These options are:
|
138 | ```typescript
|
139 | export interface AnnotationProperties {
|
140 | /**
|
141 | * A title for the annotation.
|
142 | */
|
143 | title?: string
|
144 |
|
145 | /**
|
146 | * The name of the file for which the annotation should be created.
|
147 | */
|
148 | file?: string
|
149 |
|
150 | /**
|
151 | * The start line for the annotation.
|
152 | */
|
153 | startLine?: number
|
154 |
|
155 | /**
|
156 | * The end line for the annotation. Defaults to `startLine` when `startLine` is provided.
|
157 | */
|
158 | endLine?: number
|
159 |
|
160 | /**
|
161 | * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values.
|
162 | */
|
163 | startColumn?: number
|
164 |
|
165 | /**
|
166 | * The end column for the annotation. Cannot be sent when `startLine` and `endLine` are different values.
|
167 | * Defaults to `startColumn` when `startColumn` is provided.
|
168 | */
|
169 | endColumn?: number
|
170 | }
|
171 | ```
|
172 |
|
173 | #### Styling output
|
174 |
|
175 | 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.
|
176 |
|
177 | Foreground colors:
|
178 |
|
179 | ```js
|
180 | // 3/4 bit
|
181 | core.info('\u001b[35mThis foreground will be magenta')
|
182 |
|
183 | // 8 bit
|
184 | core.info('\u001b[38;5;6mThis foreground will be cyan')
|
185 |
|
186 | // 24 bit
|
187 | core.info('\u001b[38;2;255;0;0mThis foreground will be bright red')
|
188 | ```
|
189 |
|
190 | Background colors:
|
191 |
|
192 | ```js
|
193 | // 3/4 bit
|
194 | core.info('\u001b[43mThis background will be yellow');
|
195 |
|
196 | // 8 bit
|
197 | core.info('\u001b[48;5;6mThis background will be cyan')
|
198 |
|
199 | // 24 bit
|
200 | core.info('\u001b[48;2;255;0;0mThis background will be bright red')
|
201 | ```
|
202 |
|
203 | Special styles:
|
204 |
|
205 | ```js
|
206 | core.info('\u001b[1mBold text')
|
207 | core.info('\u001b[3mItalic text')
|
208 | core.info('\u001b[4mUnderlined text')
|
209 | ```
|
210 |
|
211 | ANSI escape codes can be combined with one another:
|
212 |
|
213 | ```js
|
214 | core.info('\u001b[31;46mRed foreground with a cyan background and \u001b[1mbold text at the end');
|
215 | ```
|
216 |
|
217 | > Note: Escape codes reset at the start of each line
|
218 |
|
219 | ```js
|
220 | core.info('\u001b[35mThis foreground will be magenta')
|
221 | core.info('This foreground will reset to the default')
|
222 | ```
|
223 |
|
224 | Manually typing escape codes can be a little difficult, but you can use third party modules such as [ansi-styles](https://github.com/chalk/ansi-styles).
|
225 |
|
226 | ```js
|
227 | const style = require('ansi-styles');
|
228 | core.info(style.color.ansi16m.hex('#abcdef') + 'Hello world!')
|
229 | ```
|
230 |
|
231 | #### Action state
|
232 |
|
233 | You can use this library to save state and get state for sharing information between a given wrapper action:
|
234 |
|
235 | **action.yml**:
|
236 |
|
237 | ```yaml
|
238 | name: 'Wrapper action sample'
|
239 | inputs:
|
240 | name:
|
241 | default: 'GitHub'
|
242 | runs:
|
243 | using: 'node12'
|
244 | main: 'main.js'
|
245 | post: 'cleanup.js'
|
246 | ```
|
247 |
|
248 | In action's `main.js`:
|
249 |
|
250 | ```js
|
251 | const core = require('@actions/core');
|
252 |
|
253 | core.saveState("pidToKill", 12345);
|
254 | ```
|
255 |
|
256 | In action's `cleanup.js`:
|
257 |
|
258 | ```js
|
259 | const core = require('@actions/core');
|
260 |
|
261 | var pid = core.getState("pidToKill");
|
262 |
|
263 | process.kill(pid);
|
264 | ```
|
265 |
|
266 | #### OIDC Token
|
267 |
|
268 | You can use these methods to interact with the GitHub OIDC provider and get a JWT ID token which would help to get access token from third party cloud providers.
|
269 |
|
270 | **Method Name**: getIDToken()
|
271 |
|
272 | **Inputs**
|
273 |
|
274 | audience : optional
|
275 |
|
276 | **Outputs**
|
277 |
|
278 | A [JWT](https://jwt.io/) ID Token
|
279 |
|
280 | In action's `main.ts`:
|
281 | ```js
|
282 | const core = require('@actions/core');
|
283 | async function getIDTokenAction(): Promise<void> {
|
284 |
|
285 | const audience = core.getInput('audience', {required: false})
|
286 |
|
287 | const id_token1 = await core.getIDToken() // ID Token with default audience
|
288 | const id_token2 = await core.getIDToken(audience) // ID token with custom audience
|
289 |
|
290 | // this id_token can be used to get access token from third party cloud providers
|
291 | }
|
292 | getIDTokenAction()
|
293 | ```
|
294 |
|
295 | In action's `actions.yml`:
|
296 |
|
297 | ```yaml
|
298 | name: 'GetIDToken'
|
299 | description: 'Get ID token from Github OIDC provider'
|
300 | inputs:
|
301 | audience:
|
302 | description: 'Audience for which the ID token is intended for'
|
303 | required: false
|
304 | outputs:
|
305 | id_token1:
|
306 | description: 'ID token obtained from OIDC provider'
|
307 | id_token2:
|
308 | description: 'ID token obtained from OIDC provider'
|
309 | runs:
|
310 | using: 'node12'
|
311 | main: 'dist/index.js'
|
312 | ```
|
313 |
|
314 | #### Filesystem path helpers
|
315 |
|
316 | You can use these methods to manipulate file paths across operating systems.
|
317 |
|
318 | The `toPosixPath` function converts input paths to Posix-style (Linux) paths.
|
319 | The `toWin32Path` function converts input paths to Windows-style paths. These
|
320 | functions work independently of the underlying runner operating system.
|
321 |
|
322 | ```js
|
323 | toPosixPath('\\foo\\bar') // => /foo/bar
|
324 | toWin32Path('/foo/bar') // => \foo\bar
|
325 | ```
|
326 |
|
327 | The `toPlatformPath` function converts input paths to the expected value on the runner's operating system.
|
328 |
|
329 | ```js
|
330 | // On a Windows runner.
|
331 | toPlatformPath('/foo/bar') // => \foo\bar
|
332 |
|
333 | // On a Linux runner.
|
334 | toPlatformPath('\\foo\\bar') // => /foo/bar
|
335 | ```
|