Skip to content

Retry Bioconductor R-package installs to survive transient SSL blips - #196

Open
GuyTeichman wants to merge 1 commit into
developmentfrom
fix/ci-r-install-retry
Open

Retry Bioconductor R-package installs to survive transient SSL blips#196
GuyTeichman wants to merge 1 commit into
developmentfrom
fix/ci-r-install-retry

Conversation

@GuyTeichman

Copy link
Copy Markdown
Owner

Summary

  • CI job build (macos-latest, 3.12) (run 30758840006, job 91525659929) flaked on tests/test_differential_expression.py::TestDESeqRunner::test_run_deseq2_analysis with ChildProcessError: ... could not find function "DESeqDataSetFromMatrix".
  • Root cause: BiocManager::install("DESeq2", ...) in deseq2_install.R downloads ~30 transitive Bioconductor/CRAN dependencies with no retry. A single transient SSL connect error on one dependency (Biobase, downloaded from bioconductor.org) only produces an R warning, not an error, so BiocManager::install() does not raise and the install script still exits 0 with DESeq2 partially installed. The next script (deseq2_run_parametric.R) does require("DESeq2"), which silently returns FALSE instead of halting, so execution proceeds and only fails much later at DESeqDataSetFromMatrix() with a misleading "could not find function" error, surfaced to Python as ChildProcessError in rnalysis/utils/io.py.
  • Fix: deseq2_install.R, limma_install.R, and rsubread_install.R now retry the BiocManager::install() call up to 5 times with a 15s backoff (mirroring the existing dl() retry wrapper used for the kallisto/bowtie2 downloads in build_ci.yml), verifying via require(pkg, quietly = TRUE) that the package actually loads before declaring success. Also raises R's default download timeout (60s -> 300s) for slow/degraded connections.
  • This lives in the R install templates (not just CI config), so real users hitting the same flaky-network install path on first use of DESeq2/limma/Rsubread benefit too, not just CI.
  • No change to installed package versions, to installs.py's existing user-facing error messages/exception types, or to any serialized format.

Test plan

  • conda run --no-capture-output -n rnalysis python -m pytest tests/test_differential_expression.py -k "not test_run_deseq2_analysis and not test_run_limma_analysis" — 22 passed (golden-file script-generation tests untouched by this change).
  • conda run --no-capture-output -n rnalysis python -m pytest tests/test_installs.py -k "not test_install_limma and not test_install_deseq2 and not test_install_rsubread" — 13 passed.
  • pytest --collect-only on both modules — no collection errors.
  • Manually verified brace/paren balance and reviewed the R syntax of the three edited templates line by line.
  • Could NOT verify locally: this repo's local dev environment has no R, kallisto, or bowtie2 installed (and no network access to Bioconductor), so the actual Rscript execution of the modified install templates, and the real test_run_deseq2_analysis / test_install_deseq2 / test_install_limma / test_install_rsubread integration tests, could not be run. These will only be exercised for real by CI. I could not reproduce the transient SSL failure to confirm the retry fires in practice; the fix is based on careful reading of the BiocManager/R warning-vs-error semantics observed in the failing job's captured log.

🤖 Generated with Claude Code

https://claude.ai/code/session_016f1K2LQyVMdofggdMAEp9y

CI job build (macos-latest, 3.12) flaked in
tests/test_differential_expression.py::TestDESeqRunner::test_run_deseq2_analysis
with a confusing "could not find function DESeqDataSetFromMatrix" error.

Root cause: BiocManager::install("DESeq2", ...) in deseq2_install.R downloads
~30 transitive Bioconductor/CRAN dependencies via download.file(), with no
retry. A single transient SSL connect error on one dependency (Biobase) only
emits a warning -- it does not make BiocManager::install() raise -- so the
install script still exits 0 with DESeq2 partially installed. The next R
script (deseq2_run_parametric.R) does `require("DESeq2")`, which silently
returns FALSE instead of halting, so the script proceeds and only fails much
later at DESeqDataSetFromMatrix() with a misleading "could not find function"
error surfaced to Python as ChildProcessError (rnalysis/utils/io.py).

Fix deseq2_install.R, limma_install.R, and rsubread_install.R to retry the
BiocManager::install() call up to 5 times with a 15s backoff (mirroring the
dl() retry wrapper already used for kallisto/bowtie2 downloads in
build_ci.yml), verifying via require(pkg, quietly=TRUE) that the package
actually loads before declaring success. Also raise R's default download
timeout to 300s. This lives in the R templates (not just CI config) so real
users hitting the same flaky-network install path benefit too, with no
change to installed package versions or to installs.py's existing
user-facing error messages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016f1K2LQyVMdofggdMAEp9y
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