Skip to content

Spell check workflow fails silently due to bash errexit behavior #278

@WilliamBerryiii

Description

@WilliamBerryiii

Summary

The spell-check CI workflow silently passes even when cspell detects spelling errors, allowing PRs with misspellings to merge.

Evidence

PR #250 introduced codecov.yml containing the word "carryforward" which was not in the dictionary. The CI artifact confirms cspell detected the error:

codecov.yml:25:5 - Unknown word (carryforward)
CSpell: Files checked: 73, Issues found: 1 in 1 file.

The CI log shows cspell exited with code 1:

##[error]Process completed with exit code 1.

Yet the "Fail job if errors found" step was skipped and the job passed.

Root Cause

The workflow in .github/workflows/spell-check.yml has this step:

- name: Run spell check
  run: |
    npm run spell-check > logs/spell-check-results.txt 2>&1
    EXIT_CODE=$?
    if [ $EXIT_CODE -ne 0 ]; then
      echo "SPELL_CHECK_FAILED=true" >> $GITHUB_ENV
    fi
    cat logs/spell-check-results.txt
    exit $EXIT_CODE
  continue-on-error: true

GitHub Actions runs bash with -e (errexit) by default. When npm run spell-check returns exit code 1:

  1. bash immediately terminates the script block due to set -e
  2. EXIT_CODE=$? is never executed
  3. SPELL_CHECK_FAILED=true is never written to $GITHUB_ENV
  4. continue-on-error: true marks the step as "success"
  5. The later "Fail job if errors found" step checks env.SPELL_CHECK_FAILED == 'true' which is unset → condition is false → step is skipped
  6. Job passes despite the spelling error

Proposed Fix

Disable errexit before the command that may fail:

- name: Run spell check
  run: |
    set +e  # Disable errexit for exit code capture
    npm run spell-check > logs/spell-check-results.txt 2>&1
    EXIT_CODE=$?
    set -e  # Re-enable errexit
    if [ $EXIT_CODE -ne 0 ]; then
      echo "SPELL_CHECK_FAILED=true" >> $GITHUB_ENV
    fi
    cat logs/spell-check-results.txt
    exit $EXIT_CODE
  continue-on-error: true

Alternative: Use command grouping to capture exit code without triggering errexit:

npm run spell-check > logs/spell-check-results.txt 2>&1 || EXIT_CODE=$?
EXIT_CODE=${EXIT_CODE:-0}

Acceptance Criteria

  • Spell check step correctly sets SPELL_CHECK_FAILED=true when cspell finds errors
  • "Fail job if errors found" step executes and fails the job when errors exist
  • Verify fix by running workflow against a file with intentional misspelling

Additional Context

This same pattern may exist in other workflows. Consider auditing:

  • .github/workflows/markdown-lint.yml
  • .github/workflows/table-format-check.yml
  • Any workflow using continue-on-error: true with deferred failure logic

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingciContinuous integrationgood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions