From 88da9520d74c938e90767c748e7588c01cdfbb0b Mon Sep 17 00:00:00 2001 From: ASUQ Date: Sat, 1 Aug 2026 15:22:58 +0200 Subject: [PATCH 1/2] feat(container): add source-built SPAdes image Build the checked-out SPAdes source in an Ubuntu 24.04 builder and copy only the installed toolkit into the runtime stage. The release project set and NCBI SRA support match the upstream release build configuration.\n\nInstall pigz so corrected-read compression can use the thread count supplied to SPAdes. Run the final image as an unprivileged user from a writable work directory while keeping the full SPAdes toolkit on PATH.\n\nValidation: git diff --cached --check. Image builds and runtime smoke tests are added in the follow-up container CI commit because no local container daemon is available. --- .dockerignore | 10 ++++++++++ Dockerfile | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..cd302faf8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.github +docs +.DS_Store +**/__pycache__/ +**/*.py[cod] +/bin/ +/build*/ +/spades_test/ +*.tar.gz diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..bfbc1ccd9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,54 @@ +FROM ubuntu:24.04 AS builder + +ARG BUILD_JOBS=8 +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update \ + && apt-get install --yes --no-install-recommends \ + build-essential \ + cmake \ + libbz2-dev \ + python3 \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /src +COPY . . + +RUN PREFIX=/opt/spades ./spades_compile.sh \ + -j "${BUILD_JOBS}" \ + -DSPADES_ENABLE_PROJECTS=release \ + -DSPADES_USE_NCBISDK=ON + + +FROM ubuntu:24.04 + +ARG DEBIAN_FRONTEND=noninteractive + +LABEL org.opencontainers.image.title="SPAdes" \ + org.opencontainers.image.description="Genome assembler for isolate, single-cell, metagenomic, and transcriptomic sequencing data" \ + org.opencontainers.image.url="https://ablab.github.io/spades/" \ + org.opencontainers.image.source="https://github.com/ablab/spades" \ + org.opencontainers.image.licenses="GPL-2.0-only" + +RUN apt-get update \ + && apt-get install --yes --no-install-recommends \ + ca-certificates \ + libbz2-1.0 \ + libgomp1 \ + pigz \ + python3 \ + zlib1g \ + && groupadd --gid 1000 spades \ + && useradd --uid 1000 --gid spades --create-home --shell /bin/bash spades \ + && install --directory --owner spades --group spades /work \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /opt/spades /opt/spades + +ENV PATH="/opt/spades/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + +WORKDIR /work +USER spades + +CMD ["/bin/bash"] From 5c08505e86f64693b0c756cb37d3ccbb077d3ba3 Mon Sep 17 00:00:00 2001 From: ASUQ Date: Sat, 1 Aug 2026 15:25:56 +0200 Subject: [PATCH 2/2] test(container): add Docker image validation Build and load the SPAdes image on native Linux AMD64 and ARM64 GitHub-hosted runners for the same non-documentation events as the existing test suite. Architecture-scoped layer caches reduce repeated source-build cost without publishing an image.\n\nCheck the embedded version, unprivileged writable runtime, pigz availability, absence of build tools, and the bundled SPAdes assembly test. The smoke test also verifies that corrected-read compression selected pigz.\n\nValidation: workflow YAML syntax parsed successfully and git diff --cached --check passed. Runtime validation is performed by this workflow because no local container daemon is available. --- .github/workflows/docker.yml | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 000000000..6b1de6e83 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,89 @@ +name: SPAdes container tests + +on: + workflow_dispatch: + push: + branches: + - master + - main + - next + tags: + - '*' + paths-ignore: + - 'docs/**' + - 'mkdocs.yml' + pull_request: + paths-ignore: + - 'docs/**' + - 'mkdocs.yml' + +permissions: + contents: read + +concurrency: + group: container-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + container: + name: Container (${{ matrix.platform }}) + runs-on: ${{ matrix.runner }} + timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-24.04 + platform: linux/amd64 + architecture: amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + architecture: arm64 + + steps: + - name: Check out SPAdes + uses: actions/checkout@v7 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Build container + uses: docker/build-push-action@v7 + with: + context: . + platforms: ${{ matrix.platform }} + load: true + push: false + tags: spades:ci-${{ matrix.architecture }} + cache-from: type=gha,scope=spades-container-${{ matrix.architecture }} + cache-to: type=gha,mode=max,scope=spades-container-${{ matrix.architecture }} + + - name: Check runtime environment + env: + IMAGE_TAG: spades:ci-${{ matrix.architecture }} + run: | + set -euo pipefail + + expected_version="$(tr -d '\n' < VERSION)" + actual_version="$(docker run --rm "${IMAGE_TAG}" spades.py --version)" + grep -F "${expected_version}" <<< "${actual_version}" + + docker run --rm "${IMAGE_TAG}" bash -euc ' + test "$(id -u)" -ne 0 + touch /work/write-test + rm /work/write-test + command -v spades.py + command -v pigz + ! command -v cmake + ! command -v g++ + pigz --version + ' + + - name: Run SPAdes smoke test + env: + IMAGE_TAG: spades:ci-${{ matrix.architecture }} + run: | + docker run --rm "${IMAGE_TAG}" bash -euc ' + spades.py -t 4 --test + grep -F "Compressing corrected reads (with pigz)" spades_test/spades.log + '