Skip to content

Use frozen container for package CI and keep ggalluvial optional - #107

Draft
phoman14 wants to merge 26 commits into
DEVfrom
DEV-frozen-container-ci
Draft

phoman14 wants to merge 26 commits into
DEVfrom
DEV-frozen-container-ci

Conversation

@phoman14

@phoman14 phoman14 commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Changes

Problem

SCWorkflow CI did not consistently validate the checked-out package in the runtime used by NIDAP. Some jobs rebuilt dependencies from package metadata, while others used a different container. This made it difficult to distinguish environment failures from problems in SCWorkflow itself.

The goal is to test the current source in the preserved NIDAP R 4.1.3 environment without upgrading Seurat or other existing dependencies.

Strategy

  • Freeze the runtime: use the existing rs413s Docker image pinned by immutable digest, rather than rebuild or update the base environment.
  • Add only what is missing: reuse installed packages and prepare nine version/checksum-pinned additions in an isolated library. Do not replace or shadow base packages.
  • Preserve the existing validation strategy: retain the package-check, goodpractice, lintr, coverage, Codecov, and merged-PR deployment paths wherever compatible with the frozen runtime. Do not suppress package warnings or change existing test skip policies to obtain a passing result.
  • Separate environment readiness from package correctness: fail preparation or preflight when the environment is incomplete, then report actual package-check and test results independently.

This does not require a Pixi migration, a new container build, or changes to the original SIF image.

Implementation

Environment and CI

  1. Prepare one reusable tool library. The NIDAP environment workflow downloads HTTPS source archives and verifies their checksums. The preparation script installs missing packages offline with a read-only container base, rejects base-package shadowing, and verifies that the complete base inventory is unchanged. Preparation now runs one combined preflight instead of repeating inventory and namespace checks for three modes. The resulting library and inventories are shared as the NIDAP-ci-tools artifact.
  2. Restore that library before the existing checks. All five consumer jobs use one shared setup action for artifact download, extraction, library configuration, and job-specific preflight. Package-check, lint, coverage, and Gitflow validation use the same pinned image and prepared artifact. The preflight script checks required tooling and namespace imports without installing or upgrading anything. This removes the five copied setup blocks added by this PR; existing check commands, advisory lint behavior, both coverage workflows, uploads, and failure artifacts are retained.
  3. Adapt Gitflow to the frozen runtime. The local Gitflow adapter replaces validation scripts that assume Conda and a hard-coded renv library. The original shared deployment parser remains in use for merged PRs. Review the adapter separately: push lint currently compares with the previous push instead of main, and main-PR checks explicitly fail on warnings. These are validation-policy details, not requirements of container preparation.

Package changes included alongside the environment setup

  • Declare the already-used patchwork namespace dependency in Imports; reuse the version already installed in the image.
  • Declare already-installed TSCAN, TrajectoryUtils, and mclust in Suggests. Mark the trajectory example as non-executing because its input lacks the PCA reduction it needs; this is a separate example-policy change, not an environment fix.
  • Keep ggalluvial required in Imports, add version 0.12.3 to the isolated library, use explicit namespace qualification, and add an alluvial plotting smoke test without removing existing cases. This supersedes the earlier optional-dependency approach. The nine additions are eight CI/tool dependencies plus ggalluvial.

The implementation report contains environment provenance, safety checks, reproduction steps, and the historical investigation.

Verification and review boundaries

Latest published revision: c03e74f7aebdcc2754e6fa4aa3c102f1ee41c31d (2026-10-27). Verification below comes from GitHub Actions, not local Docker.

Area Current result
Environment preparation and consumer preflights Pass; the combined preparation preflight and all five shared-action calls succeed, and the base package inventory remains unchanged.
Lint, both coverage jobs, and Gitflow validation Pass.
Package check and aggregate gate Fail; R CMD check reports 6 warnings and 6 notes. Warnings are not suppressed.
Full nested test suite Not established by these green jobs; see the discovery limitation below.

Evidence: package-check/lint/coverage run, separate coverage run, and Gitflow run.

