Git Product home page Git Product logo

http-request-action's Introduction

HTTP Request Action

Create HTTP Requests from GitHub Actions. This action allows GitHub events to engage with tools like Ansible AWX that use HTTP APIs.

Example

jobs:
  deployment:
    runs-on: ubuntu-latest
    steps:
    - name: Deploy Stage
      uses: fjogeleit/http-request-action@v1
      with:
        url: 'https://ansible.io/api/v2/job_templates/84/launch/'
        method: 'POST'
        username: ${{ secrets.AWX_USER }}
        password: ${{ secrets.AWX_PASSWORD }}
        customHeaders: '{"Content-Type": "application/json"}'
        data: '{"key_1": "value_1", "key_2": "value_2"}'

Versioning

master branch is deprecated. Please use main or v1 to get the latest version of this action. It is recommended to use a fixed version.

Request Configuration

Argument Description Default
url Request URL required Field
method Request Method POST
contentType Request ContentType application/json
data Request Body Content:
- text content like JSON or XML
- key=value pairs separated by '&' or JSON data and contentType: application/x-www-form-urlencoded

only for POST / PUT / PATCH Requests
'{}'
files Map of key / absolute file paths send as multipart/form-data request to the API, if set the contentType is set to multipart/form-data, values provided by data will be added as additional FormData values, nested objects are not supported. Example provided in the test Workflow of this Action '{}'
file Single absolute file path send as application/octet-stream request to the API, if set the contentType is set to application/octet-stream. This input will be ignored if either data or files input is present. Example provided in the test Workflow of this Action
timeout Request Timeout in ms 5000 (5s)
username Username for Basic Auth
password Password for Basic Auth
bearerToken Bearer Authentication Token (without Bearer Prefix)
customHeaders Additional header values as JSON string, keys in this object overwrite default headers like Content-Type '{}'
escapeData Escape newlines in data string content. Use 'true' (string) as value to enable it
preventFailureOnNoResponse Prevent this Action to fail if the request respond without an response. Use 'true' (string) as value to enable it
ignoreStatusCodes Prevent this Action to fail if the request respond with one of the configured Status Codes. Example: '404,401'
httpsCA Certificate authority as string in PEM format
httpsCert Client Certificate as string
httpsKey Client Certificate Key as string
responseFile Persist the response data to the specified file path
maskResponse If set to true, the response will be masked in the logs of the action 'false'
retry optional amount of retries if the request is failing, does not retry if the status code is ignored
retryWait time between each retry in millseconds 3000
ignoreSsl ignore ssl verify (rejectUnauthorized: false) false

Response

Variable Description
response Response as JSON String
headers Headers

To display HTTP response data in the GitHub Actions log give the request an id and access its outputs. You can also access specific field from the response data using fromJson() expression.

steps:
  - name: Make Request
    id: myRequest
    uses: fjogeleit/http-request-action@v1
    with:
      url: "http://yoursite.com/api"
  - name: Show Response
    run: |
      echo ${{ steps.myRequest.outputs.response }}
      echo ${{ steps.myRequest.outputs.headers }}
      echo ${{ fromJson(steps.myRequest.outputs.response).field_you_want_to_access }}

Additional Information

Additional information is available if debug logging is enabled:

  • Instance Configuration (Url / Timeout / Headers)
  • Request Data (Body / Auth / Method)

To enable debug logging in GitHub Actions create a secret ACTIONS_RUNNER_DEBUG with a value of true

Local Usage

  • You can execute this tool locally with the provided CLI bin/http-action.
bin/http-action --help                   
Positionals:
  url  request URL                                                     [string]

Optionen:
      --help           helper text                                     [boolean]
  -d, --data           request body data                               [string] [default: "{}"]
  -f, --files          request files, send as multipart/form-data      [string] [default: "{}"]
      --file           single file, send as application/octet-stream   [string]
  -h, --customHeaders  custom request headers                          [string] [default: "{}"]
  -m, --method         request method (GET, POST, PATCH, PUT, DELETE)  [string] [default: "POST"]
  -t, --contentType    request content type                            [string] [default: "application/json"]
      --bearerToken    bearer token without Bearer prefix, added as
                       Authorization header                            [string]
      --timeout        request timeout                                 [number] [default: 5000]

http-request-action's People

Contributors

boro2g avatar clayenkitten avatar dependabot[bot] avatar fjogeleit avatar jstlwk avatar kittizz avatar nhan-nguyen-se avatar rgb2hsl avatar swharden avatar understructure avatar uzlopak avatar yesjinu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

