thunderbird / thunderbird/github-action-thunderbird-aaq

Orchestrator swallowed fetch exit code, so JS-challenge runs reported success

Open
#33 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Ruby
Stars
0
Forks
2
PR merge metrics
No merged PRs in 30d

Description

Problem

When the fetch scripts abort on a detected JavaScript/bot challenge (#31, exit 1), the GitHub Actions run still reported success and refreshed no data — see commit 6d85b31a88, where a run logged 3 challenges to javascript-challenges.log yet the workflow was green.

Root cause: the orchestrator get_answers_for_last_2_days_and_1_of_last_12.rb (what the cron workflows run) invoked each fetch via system(...) and ignored the return value:

update_questions_for_yyyymmdd(today.year, today.month, today.day)
update_answers_for_yyyymmdd(today.year, today.month, today.day)

system returns false on a non-zero child exit and nil when it can't run, but nothing checked it, so the orchestrator always exited 0. This defeated #31's intent ("abort the day's run with a non-zero exit so the failure is visible").

Fix (done in cde78aa1ba)

Check each system(...) result and abort on the first failure. The update_* helpers already return the system value (because Dir.chdir returns its block's value), so a guard wraps each call:

def abort_unless_ok(ok)
  return if ok

  warn 'fetch failed (JavaScript/bot challenge or other error); aborting run'
  exit 1
end

abort_unless_ok update_questions_for_yyyymmdd(today.year, today.month, today.day)
abort_unless_ok update_answers_for_yyyymmdd(today.year, today.month, today.day)
abort_unless_ok update_questions_for_yyyymmdd(day_to_refresh.year, day_to_refresh.month, day_to_refresh.day)
abort_unless_ok update_answers_for_yyyymmdd(day_to_refresh.year, day_to_refresh.month, day_to_refresh.day)

Now a challenge exit 1system returns false → orchestrator exit 1 → the workflow step fails (CI red). The empty-CSV "command to re-run" path in the fetch scripts exits 0, so it stays non-fatal — only a real challenge (or a script that can't run) aborts.

How the three pieces compose on a challenge:

  1. Fetch script detects HTML-instead-of-JSON → appends to javascript-challenges.logexit 1 (before any CSV write, so good data is preserved).
  2. Orchestrator sees system returned false → exit 1.
  3. Workflow step fails → CI red, and the if: always() commit step (#32) still commits the log line.

Tradeoff

CI now goes red on every run that hits a challenge, including intermittent ones. That is the intended "visible failure" behavior; if challenges turn out to be frequent the noise can be revisited (e.g. run-all-then-fail instead of abort-on-first).

Related

  • #31 (detection + logging)
  • #32 (commit the audit log even on failed runs, via if: always())

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The fix is already recorded in commit cde78aa1ba in get_answers_for_last_2_days_and_1_of_last_12.rb; start by reviewing the four update_* calls and their system return handling. Verify that a failed fetch propagates a non-zero exit to the GitHub Actions workflow while the empty-CSV path remains non-fatal.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, ruby
Domain
ci-cd
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.