Skip to content

fix(coverage): detect branch on Travis CI push builds#2753

Draft
davehenton wants to merge 1 commit intomainfrom
fix/travis-push-build-branch-detection
Draft

fix(coverage): detect branch on Travis CI push builds#2753
davehenton wants to merge 1 commit intomainfrom
fix/travis-push-build-branch-detection

Conversation

@davehenton
Copy link
Copy Markdown
Member

Fixes qltysh/cloud#8231.

Summary

Fix qlty coverage publish failing on Travis CI push builds (merge commits, direct pushes to a branch) with:

ERROR
> A branch, tag, or pull request must be specified.
> Please provide it using a supported CI provider or with one of
> --override-branch, --override-git-tag, or --override-pr-number

PR builds were unaffected — only push builds hit this.

The bug

TravisCI::branch() in qlty-coverage/src/ci/travisci.rs reads:

self.env
    .var("TRAVIS_PULL_REQUEST_BRANCH")
    .or_else(|| self.env.var("TRAVIS_BRANCH"))
    .unwrap_or_default()

On a Travis push build, TRAVIS_PULL_REQUEST_BRANCH is exported as an empty string, not unset. SystemEnv::var() is std::env::var(name).ok(), which returns Some("") for set-but-empty vars — so the Option is Some(""), .or_else(...) never fires, the TRAVIS_BRANCH fallback is skipped, and branch() returns "".

With an empty branch, empty pull_number() (it's "false" on push builds), and empty git_tag(), reference_type resolves to Unspecified and validation at qlty-cli/src/commands/coverage/utils.rs aborts the upload.

PR builds work because TRAVIS_PULL_REQUEST_BRANCH is populated with the source branch, so the Some("<branch>") path returns a valid value.

Reference: Travis default environment variables.

The fix

One-line change: filter out the empty string before falling through to TRAVIS_BRANCH.

 fn branch(&self) -> String {
     self.env
         .var("TRAVIS_PULL_REQUEST_BRANCH")
+        .filter(|b| !b.is_empty())
         .or_else(|| self.env.var("TRAVIS_BRANCH"))
         .unwrap_or_default()
 }

This mirrors the pattern the same file already uses in git_tag() for TRAVIS_TAG. PR builds keep working: TRAVIS_PULL_REQUEST_BRANCH is non-empty, the filter passes it through unchanged.

Testing

  • Added branch_push_build_with_empty_pr_branch — sets TRAVIS_BRANCH=main, TRAVIS_PULL_REQUEST_BRANCH="", TRAVIS_PULL_REQUEST=false (exactly what Travis exports on a push build) and asserts branch() == "main".
  • Reproduced the bug first: ran the new test against the unfixed code and confirmed it failed with left: "" right: "main" — matching the real-world error.
  • Applied the fix, new test passes.
  • Full qlty-coverage suite passes: 255/255 tests, 0 failures.
  • Existing branch and branch_pull_request tests continue to pass, confirming no regression in the push-without-PR-var and PR-build codepaths.

On Travis push builds, `TRAVIS_PULL_REQUEST_BRANCH` is exported as
an empty string rather than being unset. `SystemEnv::var()` wraps
`std::env::var().ok()`, which returns `Some("")` for set-but-empty
vars, so the `or_else` chain in `TravisCI::branch()` never falls
back to `TRAVIS_BRANCH`. Coverage uploads from any push build
(e.g. merge commits on the default branch) then fail validation
with "A branch, tag, or pull request must be specified."

Filter out the empty string before the fallback, matching the
pattern already used by `git_tag()` for `TRAVIS_TAG`. PR builds
are unaffected because they populate `TRAVIS_PULL_REQUEST_BRANCH`
with the source branch.

Adds a regression test for the push-build case with an explicit
empty `TRAVIS_PULL_REQUEST_BRANCH`.
@qltysh
Copy link
Copy Markdown
Contributor

qltysh bot commented Apr 13, 2026

Qlty

Coverage Impact - ubuntu-latest

This PR will not change total coverage.

Modified Files with Diff Coverage (1)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
qlty-coverage/src/ci/travisci.rs100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@qltysh
Copy link
Copy Markdown
Contributor

qltysh bot commented Apr 13, 2026

Qlty

Coverage Impact - macos-15

This PR will not change total coverage.

Modified Files with Diff Coverage (1)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
qlty-coverage/src/ci/travisci.rs100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

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