Skip to content

fix(branch-suggestion): output critical JSON issue on JIRA error and add missing tests#120

Open
probelabs[bot] wants to merge 18 commits intomainfrom
fix/TT-17120-branch-suggestion-critical-error
Open

fix(branch-suggestion): output critical JSON issue on JIRA error and add missing tests#120
probelabs[bot] wants to merge 18 commits intomainfrom
fix/TT-17120-branch-suggestion-critical-error

Conversation

@probelabs
Copy link
Copy Markdown

@probelabs probelabs Bot commented May 1, 2026

Problem / Task

Resolves TT-17120

When the JIRA_TOKEN is misconfigured or invalid, the branch suggestion workflow fails but Visor exits with code 0 because the severity is only 'error'. This causes the GitHub Action to succeed even though the PR comment is not posted.

Additionally, the error handling conflated two distinct failure modes: a JIRA API/configuration error and a ticket having no 'fix versions'. Treating both as a critical failure is architecturally unsound. An API error is a genuine critical failure, but a ticket without a fix version might be a valid, non-blocking state.

The workflow was also timing out because the timeout values were set to 90 and 30, which Visor interprets as milliseconds.

Changes

  • Updated branch_suggestion.yml to output a JSON issue with severity: "critical" when the JIRA API fails.
  • Changed the exit code for "no fix versions found" to 3 in get-fixedversion.js.
  • Updated branch_suggestion.yml to handle exit code 3 by outputting a JSON issue with severity: "info".
  • Updated the post-pr-comment step to gracefully skip instead of failing when the markdown file is missing (since analyze-and-suggest might exit early with info severity).
  • Added tags: ["remote"] to the analyze-and-suggest check in branch_suggestion.yml so it runs when Visor is executed with --tags remote.
  • Updated timeout values in branch_suggestion.yml from 90 to 90000 and 30 to 30000 to fix the timeout issue.

Testing

  • Ran npm test in branch-suggestion directory and all tests passed.

@probelabs
Copy link
Copy Markdown
Author

probelabs Bot commented May 1, 2026

This PR overhauls error handling in the branch-suggestion workflow to prevent silent failures and provide clearer, structured feedback. It addresses an issue where a JIRA configuration error would not fail the GitHub Action, and it refines the logic to distinguish between critical API errors and non-critical informational states.

Files Changed Analysis

  • Workflow Configuration (.github/workflows/branch-suggestion.yml, branch-suggestion/branch_suggestion.yml): The core workflow logic is updated to handle new exit codes from its scripts. It now correctly interprets a JIRA API failure as a critical issue and a ticket without "fix versions" as an info issue. Timeouts have been corrected from milliseconds to the intended seconds (e.g., 90 to 90000), and the JIRA authentication method was updated to use a raw token plus an email instead of a pre-encoded token. The post-pr-comment step is now more resilient, exiting gracefully if no suggestion file is created.
  • JIRA Scripts (branch-suggestion/scripts/jira/): get-fixedversion.js has been modified to use distinct exit codes: 1 for critical API/config errors and 3 for tickets found with no fix versions. jira-api.js has been refactored to handle the new authentication scheme and improve testability.
  • Testing (branch-suggestion/scripts/jira/__tests__/): Test coverage has been significantly increased. get-fixedversion.test.js is expanded to cover the new exit code logic, and a new test file, jira-api.test.js, has been added to validate the JIRA API client. The bulk of the 506 added lines are from these new tests.
  • Documentation (README.md, .github/workflows/example-usage.yml.template): The documentation has been updated to reflect the new JIRA_USER_EMAIL and JIRA_TOKEN secrets, simplifying the setup process for users.

Architecture & Impact Assessment

  • What this PR accomplishes: It makes the branch-suggestion workflow more robust and observable by introducing structured error handling. This prevents silent failures and provides clear, machine-readable JSON output that distinguishes between critical and informational events.
  • Key technical changes introduced: The primary architectural change is the use of distinct script exit codes to signal different outcomes. This allows the calling workflow to react appropriately—failing the build on a critical error while only logging an informational message for non-blocking cases. The JIRA authentication mechanism was also simplified from a user perspective.
  • Affected system components: The changes are primarily contained within the branch-suggestion action. Consumers of this reusable workflow will benefit from more reliable execution and clearer feedback without needing to change their own configurations, though they should adopt the new, simpler secret format as documented.

