A GitHub Action that performs HTTP requests using the Fetch API and returns the response status, headers, and body. Supports all HTTP methods. Completely stateless — no data is stored or logged.
| Input | Required | Default | Description |
|---|---|---|---|
url |
Yes | — | The URL to fetch |
method |
No | GET |
HTTP method (GET, POST, PUT, DELETE, PATCH, etc.) |
headers |
No | {} |
JSON string of request headers |
body |
No | — | Request body (ignored for GET/HEAD) |
timeout |
No | 30000 |
Request timeout in milliseconds (0 = no timeout) |
| Output | Description |
|---|---|
status |
The HTTP response status code |
headers |
The HTTP response headers as a JSON string |
body |
The HTTP response body |
jobs:
getRequest_job:
name: "SAMPLE GET REQUEST"
runs-on: ubuntu-latest
steps:
- name: GET REQUEST SAMPLE
id: getRequest
uses: skgandikota/FetchUrl@v2
with:
url: "https://jsonplaceholder.typicode.com/posts/1"
- name: Get the getRequest outputs
run: |
echo "status: ${{ steps.getRequest.outputs.status }}"
echo "date: $(echo '${{ steps.getRequest.outputs.headers }}' | jq -r '.date')"
echo "responseBody: ${{ steps.getRequest.outputs.body }}"jobs:
postRequest_job:
name: "SAMPLE POST REQUEST"
runs-on: ubuntu-latest
steps:
- name: POST REQUEST SAMPLE
id: postRequest
uses: skgandikota/FetchUrl@v2
with:
url: "https://jsonplaceholder.typicode.com/posts"
method: POST
headers: '{"Content-type": "application/json; charset=UTF-8"}'
body: '{"title": "foo", "body": "bar", "userId": 1}'
- name: Get the postRequest outputs
run: |
echo "status: ${{ steps.postRequest.outputs.status }}"
echo "responseBody: ${{ steps.postRequest.outputs.body }}"- Runtime upgraded from
node16tonode20— GitHub deprecated Node.js 16 runners. No action needed if you pin to@v2. node-fetchreplaced with built-infetch— Response headers are now a flat JSON object ({"date": "..."}) instead of arrays ({"date": ["..."]}). Update any header parsing logic.- Non-JSON responses now work — Previously the action called
response.json()unconditionally, which threw on HTML/text/XML responses. It now falls back to plain text. bodydefault changed — from"null"(string) to empty string. No impact for most users.
timeoutinput (default 30s) withAbortController- Proper
async/awaiterror handling — failures now correctly callcore.setFailed()
MIT