mirror of
https://github.com/fjogeleit/http-request-action.git
synced 2024-11-25 05:10:57 -05:00
add persist handler
Signed-off-by: Frank Jogeleit <frank.jogeleit@lovoo.com>
This commit is contained in:
parent
0f4905efb7
commit
2c712a0557
10 changed files with 1266 additions and 720 deletions
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
|
@ -132,6 +132,17 @@ jobs:
|
||||||
data: '{ "key": "value" }'
|
data: '{ "key": "value" }'
|
||||||
files: '{ "file": "${{ github.workspace }}/testfile.txt" }'
|
files: '{ "file": "${{ github.workspace }}/testfile.txt" }'
|
||||||
|
|
||||||
|
- name: Request Postman Echo POST and persist response
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
url: 'https://postman-echo.com/post'
|
||||||
|
method: 'POST'
|
||||||
|
file: "${{ github.workspace }}/testfile.txt"
|
||||||
|
responseFile: "${{ github.workspace }}/response.json"
|
||||||
|
- name: Output responseFile
|
||||||
|
run: |
|
||||||
|
cat "${{ github.workspace }}/response.json"
|
||||||
|
|
||||||
- name: Request Postman Echo POST Multipart without data
|
- name: Request Postman Echo POST Multipart without data
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -42,6 +42,7 @@ jobs:
|
||||||
|preventFailureOnNoResponse| Prevent this Action to fail if the request respond without an response. 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' ||
|
|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 ||
|
|httpsCA| Certificate authority as string in PEM format ||
|
||||||
|
|responseFile| Persist the response data to the specified file path ||
|
||||||
|
|
||||||
### Response
|
### Response
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,9 @@ inputs:
|
||||||
httpsCA:
|
httpsCA:
|
||||||
description: 'Certificate authority as string in PEM format'
|
description: 'Certificate authority as string in PEM format'
|
||||||
required: false
|
required: false
|
||||||
|
responseFile:
|
||||||
|
description: 'Persist the response data to the specified file path'
|
||||||
|
required: false
|
||||||
outputs:
|
outputs:
|
||||||
response:
|
response:
|
||||||
description: 'HTTP Response Content'
|
description: 'HTTP Response Content'
|
||||||
|
|
1880
dist/index.js
vendored
1880
dist/index.js
vendored
File diff suppressed because it is too large
Load diff
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -13,7 +13,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vercel/ncc": "^0.36.1",
|
"@vercel/ncc": "^0.36.1",
|
||||||
"axios": "^1.2.6",
|
"axios": "^1.2",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"yargs": "^17.6.2"
|
"yargs": "^17.6.2"
|
||||||
},
|
},
|
||||||
|
@ -78,9 +78,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.2.6",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.2.tgz",
|
||||||
"integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==",
|
"integrity": "sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.0",
|
||||||
|
@ -386,9 +386,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"version": "1.2.6",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.2.tgz",
|
||||||
"integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==",
|
"integrity": "sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.0",
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
"homepage": "https://github.com/fjogeleit/http-request-action#readme",
|
"homepage": "https://github.com/fjogeleit/http-request-action#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vercel/ncc": "^0.36.1",
|
"@vercel/ncc": "^0.36.1",
|
||||||
"axios": "^1.2.6",
|
"axios": "^1.2",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"yargs": "^17.6.2"
|
"yargs": "^17.6.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,10 @@ class GithubActions {
|
||||||
core.debug(message)
|
core.debug(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info(message) {
|
||||||
|
core.info(message)
|
||||||
|
}
|
||||||
|
|
||||||
warning(message) {
|
warning(message) {
|
||||||
core.warning(message)
|
core.warning(message)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +25,10 @@ class GithubActions {
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogActions {
|
class LogActions {
|
||||||
|
info(message) {
|
||||||
|
console.info(message)
|
||||||
|
}
|
||||||
|
|
||||||
debug(message) {
|
debug(message) {
|
||||||
console.info(message)
|
console.info(message)
|
||||||
}
|
}
|
||||||
|
|
30
src/handler/persist.js
Normal file
30
src/handler/persist.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
const { GithubActions } = require('../githubActions');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filePath
|
||||||
|
* @param {GithubActions} actions
|
||||||
|
*
|
||||||
|
* @returns {(response: axios.AxiosResponse) => void}
|
||||||
|
*/
|
||||||
|
const createPersistHandler = (filePath, actions) => (response) => {
|
||||||
|
let data = response.data
|
||||||
|
|
||||||
|
if (typeof data == 'object') {
|
||||||
|
data = JSON.stringify(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFile(filePath, data, err => {
|
||||||
|
if (!err) {
|
||||||
|
actions.info(`response persisted successfully at ${filePath}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.warning(JSON.stringify({ message: error.message, data: response.data }))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { createPersistHandler }
|
|
@ -4,6 +4,7 @@ const axios = require('axios');
|
||||||
const FormData = require('form-data')
|
const FormData = require('form-data')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
|
const { GithubActions } = require('./githubActions');
|
||||||
|
|
||||||
const METHOD_GET = 'GET'
|
const METHOD_GET = 'GET'
|
||||||
const METHOD_POST = 'POST'
|
const METHOD_POST = 'POST'
|
||||||
|
@ -19,12 +20,12 @@ const CONTENT_TYPE_URLENCODED = 'application/x-www-form-urlencoded'
|
||||||
* @param {string} param0.data Request Body as string, default {}
|
* @param {string} param0.data Request Body as string, default {}
|
||||||
* @param {string} param0.files Map of Request Files (name: absolute path) as JSON String, default: {}
|
* @param {string} param0.files Map of Request Files (name: absolute path) as JSON String, default: {}
|
||||||
* @param {string} param0.file Single request file (absolute path)
|
* @param {string} param0.file Single request file (absolute path)
|
||||||
* @param {*} param0.actions
|
* @param {GithubActions} param0.actions
|
||||||
* @param {number[]} param0.ignoredCodes Prevent Action to fail if the API response with one of this StatusCodes
|
* @param {number[]} param0.ignoredCodes Prevent Action to fail if the API response with one of this StatusCodes
|
||||||
* @param {boolean} param0.preventFailureOnNoResponse Prevent Action to fail if the API respond without Response
|
* @param {boolean} param0.preventFailureOnNoResponse Prevent Action to fail if the API respond without Response
|
||||||
* @param {boolean} param0.escapeData Escape unescaped JSON content in data
|
* @param {boolean} param0.escapeData Escape unescaped JSON content in data
|
||||||
*
|
*
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<axios.AxiosResponse>}
|
||||||
*/
|
*/
|
||||||
const request = async({ method, instanceConfig, data, files, file, actions, ignoredCodes, preventFailureOnNoResponse, escapeData }) => {
|
const request = async({ method, instanceConfig, data, files, file, actions, ignoredCodes, preventFailureOnNoResponse, escapeData }) => {
|
||||||
try {
|
try {
|
||||||
|
@ -47,7 +48,7 @@ const request = async({ method, instanceConfig, data, files, file, actions, igno
|
||||||
data = convertToFormData(dataJson, filesJson)
|
data = convertToFormData(dataJson, filesJson)
|
||||||
instanceConfig = await updateConfig(instanceConfig, data, actions)
|
instanceConfig = await updateConfig(instanceConfig, data, actions)
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
actions.setFailed({ message: `Unable to convert Data and Files into FormData: ${error.message}`, data: dataJson, files: filesJson })
|
actions.setFailed(JSON.stringify({ message: `Unable to convert Data and Files into FormData: ${error.message}`, data: dataJson, files: filesJson }))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +76,7 @@ const request = async({ method, instanceConfig, data, files, file, actions, igno
|
||||||
|
|
||||||
actions.debug('Instance Configuration: ' + JSON.stringify(instanceConfig))
|
actions.debug('Instance Configuration: ' + JSON.stringify(instanceConfig))
|
||||||
|
|
||||||
|
/** @type {axios.AxiosInstance} */
|
||||||
const instance = axios.create(instanceConfig);
|
const instance = axios.create(instanceConfig);
|
||||||
|
|
||||||
actions.debug('Request Data: ' + JSON.stringify(requestData))
|
actions.debug('Request Data: ' + JSON.stringify(requestData))
|
||||||
|
@ -84,6 +86,8 @@ const request = async({ method, instanceConfig, data, files, file, actions, igno
|
||||||
actions.setOutput('response', JSON.stringify(response.data))
|
actions.setOutput('response', JSON.stringify(response.data))
|
||||||
|
|
||||||
actions.setOutput('headers', response.headers)
|
actions.setOutput('headers', response.headers)
|
||||||
|
|
||||||
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if ((typeof error === 'object') && (error.isAxiosError === true)) {
|
if ((typeof error === 'object') && (error.isAxiosError === true)) {
|
||||||
const { name, message, code, response } = error
|
const { name, message, code, response } = error
|
||||||
|
|
19
src/index.js
19
src/index.js
|
@ -5,6 +5,7 @@ const axios = require('axios');
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
const { request, METHOD_POST } = require('./httpClient');
|
const { request, METHOD_POST } = require('./httpClient');
|
||||||
const { GithubActions } = require('./githubActions');
|
const { GithubActions } = require('./githubActions');
|
||||||
|
const { createPersistHandler } = require('./handler/persist');
|
||||||
|
|
||||||
let customHeaders = {}
|
let customHeaders = {}
|
||||||
|
|
||||||
|
@ -45,15 +46,27 @@ if (!!core.getInput('username') || !!core.getInput('password')) {
|
||||||
const data = core.getInput('data') || '{}';
|
const data = core.getInput('data') || '{}';
|
||||||
const files = core.getInput('files') || '{}';
|
const files = core.getInput('files') || '{}';
|
||||||
const file = core.getInput('file')
|
const file = core.getInput('file')
|
||||||
|
const responseFile = core.getInput('responseFile')
|
||||||
const method = core.getInput('method') || METHOD_POST;
|
const method = core.getInput('method') || METHOD_POST;
|
||||||
const preventFailureOnNoResponse = core.getInput('preventFailureOnNoResponse') === 'true';
|
const preventFailureOnNoResponse = core.getInput('preventFailureOnNoResponse') === 'true';
|
||||||
const escapeData = core.getInput('escapeData') === 'true';
|
const escapeData = core.getInput('escapeData') === 'true';
|
||||||
|
|
||||||
const ignoreStatusCodes = core.getInput('ignoreStatusCodes')
|
const ignoreStatusCodes = core.getInput('ignoreStatusCodes');
|
||||||
let ignoredCodes = []
|
let ignoredCodes = [];
|
||||||
|
|
||||||
if (typeof ignoreStatusCodes === 'string' && ignoreStatusCodes.length > 0) {
|
if (typeof ignoreStatusCodes === 'string' && ignoreStatusCodes.length > 0) {
|
||||||
ignoredCodes = ignoreStatusCodes.split(',').map(statusCode => parseInt(statusCode.trim()))
|
ignoredCodes = ignoreStatusCodes.split(',').map(statusCode => parseInt(statusCode.trim()))
|
||||||
}
|
}
|
||||||
|
|
||||||
request({ data, method, instanceConfig, preventFailureOnNoResponse, escapeData, files, file, ignoredCodes, actions: new GithubActions() })
|
const handler = [];
|
||||||
|
const actions = new GithubActions();
|
||||||
|
|
||||||
|
if (!!responseFile) {
|
||||||
|
handler.push(createPersistHandler(responseFile, actions))
|
||||||
|
}
|
||||||
|
|
||||||
|
request({ data, method, instanceConfig, preventFailureOnNoResponse, escapeData, files, file, ignoredCodes, actions }).then(response => {
|
||||||
|
if (typeof response == 'object') {
|
||||||
|
handler.forEach(h => h(response))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in a new issue