diff --git a/.github/actions/json-key-value-lookup-action/README.md b/.github/actions/json-key-value-lookup-action/README.md new file mode 100644 index 0000000..3540efb --- /dev/null +++ b/.github/actions/json-key-value-lookup-action/README.md @@ -0,0 +1,75 @@ + + +# 🔑 JSON Variable Key/Value Lookup + +Action to perform a lookup from a JSON string containing a simple array of +key/value pairs. + +## json-key-value-lookup-action + +## Usage Example + +Pass a JSON string as an input to the action, along with the key to lookup. +The action will return the corresponding value, using JQ to pass the JSON. + +```yaml +- name: "Get ticket reference from JSON lookup table" + uses: lfit/releng-reusable-workflows/.github/actions/json-key-value-lookup-action@main + with: + json: ${{ inputs.issue_id_lookup_json }} + key: ${{ env.key }} +``` + +## Example JSON Variable + +Provide JSON as an array containing simple key/value pairs, as shown below. + +```json +[ + { "key": "dependabot[bot]", "value": "CIMAN-33" }, + { "key": "John Doe", "value": "CIMAN-1000" } +] +``` + +In the example above, the repository has a variable configured called: ISSUE_ID_LOOKUP_JSON + +Set/define this under: + +[ Github Repository ] -> Settings -> Secrets and variables -> Actions -> Variables + +## Inputs + +The action does not have any default values and both input parameters are mandatory. + +| Variable Name | Required | Description | +| ------------- | -------- | ------------------------------------------ | +| JSON | True | JSON dictionary containing key/value pairs | +| KEY | True | Key to use to extract corresponding value | +| DEFAULT | False | Default value in the event lookup fails | + +### Note 🗒️ + +In the event of a lookup failure, the action will exit with an error. Specifying +a default value will prevent this failure from taking place, allowing the calling +action/workflow to take alternative action, preventing the failure from +stopping the entire pipeline. + +## Outputs + +| Variable Name | Description | +| ------------- | ------------------------------------------------------ | +| VALUE | The value corresponding to the key (provided as input) | + +## Requirements/Dependencies + +Ensure validated JSON (in the format specified above) is in the variable. +The action performs validation before the lookup and will otherwise throw +an error. + +If the key is not represented in the lookup table, the action will exit with an +error. This behaviour will result in the calling action/workflow failing. +Prevent this by setting a default return value, allowing upstream code to take +alternative paths. diff --git a/.github/actions/json-key-value-lookup-action/action.yaml b/.github/actions/json-key-value-lookup-action/action.yaml new file mode 100644 index 0000000..21809a2 --- /dev/null +++ b/.github/actions/json-key-value-lookup-action/action.yaml @@ -0,0 +1,79 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2024 The Linux Foundation + +name: "🔑 JSON Variable Key/Value Lookup" + +inputs: + JSON: + description: "The JSON key/value lookup table" + type: string + required: true + KEY: + description: "The JSON key requiring lookup" + type: string + required: true + DEFAULT: + # Can be used to prevent exit/error if lookup fails + description: "Default value to return if lookup fails" + type: string + required: false + +outputs: + VALUE: + description: "The value associated with the supplied key" + value: ${{ steps.lookup.outputs.value }} + +runs: + using: "composite" + steps: + - name: "JSON Variable Key/Value Lookup" + id: lookup + shell: bash + run: | + # JSON Variable Key/Value Lookup + + echo "### 🔑 JSON Variable Key/Value Lookup" >> "$GITHUB_STEP_SUMMARY" + + KEY="${{ inputs.key }}" + DEFAULT="${{ inputs.default }}" + + # Validate that input variables are populated + if [ -z "${{ inputs.json }}" ]; then + echo "Error: variable/JSON string was NOT passed as input ❌" + exit 1 + elif [ -z "$KEY" ]; then + echo "Error: required lookup key was NOT passed as input ❌" + exit 1 + fi + + # Ensure JSON parser/binary is available + JQ=$(which jq || true) + if [ ! -x "$JQ" ]; then + echo "Error: jq command was NOT found in the PATH ❌"; exit 1 + fi + + # Check that string parses as valid JSON + if (jq -re '""' <<< '${{ inputs.json }}' 2>&1); then + echo "JSON parsing successful ✅" + else + echo "Error: jq command was NOT able to parse JSON ❌"; exit 1 + fi + + echo "Key to lookup: $KEY 🔑" + + VALUE=$(echo '${{ inputs.JSON }}' | \ + jq -r --arg KEY "$KEY" '.[] | select(.key==$KEY) | .value') + if [ -z "$VALUE" ] && [ -z "$DEFAULT" ]; then + # If no default return value provided, throw a fatal error + echo "Key/value lookup failed ❌"; exit 1 + elif [ -z "$VALUE" ]; then + echo "Key/value lookup failed ⚠️" + VALUE="$DEFAULT" + fi + + echo "Returning value: $VALUE 💬" + echo "value=$VALUE" >> "$GITHUB_ENV" + echo "value=$VALUE" >> "$GITHUB_OUTPUT" + echo "Key to lookup: ${{ inputs.key }}" >> "$GITHUB_STEP_SUMMARY" + echo "Value returned: $VALUE" >> "$GITHUB_STEP_SUMMARY"