There is a pre-existing missing standard testthat entry point under tests/, so a successful coverage job does not establish that the nested suite ran. The earlier changed-file Gitflow run executes the new comparison smoke test, but eight existing fixture tests skip on CI. The latest commit changes only CI files, so its changed-file Gitflow selection does not rerun that test. Neither test discovery nor those skip policies is changed by this environment work.

For review, separate three decisions: whether the frozen environment is correctly prepared; whether the workflow commands and Gitflow behavior preserve the intended CI policy; and whether the accompanying package metadata, plotting, and example changes are appropriate. Environment readiness is verified; full package validation is not yet passing.

Issues

No linked issue. This addresses reproducible package-CI environment readiness; dependency-metadata cleanup remains separate.

PR Checklist

(Strikethrough any points that are not applicable.)

  • This comment contains a description of changes with justifications, with any relevant issues linked.
  • Write unit tests for any new features, bug fixes, or other code changes. A focused optional-dependency regression test is included; CI preparation has executable safety checks.
  • Update the docs if there are any API changes (roxygen2 comments, vignettes, readme, etc.). No public API/signature changes; the collaborator environment report is updated.
  • Update NEWS.md with a short description of any user-facing changes and reference the PR number. Follow the style described in https://style.tidyverse.org/news.html
  • Run devtools::check() locally and fix all notes, warnings, and errors.

Keep this PR draft and unmerged. Environment readiness is distinct from full code-validation success.

@kelly-sovacool kelly-sovacool 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.

So my understanding is the new NIDAP-environment workflow uses Rich's container, then installs other development dependencies with specific frozen versions and uploads that as an artifact. This ensures that R-CMD-check and other CI workflows can run in an environment with exactly the same package versions as NIDAP, rather than installing the latest versions of packages. This approach looks reasonable.

I'm wondering how you plan to update the frozen package versions in .github/scripts/ci-tool-sources.json? I assume that file was LLM-generated. Some documentation (e.g. a section added to .github/CONTRIBUTING.md) would be helpful for you / other maintainers to be aware of the intended process.

I have several small but important suggested changes to make the files in the PR compliant with R package specs. See comments below.

Also, I created (with LLM assistance) .github/scripts/check-r-package-podman.sh so you can run R-CMD-check locally with the same environment as the CI workflows.

Comment thread docs/frozen_container_ci_report.md Resolved
Comment thread docs/session_notes.md Resolved
Comment thread CHANGELOG.md Resolved
Comment thread CHANGELOG.md Resolved
Comment thread CHANGELOG.md Resolved
Comment thread NEWS.md Resolved
@phoman14

phoman14 commented Oct 27, 2026 •

Copy link
Copy Markdown
Member Author

@kelly-sovacool Yes this is all LLM. We had played around with this a while back, trying to get CI tests to pass but we kept running into dependency errors. My prompt was to task the LLM to use the already built Container to use with Github actions so it doesn't have to build the library each time.
I have not thought long term on how i want this to work i just wanted to see if it was even possible to get past these dependency errors.
This is very much the point where i would appreciate some guidance on how to make this robust. My limited understanding on this approach that it is a short term fix, as we continue to develop and add new libraries this will be harder to maintain.

phoman14 and others added 9 commits October 27, 2026 16:17
docs: remove CI-only changelog entries

Keep the changelog focused on user-facing changes. Remove internal CI implementation details while preserving relevant release notes.

Co-authored-by: Kelly Sovacool, PhD <kelly-sovacool@users.noreply.github.com>
docs: remove internal planning notes from the changelog

Remove entries about agent-generated plans and internal investigations. Keep release notes focused on user-facing changes.

Co-authored-by: Kelly Sovacool, PhD <kelly-sovacool@users.noreply.github.com>
Run each raw-data case in a fresh callr process, preserving expectations and skip policies. Add the standard testthat runner and align local Podman checks with the pinned CI environment.

Validated all ten cases without OOM: 17 passing expectations, three skips, and five known cc.genes errors left for a separate branch. Coverage and source-loading probes pass.

This branch has not been deployed

No deployments
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