{"id":18282938,"url":"https://github.com/zentered/issue-forms-body-parser","last_synced_at":"2025-07-23T01:32:50.398Z","repository":{"id":39888969,"uuid":"471388685","full_name":"zentered/issue-forms-body-parser","owner":"zentered","description":"GitHub Issue Forms Body Parser Action","archived":false,"fork":false,"pushed_at":"2025-05-15T16:32:30.000Z","size":4344,"stargazers_count":22,"open_issues_count":2,"forks_count":7,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-30T15:06:33.341Z","etag":null,"topics":["github-issue-forms","issue-forms","parser"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zentered.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-18T13:56:58.000Z","updated_at":"2025-05-30T15:50:30.000Z","dependencies_parsed_at":"2023-10-02T16:26:38.447Z","dependency_job_id":"f8c484c2-4145-4fc3-b1d8-96bc31b9289d","html_url":"https://github.com/zentered/issue-forms-body-parser","commit_stats":{"total_commits":73,"total_committers":7,"mean_commits":"10.428571428571429","dds":"0.31506849315068497","last_synced_commit":"d3b0f8142b4259ccb1136574518dd18b2af12571"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/zentered/issue-forms-body-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zentered%2Fissue-forms-body-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zentered%2Fissue-forms-body-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zentered%2Fissue-forms-body-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zentered%2Fissue-forms-body-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zentered","download_url":"https://codeload.github.com/zentered/issue-forms-body-parser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zentered%2Fissue-forms-body-parser/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266602790,"owners_count":23954694,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-issue-forms","issue-forms","parser"],"created_at":"2024-11-05T13:06:46.142Z","updated_at":"2025-07-23T01:32:50.375Z","avatar_url":"https://github.com/zentered.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitHub Issue Forms Body Parser\n\n![Test](https://github.com/zentered/issue-forms-body-parser/workflows/Test/badge.svg)\n![Release](https://github.com/zentered/issue-forms-body-parser/workflows/Publish/badge.svg)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n[![zentered.co](https://img.shields.io/badge/%3E-zentered.co-blue.svg?style=flat)](https://zentered.co)\n\n[Issue Forms](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#creating-issue-forms)\nis a great way to structure GitHub Issues to an expected format, and to make it\neasier to capture information from the user. Unfortunately, the schema only\ndefined the input of the data, not the output. So the markdown body needs to be\nparsed to extract the information in a structured way and to make further\nprocessing easier.\n\nWe use this Action at the\n[Cyprus Developer Community](https://github.com/cyprus-developer-community) to\n[create issues with event data](https://github.com/cyprus-developer-community/events/issues/new?assignees=\u0026labels=Event+%3Asparkles%3A\u0026template=event.yml\u0026title=Event+Title)\nfor upcoming meetups etc. The parser extracts the information from the issues\nand provides structured data to create calendar entries (ie `.ics` files for\n[calendar subscriptions with GitEvents](https://github.com/gitevents/ics)),\ncalling 3rd party APIs, etc.\n\n_Inspired by:\n[Peter Murray's Issue Forms Body Parser](https://github.com/peter-murray/issue-forms-body-parser)\nwith valuable feedback from [Steffen](https://gist.github.com/steffen)_\n\n## Features\n\n- :white_check_mark: npm version available\n  `npm i @zentered/issue-forms-body-parser`\n- :white_check_mark: parse question/answer format into title/text as JSON\n- :white_check_mark: parse line items and \"tasks\" with separate `checked`\n  attributes\n- :white_check_mark: slugify title to id to find data\n- :white_check_mark: parse dates and times into separate `date` and `time`\n  fields\n- :negative_squared_cross_mark: no tokens/input required\n- :negative_squared_cross_mark: zero configuration\n\nTransforms markdown from GitHub Issue Forms:\n\n```markdown\n### Event Description\n\nLet's meet for coffee and chat about tech, coding, Cyprus and the newly formed\nCDC (Cyprus Developer Community).\n\n### Location\n\nCafe Nero Finikoudes, Larnaka\n\n### Date\n\n11.03.2022\n\n### Time\n\n16:00\n```\n\nto structured, usable data:\n\n```json\n{\n  \"event-description\": {\n    \"order\": 0,\n    \"title\": \"Event Description\",\n    \"text\": \"Let's meet for coffee and chat about tech, coding, Cyprus and the newly formed\\nCDC (Cyprus Developer Community).\"\n  },\n  \"location\": {\n    \"order\": 1,\n    \"title\": \"Location\",\n    \"text\": \"Cafe Nero Finikoudes, Larnaka\"\n  },\n  \"date\": {\n    \"order\": 2,\n    \"title\": \"Date\",\n    \"text\": \"11.03.2022\",\n    \"date\": \"2022-03-11\"\n  },\n  \"time\": {\n    \"order\": 3,\n    \"title\": \"Time\",\n    \"text\": \"16:00\",\n    \"time\": \"16:00\"\n  }\n}\n```\n\nSee more examples in [md test cases](./test/test-issue-1.md) and\n[test results](./test/parse-issue-test.md]).\n\n### Parsers\n\n- `date`: checks if the value matches a\n  [common date format](https://github.com/zentered/issue-forms-body-parser/blob/main/src/parsers/date.js#L7)\n  and returns a formatted `date` field (in UTC).\n- `time`: checks if the value matches a\n  [common time format](https://github.com/zentered/issue-forms-body-parser/blob/main/src/parsers/time.js#L7)\n  and returns a formatted `time` field.\n- `lists`: automatically returns lists as arrays\n- `duration`: currently only the format `XXhYYm` is supported as duration, ie.\n  `1h30m` returns a `duration` object with `hours` and `minutes`.\n\n## Installation \u0026 Usage\n\n### GitHub Actions\n\n```yml\nname: Issue Forms Body Parser\n\non: issues\n\njobs:\n  process:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Issue Forms Body Parser\n        id: parse\n        uses: zentered/issue-forms-body-parser@v2.0.0\n      - run: echo ${{ toJSON(steps.parse.outputs.data) }}\n```\n\nYou can also provide a custom `body` input:\n\n```yml\nname: Issue Forms Body Parser\n\non:\n  workflow_dispatch:\n    inputs:\n      issue_number:\n        type: string\n        required: true\nenv:\n  GH_TOKEN: ${{ github.token }}\n\njobs:\n  process:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Fetch the issue\n        id: read_issue_body\n        run:\n          echo \"body=$(gh issue view ${{ inputs.issue_number }} --repo ${{\n          github.repo }} --json body --jq '.body')\" \u003e\u003e $GITHUB_OUTPUT\n\n      - name: Issue Forms Body Parser\n        id: parse\n        uses: zentered/issue-forms-body-parser@v2.0.0\n        with:\n          body: ${{ steps.read_issue_body.output.body }}\n\n      - run: echo ${{ toJSON(steps.parse.outputs.data) }}\n```\n\n### NPM\n\nThe parser is available as a standalone library:\n\n```\n    npm i @zentered/issue-forms-body-parser\n    # OR yarn add @zentered/issue-forms-body-parser\n```\n\nUsage:\n\n```\nimport bodyParser from '@zentered/issue-forms-body-parser'\nconst issueData = await bodyParser(issue.body)\n```\n\n## Development \u0026 Testing\n\nYou can use [act](https://github.com/nektos/act) to test this Action locally.\n\n`npm run build \u0026\u0026 act issues -e test/issue.json`\n\nor run:\n\n`npm test`\n\nto test the parser.\n\n## Links\n\n- [Creating issue forms](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#creating-issue-forms)\n- [Syntax for GitHub's form schema](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema)\n\n## License\n\nLicensed under [MIT](./LICENSE).\n\nHere is a list of all the licenses of our\n[production dependencies](./dist/licenses.txt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzentered%2Fissue-forms-body-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzentered%2Fissue-forms-body-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzentered%2Fissue-forms-body-parser/lists"}