- 
                Notifications
    You must be signed in to change notification settings 
- Fork 388
Adding reusable and composite action katas #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple of problems in the action and the workflows in the lab that causes the workflow to fail. They should be fixed.
For readability and to reduce the risk of copy paste errors, I'd also like the print_summary_text script extracted into a separate file.
Other than that, it could be nice if the exercices follow the same template as the other exercises. Given the time until the first run, that is not a blocker, though.
| sys.exit(4) | ||
|  | ||
| out = summarize(numbers) | ||
| print(json.dumps(out, indent=2)) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
json.dumps(out, indent=2) produces multiline output, which causes the command in the Set output step of summary-action to fail.
Removing the indent parameter will print the json output on a single line, simplifying the handling of it in the custom action.
| print(json.dumps(out, indent=2)) | |
| print(json.dumps(out)) | 
| summary: | ||
| description: 'JSON summary produced by the helper' | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outputs in custom actions must have their values set explicitly. Without a values field, the value will be empty.
| summary: | |
| description: 'JSON summary produced by the helper' | |
| summary: | |
| description: 'JSON summary produced by the helper' | |
| value: ${{ steps.set-output.outputs.summary }} | 
| - name: Set output | ||
| shell: bash | ||
| run: echo "summary=$(cat summary.json)" >> $GITHUB_OUTPUT | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to set an id for the step, so that its outputs can be referenced from the action output definition.
| - name: Set output | |
| shell: bash | |
| run: echo "summary=$(cat summary.json)" >> $GITHUB_OUTPUT | |
| - name: Set output | |
| id: set-output | |
| shell: bash | |
| run: echo "summary=$(cat summary.json)" >> $GITHUB_OUTPUT | 
| ## Create the reusable workflow | ||
|  | ||
| 1. Create `.github/workflows/reusable-2.yml`. | ||
| 2. Use the `workflow_call` trigger and add an input `numbers` of type `string` (JSON array encoded as a string). The input should have a default of `[1,2,3]`. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 2. Use the `workflow_call` trigger and add an input `numbers` of type `string` (JSON array encoded as a string). The input should have a default of `[1,2,3]`. | |
| 2. Use the `workflow_call` trigger and add an input `numbers` of type `string` (JSON array encoded as a string). The input should have a default of `'[1,2,3]'`. | 
| python3 - <<'PY' > summary_text.txt | ||
| import json | ||
| try: | ||
| s = json.load(open('summary.json')) | ||
| except Exception: | ||
| print('Invalid summary JSON') | ||
| raise | ||
| if not isinstance(s, dict) or s.get('count', 0) == 0: | ||
| print('No numbers provided') | ||
| else: | ||
| print(f"count={s['count']}, sum={s['sum']}, avg={s['avg']:.2f}, min={s['min']}, max={s['max']}") | ||
| PY | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a bit obscure and difficult to read. Also, the syntax coloring is messed up by the heredoc python blob. I'd like to have the script extracted into a separate python file and called directly from the ci folder.
| id: format | ||
| shell: bash | ||
| run: | | ||
| printf '%s' "${{ steps.call-summary.outputs.summary }}" > summary.json || true | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The printf fails because the summary has quotes in it. When steps.call-summary.outputs.summary is expanded, that leads to nested quotes. Replace the double quotes in this line with single quotes.
| printf '%s' "${{ steps.call-summary.outputs.summary }}" > summary.json || true | |
| printf '%s' '${{ steps.call-summary.outputs.summary }}' > summary.json || true | 
| steps: | ||
| - name: Print reusable workflow outputs | ||
| run: | | ||
| echo "Reusable summary (JSON): ${{ needs.call-reusable.outputs.summary }}" | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason,needs.call-reusable.outputs.summary comes out empty.
This pull request introduces a hands-on lab for creating and using composite actions and reusable workflows in GitHub Actions. The main additions are a Python helper script for summarizing a list of numbers, step-by-step markdown guides for building a composite action around this script, and instructions for composing it into reusable workflows and consumer jobs. These changes provide practical examples for learning how to pass inputs/outputs between actions and workflows.
Composite Action and Python Helper:
ci/print_summary.py, a Python script that reads a JSON array of numbers and prints a summary (count, sum, average, min, max); includes error handling for input validation.labs/composite-action.md, a lab guide explaining how to create a composite action that pipes numbers to the Python helper, exposes outputs, and is called from a workflow.Reusable Workflow and Consumer Example:
labs/reusable-2.md, a lab guide for building a reusable workflow that calls the composite action, formats the summary output, and exposes both JSON and human-readable outputs. Includes example consumer workflow and tips for testing.