Skip to content

Commit 1182a1e

Browse files
author
Ludovic TOURMAN
committed
Add more outputs and improve test
1 parent 881d6a2 commit 1182a1e

File tree

8 files changed

+232
-21
lines changed

8 files changed

+232
-21
lines changed

.github/workflows/build-test.yaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,11 @@ jobs:
242242
wait-for-completion-timeout: 120s
243243
display-workflow-run-url-interval: 10s
244244
display-workflow-run-url-timeout: 120s
245-
workflow-logs: print
245+
workflow-logs: json-output
246246
inputs: >-
247247
{
248-
"run-name": "${{ env.RUN_NAME }}"
248+
"run-name": "${{ env.RUN_NAME }}",
249+
"environment": "${{ matrix.environment }}",
249250
}
250251
continue-on-error: true
251252
- uses: nick-invision/assert-action@v1
@@ -257,9 +258,11 @@ jobs:
257258
expected: success
258259
actual: ${{ steps.named-run-workflow.outcome }}
259260
- uses: nick-invision/assert-action@v1
261+
env:
262+
EXPECTED_LOG_MESSAGE: "### Env: ${{ matrix.environment }} ###"
260263
with:
261-
expected: "Run name: ${{ env.RUN_NAME }}"
262-
actual: ${{ steps.named-run-workflow.outcome }}
264+
expected: "true"
265+
actual: ${{ fromJson(steps.named-run-workflow.outputs.workflow-logs).echo.*.message == env.EXPECTED_LOG_MESSAGE }}
263266

264267
deploy:
265268
needs:

.github/workflows/named-run.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ on:
88
description: 'The distinct run name used to retrieve the run ID. Defaults to the workflow name'
99
type: string
1010
required: false
11+
environment:
12+
description: 'The environment name'
13+
type: string
14+
required: true
1115

1216
jobs:
1317
echo:
@@ -17,4 +21,4 @@ jobs:
1721
run: sleep 10s
1822
- name: Echo message
1923
run: |
20-
echo 'Run name: ${{ github.event.inputs.run-name || github.workflow }}'
24+
echo '### Env: ${{ github.event.inputs.environment }} ###'

