Skip to content

chore: check JIRA vars before making api calls - #876

Merged
ralphbean merged 4 commits into
mainfrom
jira-var-check
Aug 21, 2026
Merged

chore: check JIRA vars before making api calls#876
ralphbean merged 4 commits into
mainfrom
jira-var-check

Conversation

@ralphbean

Copy link
Copy Markdown
Member

This will also help with debugging when wiring up jira poller to dispatch.

This will also help with debugging when wiring up jira poller to
dispatch.

Signed-off-by: Ralph Bean <rbean@redhat.com>
@ralphbean
ralphbean requested a review from a team as a code owner August 19, 2026 01:57
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fail Fast on Missing Jira API Configuration

✨ Enhancement ⚙️ Configuration changes 🕐 Less than 5 minutes

Grey Divider

AI Description

• Checks Jira endpoint and credential variables before issuing API requests.
• Emits variable-specific errors to simplify poller and dispatch integration debugging.
Diagram

graph TD
  A["Triage operation"] --> B["Jira API helper"] --> C{"Vars present?"} -->|Yes| D["Jira API call"]
  C -->|No| E["Error and exit"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Shared Jira configuration validator
  • ➕ Applies identical checks to both Jira request helpers
  • ➕ Prevents validation behavior from drifting between call paths
  • ➕ Keeps required variable names centralized
  • ➖ Introduces a small helper abstraction for only three checks
2. Validate during script initialization
  • ➕ Reports configuration failures before any triage processing begins
  • ➕ Avoids repeating checks for multiple API calls
  • ➖ May reject workflows that load the library without making Jira requests
  • ➖ Couples initialization to runtime configuration availability

Recommendation: Use a shared validator called by both _jira_api and _jira_api_with_status. It retains request-time validation while covering every direct curl path. The base URL check should reference JIRA_BASE_URL, matching the documented variable and request URL; the introduced JIRA_JIRA_BASE_URL name would otherwise cause valid configurations to fail.

Files changed (1) +5 / -0

Other (1) +5 / -0
jira-triage-ops.lib.shValidate Jira configuration before REST requests +5/-0

Validate Jira configuration before REST requests

• Adds fail-fast checks for the Jira base URL, user email, and API token before '_jira_api' invokes curl. Each missing value produces a targeted error and exits immediately. The base URL guard currently checks 'JIRA_JIRA_BASE_URL', while the request and documentation use 'JIRA_BASE_URL'.

scripts/lib/jira-triage-ops.lib.sh

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 19, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 1:58 AM UTC · Completed 2:12 AM UTC

Commit: b135f01 · View workflow run →

@qodo-code-review

qodo-code-review Bot commented Aug 19, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (1)

Grey Divider


Action required

1. Jira guard checks wrong variable ✓ Resolved 📜 Skill insight ≡ Correctness
Description
_jira_api validates the nonexistent JIRA_JIRA_BASE_URL, while Jira setup, URL parsing, and curl
construction use JIRA_BASE_URL. Under callers' set -u, expanding the unset variable aborts
before the intended diagnostic; without nounset, the guard incorrectly reports a missing base URL
even when Jira is validly configured, preventing the API call.
Code

scripts/lib/jira-triage-ops.lib.sh[48]

+  if [[ -z "${JIRA_JIRA_BASE_URL}" ]]; then echo "ERROR: JIRA_JIRA_BASE_URL is not set"; exit 1; fi
Relevance

●●● Strong

Clear variable-name bug; recent Jira review accepted correcting configuration-variable handling.

PR-#827

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 1538315 requires guards to reference real variables and trigger at runtime, but the added guard
references JIRA_JIRA_BASE_URL while the library documents and assigns JIRA_BASE_URL and
_jira_api uses it to construct the curl URL at line 57. Both generated callers enable set -u, so
directly expanding the nonexistent variable terminates execution before the intended check can run.

scripts/lib/jira-triage-ops.lib.sh[48-57]
scripts/post-triage.src.sh[20-20]
scripts/lib/jira-triage-ops.lib.sh[15-25]
scripts/lib/jira-triage-ops.lib.sh[108-123]
scripts/lib/jira-triage-ops.lib.sh[52-58]
scripts/pre-triage.sh[17-21]
scripts/post-triage.sh[21-25]
PR-#827
Skill: code-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Jira API guard checks the nonexistent `JIRA_JIRA_BASE_URL` instead of the consumed `JIRA_BASE_URL`, preventing `_jira_api` from operating with valid configuration. Its direct expansion also cannot safely handle an unset variable when callers enable `set -u`.

## Issue Context
All Jira setup, URL parsing, and curl construction use `JIRA_BASE_URL`, and the host scripts enable nounset. Validate the correct variable and use default-value expansion so the guard can emit its intended diagnostic when configuration is absent.

## Fix Focus Areas
- scripts/lib/jira-triage-ops.lib.sh[48-50]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Bundled scripts omit Jira guards ✓ Resolved 📜 Skill insight ≡ Correctness
Description
The modified Jira library is bundled into the generated pre-triage.sh and post-triage.sh scripts
used by the triage harness, but both committed runtime bundles still call curl without the new
checks. Consequently, deployed Jira triage silently retains the old behavior, and the repository's
check-bundle target will detect the stale bundles.
Code

scripts/lib/jira-triage-ops.lib.sh[R48-50]

+  if [[ -z "${JIRA_JIRA_BASE_URL}" ]]; then echo "ERROR: JIRA_JIRA_BASE_URL is not set"; exit 1; fi
+  if [[ -z "${JIRA_USER_EMAIL}" ]]; then echo "ERROR: JIRA_USER_EMAIL is not set"; exit 1; fi
+  if [[ -z "${JIRA_TOKEN}" ]]; then echo "ERROR: JIRA_TOKEN is not set"; exit 1; fi
Relevance

●●● Strong

Bundled artifacts must be regenerated; accepted bundling and stale-bundle enforcement precedent is
directly applicable.

PR-#38

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 1538370 requires the guard to function through the complete producer-to-consumer path. The
changed library identifies itself as a source bundled into the two triage scripts, while
harness/triage.yaml selects those generated scripts and both bundled _jira_api implementations
proceed directly to curl without the new validation; the generated-file instructions require `make
script-build, and the Makefile's check-bundle` target explicitly rejects stale committed bundles.

scripts/lib/jira-triage-ops.lib.sh[3-6]
scripts/pre-triage.sh[505-516]
scripts/post-triage.sh[509-520]
Makefile[24-37]
harness/triage.yaml[86-102]
scripts/pre-triage.sh[1-2]
scripts/post-triage.sh[1-2]
Skill: pr-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Jira guard was added only to the source library without rebuilding the generated scripts used by the triage harness, so runtime Jira calls in both committed bundles still bypass the validation.

## Issue Context
The library documents that it is bundled into both triage scripts, and `harness/triage.yaml` invokes those generated files directly. The generated files require `make script-build`, while `make check-bundle` requires committed outputs to match the regenerated output.

## Fix Focus Areas
- scripts/lib/jira-triage-ops.lib.sh[48-50]
- scripts/pre-triage.sh[505-516]
- scripts/post-triage.sh[509-520]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Jira guards lack tests ✓ Resolved 📜 Skill insight ▣ Testability
Description
The PR introduces new failure behavior for three Jira configuration values without adding or
updating a test that exercises missing-variable cases and verifies that curl is not invoked. This
leaves the guard behavior—including the misspelled variable and nounset handling—unconstrained.
Code

scripts/lib/jira-triage-ops.lib.sh[R48-50]

+  if [[ -z "${JIRA_JIRA_BASE_URL}" ]]; then echo "ERROR: JIRA_JIRA_BASE_URL is not set"; exit 1; fi
+  if [[ -z "${JIRA_USER_EMAIL}" ]]; then echo "ERROR: JIRA_USER_EMAIL is not set"; exit 1; fi
+  if [[ -z "${JIRA_TOKEN}" ]]; then echo "ERROR: JIRA_TOKEN is not set"; exit 1; fi
Relevance

●●● Strong

Recent behavioral changes routinely gain regression tests, especially validation and failure-path
coverage.

PR-#757

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 1538339 requires every production behavioral change to have a corresponding test change. The
diff adds three early-exit paths to _jira_api but contains no test-file modification covering
those paths.

scripts/lib/jira-triage-ops.lib.sh[48-50]
Skill: code-implementation

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly introduced Jira configuration guards have no corresponding behavioral tests.

## Issue Context
Add tests for absent `JIRA_BASE_URL`, `JIRA_USER_EMAIL`, and `JIRA_TOKEN`. Each test should assert a nonzero result, the expected diagnostic, and that no API call occurs.

## Fix Focus Areas
- scripts/lib/jira-triage-ops.lib.sh[48-50]
- scripts/pre-triage-test.sh[1-10]
- scripts/post-triage-test.sh[1-10]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View high (1)
4. Protected script requires human approval 📜 Skill insight § Compliance
Description
This PR modifies the protected scripts/ path without a linked issue or explicit protected-path
justification. The change therefore requires human approval and must not be auto-approved.
Code

scripts/lib/jira-triage-ops.lib.sh[48]

+  if [[ -z "${JIRA_JIRA_BASE_URL}" ]]; then echo "ERROR: JIRA_JIRA_BASE_URL is not set"; exit 1; fi
Relevance

●●● Strong

Protected-path enforcement is an explicit repository convention, with recent accepted script-path
compliance precedent.

PR-#569

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 1538392 explicitly identifies scripts/ as a protected path and requires a finding whenever it
is modified. The sole changed file is under that path, while the supplied PR metadata contains no
linked issue or explicit protected-path authorization.

scripts/lib/jira-triage-ops.lib.sh[48-50]
Skill: pr-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR changes a protected infrastructure path without linked authorization or explicit justification.

## Issue Context
Document why the protected script change is necessary, link the authorizing issue or ADR, and route the PR for human approval.

## Fix Focus Areas
- scripts/lib/jira-triage-ops.lib.sh[48-50]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Issue creation bypasses checks ✓ Resolved 🐞 Bug ≡ Correctness
Description
tracker_create_issue calls _jira_api_with_status, which performs its own curl without the newly
added environment validation. Missing Jira variables therefore still produce an unbound-variable
failure or malformed request on the issue-creation path instead of the intended diagnostic.
Code

scripts/lib/jira-triage-ops.lib.sh[R48-50]

+  if [[ -z "${JIRA_JIRA_BASE_URL}" ]]; then echo "ERROR: JIRA_JIRA_BASE_URL is not set"; exit 1; fi
+  if [[ -z "${JIRA_USER_EMAIL}" ]]; then echo "ERROR: JIRA_USER_EMAIL is not set"; exit 1; fi
+  if [[ -z "${JIRA_TOKEN}" ]]; then echo "ERROR: JIRA_TOKEN is not set"; exit 1; fi
Relevance

●●● Strong

Recent Jira review accepted fixing alternate tracker paths that bypass shared behavior; this is the
same integration context.

PR-#827

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
_jira_api_with_status directly expands all three Jira variables in curl, and
tracker_create_issue invokes that wrapper rather than the newly guarded _jira_api.

scripts/lib/jira-triage-ops.lib.sh[61-76]
scripts/lib/jira-triage-ops.lib.sh[328-344]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The required Jira environment validation exists only in `_jira_api`, while `_jira_api_with_status` independently makes API calls for issue creation.

## Issue Context
Move the checks into a shared validation helper and call it from both Jira API wrappers before curl executes.

## Fix Focus Areas
- scripts/lib/jira-triage-ops.lib.sh[42-75]
- scripts/lib/jira-triage-ops.lib.sh[328-343]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Unset checks lose diagnostics ✓ Resolved 🐞 Bug ◔ Observability
Description
All three checks expand their variables as ${VAR}, so callers running with set -u terminate with
an unbound variable shell error before the custom error messages execute. This defeats the PR’s
stated debugging improvement whenever a variable is genuinely unset rather than explicitly set to an
empty string.
Code

scripts/lib/jira-triage-ops.lib.sh[R48-50]

+  if [[ -z "${JIRA_JIRA_BASE_URL}" ]]; then echo "ERROR: JIRA_JIRA_BASE_URL is not set"; exit 1; fi
+  if [[ -z "${JIRA_USER_EMAIL}" ]]; then echo "ERROR: JIRA_USER_EMAIL is not set"; exit 1; fi
+  if [[ -z "${JIRA_TOKEN}" ]]; then echo "ERROR: JIRA_TOKEN is not set"; exit 1; fi
Relevance

●●● Strong

Nounset-safe validation was explicitly accepted recently for preserving intended configuration
diagnostics.

PR-#573

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The newly added lines directly expand potentially absent environment variables, while both runtime
scripts enable set -u. A previously accepted review identified this exact validation pattern as
preventing the intended clean error handling.

scripts/pre-triage.sh[17-21]
scripts/post-triage.sh[21-25]
PR-#573

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The added required-variable checks are not safe under the calling scripts' nounset mode and therefore cannot emit their intended diagnostics for unset variables.

## Issue Context
Use default-safe expansions such as `${VAR:-}` for each validation check.

## Fix Focus Areas
- scripts/lib/jira-triage-ops.lib.sh[48-50]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 55 rules
✅ Skills: 4 invoked
  code-review
  code-implementation
  pr-review
  docs-review

Grey Divider

Tip of the day
💡 Did you know, you can tweak Display preferences with a live preview to see your comment before it ships

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread scripts/lib/jira-triage-ops.lib.sh Outdated
Comment thread scripts/lib/jira-triage-ops.lib.sh Outdated
Comment thread scripts/lib/jira-triage-ops.lib.sh Outdated
Comment thread scripts/lib/jira-triage-ops.lib.sh Outdated
Comment thread scripts/lib/jira-triage-ops.lib.sh Outdated
Comment thread scripts/lib/jira-triage-ops.lib.sh Outdated
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 19, 2026

Copy link
Copy Markdown

Review

Findings

High

  • [protected-path] scripts/ — All 5 changed files (scripts/lib/jira-triage-ops.lib.sh, scripts/post-triage-test.sh, scripts/post-triage.sh, scripts/pre-triage-test.sh, scripts/pre-triage.sh) are under scripts/, a protected path requiring human approval. This PR has no linked issue justifying the changes to governance/infrastructure files. Human review is required before merging.

Low

  • [test-inadequate] scripts/post-triage-test.sh:2100 — The credential guard tests pass an empty expected_pattern to run_jira_test, which does not verify error message content in the expect_failure path — it only checks for a non-zero exit code. By contrast, the analogous tests in pre-triage-test.sh verify the specific error message (e.g., JIRA_TOKEN must be set). A post-triage test could pass even if the script fails for an unrelated reason without detecting that the credential guard was not the cause.
    Remediation: Add error-message pattern verification to run_jira_test's expect_failure path and pass the expected error strings.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run

Review

Findings

High

  • [protected-path] scripts/lib/jira-triage-ops.lib.sh, scripts/post-triage.sh, scripts/pre-triage.sh — All three changed files reside under scripts/, a protected path that requires human approval. The PR has no linked issue providing justification for modifying governance/infrastructure files. The changes themselves — adding JIRA credential validation guards at source time and per-call JIRA_BASE_URL checks — are a sound defensive improvement with correct guard placement across all API entry points. Human sign-off is required for protected-path changes regardless of technical merit.
    Remediation: Link an issue that authorizes these changes, or obtain explicit human approval for the protected-path modifications.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (2)

Review

Findings

High

  • [protected-path] scripts/lib/jira-triage-ops.lib.sh — This file is under the scripts/ protected path. The PR has no linked issue providing authorization for modifying governance/infrastructure files. Human approval is required for protected-path changes.

Medium

  • [error-handling-idiom] scripts/lib/jira-triage-ops.lib.sh:43_jira_require_vars uses exit 1 on validation failure, but every other error path in this file and its sibling lib files (gitlab-triage-ops.lib.sh, github-triage-ops.lib.sh) uses return 1. Since this is a sourced library, exit 1 terminates the calling shell rather than letting callers handle the error, which is inconsistent with the established convention. Non-subshell callers (e.g., tracker_add_label, tracker_remove_label, tracker_strip_labels) would have their entire shell terminated rather than receiving a recoverable error.
    Remediation: Replace exit 1 with return 1 on all three guard lines in _jira_require_vars, and ensure the callers propagate the failure, e.g., _jira_require_vars || return 1.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (3)

Review

Findings

Critical

  • [logic-error] scripts/lib/jira-triage-ops.lib.sh:48 — The guard checks JIRA_JIRA_BASE_URL (doubled JIRA_ prefix), but the variable used everywhere else in the file — including the curl command on line 52, the file header documentation, and all other functions — is JIRA_BASE_URL. JIRA_JIRA_BASE_URL does not appear anywhere else in the repository. This means the guard will always trigger exit 1 when JIRA_BASE_URL is correctly set but JIRA_JIRA_BASE_URL is not, killing the calling script on every _jira_api invocation.
    Remediation: Change JIRA_JIRA_BASE_URL to JIRA_BASE_URL on line 48.

High

  • [protected-path] scripts/lib/jira-triage-ops.lib.sh — This PR modifies a file under the protected scripts/ path. The PR has no linked issue providing authorization for this change. Human approval is required for protected-path changes.

Medium

  • [error-handling-idiom] scripts/lib/jira-triage-ops.lib.sh:48 — The new guard checks emit errors to stdout via bare echo, but the established error-handling idiom in this file writes errors to stderr via >&2 (see _jira_api_with_status). Mixing stdout and stderr for error messages could cause downstream callers that capture stdout to receive error text instead of API responses.
    Remediation: Change each guard to write to stderr: echo "ERROR: ..." >&2; exit 1.

Low

  • [logic-error] scripts/lib/jira-triage-ops.lib.sh:61 — The new guards are added only to _jira_api but not to _jira_api_with_status, which uses the same environment variables. If _jira_api_with_status is called without the required variables set, the error message will be a confusing curl failure rather than a clear "variable not set" message.
    Remediation: Add the same guards (with the corrected JIRA_BASE_URL name) to _jira_api_with_status, or extract validation into a shared helper.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

Comment thread scripts/lib/jira-triage-ops.lib.sh Outdated
@ralphbean

Copy link
Copy Markdown
Member Author

/fs-fix address the open findings, please

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

🤖 Finished Fix · ✅ Success · Started 7:47 PM UTC · Completed 7:51 PM UTC

Commit: b135f01 · View workflow run →

- Fix JIRA_JIRA_BASE_URL typo → JIRA_BASE_URL in _jira_api guard
- Redirect guard error messages to stderr (>&2) to match file idiom
- Extract _jira_require_vars helper and call from both _jira_api and
  _jira_api_with_status so both API entry points validate env vars

Addresses review feedback on #876
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

🔧 Fix agent — iteration 1 (human-triggered)

Addressed all 3 review findings: fixed JIRA_JIRA_BASE_URL typo, redirected error messages to stderr, and added env var guards to _jira_api_with_status via a shared _jira_require_vars helper.

Fixed (3):

  1. JIRA_JIRA_BASE_URL typo in _jira_api guard (scripts/lib/jira-triage-ops.lib.sh): Fixed doubled JIRA_ prefix: changed JIRA_JIRA_BASE_URL to JIRA_BASE_URL to match the variable used everywhere else in the file
  2. Error messages written to stdout instead of stderr (scripts/lib/jira-triage-ops.lib.sh): Redirected guard error messages to stderr via >&2 to match the established error-handling idiom used throughout the file
  3. Missing env var guards in _jira_api_with_status (scripts/lib/jira-triage-ops.lib.sh): Extracted shared _jira_require_vars helper and called it from both _jira_api and _jira_api_with_status so both API entry points validate JIRA_BASE_URL, JIRA_USER_EMAIL, and JIRA_TOKEN before making curl calls

Tests: passed

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 19, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 7:53 PM UTC · Ended 8:08 PM UTC

Commit: 9ac6268 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review-only follow-up on the current head (9ac6268): two MEDIUM findings that are not covered by the existing threads.

Note: these anchor to lines outside this PR's diff hunks, so GitHub rejects them as inline comments; they are included here with explicit file:line references instead.


1. scripts/lib/jira-triage-ops.lib.sh:208

MEDIUM — Guard diagnostics are swallowed by 2>/dev/null at every redirecting call site — survives the exit-1 -> return-1 fix

Distinct from the already-posted exit-vs-return thread and from the already-fixed stdout->stderr issue. Even after _jira_require_vars was moved to >&2 (commit 9ac6268), five call sites redirect the helper's stderr to /dev/null, so the new diagnostic is written and immediately discarded:

  • tracker_remove_label — line 149
  • tracker_strip_labels — line 156
  • tracker_verify_labels_stripped — line 163
  • tracker_list_repo_labels — line 208
  • tracker_close_issue — line 281

This residue is not resolved by changing exit 1 to return 1 — the message is lost either way. Verified empirically with a reduced repro of the exact call shapes under set -euo pipefail:

(a) At the || true sites the script terminates with rc=1 and produces zero output — no ERROR line at all, which is the exact opposite of this PR's stated goal of helping debug jira-poller wiring.

(b) At batch=$(_jira_api GET "/label?..." 2>/dev/null) || break (line 208) the subshell dies, the message is discarded, break ends pagination, and tracker_list_repo_labels returns an empty list with rc=0. post-triage.src.sh:601 consumes that as EXISTING_LABELS, so label_exists() then reports every label as non-existent and the "will not auto-create labels" logic silently changes behavior with no diagnostic anywhere.

Confirmed that pre-triage.src.sh reaches tracker_strip_labels (line 35) as its first Jira operation, right after tracker_parse_issue_url (line 29).

Suggestion: Hoist the credential validation to script startup rather than per-call, using the idiom pre-triage.src.sh:18-20 already uses (: "${JIRA_TOKEN:?JIRA_TOKEN must be set}"), gated on the resolved FULLSEND_TRACKER being jira. That fails once, early, on an unredirected stderr, before any label mutation, and simultaneously resolves the exit-vs-return question already raised on this PR. If per-call guards are kept instead, drop the blanket 2>/dev/null at lines 149/156/163/208/281 so the credential error is visible, and make tracker_list_repo_labels distinguish "API failed" from "no labels" rather than returning empty with rc=0.


2. scripts/lib/jira-triage-ops.lib.sh:244

MEDIUMtracker_post_comment / tracker_post_sticky_comment reach the Jira API with the same credentials but bypass the new guard

New location, not covered by the existing threads (qodo finding 5 and the review bot's file-level note both concerned _jira_api_with_status / tracker_create_issue, which the fix commit already addressed).

tracker_post_comment (line 228) and tracker_post_sticky_comment (line 250) also call the Jira Cloud API — via fullsend issues post-comment --tracker jira --jira-url "${JIRA_BASE_URL}" --jira-email "${JIRA_USER_EMAIL}" --token "${JIRA_TOKEN}" at lines 244-247 and 253-256 — and never call _jira_require_vars, so the PR title's claim ("check JIRA vars before making api calls") does not hold for these paths.

I verified against the fullsend CLI source that this path does self-validate (internal/cli/tracker_client.go:63/75/120 return --jira-url or JIRA_BASE_URL required for Jira tracker, --jira-email or JIRA_USER_EMAIL required for Jira tracker (Jira Cloud auth is email+token, not a bare token), --token or JIRA_TOKEN required for Jira tracker), which is why this is MEDIUM and not HIGH: the consequence is inconsistent, differently-formatted diagnostics arriving at a different point in the run for identical missing config, not a silent bad API call.

Suggestion: Cover this with the single up-front startup validation suggested above (validate once when the jira tracker is selected), which guards every Jira path — raw curl and CLI shell-out alike — instead of adding a second per-function guard. If per-call guards are kept, add _jira_require_vars || return 1 at the top of both comment functions for consistency.

@ralphbean

Copy link
Copy Markdown
Member Author

/fs-fix

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

🤖 Finished Fix · ✅ Success · Started 5:56 PM UTC · Completed 6:05 PM UTC

Commit: 9ac6268 · View workflow run →

…funcs

Hoist JIRA_USER_EMAIL / JIRA_TOKEN validation to source time using the
: "${VAR:?msg}" idiom already established by pre-triage.src.sh and
post-triage.src.sh. This ensures the diagnostic fires once on
unredirected stderr before any call site can swallow it with
2>/dev/null — addressing the five call sites (lines 149/156/163/208/281)
where the per-call guard's message was previously discarded.

Narrow _jira_require_vars to only check JIRA_BASE_URL (which is derived
at runtime by tracker_parse_issue_url and cannot be validated at source
time), and change exit 1 to return 1 for correct subshell propagation.
Use _jira_require_vars || return 1 in all API entry points.

Add _jira_require_vars || return 1 to tracker_post_comment and
tracker_post_sticky_comment, which reach the Jira API via the fullsend
CLI and previously bypassed the credential guard entirely.

Addresses review feedback on #876
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

🔧 Fix agent — iteration 2 (human-triggered)

Addressed both review findings. Hoisted credential validation to source time to prevent diagnostics from being swallowed by 2>/dev/null at call sites. Added JIRA_BASE_URL guard to comment functions that previously bypassed validation. All triage tests pass.

Fixed (2):

  1. Guard diagnostics swallowed by 2>/dev/null at five call sites (scripts/lib/jira-triage-ops.lib.sh): Hoisted JIRA_USER_EMAIL and JIRA_TOKEN validation to source time using the : "${VAR:?msg}" idiom already used by pre-triage.src.sh and post-triage.src.sh. This fails once, early, on unredirected stderr before any call site can swallow the diagnostic with 2>/dev/null. Narrowed _jira_require_vars to only check JIRA_BASE_URL (which is derived at runtime by tracker_parse_issue_url), changed exit 1 to return 1, and used _jira_require_vars || return 1 for proper error propagation.
  2. tracker_post_comment and tracker_post_sticky_comment bypass credential guard (scripts/lib/jira-triage-ops.lib.sh): Added _jira_require_vars || return 1 to both tracker_post_comment and tracker_post_sticky_comment so the JIRA_BASE_URL check covers the fullsend CLI shell-out paths in addition to the raw curl paths.

Tests: passed

Decision points
  • Chose source-time validation over removing 2>/dev/null from call sites (alternatives: Remove 2>/dev/null from call sites, Keep per-call guard for all three vars; rationale: Source-time validation matches the existing idiom in pre-triage.src.sh/post-triage.src.sh, fails earlier with a clearer diagnostic, and avoids changing call-site error suppression that exists to hide expected curl failures (e.g., removing a label that may not exist). JIRA_BASE_URL still needs a per-call guard because it is set dynamically by tracker_parse_issue_url after the library is sourced.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 20, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:07 PM UTC · Completed 6:21 PM UTC

Commit: b6e40d4 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated multi-agent review pass (independent parallel reviewers, findings cross-checked against the current head before posting — all three reviewers independently flagged the missing negative-path test coverage).

Comment thread scripts/lib/jira-triage-ops.lib.sh
@ralphbean

Copy link
Copy Markdown
Member Author

/fs-fix Add the test case as suggested by @waynesun09

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

🤖 Finished Fix · ✅ Success · Started 2:57 PM UTC · Completed 3:04 PM UTC

Commit: b6e40d4 · View workflow run →

Add test cases for unset and empty JIRA_TOKEN / JIRA_USER_EMAIL in both
pre-triage-test.sh and post-triage-test.sh, verifying the source-time
:? guards reject missing credentials before any API call is made.

Addresses review feedback from @waynesun09 on #876.
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

🔧 Fix agent — iteration 3 (human-triggered)

Addressed @waynesun09 review feedback: added 8 negative-path test cases (4 per test file) for the Jira credential guards introduced in this PR. Tests cover both unset and empty-string scenarios for JIRA_TOKEN and JIRA_USER_EMAIL, ensuring the source-time :? guards reject missing credentials before any API call is made.

Fixed (1):

  1. New fail-fast credential guards have zero test coverage: Added 4 negative-path test cases to pre-triage-test.sh and 4 to post-triage-test.sh, covering JIRA_TOKEN unset, JIRA_TOKEN empty, JIRA_USER_EMAIL unset, and JIRA_USER_EMAIL empty. Each test verifies the source-time :? guards exit with code 1 and produce no API calls.

Tests: passed

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 21, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:06 PM UTC · Completed 3:23 PM UTC

Commit: e2ec81f · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

Comment thread scripts/post-triage-test.sh

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at head e2ec81f.

Validated the credential-guard fix empirically: ran both pre-triage-test.sh and post-triage-test.sh from a clean worktree at this exact head — all 8 new negative-path cases pass and both suites report "All tests passed". Confirmed the source-time :? guards sit inside the jira) branch of the bundled scripts, so github/gitlab tracker runs are unaffected, and that :? (colon form) rejects both unset and empty values.

Remaining nit (non-blocking, tracked in the two open threads): the post-triage cases assert only a non-zero exit, while the pre-triage cases assert the exact message plus no-mutation. Note for whoever picks it up — passing an expected_pattern alone will not fix it: run_jira_test's expect_failure branch returns before the pattern grep, so the harness needs the check added inside that branch plus an expect_no_mutation arg to match run_test.

@ralphbean
ralphbean added this pull request to the merge queue Aug 21, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 21, 2026
@ralphbean
ralphbean added this pull request to the merge queue Aug 21, 2026
Merged via the queue into main with commit 83e8280 Aug 21, 2026
38 checks passed
@ralphbean
ralphbean deleted the jira-var-check branch August 21, 2026 20:01
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 21, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ❌ Failure · Started 8:03 PM UTC · Completed 8:03 PM UTC

Commit: e2ec81f · View workflow run →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants