diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d87d1a2..cadd4e0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -272,3 +272,48 @@ jobs: fi grep -q "must be a valid JSON array" "$OUTPUT" rm -f "$OUTPUT" + + - name: 'Test: warning_days non-integer value' + shell: bash + run: | + OUTPUT=$(mktemp) + EXIT=0 + INPUT_CERTIFICATES='["tests/fixtures/valid.pem"]' \ + INPUT_WARNING_DAYS=abc \ + bash validate.sh > "$OUTPUT" 2>&1 || EXIT=$? + if [[ "$EXIT" -ne 1 ]]; then + echo "::error::Expected exit code 1 for non-integer warning_days, got $EXIT" + cat "$OUTPUT" + exit 1 + fi + grep -q "positive integer" "$OUTPUT" + rm -f "$OUTPUT" + + - name: 'Test: warning_days zero' + shell: bash + run: | + OUTPUT=$(mktemp) + EXIT=0 + INPUT_CERTIFICATES='["tests/fixtures/valid.pem"]' \ + INPUT_WARNING_DAYS=0 \ + bash validate.sh > "$OUTPUT" 2>&1 || EXIT=$? + if [[ "$EXIT" -ne 1 ]]; then + echo "::error::Expected exit code 1 for warning_days=0, got $EXIT" + cat "$OUTPUT" + exit 1 + fi + grep -q "positive integer" "$OUTPUT" + rm -f "$OUTPUT" + + - name: 'Test: GITHUB_STEP_SUMMARY unset' + shell: bash + run: | + EXIT=0 + ( unset GITHUB_STEP_SUMMARY + INPUT_CERTIFICATES='["tests/fixtures/valid.pem"]' \ + INPUT_WARNING_DAYS=30 \ + bash validate.sh ) || EXIT=$? + if [[ "$EXIT" -ne 0 ]]; then + echo "::error::Expected exit code 0 when GITHUB_STEP_SUMMARY is unset, got $EXIT" + exit 1 + fi diff --git a/README.md b/README.md index 0fe89ca..5e93666 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,8 @@ See the [`examples/`](examples/) directory for ready-to-use workflow files. ## Requirements - Runner must have `openssl` and `jq` installed (both are available by default on `ubuntu-latest` and `macos-latest` GitHub-hosted runners) +- The action checks for both tools at startup and exits with a clear `::error::` message if either is missing +- Safe to run locally or with [`act`](https://github.com/nektos/act): when `GITHUB_STEP_SUMMARY` is unset the Step Summary block is silently skipped — all other output and exit codes remain stable --- diff --git a/validate.sh b/validate.sh index 7dc55c1..b695fa2 100644 --- a/validate.sh +++ b/validate.sh @@ -17,10 +17,19 @@ set -uo pipefail +# ------------------------------------------------------- +# Tool availability check — fail fast with a clear message +# ------------------------------------------------------- +for tool in openssl jq; do + if ! command -v "$tool" &>/dev/null; then + echo "::error::Required tool '$tool' is not installed on this runner." + exit 1 + fi +done + INPUT_CERTIFICATES="${INPUT_CERTIFICATES:?'INPUT_CERTIFICATES environment variable is required'}" INPUT_WARNING_DAYS="${INPUT_WARNING_DAYS:-30}" INPUT_FAIL_ON_WARN="${INPUT_FAIL_ON_WARN:-false}" -GITHUB_STEP_SUMMARY="${GITHUB_STEP_SUMMARY:-/dev/null}" GITHUB_OUTPUT="${GITHUB_OUTPUT:-/dev/null}" FAIL_ON_WARN="${INPUT_FAIL_ON_WARN,,}" @@ -29,8 +38,8 @@ if [[ "$FAIL_ON_WARN" != "true" && "$FAIL_ON_WARN" != "false" ]]; then exit 1 fi -if [[ ! "$INPUT_WARNING_DAYS" =~ ^[0-9]+$ ]]; then - echo "::error::INPUT_WARNING_DAYS must be a non-negative integer, got: '$INPUT_WARNING_DAYS'" +if ! [[ "$INPUT_WARNING_DAYS" =~ ^[0-9]+$ ]] || [[ "$((10#$INPUT_WARNING_DAYS))" -eq 0 ]]; then + echo "::error::warning_days must be a positive integer, got: '$INPUT_WARNING_DAYS'" exit 1 fi @@ -260,28 +269,30 @@ echo "" # ------------------------------------------------------- # Write summary to GitHub Step Summary for a nice UI table # ------------------------------------------------------- -{ - echo "## 🔐 Certificate Validation Summary" - echo "" - echo "| Certificate | Status |" - echo "|-------------|--------|" - for row in "${SUMMARY_ROWS[@]}"; do - echo "$row" - done - echo "" - if [[ $FAIL_COUNT -gt 0 ]]; then - echo "> ❌ **$FAIL_COUNT certificate(s) FAILED validation with no valid replacement.**" - elif [[ $WARN_COUNT -gt 0 ]]; then - echo "> ⚠️ **$WARN_COUNT certificate(s) are nearing expiry with no newer replacement.**" - else - echo "> ✅ **All certificate(s) are valid (or have valid replacements).**" - fi - echo "" - echo "| Metric | Count |" - echo "|--------|-------|" - echo "| Failed | $FAIL_COUNT |" - echo "| Warnings | $WARN_COUNT |" -} >> "$GITHUB_STEP_SUMMARY" +if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then + { + echo "## 🔐 Certificate Validation Summary" + echo "" + echo "| Certificate | Status |" + echo "|-------------|--------|" + for row in "${SUMMARY_ROWS[@]}"; do + echo "$row" + done + echo "" + if [[ $FAIL_COUNT -gt 0 ]]; then + echo "> ❌ **$FAIL_COUNT certificate(s) FAILED validation with no valid replacement.**" + elif [[ $WARN_COUNT -gt 0 ]]; then + echo "> ⚠️ **$WARN_COUNT certificate(s) are nearing expiry with no newer replacement.**" + else + echo "> ✅ **All certificate(s) are valid (or have valid replacements).**" + fi + echo "" + echo "| Metric | Count |" + echo "|--------|-------|" + echo "| Failed | $FAIL_COUNT |" + echo "| Warnings | $WARN_COUNT |" + } >> "$GITHUB_STEP_SUMMARY" +fi # ------------------------------------------------------- # Emit outputs for programmatic use