Skip to content

chore: add source distribution collection to container builds for license compliance - #1266

Open
ironcommit wants to merge 2 commits into
mainfrom
licensing-updates/rsadler
Open

chore: add source distribution collection to container builds for license compliance#1266
ironcommit wants to merge 2 commits into
mainfrom
licensing-updates/rsadler

Conversation

@ironcommit

@ironcommit ironcommit commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds automated source distribution collection to all container images so that shipped containers include the source code required by open-source licenses (GPL, LGPL, etc.). Also adds a third-party materials disclaimer to the README.

Changes

New collection scripts (docker/scripts/)

  • collect-apt-sources.sh — downloads Debian/Ubuntu source packages for installed or explicitly listed apt packages, with deb-src auto-enablement for official repos
  • collect-cpython-source.py — fetches the CPython source tarball matching the interpreter version from python.org
  • collect-python-sdists.py — collects PyPI source distributions for all non-editable packages in a virtualenv, using uv.lock URLs when available and falling back to the PyPI JSON API; supports baseline freeze diffing, hash verification, and labeled multi-environment manifests
  • collect-workspace-sdists.py — builds sdists for local workspace packages (editable installs) using uv build --sdist

Dockerfile integration

Each container image now runs the appropriate collection scripts during build and copies results to /usr/share/nemo-platform/source-distributions/<image>/:

  • Dockerfile.nmp-python-base — apt sources, CPython source, seed venv sdists
  • Dockerfile.nmp-api — workspace + PyPI sdists
  • Dockerfile.nmp-core — workspace + PyPI sdists
  • Dockerfile.nmp-cpu-tasks — workspace + PyPI sdists
  • Dockerfile.nmp-customizer-tasks — apt sources, workspace + PyPI sdists
  • Dockerfile.nmp-unsloth-training — apt sources, git archives (bitsandbytes), workspace + PyPI sdists
  • Dockerfile.safe-synthesizer-tasks — apt sources, CPython source, workspace + PyPI sdists
  • Dockerfile.auditor-tasks — apt sources, CPython source, workspace + PyPI sdists (app + garak venvs)
  • Dockerfile.nmp-automodel-base — apt sources, git archives (grouped_gemm, bitsandbytes), workspace + PyPI sdists
  • Dockerfile.nmp-automodel-training — workspace + delta PyPI sdists (baseline freeze diff)
  • Dockerfile.nmp-rl-base — apt sources, workspace + PyPI sdists across nemo-rl, ray, and gym venvs
  • Dockerfile.nmp-rl-training — workspace + delta PyPI sdists (baseline freeze diff)

Other changes

  • Standardized COPY --chown from 1000:1000 to nvs:nvs in Dockerfile.nmp-api and Dockerfile.nmp-core
  • Added third-party materials notice and disclaimer to README.md

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with documentation updates
  • Documentation only
  • Contributor tooling or automation
  • CI, build, or test infrastructure

Quality Gates

  • Tests not applicable — justification: build-time source collection scripts; verified by successful container builds
  • Documentation not applicable — justification: internal build infrastructure, not user-facing behavior

Verification

  • Pull request title follows the repository's Conventional Commit format
  • Every commit includes an appropriate Signed-off-by: trailer
  • uv run pre-commit run -a passes, or any blocked checks are identified below
  • Targeted tests pass, or tests are marked not applicable above
  • No secrets, API keys, or credentials are included

Summary by CodeRabbit

  • New Features

    • Container builds can optionally collect source distributions for Python packages, workspace projects, operating-system packages, and the Python runtime.
    • Collected source artifacts, manifests, checksums, and failure records are included in supported release images.
    • Release builds enable source collection for improved software provenance and inspection.
  • Documentation

    • Added a notice clarifying terms and responsibilities for externally retrieved materials.
  • Chores

    • Updated dependency license metadata and compatibility declarations.

@ironcommit
ironcommit requested review from a team as code owners August 12, 2026 22:22
@github-actions github-actions Bot added the chore label Aug 12, 2026
@ironcommit
ironcommit force-pushed the licensing-updates/rsadler branch from bd6bff2 to 4ffc6c1 Compare August 12, 2026 22:23
@ironcommit ironcommit changed the title chore: update source distributions in containers chore: add source distribution collection to container builds for license compliance Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

Source collection and image integration