README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ For details of the `workflow_dispatch` even see [this blog post introducing this
8686
8787
## Outputs
8888

89+
### `workflow-id`
90+
91+
> The ID of the worflow run that has been triggered.
92+
8993
### `workflow-url`
9094

9195
> The URL of the workflow run that has been triggered. It may be undefined if the URL couldn't be retrieved (timeout reached) or if `wait-for-completion` and `display-workflow-run-url` are > both `false`
@@ -95,6 +99,36 @@ For details of the `workflow_dispatch` even see [this blog post introducing this
9599
> The result of the triggered workflow. May be one of `success`, `failure`, `cancelled`, `timed_out`, `skipped`, `neutral`, `action_required`. The step in your workflow will fail if the triggered workflow completes with `failure`, `cancelled` or `timed_out`. Other workflow conlusion are considered success.
96100
> Only available if `wait-for-completion` is `true`
97101
102+
### `workflow-logs`
103+
104+
> The logs of the triggered workflow based if `inputs.workflow-logs` is set to either `output`, or `json-output`.
105+
> Based on the value, result will be:
106+
>
107+
> * `output`: Multiline string
108+
>
109+
> ```log
110+
> <job-name> | <datetime> <message>
111+
> <job-name> | <datetime> <message>
112+
> ...
113+
> ```
114+
>
115+
> * `json-output`: JSON string
116+
>
117+
> ```json
118+
> {
119+
> "<job-name>": [
120+
> {
121+
> "datetime": "<datetime>",
122+
> "message": "<message>"
123+
> },
124+
> {
125+
> "datetime": "<datetime>",
126+
> "message": "<message>"
127+
> }
128+
> ]
129+
> }
130+
> ```
131+
98132
## Example usage
99133
100134
### Invoke workflow without inputs. Wait for result
@@ -155,6 +189,32 @@ For details of the `workflow_dispatch` even see [this blog post introducing this
155189
run: echo "Another Workflow conclusion: ${{ steps.trigger-step.outputs.workflow-conclusion }}"
156190
```
157191
192+
### Invoke workflow and scrap output
193+
194+
```yaml
195+
- name: Invoke workflow and scrap output
196+
id: trigger-step
197+
uses: aurelien-baudet/workflow-dispatch@v2
198+
with:
199+
workflow: Another Workflow
200+
token: ${{ secrets.PERSONAL_TOKEN }}
201+
workflow-logs: json-output
202+
- name: Another step that can handle the result
203+
if: always()
204+
run: echo '${{ fromJSON(steps.trigger-step.outputs.workflow-logs).my-remote-job }}'
205+
```
206+
207+
```yaml
208+
name: Another Workflow
209+
210+
on:
211+
workflow_dispatch:
212+
213+
jobs:
214+
my-remote-job:
215+
- run: echo "Hello world!"
216+
```
217+
158218
### Invoke workflow with a unique run name (since 3.0.0)
159219
160220
```yaml

action.yaml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ name: 'Workflow Dispatch and wait'
22
description: 'Trigger and chain GitHub Actions workflows with workflow_dispatch events and wait for result'
33

44
inputs:
5-
workflow:
5+
workflow:
66
description: 'Name or ID of workflow to run'
77
required: true
8-
token:
8+
token:
99
description: 'GitHub token with repo write access, can NOT use secrets.GITHUB_TOKEN, see readme'
1010
required: true
1111
inputs:
@@ -37,18 +37,36 @@ inputs:
3737
required: false
3838
default: true
3939
wait-for-completion-timeout:
40-
description: 'Maximum amount of time (+unit) to wait to mark workflow as timed out'
40+
description: 'Maximum amount of time (+unit) to wait to mark workflow as timed out'
4141
required: false
4242
default: 1h
4343
wait-for-completion-interval:
4444
description: 'Time to wait (+unit) between two polls to get run status'
4545
required: false
4646
default: 1m
4747
workflow-logs:
48-
description: 'Indicate what to do with logs of the triggered workflow. `ignore` do not retrieve logs from tiggered workflow. `print` retrieves logs from triggered workflow and print in the workflow that triggered the other workflow.'
48+
description: >-
49+
Indicate what to do with logs of the triggered workflow.
50+
`ignore` do not retrieve logs from tiggered workflow.
51+
`print` retrieves logs from triggered workflow and print in the workflow that triggered the other workflow.
52+
`output` retrieves logs from triggered workflow and set them as `workflow-logs` output.
53+
`json-output` retrieves logs from triggered workflow and return a json array groupped by job name.
4954
required: false
5055
default: ignore
5156

57+
outputs:
58+
workflow-conclusion:
59+
description: 'Conclusion of the triggered workflow'
60+
workflow-id:
61+
description: 'ID of the triggered workflow'
62+
workflow-url:
63+
description: 'URL of the triggered workflow'
64+
workflow-logs:
65+
description: |
66+
Logs of the triggered workflow. Based on `inputs.workflow-logs`, format is set to:
67+
- `output`: Multiline logs formatted as: '<job-name> | <datetime> <message>'
68+
- `json-output`: JSON logs formatted as: '{"<job-name>": [{"<datetime>": "<message>"}]'
69+
5270
runs:
5371
using: 'node16'
5472
main: 'dist/index.js'

dist/index.js

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9768,7 +9768,7 @@ function handleLogs(args, workflowHandler) {
97689768
yield (0, workflow_logs_handler_1.handleWorkflowLogsPerJob)(args, workflowRunId);
97699769
}
97709770
catch (e) {
9771-
core.error(`Failed to handle logs of tirggered workflow. Cause: ${e}`);
9771+
core.error(`Failed to handle logs of triggered workflow. Cause: ${e}`);
97729772
}
97739773
});
97749774
}
@@ -9794,6 +9794,7 @@ function run() {
97949794
core.info(`Waiting for workflow completion`);
97959795
const { result, start } = yield waitForCompletionOrTimeout(workflowHandler, args.checkStatusInterval, args.waitForCompletionTimeout);
97969796
yield handleLogs(args, workflowHandler);
9797+
core.setOutput('workflow-id', result === null || result === void 0 ? void 0 : result.id);
97979798
core.setOutput('workflow-url', result === null || result === void 0 ? void 0 : result.url);
97989799
computeConclusion(start, args.waitForCompletionTimeout, result);
97999800
}
@@ -10053,6 +10054,7 @@ class WorkflowHandler {
1005310054
});
1005410055
(0, debug_1.debug)('Workflow Run status', response);
1005510056
return {
10057+
id: runId,
1005610058
url: response.data.html_url,
1005710059
status: ofStatus(response.data.status),
1005810060
conclusion: ofConclusion(response.data.conclusion)
@@ -10075,6 +10077,7 @@ class WorkflowHandler {
1007510077
});
1007610078
(0, debug_1.debug)('Workflow Run artifacts', response);
1007710079
return {
10080+
id: runId,
1007810081
url: response.data.html_url,
1007910082
status: ofStatus(response.data.status),
1008010083
conclusion: ofConclusion(response.data.conclusion)
@@ -10098,7 +10101,6 @@ class WorkflowHandler {
1009810101
repo: this.repo,
1009910102
workflow_id: workflowId,
1010010103
event: 'workflow_dispatch',
10101-
branch: this.ref,
1010210104
created: `>=${new Date(this.triggerDate).toISOString()}`
1010310105
});
1010410106
(0, debug_1.debug)('List Workflow Runs', response);
@@ -10243,6 +10245,16 @@ function handleWorkflowLogsPerJob(args, workflowRunId) {
1024310245
yield handler.handleError(job, error);
1024410246
}
1024510247
}
10248+
switch (mode) {
10249+
case 'json-output':
10250+
core.setOutput('workflow-logs', handler.getJsonLogs());
10251+
break;
10252+
case 'output':
10253+
core.setOutput('workflow-logs', handler.getRawLogs());
10254+
break;
10255+
default:
10256+
break;
10257+
}
1024610258
});
1024710259
}
1024810260
exports.handleWorkflowLogsPerJob = handleWorkflowLogsPerJob;
@@ -10265,10 +10277,63 @@ class PrintLogsHandler {
1026510277
});
1026610278
}
1026710279
}
10280+
class OutputLogsHandler {
10281+
constructor() {
10282+
this.logs = new Map();
10283+
}
10284+
handleJobList(jobs) {
10285+
return __awaiter(this, void 0, void 0, function* () {
10286+
(0, debug_1.debug)('Retrieving logs for jobs in workflow', jobs);
10287+
});
10288+
}
10289+
handleJobLogs(job, logs) {
10290+
return __awaiter(this, void 0, void 0, function* () {
10291+
this.logs.set(job.name, logs);
10292+
});
10293+
}
10294+
handleError(job, error) {
10295+
return __awaiter(this, void 0, void 0, function* () {
10296+
core.warning(escapeImportedLogs(error.message));
10297+
});
10298+
}
10299+
getJsonLogs() {
10300+
const result = {};
10301+
const logPattern = /(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{7}Z)\s+(.*)/;
10302+
this.logs.forEach((logs, jobName) => {
10303+
result[jobName] = [];
10304+
for (const line of logs.split('\n')) {
10305+
if (line === '') {
10306+
continue;
10307+
}
10308+
const splitted = line.split(logPattern);
10309+
result[jobName].push({
10310+
datetime: splitted[1],
10311+
message: splitted[2]
10312+
});
10313+
}
10314+
// result[jobName] = logs;
10315+
});
10316+
return JSON.stringify(result);
10317+
}
10318+
getRawLogs() {
10319+
let result = '';
10320+
this.logs.forEach((logs, jobName) => {
10321+
for (const line of logs.split('\n')) {
10322+
result += `${jobName} | ${line}\n`;
10323+
}
10324+
});
10325+
return result;
10326+
}
10327+
}
1026810328
function logHandlerFactory(mode) {
1026910329
switch (mode) {
10270-
case 'print': return new PrintLogsHandler();
10271-
default: return null;
10330+
case 'print':
10331+
return new PrintLogsHandler();
10332+
case 'output':
10333+
case 'json-output':
10334+
return new OutputLogsHandler();
10335+
default:
10336+
return null;
1027210337
}
1027310338
}
1027410339
function escapeImportedLogs(str) {

src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ async function run(): Promise<void> {
9797

9898
await handleLogs(args, workflowHandler);
9999

100+
core.setOutput('workflow-id', result?.id);
100101
core.setOutput('workflow-url', result?.url);
101102
computeConclusion(start, args.waitForCompletionTimeout, result);
102103

src/workflow-handler.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const ofConclusion = (conclusion: string | null): WorkflowRunConclusion => {
3636
}
3737

3838
export interface WorkflowRunResult {
39+
id: number,
3940
url: string,
4041
status: WorkflowRunStatus,
4142
conclusion: WorkflowRunConclusion
@@ -87,6 +88,7 @@ export class WorkflowHandler {
8788
debug('Workflow Run status', response);
8889

8990
return {
91+
id: runId,
9092
url: response.data.html_url,
9193
status: ofStatus(response.data.status),
9294
conclusion: ofConclusion(response.data.conclusion)
@@ -110,6 +112,7 @@ export class WorkflowHandler {
110112
debug('Workflow Run artifacts', response);
111113

112114
return {
115+
id: runId,
113116
url: response.data.html_url,
114117
status: ofStatus(response.data.status),
115118
conclusion: ofConclusion(response.data.conclusion)

0 commit comments

Comments
 (0)