{"id":14551207,"url":"https://github.com/boasiHQ/interactive-inputs","last_synced_at":"2025-09-03T21:32:50.642Z","repository":{"id":251444153,"uuid":"836529252","full_name":"boasiHQ/interactive-inputs","owner":"boasiHQ","description":"Enable dynamic runtime inputs for your GitHub Actions workflows and composite actions (with support for file type inputs, slack/discord integration and more)","archived":false,"fork":false,"pushed_at":"2024-09-13T05:05:44.000Z","size":24550,"stargazers_count":6,"open_issues_count":12,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-09-14T14:53:35.197Z","etag":null,"topics":["ci","ci-cd","cicd","continuous-delivery","continuous-deployment","continuous-integration","github-actions","golang","input-output","inputs"],"latest_commit_sha":null,"homepage":"https://interactiveinputs.com","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/boasiHQ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"leonTheEighth","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2024-08-01T03:36:24.000Z","updated_at":"2024-09-14T06:53:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"8c07d711-a427-40e2-b1cc-27c33755ca85","html_url":"https://github.com/boasiHQ/interactive-inputs","commit_stats":null,"previous_names":["boasihq/interactive-inputs"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boasiHQ%2Finteractive-inputs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boasiHQ%2Finteractive-inputs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boasiHQ%2Finteractive-inputs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boasiHQ%2Finteractive-inputs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boasiHQ","download_url":"https://codeload.github.com/boasiHQ/interactive-inputs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231921665,"owners_count":18446374,"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","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":["ci","ci-cd","cicd","continuous-delivery","continuous-deployment","continuous-integration","github-actions","golang","input-output","inputs"],"created_at":"2024-09-06T14:00:34.024Z","updated_at":"2024-12-30T22:31:13.686Z","avatar_url":"https://github.com/boasiHQ.png","language":"JavaScript","readme":"# Interactive Inputs\n\nInteractive Inputs now enables GitHub Actions to support dynamic runtime user inputs for workflows and composite actions. This action allows you to leverage various [input field types](#input-fields-types), including but not limited to [text](#text-input---text), [multiple choice](#multi-select-input---multiselect), and even [uploading files](#multifile-input---multifile), creating dynamic workflows that adapt to your CI/CD needs.\n\nUse the reference **`boasihq/interactive-inputs@v2`** in your workflows to ensure you are using the latest features of this action.\n\n## Motivation and Context\n\nThe action was developed to address the issue of GitHub Actions not having a core feature found in other CI tools such as Jenkins - dynamic runtime inputs. With this action, you can now create an dynamic runtime input portal that will prompt the user for input(s) during runtime. Then, you can use that given input value in the workflow via a deterministic output id, some examples can be found in the [examples](#examples) section.\n\nSince the initial release, we have continued to add features, i.e., [**Slack**/ **Discord** integration](#sending-notifications-to-slack-discord) for portal notifications, in-runtime file uploads via the [`files`](#file-input---file)/[`multifile`](#multifile-input---multifile) field type and more. We are eager to develop an excellent GitHub Action that allows you to deliver exceptional value with your CI/CD pipelines. If you have any ideas for additional features that could enhance the value of this action, please [**create an issue**](https://github.com/boasiHQ/interactive-inputs/issues/new/choose) with an explanation of your thoughts and use case(s). This will allow us to review and discuss it and then work on implementing it as soon as possible.\n\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch2 id=\"view-action-inputs\"\u003e •• View Action Inputs •• \u003c/h2\u003e\u003c/summary\u003e\u003cbr\u003e\n\nTo see the complete list of input field types and their respective properties supported by the `interactive` input mentioned below, go to the [Input Fields Types](#input-fields-types) section of this README.\u003cbr\u003e\n\n\n\u003c!-- action-docs-inputs source=\"action.yml\" --\u003e\n## Inputs\n\n| name | description | required | default |\n| --- | --- | --- | --- |\n| `title` | \u003cp\u003eThe title of the interactive inputs form\u003c/p\u003e | `false` | `\"\"` |\n| `interactive` | \u003cp\u003eThe representation (in yaml) of fields to be displayed\u003c/p\u003e | `true` | `fields:   - label: requested-files     properties:       display: Upload desired files       type: multifile       required: true       description: Upload desired files that are to be uploaded to the runner for processing   - label: random-string     properties:       display: Enter a random string       type: text       description: A random string up to 20 characters long       maxLength: 20       required: false   - label: choice     properties:       display: Select a monitoring tool       type: select       description: Available options to chose from       choices: [\"datadog\", \"sentry\", \"grafana\"]       required: true ` |\n| `timeout` | \u003cp\u003eThe timeout in seconds for the interactive inputs form\u003c/p\u003e | `false` | `300` |\n| `ngrok-authtoken` | \u003cp\u003eThe authtoken for ngrok used to expose the interactive inputs form\u003c/p\u003e | `true` | `\"\"` |\n| `github-token` | \u003cp\u003eThe token used to authenticate with GitHub API\u003c/p\u003e | `true` | `${{ github.token }}` |\n| `notifier-slack-enabled` | \u003cp\u003eWhether to send a notification to Slack about the status of the interative inputs form\u003c/p\u003e | `true` | `false` |\n| `notifier-slack-thread-ts` | \u003cp\u003eThe timestamp of the message to reply to in the thread\u003c/p\u003e | `false` | `\"\"` |\n| `notifier-slack-token` | \u003cp\u003eThe token used to authenticate with Slack API\u003c/p\u003e | `true` | `xoxb-secret-token` |\n| `notifier-slack-channel` | \u003cp\u003eThe channel to send the notification to\u003c/p\u003e | `true` | `#notificaitons` |\n| `notifier-slack-bot` | \u003cp\u003eThe name of the bot to send the notification as\u003c/p\u003e | `false` | `\"\"` |\n| `notifier-discord-enabled` | \u003cp\u003eWhether to send a notification to Discord about the status of the interative inputs form\u003c/p\u003e | `true` | `false` |\n| `notifier-discord-thread-id` | \u003cp\u003eThe ID of the Discord thread the message should be sent to\u003c/p\u003e | `false` | `\"\"` |\n| `notifier-discord-webhook` | \u003cp\u003eThe webhook URL used to send the notification(s) to Discord\u003c/p\u003e | `true` | `secret-webhook` |\n| `notifier-discord-username` | \u003cp\u003eThe username to send the notification(s) as\u003c/p\u003e | `false` | `\"\"` |\n\u003c!-- action-docs-inputs source=\"action.yml\" --\u003e\n\u003c/details\u003e\n\n### See In Action\n\nHere are some examples of the Interactive Input action... in action 👀😔:\n\n.\u003cimg src=\"./assets/InteractiveInputs_LiveFileInputTypeSupport.gif\" alt=\"Demonstrating Multifile input field type\" width=\"400\"/\u003e\n\u003cimg src=\"./assets/InteractiveInput_MultiselectToControlFlow.gif\" alt=\"Example of using Interactive Input's multiselect to control flow\" width=\"400\"/\u003e\n\u003cimg src=\"./assets/InteractiveInput_GeneratedNumberCheckerFlow.gif\" alt=\"Example of using Interactive Input to run a comparison on user input vs generated number\" width=\"400\"/\u003e\n\u003cimg src=\"./assets/notifier-slack-message.png\" alt=\"Integration - Slack\" width=\"400\"/\u003e\n\u003cimg src=\"./assets/notifier-discord-message.png\" alt=\"Integration - Discord\" width=\"400\"/\u003e\n\n\n## Getting Started\n\nTo get started, there are three main steps:\n\n1. Sign up to NGROK and get your auth token if you do not already have one by [**clicking here**](https://dashboard.ngrok.com/signup)\n2. Add this action `boasihq/interactive-inputs@v2` to your workflow file. See below the [various example implemenations](#example) for inspiration.\n3. Use the predictable output variables from your interactive input portal to create dynamic workflows.\n\n\u003e Note, this action requires an ARM64 or AMD64 (x86) runner to run i.e. `ubuntu-latest`\n\n### Sending notifications to Slack/ Discord\n\nTo send notifications to Slack/ Discord, you will need to do the  following:\n\n1) Create your desired [Slack](#creating-a-slack-integration)/[Discord](#creating-a-discord-integration) integration token or webhook respectively.\n2) Ensure you've enabled `notifier-slack-enabled` or `notifier-discord-enabled` respectively.\n3) Pass the token or webhook to the action with `notifier-slack-token` or `notifier-discord-webhook`, respectively.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch4 id=\"creating-a-slack-integration\"\u003eCreating a Slack integration\u003c/h4\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\u003cimg src=\"./assets/notifier-slack-message.png\" alt=\"Integration - Slack\" width=\"400\"/\u003e\n\nTo create a Slack integration, follow these steps:\n1. Go to the Slack API website at https://api.slack.com/apps.\n2. Click on the \"Create New App\" button.\n3. Enter a name for your app and select the workspace where you want to create the integration.\n4. Click on the \"Create App\" button.\n5. In the app's settings, navigate to the \"OAuth \u0026 Permissions\" section.\n6. Under the \"Scopes\", add the following permissions:\n   - `chat:write`\n   - `chat:write. customise`\n7. Click on the \"Install App to Workspace\" button.\n8. Follow the instructions to install the app in your workspace.\n9. Once the installation is complete, you will receive a \"Bot User OAuth Access Token\".\n10. Copy the token and use it in your GitHub Action declaration (We recommended saving it as a secret in your GitHub repository/organisation).\n\n\u003e Note: If you want to send/create a notification to a specific thread, you will need to pass the thread timestamp to the action with the `notifier-slack-thread-ts` input.\n\u003e\n\u003e \u003cimg src=\"./assets/notifier-slack-message-to-thread.png\" alt=\"Integration - Discord\" width=\"400\"/\u003e\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch4 id=\"creating-a-discord-integration\"\u003eCreating a Discord integration\u003c/h4\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\u003cimg src=\"./assets/notifier-discord-message.png\" alt=\"Integration - Discord\" width=\"400\"/\u003e\n\nTo create a Discord integration, follow these steps:\n1. Go to the Discord app or web client at https://discord.com/channels/@me.\n2. Right-click on the server you want to create the integration, followed by \"Server Settings\" and \"Integrations\".\n3. Click on the \"Webhook\".\n4. Click on the \"New Webhook\" button.\n5. Select the new webhook and change the \"Name\" and target \"Channel\".\n6. Press the \"Copy Webhook URL\" button and use it in your GitHub Action declaration (We recommended saving it as a secret in your GitHub repository/organisation).\n\n\u003e Note: If you want to send a notification to a specific thread, you will need to pass the thread ID to the action with the `notifier-discord-thread-id input\n\u003e\n\u003e \u003cimg src=\"./assets/notifier-discord-message-to-thread.png\" alt=\"Integration - Discord\" width=\"400\"/\u003e\n\n\u003c/details\u003e\n\n\n## Examples\n\nHere are various examples demonstrating how to use this action in your workflows. Note that this is not an exhaustive list of all the possible use cases. Please share your implementations with us; we will add them to this list!\n\nIt is worth noting that these example workflows can be leveraged this action in your workflow file, but to do so, you will need to replace the `NGROK_AUTHTOKEN` secret with your own, and if you wish to send notifications to Slack/ Discord, you will need to replace the `SLACK_TOKEN` and `DISCORD_WEBHOOK` secrets with your own as well as enabling the `notifier-slack-enabled` and `notifier-discord-enabled` inputs. More information on how to do this can be found in the [Getting Started](#getting-started) section.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb id=\"example-workflow-with-all-field-types\"\u003e •• example workflow with all field types •• \u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThis example workflow demonstrates how the different [input field types](#input-fields-types) supported by this action can be used with their respective properties to build out many possibilities when creating a bespoke user experience when it comes the CI/CD flow for you/ your user's needs.\n\n\n```yaml\nname: '[Example] Interactive Inputs'\n\non:\n  push:\n\njobs:\n  interactive-inputs:\n    timeout-minutes: 3\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      actions: write\n    steps:\n      - name: Example Interactive Inputs Step\n        id: interactive-inputs\n        uses: boasihq/interactive-inputs@v2\n        with:\n          ngrok-authtoken: ${{ secrets.NGROK_AUTHTOKEN }}\n          notifier-slack-enabled: \"false\"\n          notifier-slack-channel: \"#notificaitons\"\n          notifier-slack-token: ${{ secrets.SLACK_TOKEN }}\n          notifier-slack-thread-ts: \"\"\n          notifier-discord-enabled: \"false\"\n          notifier-discord-webhook: ${{ secrets.DISCORD_WEBHOOK }}\n          notifier-discord-thread-id: \"\"\n          timeout: 160\n          title: 'A batch of 10 feature flags have been added to be deployed. Would you like to proceed?'\n          interactive: |\n            fields:\n              - label: overview\n                properties:\n                  type: textarea\n                  description: Information on what this action does\n                  defaultValue: \"This example is a powerful demonstration of how you can utilize the boasiHQ/interactive-inputs action to tailor the dynamic portal to your specific needs and desired output.\"\n                  readOnly: true\n              - label: custom-file\n                properties:\n                  display: Choose a file\n                  type: file\n                  description: Select the media you wish to send to the channel\n                  acceptedFileTypes:\n                    - image/png\n                    - video/mp4\n              - label: requested-files\n                properties:\n                  display: Upload desired files\n                  type: multifile\n                  required: true\n                  description: Upload desired files that are to be uploaded to the runner for processing\n              - label: name\n                properties:\n                  display: What is your name?\n                  type: text\n                  description: Name of the user\n                  maxLength: 20\n                  required: true\n              - label: age\n                properties:\n                  display: How old are you?\n                  type: number\n                  description: Age of the user\n                  placeholder: 18\n                  maxNumber: 110\n                  minNumber: 4\n                  required: false\n              - label: car\n                properties:\n                  display: Favourite Car\n                  type: select\n                  description: The name of your favourite car\n                  disableAutoCopySelection: false\n                  choices:\n                    - Ford\n                    - Toyota\n                    - Honda\n                    - Volvo\n                    - BMW\n                    - Mercedes\n                    - Audi\n                    - Lexus\n                    - Tesla\n                    - Other\n                  required: true\n              - label: colour\n                properties:\n                  display: What are your favourite colours\n                  type: multiselect\n                  disableAutoCopySelection: true\n                  choices: \n                    [\"Red\", \"Green\", \"Blue\", \"Orange\", \"Purple\", \"Pink\", \"Yellow\"]\n                  required: true\n              - label: verify\n                properties:\n                  display: Are you sure you want to continue?\n                  defaultValue: 'false'\n                  type: boolean\n                  required: true'\n              - label: additional-info\n                properties:\n                  type: textarea\n                  display: More information\n                  description: Any more information you would like to add\n\n      - name: Display Outputs\n        shell: bash\n        run: |\n          echo \"Display Outputs\"\n          echo -e \"\\n==============================\\n\"\n          echo \"Detected Outputs: ${{join(steps.interactive-inputs.outputs.*, '\\n')}}\"\n          echo -e \"\\n==============================\\n\"\n\n      - name: List the uploaded files in the directory\n        shell: bash\n        run: |\n          echo \"Display uploaded files\"\n          echo -e \"\\n==============================\\n\"\n          ls -la ${{ steps.interactive-inputs.outputs.requested-files }} # Use the label of the multifile/file field as the key to get the uploaded file directory\n          echo -e \"\\n==============================\\n\"\n\n```  \n\n\u003c/details\u003e  \n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb id=\"example-workflow-multiselect-to-control-flow\"\u003e •• multiselect to control flow •• \u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThis is the workflow file for the [\"multiselect to control flow\"](./assets/InteractiveInput_MultiselectToControlFlow.gif) gif [referenced above](#see-in-action). \u003cbr\u003e\n\n```yaml\nname: '[Example] Multiselect to invoke other flows'\n\non:\n workflow_dispatch:\n\njobs:\n\n  interactive-inputs:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      actions: write\n    steps:\n      - name: Example Interactive Inputs Step\n        id: interactive-inputs\n        uses: boasiHQ/interactive-inputs@v2\n        with:\n          timeout: 300\n          title: 'We need you to select your desired flow(s) to execute'\n          interactive: |\n            fields:\n              - label: runtime-options\n                properties:\n                  description: Below are the available flows that can be executed\n                  display: Select the flow(s) to execute\n                  type: multiselect\n                  choices: \n                    [\"option-a\", \"option-b\", \"option-c\"]\n                  required: true\n              - label: notes\n                properties:\n                  display: Optional - Additional note(s)\n                  type: textarea\n                  description: Additional notes on why this selection was made.\n          notifier-slack-enabled: \"false\"\n          notifier-slack-channel: \"#random\"\n          notifier-slack-token: ${{ secrets.SLACK_TOKEN }}\n          notifier-discord-enabled: \"false\"\n          notifier-discord-webhook: ${{ secrets.DISCORD_WEBHOOK }}\n          github-token: ${{ github.token }}\n          ngrok-authtoken: ${{ secrets.NGROK_AUTHTOKEN }}\n    outputs:\n        runtime-options: ${{ steps.interactive-inputs.outputs.runtime-options }}\n\n  option-a:\n    runs-on: ubuntu-latest\n    needs: [\"interactive-inputs\"]\n    if: ${{ contains( needs.interactive-inputs.outputs.runtime-options, 'option-a' ) }}\n    steps:\n      - name: Run option-a\n        shell: bash\n        run: |\n          echo \"Running flow option-a \"\n          echo -e \"\\n==============================\\n\"\n          echo \"Detected Selection: ${{join(needs.interactive-inputs.outputs.runtime-options, '\\n')}}\"\n          echo -e \"\\n==============================\\n\"\n\n  option-b:\n    runs-on: ubuntu-latest\n    needs: [\"interactive-inputs\"]\n    if: ${{ contains( needs.interactive-inputs.outputs.runtime-options, 'option-b' ) }}\n    steps:\n      - name: Run option-b\n        shell: bash\n        run: |\n            echo \"Running flow option-b \"\n            echo -e \"\\n==============================\\n\"\n            echo \"Detected Selection: ${{join(needs.interactive-inputs.outputs.runtime-options, '\\n')}}\"\n            echo -e \"\\n==============================\\n\"\n\n  option-c:\n      runs-on: ubuntu-latest\n      needs: [\"interactive-inputs\"]\n      if: ${{ contains( needs.interactive-inputs.outputs.runtime-options, 'option-c' ) }}\n      steps:\n        - name: Run option-c\n          shell: bash\n          run: |\n              echo \"Running flow option-c \"\n              echo -e \"\\n==============================\\n\"\n              echo \"Detected Selection: ${{join(needs.interactive-inputs.outputs.runtime-options, '\\n')}}\"\n              echo -e \"\\n==============================\\n\"\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb id=\"example-workflow-generated-number-checker-flow\"\u003e •• generated number checker flow •• \u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThis is the workflow file for the [\"generated number checker flow\"](./assets/InteractiveInput_GeneratedNumberCheckerFlow.gif) gif [referenced above](#see-in-action). \u003cbr\u003e\n\n```yaml\nname: '[Example] Match generated number flow'\n\non:\n  workflow_dispatch:\n\njobs:\n\n  interactive-inputs:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      actions: write\n    steps:\n      - name: Generate random number\n        id: get-random-number\n        uses: actions/github-script@v7\n        with:\n          result-encoding: string\n          # Script for generating random number sourced from: https://stackoverflow.com/a/7228322\n          script: |\n            function randomIntFromInterval(min, max) { // min and max included \n              return Math.floor(Math.random() * (max - min + 1) + min);\n            }\n\n            return randomIntFromInterval(1, 5);\n\n      - name: Example Interactive Inputs Step\n        id: interactive-inputs\n        uses: boasiHQ/interactive-inputs@v2\n        with:\n          timeout: 300\n          title: 'We need you to select your desired flow(s) to execute'\n          interactive: |\n            fields:\n              - label: display-number\n                properties:\n                  description: This is a generated number\n                  display: Generated Number\n                  type: textarea\n                  defaultValue: ${{ steps.get-random-number.outputs.result }}\n                  readOnly: true\n              - label: selected-number\n                properties:\n                  description: Match the generated number specified in the text field above\n                  display: Enter the number you see above\n                  type: number\n                  required: true\n          notifier-slack-enabled: \"false\"\n          notifier-slack-channel: \"#random\"\n          notifier-slack-token: ${{ secrets.SLACK_TOKEN }}\n          notifier-discord-enabled: \"false\"\n          notifier-discord-webhook: ${{ secrets.DISCORD_WEBHOOK }}\n          github-token: ${{ github.token }}\n          ngrok-authtoken: ${{ secrets.NGROK_AUTHTOKEN }}\n\n      - name: Check if number matches\n        id: check-number\n        shell: bash\n        run: |\n          if [[ ${{ steps.interactive-inputs.outputs.selected-number }} -eq ${{ steps.get-random-number.outputs.result }} ]]; then\n            echo \"The number matches!\"\n          else\n            echo \"The number does not match.\"\n          fi\n\n```\n\u003c/details\u003e\n\n\n\n### Key points\n\nWhen using this action, here are a few key points to note:\n\n- The [`multifile` input field type](#multifile-input---multifile) and the [`file` input field type](#file-input---file) will provide the path to where the uploaded files are located on the runner. You can then use this information in later stages of your workflow.\n- To enable the external notifications, you will need to set the `notifier-slack-enabled` or `notifier-discord-enabled` property to `true` in the `with` object. Follow the [**Creating a Slack integration**](#creating-a-slack-integration) or [**Creating a Discord integration**](#creating-a-discord-integration) sections above for more information.\n  - To send a message to a thread, you will need to set the `notifier-slack-thread-ts` or `notifier-discord-thread-id` property to the thread timestamp or thread ID, respectively.\n- The portal will display fields in the order defined in the `fields` array.\n- The `label` property is used to identify the input field and its corresponding output. For example, the `label` property in the `fields` array for **Continue to roll out?** is `continue-roll-out`. This means that the output will be stored in a variable called `continue-roll-out`, which can be accessed using the syntax `${{ steps.interactive-inputs.outputs.continue-roll-out }}`.\n- The env `ngrok-authtoken` input is used to open the Ngrok tunnel, which is used to give access to your runner-hosted portal. It is needed to be set in the workflow file.\n  - Signing up for NGROK is free and quick; it can be done [here](https://dashboard.ngrok.com/signup).\n- There are various [types of input fields](#input-fields-types) that can be used, [**vist the input fields types**](#input-fields-types) in this README for more information.\n- The `timeout` property sets the timeout for the interactive input. The workflow will fail if the user does not respond within the timeout period.\n\n\n## Input Fields Types\n\nThe input fields shape the user interface of the interactive input. The input fields are defined in the `fields` property of the `interactive` attribute of the `with` object.\n\n```yaml\n      ...\n      - name: Example Interactive Inputs Step\n        id: interactive-inputs\n        uses: boasihq/interactive-inputs@v2\n        with:\n          ...\n          interactive: |\n            fields:\n              - label: continue-roll-out\n                properties:\n                  display: Continue to roll out?\n                  ...\n```\n\nThe `fields` property is an array of objects, each object representing a field. Each field type has its properties, some unique to the particular field type. See below the supported field types and their respective properties.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"multifile-input---multifile\"\u003eMultifile Input - \u003ccode\u003emultifile\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\nThe `multifile` input field is used to allow the user to upload multiple files. It is the most commonly used to allow the \nuser to upload a collection of files that can be used in the workflow.\n\n\u003e Note: unlike the other input fields, the `multifile` input field's output points to a direcry (the file cache), not the direct value/input provided by the user.\n\u003e\n\u003e The `acceptedFileTypes` property can be represented as a hyphenated list of strings or also an array of strings, i.e. `[\"image/*\", \"video/*\"]`. [Click here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers) for more information on file type specifiers.\n\n#### Example\n\n```yaml\nfields:\n  - label: requested-files # Required\n    properties:\n      display: Upload desired files # Optional: if not specified, the title for the field will not be displayed on the portal\n      type: file # Required\n      required: true # Optional: If not added, will default to `false`\n      description: Upload desired files that are to be uploaded to the runner for processing # Optional: If not added, \"i\" won't be on the portal for the field\n      acceptedFileTypes: # Optional: A list of file type specifiers that the user will be able to upload (more information on file type specifiers: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers). If not added or left empty, the user will be able to upload any file.\n        - image/png # example accepted file types\n        - video/mp4 # example accepted file types\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"file-input---file\"\u003eFile Input - \u003ccode\u003efile\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\nThe `file` input field is used to capture a file input from the user. It is the most commonly used to allow the \nuser to upload a file that can be used in the workflow.\n\n\u003e Note: Unlike the other input fields, the `file` input field's output points to a direcry (the file cache), not the direct value/input provided by the user.\n\u003e\n\u003e The `acceptedFileTypes` property can be represented as a hyphenated list of strings or also an array of strings, i.e. `[\"image/*\", \"video/*\"]`. [Click here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers) for more information on file type specifiers.\n\n#### Example\n\n```yaml\nfields:\n  - label: requested-file # Required\n    properties:\n      display: Upload desired file # Optional: if not specified, the title for the field will not be displayed on the portal\n      type: file # Required\n      required: true # Optional: If not added, will default to `false`\n      description: Upload desired files that are to be uploaded to the runner for processing # Optional: If not added, \"i\" won't be on the portal for the field\n      acceptedFileTypes: [] # Optional: A list of file type specifiers that the user will be able to upload (more information: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers). If not added or left empty, the user will be able to upload any file.\n\n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"text-input---text\"\u003eText Input - \u003ccode\u003etext\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\n\nThe text input field is used to capture text input from the user. It is the most commonly used input field type.\n\n#### Example\n\n```yaml\nfields:\n - label: name # Required\n    properties:\n      display: Name # Optional: if not specified, the title for the field will not be displayed on the portal\n      type: text # Required\n      description: The name of the user # Optional: If not added, \"i\" won't be on the portal for the field\n      required: true # Optional: If not added, will default to `false`\n      maxLength: 20 # Optional: If not added, the user will not have a limit\n      placeholder: Enter your name # Optional: If not added, the placeholder won't be displayed on the portal\n      defaultValue: John Doe # Optional: If not added, the default value won't be displayed on the portal\n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"textarea-input---textarea\"\u003eTextarea Input - \u003ccode\u003etextarea\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe textarea input field is used to capture or display ( set `readOnly` to `true`) multi-line text input from the user. It is commonly used to capture long text input from the user.\n\n\u003e Note, when set to `readOnly` true, the data will still be stored in the output variable, but the user cannot change the value.\n\n#### Example\n\n```yaml\nfields:\n - label: notes # Required\n    properties:\n      display: Additional note(s)  # Optional\n      type: textarea # Required\n      description: Additional notes on this decision  # Optional\n      required: false  # Optional\n      maxLength: 200  # Optional\n      placeholder: Enter your notes  # Optional\n      defaultValue: This is a note  # Optional\n      readOnly: false # Optional: If not added, will default to `false`. If set to `true` the field will be read-only, and the user will not be able to change the value, which can be useful for displaying information to the user. \n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"number-input---number\"\u003eNumber Input - \u003ccode\u003enumber\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\nThe number input field is used to capture numerical input from the user.\n\n#### Example\n\n```yaml\nfields:\n - label: cache-wipe-days # Required\n    properties:\n      display: Wipe cache data by (days)  # Optional\n      type: number # Required\n      description: The number of days to wipe cache the data for  # Optional\n      required: true  # Optional\n      minNumber: 0  # Optional: This is the minimum number that the user can enter\n      maxNumber: 17  # Optional: This is the maximum number that the user can enter\n      placeholder: Enter the number of days to wipe cache data # Optional\n      defaultValue: 14  # Optional: This is the value that will be displayed on the portal and used for the output if the user enters no value\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"boolean-input---boolean\"\u003eBoolean Input - \u003ccode\u003eboolean\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\nThe boolean input field captures a boolean input from the user (`True` or `False`). It is commonly used to determine where the expected output should be `True` or `False` from the user.\n\n#### Example\n\n```yaml\nfields:\n - label: use-interactive-inputs # Required\n    properties:\n      display: Should you use Interactive Inputs? # Optional\n      type: boolean # Required\n      description: Whether you should use Interactive Inputs in your workflows # Optional\n      defaultValue: true # Optional: If not added, neither True nor False will be selected on the portal\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"select-input---select\"\u003eSelect Input - \u003ccode\u003eselect\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\n\nThe select input field captures a single selection from a list of options from the user. It is commonly used to capture when you wish to scope the user's choice for a particular set of options.\n\n\u003e Note, the `choices` property can be represented as a hyphenated list of strings (shown in the example below) or also an array of strings, i.e. `[\"US\", \"UK\", \"DE\", \"FR\", \"JP\"]`.\n\n#### Example\n\n```yaml\nfields:\n - label: country-rate-limit # Required\n    properties:\n      display: Which country should have a limited request rate? # Optional\n      type: select # Required\n      description: The country that should have requests for unregistered users rate limited # Optional\n      required: false # Optional\n      disableAutoCopySelection: false # Optional: If set to `true`, the user's selected choice will not be automatically copied to the clipboard.\n      choices: # Required: This is the list of options the user can select. It can be generated by a previous step or a static list of options.\n        - US\n        - UK\n        - DE\n        - FR\n        - JP\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3 id=\"multi-select-input---multiselect\"\u003eMulti-Select Input - \u003ccode\u003emultiselect\u003c/code\u003e\u003c/h3\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe multi-select input field captures multiple selections from a list of user options. It is commonly used to capture when you wish to scope the user's selection for a particular set of options.\n\n\u003e Note, the `choices` property can be represented as a hyphenated list of strings (shown in the example below) or also an array of strings, i.e. `[\"US\", \"UK\", \"DE\", \"FR\", \"JP\"]`.\n\n#### Example\n\n```yaml\nfields:\n - label: countries-to-rate-limit # Required\n    properties:\n      display: Which countries should have a limited request rate? # Optional\n      type: multiselect # Required\n      description: The countries that should have requests for unregistered users rate limited # Optional\n      required: false # Optional\n      disableAutoCopySelection: false # Optional: If set to `true`, the user's selected choice will not be automatically copied to the clipboard.\n      choices: # Required: This is the list of options the user can select. It can be generated by a previous step or a static list of options.\n        - US\n        - UK\n        - DE\n        - FR\n        - JP\n```\n\u003c/details\u003e\n\n\n## 💻 Contributing, 🐛 Reporting Bugs \u0026 💫 Feature Requests\n\nWe are currently developing a process to facilitate contributions. Please be patient with us! In the meantime, please create an issue if you would like to request additional features, report any unexpected behaviour, or provide any other feedback.\n\nSoon, we will use issues to gather feedback on bugs, feature requests, and more. When testing new features or bug fixes, we will create pull requests (PRs) and keep them focused on a single feature or bug fix, allowing you to test them.\n\nWhen expressing interest in a bug, enhancement, PR, or issue, please use the thumbs-up or thumbs-down emoji on the original message rather than adding duplicate comments.\n\n### Developing Locally\n\nIf you want to contribute, fix a bug, or play around with this action locally, please follow the instructions outlined in the [**getting started** file](./gettting-started.md).\n\n\n## Licence\n\nMIT License - see [LICENSE.md](LICENSE.md) for details\n","funding_links":["https://ko-fi.com/leonTheEighth"],"categories":["Recently Updated","Community Resources"],"sub_categories":["[Sep 02, 2024](/content/2024/09/02/README.md)","Utility"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FboasiHQ%2Finteractive-inputs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FboasiHQ%2Finteractive-inputs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FboasiHQ%2Finteractive-inputs/lists"}