Layer / File(s) Summary
Source collection utilities
docker/scripts/*, tests/unit/test_collect_*
Added APT, CPython, Python sdist, and workspace sdist collectors with manifests, validation, retries, and checksum verification.
Base and application image integration
docker/base/*, docker/Dockerfile.*
Integrated source collection into application images and copied collected artifacts into image-specific directories.
Automodel and RL image integration
docker/automodel/*, docker/rl/*
Added package baselines, archived local sources, and collected Python and APT sources for Automodel and NeMo-RL images.
Release and build configuration
.github/workflows/release.yaml, docker-bake.hcl
Added NMP_COLLECT_SOURCES and propagated it through release and Docker Bake targets.

License metadata corrections

Layer / File(s) Summary
License inventory and override validation
third_party/licenses.jsonl, tools/nemo-platform-sdk-tools/src/.../overrides.yaml, tools/nemo-platform-sdk-tools/tests/license/*
Corrected seven dependency license expressions and added validation for the inventory and overrides.

Documentation notice

Layer / File(s) Summary
External materials notice
NOTICE
Added terms and liability language for externally retrieved materials.

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseWorkflow
  participant DockerBake
  participant DockerImageBuild
  participant SourceCollectors
  participant SourceDistributionDirectory
  ReleaseWorkflow->>DockerBake: set NMP_COLLECT_SOURCES=1
  DockerBake->>DockerImageBuild: pass collection argument
  DockerImageBuild->>SourceCollectors: collect APT, CPython, workspace, and Python sources
  SourceCollectors->>SourceDistributionDirectory: write archives and manifests
  DockerImageBuild->>SourceDistributionDirectory: copy artifacts into runtime image
Loading

Suggested reviewers: mckornfield

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: collecting source distributions in container builds for license compliance.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch licensing-updates/rsadler

Comment @coderabbitai help to get the list of available commands.

@ironcommit
ironcommit requested a review from mckornfield August 12, 2026 22:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker/base/Dockerfile.nmp-python-base`:
- Around line 37-49: Run every listed collector through the appropriate uv
runner, using `uv run --no-project --python <runner>
/usr/local/bin/<collector>.py ...` while preserving each collector’s `--python`
argument. In docker/base/Dockerfile.nmp-python-base lines 37-49, move the uv
copy before the first collector and update both collectors; apply the same
collector updates in docker/Dockerfile.auditor-tasks lines 93-112 and 135-138,
docker/Dockerfile.nmp-api lines 58-66, docker/Dockerfile.nmp-core lines 21-29,
docker/Dockerfile.nmp-cpu-tasks lines 14-22, and
docker/rl/Dockerfile.nmp-rl-base lines 434-454. In
docker/rl/Dockerfile.nmp-rl-training lines 65-79, use uv-glue as the runner and
preserve UV_BIN=uv-glue.

In `@docker/Dockerfile.safe-synthesizer-tasks`:
- Around line 203-217: Add `/build/packages/nmp_common` as an additional
`--project` argument to the `collect-workspace-sdists.py` invocation in the
safe-synthesizer task image, ensuring the local nmp-common source distribution
is collected alongside the existing workspace projects.

In `@docker/scripts/collect-apt-sources.sh`:
- Around line 82-122: Update the installed-package collection and
source-download flow around dpkg-query, the source_packages_file loop, and
apt-get source so installed packages retain both their source name and installed
source version. Resolve each installed binary package’s source metadata, store
entries as source_package=source_version when --installed is enabled, and pass
that exact version to apt-get source; preserve the existing unversioned behavior
for explicitly requested packages.

In `@docker/scripts/collect-workspace-sdists.py`:
- Around line 69-72: Update the explicit-project handling loop around
args.project so paths that do not exist or lack pyproject.toml are recorded in
missing-workspace-sdists.txt, while valid projects continue to be added to
projects. Reuse the existing manifest-writing mechanism and preserve its
expected path format.

In `@README.md`:
- Around line 200-201: Update the NOTICE AND DISCLAIMER text to limit the “not
distributed with this software” claim to materials fetched only at runtime.
Explicitly state that materials embedded in distributed artifacts, including
Docker images, remain subject to their original licenses and notices, while
preserving the existing responsibility and warranty language.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7c901e32-fb27-4aab-a10c-3ff514d17150

📥 Commits

Reviewing files that changed from the base of the PR and between c8cb003 and 4ffc6c1.

📒 Files selected for processing (17)
  • README.md
  • docker/Dockerfile.auditor-tasks
  • docker/Dockerfile.nmp-api
  • docker/Dockerfile.nmp-core
  • docker/Dockerfile.nmp-cpu-tasks
  • docker/Dockerfile.nmp-customizer-tasks
  • docker/Dockerfile.nmp-unsloth-training
  • docker/Dockerfile.safe-synthesizer-tasks
  • docker/automodel/Dockerfile.nmp-automodel-base
  • docker/automodel/Dockerfile.nmp-automodel-training
  • docker/base/Dockerfile.nmp-python-base
  • docker/rl/Dockerfile.nmp-rl-base
  • docker/rl/Dockerfile.nmp-rl-training
  • docker/scripts/collect-apt-sources.sh
  • docker/scripts/collect-cpython-source.py
  • docker/scripts/collect-python-sdists.py
  • docker/scripts/collect-workspace-sdists.py

Comment thread docker/base/Dockerfile.nmp-python-base Outdated
Comment thread docker/Dockerfile.safe-synthesizer-tasks Outdated
Comment thread docker/scripts/collect-apt-sources.sh Outdated
Comment thread docker/scripts/collect-workspace-sdists.py
Comment thread README.md Outdated
Comment thread docker/automodel/Dockerfile.nmp-automodel-training Outdated
Comment thread docker/base/Dockerfile.nmp-python-base Outdated
).strip()


def download(url: str, destination: Path) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder for these if we'd benefit from doing some asyncio while downloading

if destination.stat().st_size > 0:
return destination
return (
output_dir / "pypi" / f"{normalize_name(name)}-{version}-{hashlib.sha256(url.encode()).hexdigest()[:12]}.tar.gz"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol a variable or two would be nice for the last part

Comment thread docker/Dockerfile.nmp-api Outdated
Comment thread README.md Outdated

NeMo Platform is licensed under the Apache License 2.0. Third-party open-source dependencies have their own licenses; review them before use.

NOTICE AND DISCLAIMER: This software automatically retrieves, accesses or interacts with external materials. Those retrieved materials are not distributed with this software and are governed solely by separate terms, conditions and licenses. You are solely responsible for finding, reviewing and complying with all applicable terms, conditions, and licenses, and for verifying the security, integrity and suitability of any retrieved materials for your specific use case. This software is provided "AS IS", without warranty of any kind. The author makes no representations or warranties regarding any retrieved materials, and assumes no liability for any losses, damages, liabilities or legal consequences from your use or inability to use this software or any retrieved materials. Use this software and the retrieved materials at your own risk.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 32235/40906 78.8% 63.7%
Integration Tests 18646/38832 48.0% 20.7%

@ironcommit
ironcommit force-pushed the licensing-updates/rsadler branch from 4ffc6c1 to 6d5ce1d Compare August 12, 2026 23:23
@ironcommit
ironcommit requested a review from a team as a code owner August 12, 2026 23:23

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker/automodel/Dockerfile.nmp-automodel-base`:
- Around line 76-89: Declare NMP_COLLECT_SOURCES before the grouped_gemm and
bitsandbytes build commands, and condition each corresponding git archive
operation on the same enabled values used by the collectors. Ensure archives are
not created or shipped when collection is disabled, while preserving the
existing clone, checkout, and installation steps.

In `@docker/scripts/collect-cpython-source.py`:
- Around line 40-53: Update download to verify the fetched CPython archive
against the official release signature or a trusted checksum before accepting it
as valid. Perform verification before writing or recording the destination
artifact, retry or fail when verification fails, and preserve the existing
successful-download and error behavior for valid archives.

In `@docker/scripts/collect-workspace-sdists.py`:
- Around line 81-88: Update the exception handling around purelib_for() and
direct_url_projects() to catch OSError in addition to
subprocess.CalledProcessError, so missing or non-executable args.python values
are recorded in workspace-sdist-errors.txt instead of terminating the script.
Preserve the existing error message and file-writing behavior.
- Around line 99-108: Update the workspace sdist collection flow so the function
returns a non-zero status when the missing list is non-empty, while retaining
status 0 when all builds succeed. Apply this to the return path after writing
the built and missing manifests.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 020d3fb5-6a4f-4a86-8840-0eddaec3c8fd

📥 Commits

Reviewing files that changed from the base of the PR and between 4ffc6c1 and 6d5ce1d.

📒 Files selected for processing (21)
  • .github/workflows/release.yaml
  • README.md
  • docker-bake.hcl
  • docker/Dockerfile.auditor-tasks
  • docker/Dockerfile.nmp-api
  • docker/Dockerfile.nmp-core
  • docker/Dockerfile.nmp-cpu-tasks
  • docker/Dockerfile.nmp-customizer-tasks
  • docker/Dockerfile.nmp-unsloth-training
  • docker/Dockerfile.safe-synthesizer-tasks
  • docker/automodel/Dockerfile.nmp-automodel-base
  • docker/automodel/Dockerfile.nmp-automodel-training
  • docker/base/Dockerfile.nmp-python-base
  • docker/rl/Dockerfile.nmp-rl-base
  • docker/rl/Dockerfile.nmp-rl-training
  • docker/scripts/collect-apt-sources.sh
  • docker/scripts/collect-cpython-source.py
  • docker/scripts/collect-python-sdists.py
  • docker/scripts/collect-workspace-sdists.py
  • tests/unit/test_collect_apt_sources.py
  • tests/unit/test_collect_cpython_source.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • docker/automodel/Dockerfile.nmp-automodel-training
  • README.md
  • docker/Dockerfile.nmp-unsloth-training
  • docker/rl/Dockerfile.nmp-rl-base
  • docker/Dockerfile.nmp-customizer-tasks
  • docker/Dockerfile.auditor-tasks
  • docker/rl/Dockerfile.nmp-rl-training

Comment thread docker/automodel/Dockerfile.nmp-automodel-base
Comment thread docker/scripts/collect-cpython-source.py
Comment thread docker/scripts/collect-workspace-sdists.py
Comment thread docker/scripts/collect-workspace-sdists.py Outdated
@ironcommit
ironcommit force-pushed the licensing-updates/rsadler branch 2 times, most recently from bc668a3 to d6cf20e Compare August 13, 2026 00:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tools/nemo-platform-sdk-tools/tests/license/test_license_utils.py`:
- Around line 236-260: Extend
test_reviewed_license_overrides_cover_corrected_inventory_values to load
third_party/licenses.jsonl, build a package-to-license mapping from its
generated rows, and assert the corrected_packages values against it as well as
overrides. Normalize package names and use the generator’s uppercase
license-expression convention for the inventory assertion.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 36009cc1-2842-4c2d-9fc1-65b31aa6ffb9

📥 Commits

Reviewing files that changed from the base of the PR and between 6d5ce1d and bc668a3.

📒 Files selected for processing (16)
  • docker/Dockerfile.auditor-tasks
  • docker/Dockerfile.nmp-api
  • docker/Dockerfile.nmp-core
  • docker/Dockerfile.nmp-customizer-tasks
  • docker/Dockerfile.nmp-unsloth-training
  • docker/Dockerfile.safe-synthesizer-tasks
  • docker/automodel/Dockerfile.nmp-automodel-base
  • docker/automodel/Dockerfile.nmp-automodel-training
  • docker/rl/Dockerfile.nmp-rl-base
  • docker/rl/Dockerfile.nmp-rl-training
  • docker/scripts/collect-cpython-source.py
  • tests/unit/test_collect_apt_sources.py
  • tests/unit/test_collect_cpython_source.py
  • third_party/licenses.jsonl
  • tools/nemo-platform-sdk-tools/src/nemo_platform_sdk_tools/license/overrides.yaml
  • tools/nemo-platform-sdk-tools/tests/license/test_license_utils.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • docker/Dockerfile.nmp-core
  • docker/Dockerfile.auditor-tasks
  • docker/Dockerfile.nmp-unsloth-training
  • docker/automodel/Dockerfile.nmp-automodel-training
  • docker/automodel/Dockerfile.nmp-automodel-base

Comment thread tools/nemo-platform-sdk-tools/tests/license/test_license_utils.py
Signed-off-by: Ryan S <267728323+ironcommit@users.noreply.github.com>
@ironcommit
ironcommit force-pushed the licensing-updates/rsadler branch from d6cf20e to 79fa62c Compare August 13, 2026 00:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker/scripts/collect-workspace-sdists.py`:
- Around line 101-105: Update the exception handling around the uv build
invocation to also catch OSError alongside subprocess.CalledProcessError,
appending the affected project and str(error) to missing so uv startup failures
are recorded and processing continues.

In `@NOTICE`:
- Around line 6-7: Update the NOTICE disclaimer to distinguish materials
retrieved at runtime from source archives bundled in release Docker images under
the source-distributions directory, and state that bundled materials remain
subject to their own licenses and notices. Preserve the existing responsibility,
warranty, and liability language.

In `@tests/unit/test_collect_workspace_sdists.py`:
- Around line 39-40: Update the test setup around main() in
test_collect_workspace_sdists to remove the UV_BIN environment variable before
invocation, ensuring the expected command uses the default executable regardless
of the external test environment. Preserve the existing NMP_COLLECT_SOURCES
setup and assertions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: dcb5829f-65cf-4738-b7c4-935d6bf6a6b9

📥 Commits

Reviewing files that changed from the base of the PR and between d6cf20e and 79fa62c.

📒 Files selected for processing (4)
  • NOTICE
  • docker/scripts/collect-workspace-sdists.py
  • tests/unit/test_collect_workspace_sdists.py
  • tools/nemo-platform-sdk-tools/tests/license/test_license_utils.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tools/nemo-platform-sdk-tools/tests/license/test_license_utils.py

Comment thread docker/scripts/collect-workspace-sdists.py
Comment thread NOTICE Outdated
Comment thread tests/unit/test_collect_workspace_sdists.py
Signed-off-by: Ryan S <267728323+ironcommit@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants