From 140e48d1905b0dac88f9f99112b2530c8e740ef8 Mon Sep 17 00:00:00 2001 From: ch99l Date: Thu, 30 Jul 2026 20:13:49 +0800 Subject: [PATCH 1/2] visium-hd-clean-docker --- .github/workflows/build_container.yml | 158 +++++++++++------- bin/create_seurat_object.R | 14 ++ conf/base.config | 2 +- conf/containers.config | 3 +- containers/{r => bambu}/Dockerfile | 14 +- containers/seurat/Dockerfile | 11 ++ main.nf | 9 +- .../shared/cluster_level_quantification.nf | 2 +- modules/bambu/shared/construct_read_class.nf | 2 +- modules/bambu/shared/prepare_annotation.nf | 2 +- .../standard/single_cell_quantification.nf | 2 +- .../bambu/standard/transcript_discovery.nf | 10 +- modules/bambu/visium_hd/aggregate_bins.nf | 8 +- .../visium_hd/spot_level_quantification.nf | 2 +- .../bambu/visium_hd/transcript_discovery.nf | 2 +- .../standard/multi_sample_clustering.nf | 29 ++-- .../standard/single_sample_clustering.nf | 22 +-- modules/seurat/visium_hd/clustering.nf | 15 +- subworkflows/clustering_standard.nf | 12 +- 19 files changed, 192 insertions(+), 127 deletions(-) create mode 100755 bin/create_seurat_object.R rename containers/{r => bambu}/Dockerfile (71%) create mode 100644 containers/seurat/Dockerfile diff --git a/.github/workflows/build_container.yml b/.github/workflows/build_container.yml index 1b97a6a..6907417 100644 --- a/.github/workflows/build_container.yml +++ b/.github/workflows/build_container.yml @@ -1,13 +1,16 @@ -name: Build R container +name: Build R containers -# The image tag is read from conf/containers.config, so that single line is both what the -# pipeline pulls and what this workflow publishes -- the two cannot drift. -# Runs on pushes to a feature branch, whenever the container changes. +# The image tag of the container is read from conf/containers.config, so that the tag is +# what the pipeline pulls and what this workflow publishes. Each container is built independently, +# so updating one tag in conf/containers.config rebuilds only that image: +# feature branch - rebuilds its tag on every push, unless main or devel is pinned to that tag +# main or devel - builds only a tag that has never been published, so most merges are a no-op +# manual run - 'force' rebuilds and overwrites the tag on any branch on: push: paths: - - 'containers/r/**' + - 'containers/**' - 'conf/containers.config' - '.github/workflows/build_container.yml' workflow_dispatch: @@ -22,81 +25,116 @@ concurrency: cancel-in-progress: true jobs: - build: - name: Build and publish + discover: + name: Select containers to build runs-on: ubuntu-latest permissions: contents: read - packages: write + packages: read + outputs: + containers: ${{ steps.select.outputs.containers }} steps: - uses: actions/checkout@v4 - - name: Resolve image from conf/containers.config - id: image - run: | - IMAGE=$(sed -n "s|.*withLabel: *'r'.*container *= *\"\([^\"]*\)\".*|\1|p" conf/containers.config) - if [ -z "$IMAGE" ]; then - echo "::error::could not parse the 'r' container from conf/containers.config" - exit 1 - fi - case "$IMAGE" in - ghcr.io/goekelab/*) ;; - *) echo "::error::refusing to push outside ghcr.io/goekelab: $IMAGE"; exit 1 ;; - esac - echo "image=$IMAGE" >> "$GITHUB_OUTPUT" - echo "Resolved container: $IMAGE" - - - name: Refuse to overwrite a tag main or devel is pinned to - if: github.ref_name != 'main' && github.ref_name != 'devel' + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Select containers to build + id: select run: | - IMAGE="${{ steps.image.outputs.image }}" - for BASE in main devel; do - git fetch --no-tags --depth=1 origin "$BASE" 2>/dev/null || continue - PINNED=$(git show "FETCH_HEAD:conf/containers.config" 2>/dev/null \ - | sed -n "s|.*withLabel: *'r'.*container *= *\"\([^\"]*\)\".*|\1|p") - if [ "$IMAGE" = "$PINNED" ]; then - echo "::error::$BASE is pinned to $IMAGE -- bump the tag in conf/containers.config before rebuilding it" + RELEASED=false + case "${{ github.ref_name }}" in main|devel) RELEASED=true ;; esac + + # Each base branch is fetched into its own ref so both stay readable in the loop + BASES="" + for BASE in devel main; do + if git fetch --no-tags --depth=1 origin "$BASE:refs/base/$BASE" 2>/dev/null; then + BASES="$BASES refs/base/$BASE" + fi + done + + # devel is at or ahead of main, so it is the baseline for "did this container change" + DIFF_BASE=refs/base/devel + + # Every containers/