http-request-action's Issues

Outputting a response via `responseFile` results in an exception when the response is empty.

Hello!

I mentioned in this issue that in order to hide secrets, I'm storing responses in a responseFile which I later cat into a variable in a subsequent step in order to mask without GitHub displaying the contents, as it would with a step output.

The endpoint I'm trying to reach may or may not contain a response, which I use as a conditional for branching logic.

Unfortunately, when no response is returned while a responseFile is configured to be used, the action encounters an exception.

Example:
This action indicates the following {"code":401,"message":""}, the response itself being nothing at all.

I've set the following variables for the action (amongst credentials, data, method, other unrelated info):

  • ignoreStatusCodes: "401"
  • preventFailureOnNoResponse: 'true'
  • responseFile: 'http.response'

However, the failure output of the step is as follows:

Warning: ignored status code: {"code":401,"message":""}
/opt/actions-runner/runner/_work/_actions/fjogeleit/http-request-action/v1.14.1/dist/index.js:5056
    let data = response.data
                        ^

TypeError: Cannot read properties of null (reading 'data')
    at /opt/actions-runner/runner/_work/_actions/fjogeleit/http-request-action/v1.14.1/dist/index.js:5056:25
    at /opt/actions-runner/runner/_work/_actions/fjogeleit/http-request-action/v1.14.1/dist/index.js:9886:26
    at Array.forEach (<anonymous>)
    at /opt/actions-runner/runner/_work/_actions/fjogeleit/http-request-action/v1.14.1/dist/index.js:9886:13
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Conditional use of JSON.stringify on response.data causing issues parsing the response

First of all, thanks for your work in creating and maintaining this action!

In our CI workflow, we use this action to get a response from an API endpoint that returns a string. Previously, we parsed this response in the action.yml file with fromJson, but with this change an error is thrown.

After a brief investigation, we discovered that it was fromJson that was choking on trying to parse a response that was no longer serialized and the solution is to remove the fromJson but it got me thinking: this is technically a breaking change for anyone using this with APIs that return a string response (a set of users that is probably, admittedly, very tiny though). Is there any benefit to conditionally serializing the response here? It seems that consumers that want to pass response data into other steps are forced to know ahead of time whether their endpoint is returning a string or an object so you can know whether to parse the response or not. Given this, would it be worth always serializing the response as before so that the response is always consistently parsable JSON?

We were able to fix our workflows fairly easily once the problem was understood, so I don't think I would really call this a bug. My motivation for posting this was just because I thought it was an interesting edge case that revealed something to think about in terms of how to handle the serialization of response data. Curious about your thoughts, but if you prefer to keep the change as is or that it doesn't warrant discussion or further thought, feel free to close this.

Tiny update: After taking a closer look at the documentation, if no change is deemed necessary it may warrant a change to the README since it does call out that response is a JSON string which is not necessarily true anymore.

image

Happy to submit PRs for any changes, whether to the README or the code, but figured I'd wait to hear what you think first.

Error passing github commit message

Have been using this for a while now and it has been working great but since today it seems something is not allowing the github message to be passed as its breaking the data string.

  - name: 'OPTIK Patch POST API'
    uses: 'fjogeleit/http-request-action@main'
    with:
      url: 'myurl'
      method: 'POST'
      bearerToken: ${{ secrets.PATCH_BEARER }}
      timeout: 15000
      contentType : 'application/x-www-form-urlencoded'
      customHeaders: '{"Content-Type": "application/x-www-form-urlencoded"}'
      data: 'completed=N&version=${{ steps.version-bump.outputs.newTag }}&commitMessage=${{ github.event.head_commit.message }}&addedWhen=${{ steps.date.outputs.date }}&committedBy=${{ github.event.head_commit.author.name }}&system=OptikPMS'

My api is responding with the values are required so completed is required and so on.
the commit runs across multiple lines as have many others yet today its just not working

customHeaders field not recognised

Using v1.3.2 with a customHeaders input I'm getting the following error:

##[warning]Unexpected input(s) 'customHeaders', valid inputs are ['url', 'method', 'contentType', 'data', 'username', 'password', 'timeout', 'bearerToken']

Originally posted by @harmanpa in #1 (comment)

Error converting circular structure to JSON on http error

/home/runner/work/_actions/fjogeleit/http-request-action/v1/dist/index.js:1973
      actions.setOutput('requestError', JSON.stringify(error.toJSON()));
                                             ^
TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'TLSSocket'
    |     property '_httpMessage' -> object with constructor 'ClientRequest'
    --- property 'socket' closes the circle
    at JSON.stringify (<anonymous>)
    at request (/home/runner/work/_actions/fjogeleit/http-request-action/v1/dist/index.js:1973:46)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    ```

File Uploads with `\` in the path are broken

Hi @fjogeleit,
thanks a lot for this excellent action. I'm using in in quite a few projects.

I just spent about an hour trying to figure out why my file was not uploaded. Turns out that this action does not seem to like Windows-style filepaths (with \) like they are generated by path.join(...) in JS.
When I replace them with forward slashes, everything works as expected.

For example:

files: { "file": "D:/a/myApp/myApp/release/My-App-win32-x64-1.0.0.exe" }

works, but

files: { "file": "D:\a\myApp\myApp\release\My-App-win32-x64-1.0.0.exe" }

does not.

Request Entity Too Large

After trying to upload the IPA file, which is 131mb. I got the message/error below.

I should also increase the timeout to something which would allow it plenty of time for upload as well I guess, but is there a hard limit at the moment for the amount of data one can upload?

Error: {"code":413,"message":"\r\n<title>413 Request Entity Too Large</title>\r\n<body bgcolor="white">\r\n

413 Request Entity Too Large

\r\n
nginx\r\n\r\n\r\n"}

The retry functionality is wrong

The retryWait value is being replaced by retry value in the file index.js

let retryWait = 3000
if (!!core.getInput('retryWait')) {
  retry = parseInt(core.getInput('retryWait'))
}

In the file helper.js the 'retries' variable is not defined anywhere

if (i < options.retries) {
      options.actions.warning(`#${i + 1} request failed: ${err}`);
      await sleep(options.sleep);
    }

    i++;
  } while (i <= options.retry);

a way to mask the response data

I want to send back a secret value and don't want it visible to anybody that clicks on the actions tab for the repository. Is there any way to make the mask the post data?

IE assume "world" is secret - i'd want that masked or just the data not output here altogether.

image

Retries?

What are your thoughts on adding a retry count and implementing either exponential backoff or even linear backoff, given that networks are never 100% reliable?

Pass data through json file

Hello,

As we are making REST API call, instead of passing data directly we would like to input the path to json file which consits data.
Can you please help us to acheive the same.

Thanks & Regards,
Nayana Nagaraj

Can't add token manually to Authorization header in customHeaders