Workflow Error Handling Flow

sequenceDiagram
    participant Workflow as analyze-and-suggest
    participant Script as get-fixedversion.js
    participant JIRA as JIRA API

    Workflow->>Script: Execute script
    Script->>JIRA: API Call to get ticket

    alt JIRA API/Config Error
        JIRA-->>Script: Failure (e.g., 401 Unauthorized)
        Script-->>Workflow: Exit Code 1
        Workflow-->>Workflow: Output critical JSON issue & exit 0
    else No Fix Versions Found
        JIRA-->>Script: Success (ticket data w/o versions)
        Script-->>Workflow: Exit Code 3
        Workflow-->>Workflow: Output info JSON issue & exit 0
    else Success
        JIRA-->>Script: Success (ticket with versions)
        Script-->>Workflow: Exit Code 0
        Workflow-->>Workflow: Continue to generate suggestions
    end
Loading

Scope Discovery & Context Expansion

  • The impact of this change is localized to the branch-suggestion action but improves the reliability for all repositories that use it. By preventing silent failures, it enhances the overall stability of the CI/CD pipeline for its consumers.
  • The pattern of using specific exit codes and emitting structured JSON is a robust error-handling strategy that could be standardized across other scripted actions in the repository to create a consistent and observable system for CI feedback.
  • The addition of comprehensive tests for the JavaScript files not only validates the current changes but also improves the long-term maintainability of the action.
Metadata
  • Review Effort: 3 / 5
  • Primary Label: bug

Powered by Visor from Probelabs

Last updated: 2026-05-01T21:16:42.924Z | Triggered by: pr_updated | Commit: 33ac612

💡 TIP: You can chat with Visor using /visor ask <your question>

@probelabs
Copy link
Copy Markdown
Author

probelabs Bot commented May 1, 2026

✅ Security Check Passed

No security issues found – changes LGTM.

✅ Architecture Check Passed

No architecture issues found – changes LGTM.

✅ Security Check Passed

No security issues found – changes LGTM.

\n\n

✅ Architecture Check Passed

No architecture issues found – changes LGTM.

\n\n

Performance Issues (1)

Severity Location Issue
🟡 Warning branch-suggestion/scripts/jira/jira-api.js:38-46
The JIRA authentication header is generated on every call to the `jiraAPI` function. This involves reading environment variables and performing a Base64 encoding. While the performance impact is minimal in the primary workflow where the function is called only once, it's an unnecessary repeated computation. In other contexts, like the interactive pagination loop within this same file, this function is called multiple times, leading to redundant work.
💡 SuggestionCache the computed authentication header in a module-level variable to ensure the work is only done once per script execution. This improves efficiency and follows best practices.
let authHeader;

// Make JIRA API request
async function jiraAPI(endpoint, options = {}) {
  if (!authHeader) {
    const token = process.env.JIRA_TOKEN;
    const email = process.env.JIRA_USER_EMAIL;
    if (!token || !email) {
      throw new Error(&#39;JIRA_TOKEN and JIRA_USER_EMAIL must be set in environment variables&#39;);
    }
    authHeader = Buffer.from(`${email}:${token}`).toString(&#39;base64&#39;);
  }
  
  const response = await fetch(`${JIRA_BASE_URL}/rest/api/3${endpoint}`, {
    ...options,
    headers: {
      &#39;Authorization&#39;: `Basic ${authHeader}`,
      &#39;Content-Type&#39;: &#39;application/json&#39;,
    },
  });
  // ... rest of the function

✅ Quality Check Passed

No quality issues found – changes LGTM.


Powered by Visor from Probelabs

Last updated: 2026-05-01T21:16:02.497Z | Triggered by: pr_updated | Commit: 33ac612

💡 TIP: You can chat with Visor using /visor ask <your question>

@probelabs probelabs Bot force-pushed the fix/TT-17120-branch-suggestion-critical-error branch from c93b897 to 7bd153a Compare May 1, 2026 15:36
@probelabs probelabs Bot force-pushed the fix/TT-17120-branch-suggestion-critical-error branch from 98f9d84 to 33ac612 Compare May 1, 2026 21:14
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.

1 participant