diff --git a/README.md b/README.md index f00e04c..a0c314f 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,12 @@ Besides a status, meshStack can also show custom user messages consuming the ser ### inputs: - `step_id`: (required) The ID of the step -- `status`: (required) The status of the step (SUCCEEDED or FAILED) +- `step_status`: (required) The status of the step (SUCCEEDED or FAILED) - `user_message`: (optional) The user message for a failed step - `system_message`: (optional) The system message for a failed step -- `is_final`: (optional) Indicates if this is the final status report (default: 'false') -- `summary`: (optional) The summary message for the final status report +- `outputs_json`: (optional) A JSON object with outputs of the step. All step outputs in a run will be merged by +- `run_status`: (optional) Indicates if this is the final status report (default: 'false') +meshStack to produce the run outputs. See the [API documentation](https://docs.meshcloud.io/api/index.html#_update_sources_and_steps) for more details on how to use this field. ## Example Usage @@ -74,3 +75,5 @@ Besides a status, meshStack can also show custom user messages consuming the ser user_message: ${{ steps.terraform-validate.outcome == 'success' && 'Successful plan Terraform configuration.' || 'Failed to plan Terraform configuration.' }} system_message: ${{ steps.terraform-validate.outcome == 'success' && 'Successful plan Terraform configuration.' || 'Failed to plan Terraform configuration.' }} ``` + + diff --git a/action.yml b/action.yml index 891a4d3..59ca5c6 100644 --- a/action.yml +++ b/action.yml @@ -4,8 +4,8 @@ inputs: step_id: description: 'The ID of the step' required: false - status: - description: 'The status of the step (SUCCEEDED or FAILED)' + step_status: + description: 'The status of the step (IN_PROGRESS, SUCCEEDED or FAILED)' required: false user_message: description: 'The user message for a failed step' @@ -13,13 +13,13 @@ inputs: system_message: description: 'The system message for a failed step' required: false - final_status: - description: 'The final status is the end-state of the run, combining all step outcomes into one status result based on your logic.' + run_status: + description: 'The final status of the run. Sending this to a terminate status like SUCCEEDED or FAILED signals to meshStack that the run is complete. Send this only once.' required: false - summary: - description: 'The summary message for the final status report' + outputs_json: + description: 'A json objects with outputs of the step. All outputs in a run will be merged by meshStack.' required: false + default: '{}' runs: using: 'node20' main: 'dist/index.js' - diff --git a/dist/index.js b/dist/index.js index 7f3fc4a..8d87a31 100644 --- a/dist/index.js +++ b/dist/index.js @@ -28013,16 +28013,38 @@ const axios_1 = __importDefault(__nccwpck_require__(8757)); const fs = __importStar(__nccwpck_require__(7147)); const path = __importStar(__nccwpck_require__(1017)); const os = __importStar(__nccwpck_require__(2037)); +function parseAndValidateOutputsJson(input) { + try { + const parsed = JSON.parse(input); + if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) { + throw new Error('outputs_json must be a valid JSON object'); + } + return parsed; + } + catch (error) { + const errorMessage = `Invalid outputs_json provided: ${error instanceof Error ? error.message : 'Unknown parsing error'}. Input was: ${input}`; + core.error(errorMessage); + throw new Error(errorMessage); + } +} async function run() { try { let baseUrl; let bbRunUuid; const stepId = core.getInput('step_id'); - const status = core.getInput('status'); + const stepStatus = core.getInput('step_status'); const userMessage = core.getInput('user_message'); const systemMessage = core.getInput('system_message'); - const summary = core.getInput('summary'); - const finalStatus = core.getInput('final_status'); + const runStatus = core.getInput('run_status'); + const outputsJsonInput = core.getInput('outputs_json'); + let outputsJson; + try { + outputsJson = parseAndValidateOutputsJson(outputsJsonInput); + } + catch (error) { + core.setFailed(error instanceof Error ? error.message : 'Unknown error occurred while parsing outputs_json'); + return; + } const tempDir = process.env.RUNNER_TEMP || os.tmpdir(); core.debug(`Temporary directory: ${tempDir}`); console.log(`Temporary directory: ${tempDir}`); // This will also print the path to the console @@ -28053,15 +28075,15 @@ async function run() { return; } const data = { - status: finalStatus ? finalStatus : "IN_PROGRESS", - summary: summary + status: runStatus ? runStatus : "IN_PROGRESS", }; if (stepId) { data.steps = [{ id: stepId, - status: status, + status: stepStatus, userMessage: userMessage, - systemMessage: systemMessage + systemMessage: systemMessage, + outputs: outputsJson }]; } ; @@ -28079,6 +28101,10 @@ async function run() { catch (error) { if (error instanceof Error) { core.setFailed(error.message); + if (error.response) { + core.error(`API response status: ${error.response.status}`); + core.error(`API response data: ${JSON.stringify(error.response.data)}`); + } } else { core.setFailed('An unknown error occurred'); diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f21f9b5 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1754292888, + "narHash": "sha256-1ziydHSiDuSnaiPzCQh1mRFBsM2d2yRX9I+5OPGEmIE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ce01daebf8489ba97bd1609d185ea276efdeb121", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..04e4c79 --- /dev/null +++ b/flake.nix @@ -0,0 +1,16 @@ +{ + description = "A flake that installs Node.js"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; + + outputs = { self, nixpkgs }: + let + system = "aarch64-darwin"; # Change to your system if needed + pkgs = import nixpkgs { inherit system; }; + in { + packages.${system}.default = pkgs.nodejs; + devShells.${system}.default = pkgs.mkShell { + buildInputs = [ pkgs.nodejs ]; + }; + }; +} \ No newline at end of file diff --git a/package.json b/package.json index a437c1b..8c9fb5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "actions-send-status", - "version": "1.0.0", + "version": "2.0.0-beta.1", "main": "index.js", "scripts": { "build": "ncc build src/index.ts -o dist", diff --git a/src/index.ts b/src/index.ts index e4d9860..befe4d9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,17 +4,40 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; +function parseAndValidateOutputsJson(input: string): object { + try { + const parsed = JSON.parse(input); + if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) { + throw new Error('outputs_json must be a valid JSON object'); + } + + return parsed; + } catch (error) { + const errorMessage = `Invalid outputs_json provided: ${error instanceof Error ? error.message : 'Unknown parsing error'}. Input was: ${input}`; + core.error(errorMessage); + throw new Error(errorMessage); + } +} + async function run() { try { let baseUrl: string; let bbRunUuid: string; const stepId = core.getInput('step_id'); - const status = core.getInput('status'); + const stepStatus = core.getInput('step_status'); const userMessage = core.getInput('user_message'); const systemMessage = core.getInput('system_message'); - const summary = core.getInput('summary'); - const finalStatus = core.getInput('final_status'); + const runStatus = core.getInput('run_status'); + const outputsJsonInput = core.getInput('outputs_json') + + let outputsJson: object; + try { + outputsJson = parseAndValidateOutputsJson(outputsJsonInput); + } catch (error) { + core.setFailed(error instanceof Error ? error.message : 'Unknown error occurred while parsing outputs_json'); + return; + } const tempDir = process.env.RUNNER_TEMP || os.tmpdir(); core.debug(`Temporary directory: ${tempDir}`); @@ -49,16 +72,16 @@ async function run() { } const data: any = { - status: finalStatus ? finalStatus : "IN_PROGRESS", - summary: summary + status: runStatus ? runStatus : "IN_PROGRESS", }; if (stepId) { data.steps = [{ id: stepId, - status: status, + status: stepStatus, userMessage: userMessage, - systemMessage: systemMessage + systemMessage: systemMessage, + outputs: outputsJson }] }; @@ -81,6 +104,10 @@ async function run() { } catch (error) { if (error instanceof Error) { core.setFailed(error.message); + if ((error as any).response) { + core.error(`API response status: ${(error as any).response.status}`); + core.error(`API response data: ${JSON.stringify((error as any).response.data)}`); + } } else { core.setFailed('An unknown error occurred'); }