Hey, i keep getting Unsupported Format for Authorization header when i try to send a token via customHeaders (I can't use the bearerToken property because i get Authorization Header Missing in that case). It's probably something with my json format but can't figure out what exactly. The Authorization header appears empty in the logs. I've tested this is postman and the request goes through correctly. Any pointers?

My action:

- name: HTTP Request Action id: getAuth0AccessToken uses: fjogeleit/[email protected] with: url: <<removed by author>> data: <<removed by author>> - name: Show Token Response run: echo ${{ steps.getAuth0AccessToken.outputs.response }} - name: HTTP Request Action id: callNetlifyFunction uses: fjogeleit/[email protected] with: url: <<removed by author>> customHeaders: '{"Authorization":"Bearer ${{steps.getAuth0AccessToken.outputs.response.access_token}}"}' - name: Show L Response run: echo ${{ steps.callNetlifyFunction.outputs.response }}

the log response:

[debug]steps.callNetlifyFunction.outputs.requestError='{"message":"Request failed with status code 401","name":"Error","stack":"Error: Request failed with status code 401\n at createError (/home/runner/work/_actions/fjogeleit/http-request-action/v1.8.0/dist/index.js:71:15)\n at settle (/home/runner/work/_actions/fjogeleit/http-request-action/v1.8.0/dist/index.js:3108:12)\n at IncomingMessage.handleStreamEnd (/home/runner/work/_actions/fjogeleit/http-request-action/v1.8.0/dist/index.js:3552:11)\n at IncomingMessage.emit (events.js:215:7)\n at endReadableNT (_stream_readable.js:1184:12)\n at processTicksAndRejections (internal/process/task_queues.js:80:21)","config":{"method":"post","data":"{}","headers":{"Accept":"application/json, text/plain, /","Content-Type":"application/json","Authorization":"","User-Agent":"axios/0.21.1","Content-Length":2},"baseURL":,"transformRequest":[null],"transformResponse":[null],"timeout":5000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":null,"maxBodyLength":null}}

Error: {"code":401,"message":{"error":"invalid_header","error_description":"Unsupported format for the Authorization header"}}`

Feature Request: Mask responses

Hello!

I have an endpoint I'm requesting via this action that returns sensitive information. This information (the entire response) should ideally be masked before being stored as an output, as if I were to attempt to mask it in a subsequent step, the step's "Run" dropdown (displayed via dropdown menu at the top of the step, such as the one seen here) ends up displaying the response in plain text as GitHub will inject contents of the step output directly into the logic before the step is even ran - this same logic including the line to mask the string upon running.

For example, this logic masks the response from a previous step w/ the id secret-credentials:

if [[ "$MASK_VARS" == "true" ]]; then
	echo "::add-mask::${{ steps.secret-credentials.outputs.response }}"
fi

However, when viewed via the "Run" dropdown after workflow completion, it appears similar to this:

if [[ "$MASK_VARS" == "true" ]]; then
	echo "::add-mask::{"t":"THIS_IS_A_SUPER_SECRET_STRING_THAT_SHOULD_NOT_BE_VISIBLE"}"
fi

I've used responseFile to store the output for the time being, which I can cat it into a variable in the post-request step. Doing it this way prevents the dropdown from showing the automatically-replaced step output, and since the response is then stored in a var populated from the file, I can then mask it without GH showing the output itself.

However, it would be nice for the action itself to be able to mask it upon receiving the response.

I've started implementing this in a fork. JS isn't exactly my strong suit, nor do I know what sort of testing is performed to validate the package in its entirety, but I figured I'd throw this here in case there's either any guidance you can give me to complete this feature, or if you'd like to use it as a base to complete it.

Improve documentation

Hi,
I suggest you to improve the documentation because I struggle some hours before understanding the problem with a POST request and data as key=value pairs, I had to set :

contentType: application/x-www-form-urlencoded

but it's not obvious in documentation, may be you can change it like this :

Request Body Content as JSON String (or key=value pairs separated by '&' and contentType: application/x-www-form-urlencoded), only for POST / PUT / PATCH Requests

Feature request: Not fail if no response was received

Hi,
I have a feature request:
Wouldn't it be nice to have a option to disable build failure, when no response, but a HTTP 200 status code was received as answer? Such as disableFailureOnNoResponse = true / false?

Upload a file [Question]

Hi!, is there a way to upload file using this action? Im new to github actions and i was looking way to upload my artifacts on my website. Thanks

request sent successfully. no response displayed. error message

hi,
the action sent the post request successfully but there's no response displayed. also seen the error message below:

(node:2444) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'code' of undefined
at /home/runner/work/_actions/fjogeleit/http-request-action/master/dist/index.js:2656:58
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:2444) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:2444) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Feature Request: store response into a file

Hello, thanks a bunch for the action.
I need to instrument an HTTP API that yields a multi-megabyte outputs.response and then store this response as an artifact using actions/upload-artifact@v3 which is based on files.

So currently I have to have an intermediate step run: echo "${{ steps.fetch-messages.outputs.response }}" > messages.json to store the response into a file, before I pass it on to actions/upload-artifact@v3.

Could you introduce another property like storeResponseIntoFile: response.json that directly stores the raw-response into a file?

'No response received' is logged when server returns just a status code

If preventFailureOnNoResponse is set and the server returns a 2XX status code, then the 'no response received' should not occur (or not shown in the output)

::warning::no response received: {"message":"timeout of 5000ms exceeded","name":"AxiosError","stack":"AxiosError: timeout of 5000ms exceeded\n at RedirectableRequest.handleRequestTimeout (/run/act/actions/fjogeleit-http-request-action@v1/dist/index.js:32459:16)\n at RedirectableRequest.emit (node:events:519:28)\n at Timeout. (/run/act/actions/fjogeleit-http-request-action@v1/dist/index.js:2840:12)\n at listOnTimeout (node:internal/timers:573:17)\n at process.processTimers (node:internal/timers:514:7)","config":{"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false},"adapter":["xhr","http"],"transformRequest":[null],"transformRespon.......

Also, thank you for such a great tool!

GITHUB_TOKEN permissions used by this action

At https://github.com/step-security/secure-workflows we are building a knowledge-base (KB) of GITHUB_TOKEN permissions needed by different GitHub Actions. When developers try to set minimum token permissions for their workflows, they can use this knowledge-base instead of trying to research permissions needed by each GitHub Action they use.

Below you can see the KB of your GITHUB Action.

name: 'HTTP Request Action'
#GITHUB_TOKEN not used
#FIXES: #506

If you think this information is not accurate, or if in the future your GitHub Action starts using a different set of permissions, please create an issue at https://github.com/step-security/secure-workflows/issues to let us know.

This issue is automatically created by our analysis bot, feel free to close after reading :)

References:

GitHub asks users to define workflow permissions, see https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/ and https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token for securing GitHub workflows against supply-chain attacks.

Setting minimum token permissions is also checked for by Open Source Security Foundation (OpenSSF) Scorecards. Scorecards recommend using https://github.com/step-security/secure-workflows so developers can fix this issue in an easier manner.

Request body larger than maxBodyLength limit

I was trying to upload a generated APK on my webserver. I do not have issue when i trying to upload a small size apk but when there is a large size of file it gives a error. I also attached screenshot for the logs

image

Getting error: "Unable to convert Data and Files into FormData: source.on is not a function"

I'm not sure what I'm doing wrong here. The error is not very illuminating. Here's the full error message:

{"message":"Unable to convert Data and Files into FormData: source.on is not a function","data":{"metadata":{"changelog":"Version 4.2.1\n## What's Changed\n* Update issue template to use paste.gg by @benwoo1110 in [https://github.com/Multiverse/Multiverse-SignPortals/pull/69\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/69/n*) Set up Travis by @nicegamer7 in [https://github.com/Multiverse/Multiverse-SignPortals/pull/72\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/72/n*) Update to all use static logging. by @benwoo1110 in [https://github.com/Multiverse/Multiverse-SignPortals/pull/73\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/73/n*) Add support for Villagers to redstone teleports by @RoyCurtis in [https://github.com/Multiverse/Multiverse-SignPortals/pull/44\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/44/n*) Add a Missing Import by @nicegamer7 in [https://github.com/Multiverse/Multiverse-SignPortals/pull/76\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/76/n*) GitHub actions by @benwoo1110 in [https://github.com/Multiverse/Multiverse-SignPortals/pull/77\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/77/n*) Use https for dependency. by @benwoo1110 in [https://github.com/Multiverse/Multiverse-SignPortals/pull/78\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/78/n*) Implement gradle build and GHA release by @benwoo1110 in [https://github.com/Multiverse/Multiverse-SignPortals/pull/83\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/83/n*) GHA release workflow v2 by @dumptruckman in [https://github.com/Multiverse/Multiverse-SignPortals/pull/84\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/84/n*) Trigger PR release workflow. by @dumptruckman in [https://github.com/Multiverse/Multiverse-SignPortals/pull/85\n##](https://github.com/Multiverse/Multiverse-SignPortals/pull/85/n##) New Contributors\n* @RoyCurtis made their first contribution in [https://github.com/Multiverse/Multiverse-SignPortals/pull/44\n*](https://github.com/Multiverse/Multiverse-SignPortals/pull/44/n*) @dumptruckman made their first contribution in [https://github.com/Multiverse/Multiverse-SignPortals/pull/84\n**Full](https://github.com/Multiverse/Multiverse-SignPortals/pull/84/n**Full) Changelog**: https://github.com/Multiverse/Multiverse-SignPortals/compare/4.2.0...4.2.1","changelogType":"markdown","releaseType":"release","displayName":"4.2.1","gameVersions":[9561,9560,9261,9190,9016,8897,8849,8503,7915,7667,7330,7105],"relations":{"projects":[{"slug":"multiverse-core","type":"requiredDependency"}]}}},"files":{"file":"/home/runner/work/Multiverse-SignPortals/Multiverse-SignPortals/multiverse-signportals-4.2.1.jar"}}

Passing a JSON string to data

Hi! as mention on the title, i was trying to upload a json string but i everytime i add the json string to data, my other variables were undefined on my api

Here is my sample logs

[{"message":"t-12-test"}, {"message":"b-13-test"}]

Could not parse customHeaders string value

Hello,

I’m getting the following error when trying to send some custom headers

Could not parse customHeaders string value

here’s the output


Run fjogeleit/http-request-action@master
  with:
    url: https://api.github.com/repos/Ombi-app/Ombi.Apt/actions/workflows/build-deb.yml/dispatches
    method: POST
    contentType: application/json
    data: { "ref":"main", "inputs": { "version": ""} }
    customHeaders: {'Accept':'application/vnd.github.v3+json', 'Authorization':'***', 'User-Agent':'Ombi'}
    files: {}
    timeout: 5000
Error: Could not parse customHeaders string value

You can view this here:
https://github.com/Ombi-app/Ombi/runs/3842307346?check_suite_focus=true

It’s the last step

A way to see response in output?

image
Is there a way to see response in the same step?

Right now you have to do add another step that will echo the response, can it be done in same step?

- name: Call webhook
  id: webhook
  uses: fjogeleit/http-request-action@v1
  with:
    url: 'my-url'
    method: 'POST'
- name: Webhook response
  run: |
    echo ${{ steps.webhook.outputs.response }}
    echo ${{ steps.webhook.outputs.headers  }}

Access to Response Body for Ignored Status Codes

Currently, when a response returns one of the specified ignoreStatusCodes, the action's outputs (response, headers) are set to null. Although the response is logged as a warning, it is not accessible through any step outputs, limiting automated handling of these responses.

In workflows, especially those tied to CI/CD processes like PR reviews, having programmable access to these responses, even when they are intentionally ignored, is crucial. For instance, it would allow us to format the response and post it as a comment on the PR that triggered the workflow, enhancing automated feedback loops.

Possible Solutions:

  1. Always set response output: Ensure the response output is set, regardless of the status code being part of the ignoreStatusCodes. This approach may introduce breaking changes for existing workflows expecting null values.

  2. Introduce a new output, e.g., ignored_response: This output would specifically contain the response for ignored status codes, preserving the current behavior for the response output. This approach is preferable for backward compatibility and clearly distinguishes between standard and ignored responses, catering to various use cases without surprising existing users.

This enhancement would significantly improve the action's flexibility and utility in complex workflows, providing users with more options for handling different responses.

JSON object being wrapped in additional string

I'm trying to call an endpoint that expects a body of
{"config":"<yaml string>"}
this is how I am calling this action:

        # You may pin to the exact commit or the version.
        # uses: fjogeleit/http-request-action@8e939c608aea2d5df19da3e8229cf035f7aa9e4c
        uses: fjogeleit/[email protected]
        with:
          # Request URL
          url: "https://api.jernik.me/guilds/361634430626037770/config"
          # Request Method
          method: "POST"
          # Content Type
          contentType: "application/json"
          # Request Body as JSON String
          data: "{\"config\": \"${{steps.read_file.outputs.contents}}}\"}"
          # Custom HTTP Headers
          customHeaders: "{\"X-Api-Key\": \"${{ secrets.zeppelin_apikey }}\"}"

this is producing a body of
body: '"{\\"config\\": \\"<yamlstring>\\"}"'
This is an extra layer of json stringification and I cannot figure out how to tell this action "just use the body I'm giving you, don't stringify it more"

Method delete is causing AxiosError

I've noticed that using action with delete method throws 501 error without any message

{"name":"AxiosError","message":"Request failed with status code 501","code":"ERR_BAD_RESPONSE","status":501}

Action that was ran in GH:

name: drop-vm
        id: drop-vm
        uses: fjogeleit/http-request-action@v1
        with: 
          url: ${{secrets.PVE_ENDPOINT}}/nodes/somenode/qemu/${{steps.get-id.outputs.ID}}/?purge=1
          method: 'DELETE'
          customHeaders: '{"Authorization": "PVEAPIToken=${{secrets.PVE_TOKEN}}"}'
          httpsCA: ${{secrets.HL_CA}}

Rendered URL seems to be valid (xxxxx/nodes/somenode/qemu/108/?purge=1).
image

When pasted to Postman and used with same credentials action is successful.

Headers and Content-Type errors

First things first, this definitely isn't any sort of bug I'm sure. But more of a usage problem on my end.
So here's my code:

name: AAP-Repo Project Update
on:
  push:
    branches:
      - main
jobs:
  http-request:
    runs-on: ubuntu-latest
    steps:
      - name: Send HTTP Request
        uses: fjogeleit/http-request-action@v1
        with:
          url: 'https://ansible.domain.net/api/v2/projects/33/update/'
          method: 'POST'
          bearerToken: ${{ secrets.aap_bearer_token }}
          content: |
            '{"Content-Type": "application/json"}'
        id: http_request
      - name: Print HTTP Response
        run: echo "${{ steps.http_request.outputs.response }}"

This returns an error stating:

[http-request](https://github.com/company/sysops-aap/actions/runs/4441013002/jobs/7811192944#step:2:16)
Unexpected input(s) 'headers', 'Content-Type', valid inputs are ['url', 'method', 'contentType', 'data', 'files', 'file', 'username', 'password', 'timeout', 'bearerToken', 'customHeaders', 'preventFailureOnNoResponse', 'ignoreStatusCodes', 'escapeData', 'httpsCA', 'responseFile', 'retry', 'retryWait']

Ok, I'll change 'headers' to 'customHeaders'. So I change it to this:


name: AAP-Repo Project Update
on:
  push:
    branches:
      - main
jobs:
  http-request:
    runs-on: ubuntu-latest
    steps:
      - name: Send HTTP Request
        uses: fjogeleit/http-request-action@v1
        with:
          url: 'https://ansible.domain.net/api/v2/projects/33/update/'
          method: 'POST'
          bearerToken: ${{ secrets.aap_bearer_token }}
          customHeaders: |
          contentType: '{"Content-Type": "application/json"}'
        id: http_request
      - name: Print HTTP Response
        run: echo "${{ steps.http_request.outputs.response }}"

Which then re-running the GH actin returns: no response from server. Now test calls from Postman containing the same required info are successful. I'm wondering what the correct syntax for 'steps.http_request...' would be to echo out the API call before it's made?

Issue With Authentication?

Hello,

I have the following code in a github action:

    - name: Sync Airflow Dags
      id: syncAirflow
      uses: fjogeleit/http-request-action@v1
      with:
        url: ${{env.AIRFLOW_URL}}
        method: 'POST'
        username: ${{secrets.AIRFLOW_USERNAME_ALL}}
        password: ${{env.AIRFLOW_PASSWORD}}
        preventFailureOnNoResponse: 'true'

With the preventFailureOnResponse set to true, I get this warning:

{"message":"timeout of 5000ms exceeded","name":"Error","stack":"Error: timeout of 5000ms exceeded\n    at createError (/home/runner/work/_actions/fjogeleit/http-request-action/v1/dist/index.js:78:15)\n    at RedirectableRequest.handleRequestTimeout (/home/runner/work/_actions/fjogeleit/http-request-action/v1/dist/index.js:5415:16)\n    at RedirectableRequest.emit (node:events:390:28)\n    at Timeout.<anonymous> (/home/runner/work/_actions/fjogeleit/http-request-action/v1/dist/index.js:4071:12)\n    at listOnTimeout (node:internal/timers:557:17)\n    at processTimers (node:internal/timers:500:7)","config":{"method":"post","data":"{}","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","User-Agent":"axios/0.21.4","Content-Length":2},"auth":{"username":"***","password":"***"},"baseURL":<REDACTED>","transformRequest":[null],"transformResponse":[null],"timeout":5000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":null,"maxBodyLength":null,"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false}},"code":"ECONNABORTED"}

I do know that the API I am sending this request to requires the username to be base64 encoded, so I think this might be the reason for the timeout. I'm assuming this utility does not do that, is that correct? Is there an option for this?

Enable mutual TLS https authentication

Our servers sit behind teleport proxy (which enforces mutual TLS https). If this was written in python (by any chance), the python requests library already supports mutual TLS by allowing you to specify a client-side (public) certificate and client-side (private) key. It would be quite trivial to support by exposing this option via the github action interface.

Get request origin

Hi! I'm trying to use CORS to prevent any other origins from being able to request my actions endpoint. How can I know the origin of the request coming from this action? By the way, I'm new to GitHub Actions, so if there's a better way people are using to solve this problem, let me know.

Thanks!

Does JSON string supports new lines?

It seems that using heredocs may not supported for a JSON body. If I just make the body all one long JSON string everything is fine and posts to MS Teams as expected.

Additionally, if the PR has any new lines in the description it will fail. I'm not sure if it needs to be escaped on my end somehow or not. I've included the part of my yaml file including a heredoc for review.

method: "POST"
contentType: "application/json"
data: >-
  {
    "@type":"MessageCard",
    "@context":"http://schema.org/extensions",
    "themeColor":"0076D7",
    "summary":"GitHub",
    "sections":[
      {
        "title":"[${{github.repository}}] Pull request opened: #${{github.event.pull_request.number}}",
        "activityTitle":"${{github.event.pull_request.title}}",
        "activitySubtitle":"${{github.event.pull_request.user.login}}",
        "activityImage":"${{github.event.pull_request.user.avatar_url}}",
        "text":"${{github.event.pull_request.body}}",
        "markdown":true
      }
    ],
    "potentialAction":[
      {
        "@type":"OpenUri",
        "name":"View Pull Request",
        "targets":[
          {
            "os":"default",
            "uri":"${{github.event.pull_request.html_url}}"
          }
        ]
      }
    ]
  }

Unable to convert Data and Files into FormData

Not sure if I am missing something in the setup, regular posts requests work great, but when I try to upload a file, in this case .IPA file, I get this error (I get it no matter the file type actually)

{"message":"Unable to convert Data and Files into FormData: data is not defined","data":{},"files":{"file":"<WORKSPACE>/test.ipa"}}

DirectApiRequestHasMoreThanOneAuthorization Error

Whenever I try to post to an Azure Logic App, I get this message

##[error]{"message":{"error":{"code":"DirectApiRequestHasMoreThanOneAuthorization","message":"The request has both SAS authentication scheme and 'Basic' authorization scheme. Only one scheme should be used."}}}

I can confirm I can post to this url from PostMan with no issue, here is my input

    url: ***
    method: POST
    contentType: application/json
    data: { "url": "http://isaaclevin.com/about" }
    timeout: 5000

With logic apps, the auth is in the url, so I do not supply a Bearer or Basic Auth. I have a feeling that since I am not supplying either, the http request looks odd.

Request path contains unescaped characters

Hello I am trying to use this action and I am getting an error about unescaped character.

The action:

- name: Clone pre-release branch configuration for iOS
        uses: fjogeleit/[email protected]
        with:
          url: "https://api.appcenter.ms/v0.1/apps/xxx/xxx/branches​/${{ github.event.pull_request.head.ref }}/config"
          method: "POST"
          contentType: "application/json"
          data: '{"cloneFromBranch":"pre-release-appcenter"}'
          customHeader: '{"X-API-Token":"${{secrets.APP_CENTER_LOGIN_TOKEN}}"}'

The error output plus error:

Run fjogeleit/[email protected]
  with:
    url: https://api.appcenter.ms/v0.1/apps/xxx/xxx/branches​/xxx/config
    method: POST
    data: { "cloneFromBranch": "pre-release-appcenter" }
    customHeader: {"X-API-Token": "***"}
    files: {}
    timeout: 5000


Error: {"message":"Request path contains unescaped characters","data":"{ \"cloneFromBranch\": \"pre-release-appcenter\" }"}

Is there something obvious here that I am missing? Thank you in advance.

Let's Encrypt SSL issue

I try to use this extension with a backend configured with a Let's Encrypt certificate:

- name: Triggering WebHool
   uses: fjogeleit/http-request-action@v1
   with:
      url: 'https://my-letsencryptdomain/xxx'
      method: 'POST'

The result is always

Warning: "message":"unable to verify the first certificate","name":"Error","stack":"Error: unable to verify the first certificate\n at TLSSocket.onConnectSecure (node:_tls_wrap:1530:34)\n at TLSSocket.emit (node:events:390:28)\n at TLSSocket._finishInit (node:_tls_wrap:944:8)\n at TLSWrap.ssl.onhandshakedone (node:_tls_wrap:725:12)","config":"method":"post","data":"","headers":"Accept":"application/json, text/plain, /","Content-Type":"application/json","User-Agent":"axios/0.21.4","Content-

Do you have any ideas what I can do?

Array of files to upload in single files property fails

Hi, thanks for this action, helps a lot.

I'd like the multipart/form-data files upload to work like:

files: '{"attachments": ["report.html", "report.json"]}'

This is what a CMS I use for one of my apps accepts.
Using it with the action produces:

{"message":"Unable to convert Data and Files into FormData: The \"path\" argument must be of type string or an instance of Buffer or URL. Received an instance of Array","data":{"jobId":"u4oigjysc5lzwkg"},"files":{"attachments":["report.html","report.json"]}}

Can't bypass Vercel's authentication

I'm trying to send a request to an app that is hosted on Vercel. The instance is password protected.

This is my job configuration:

        uses: fjogeleit/[email protected]
        with:
          url: 'https://myapp.vercel.app'
          method: 'POST'
          contentType: application/x-www-form-urlencoded
          data: '_vercel_password=<password>'

Output:

[yolo/e2e]   💬  ::debug::Instance Configuration: {"baseURL":"https://myapp.vercel.app","timeout":5000,"headers":{"Content-Type":"application/x-www-form-urlencoded"}}
[yolo/e2e]   💬  ::debug::Request Data: {"method":"POST","data":"_vercel_password=<password>","maxContentLength":null,"maxBodyLength":null}
[yolo/e2e]   ⚙  ::set-output:: requestError={"name":"Error","message":"Request failed with status code 401","status":401}

The following, I presume equivalent, CURL command works perfectly:

curl -s -D - -X POST -d "_vercel_password=<password>" https://myapp.vercel.app

This is how you can access password protected deployments in Vercel.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.