Convert issue form responses to JSON
This action is designed to be used in conjunction with issue forms to allow you to parse created issues into machine-readable JSON for processing.
Issues submitted using issue forms use a structured Markdown format. So long as the issue body is not heavily modified by the user, we can reliably parse the issue body into a JSON object.
You can use this action to conditionally run steps in a workflow based on the contents of the issue body. For example, you may want to run a step only if the issue body contains a specific keyword, version number, etc.
Here is a simple example of how to use this action in your workflow. Make sure
to replace vX.X.X
with the latest version of this action.
steps:
- name: Parse Issue
id: parser
uses: issue-ops/parser@vX.X.X
with:
body: ${{ github.event.issue.body }}
- name: Output Issue JSON
id: output-issue
run: echo ${{ steps.parser.outputs.json }}
Input | Description |
---|---|
body |
The issue body to parse |
Default: ${{ github.event.issue.body }} |
|
issue-form-template |
The issue form template file |
e.g. example.yml |
|
workspace |
The checkout path on the runner |
Default: ${{ github.workspace }} |
Output | Description |
---|---|
json |
The parsed issue as a JSON string |
Given an example issue template and the following issue submitted with that template:
### The Name of the Thing
this-thing
### The Nickname of the Thing
thing
### The Color of the Thing
blue
### The Shape of the Thing
square
### The Sounds of the Thing
re, mi
### The Topics About the Thing
_No response_
### The Description of the Thing
This is a description.
It has lines.
### The Notes About the Thing
- Note
- Another note
- Lots of notes
### The Code of the Thing
const thing = new Thing()
thing.doThing()
### The String Method of the Code of the Thing
thing.toString()
### Is the Thing a Thing?
- [x] Yes
- [x] No
### Is the Thing Useful?
- [ ] Yes
- [x] Sometimes
- [ ] No
### Read Team
IssueOps-Demo-Readers
### Write Team
IssueOps-Demo-Writers-NotATeam
The output of this action would be:
{
"name": "this-thing",
"nickname": "thing",
"color": ["blue"],
"shape": ["square"],
"sounds": ["re", "mi"],
"topics": [],
"description": "This is a description.\n\nIt has multiple lines.\n\nIt's pretty cool!",
"notes": "- Note\n- Another note\n- Lots of notes",
"code": "const thing = new Thing()\nthing.doThing()",
"code-string": "thing.toString()",
"is-thing": {
"selected": ["Yes"],
"unselected": ["No"]
},
"is-thing-useful": {
"selected": ["Sometimes"],
"unselected": ["Yes", "No"]
},
"read-team": "IssueOps-Demo-Readers",
"write-team": "IssueOps-Demo-Writers"
}
The issue-form-template
input is optional. If not provided, the action will
still parse the issue body, however the output will be a flat JSON object. The
object keys will be slugified versions of the headers, and the values will be
the contents of the headers.
Using the same example as above, the output would instead be:
{
"the_name_of_the_thing": "this-thing",
"the_nickname_of_the_thing": "thing",
"the_color_of_the_thing": "blue",
"the_shape_of_the_thing": "square",
"the_sounds_of_the_thing": "re, mi",
"the_topics_about_the_thing": "_No response_",
"the_description_of_the_thing": "This is a description.\n\nIt has multiple lines.\n\nIt's pretty cool!",
"the_notes_about_the_thing": "- Note\n- Another note\n- Lots of notes",
"the_code_of_the_thing": "const thing = new Thing()\nthing.doThing()",
"the_string_method_of_the_code_of_the_thing": "thing.toString()",
"is_the_thing_a_thing": "- [x] Yes\n- [ ] No",
"is_the_thing_useful": "- [ ] Yes\n- [x] Sometimes\n- [ ] No",
"read_team": "IssueOps-Demo-Readers",
"write_team": "IssueOps-Demo-Writers"
}
The following transformations will take place for each heading:
Transformation | Before | After |
---|---|---|
Trim | ### This is a title! :) |
This is a title! :) |
Lowercase | This is a title! :) |
this is a title! :) |
Replace Spaces | this is a title! :) |
this_is__a_title!_:) |
Remove Symbols | this_is_a_title!_:) |
this_is__a_title_ |
Trim Underscores | this_is__a_title_ |
this_is_a_title |
The following transformations will take place for responses, depending on the input type. The type is inferred from the issue form template. For information on each specific type, see Syntax for GitHub's form schema.
Before:
This is a response
After (no change):
This is a response
Note
Empty lines are preserved in multiline responses.
Before:
First line :D
Third line!
After:
First line :D\n\nThird line!
Before:
red, blue, green
After:
["red", "blue", "green"]
Before:
- [x] Pick me!
- [ ] Don't pick me D:
After:
{
"selected": ["Pick me!"],
"unselected": ["Don't pick me D:"]
}
In the following situations, an input will be omitted from the output JSON:
Scenario | Example |
---|---|
Invalid Heading | ## This is invalid |
Empty Heading | ### |
This is a value |
|
No Value | ### This is a heading |
<empty> |
|
### This is another |
|
This is a value |
If a form is submitted with empty field(s), they will be included in the issue body as one of the following:
### Field A
_No response_
### Field B
None
### Field C
<empty>
These will be converted to one of the following, based on the type of input specified in the issue form template:
Type | Output |
---|---|
input |
Empty string ("" ) |
textarea |
Empty string ("" ) |
dropdown |
Empty list ([] ) |
checkboxes |
Empty checkboxes ({ "selected": [], "unselected": []} ) |