{"id":41989705,"url":"https://github.com/tedg-dev/merge_spdx_sboms","last_synced_at":"2026-01-26T00:30:21.363Z","repository":{"id":328230051,"uuid":"1114672205","full_name":"tedg-dev/merge_spdx_sboms","owner":"tedg-dev","description":"Python tool for merging SPDX SBOM files with intelligent deduplication and relationship preservation","archived":false,"fork":false,"pushed_at":"2026-01-16T19:37:53.000Z","size":125,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-17T07:24:33.743Z","etag":null,"topics":["python","sbom","security","software-bill-of-materials","spdx","supply-chain"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tedg-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-11T18:00:21.000Z","updated_at":"2026-01-16T19:37:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tedg-dev/merge_spdx_sboms","commit_stats":null,"previous_names":["tedg-dev/merge_spdx_sboms"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tedg-dev/merge_spdx_sboms","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tedg-dev%2Fmerge_spdx_sboms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tedg-dev%2Fmerge_spdx_sboms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tedg-dev%2Fmerge_spdx_sboms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tedg-dev%2Fmerge_spdx_sboms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tedg-dev","download_url":"https://codeload.github.com/tedg-dev/merge_spdx_sboms/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tedg-dev%2Fmerge_spdx_sboms/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28762560,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T23:06:19.311Z","status":"ssl_error","status_checked_at":"2026-01-25T23:03:50.555Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","sbom","security","software-bill-of-materials","spdx","supply-chain"],"created_at":"2026-01-26T00:30:17.068Z","updated_at":"2026-01-26T00:30:21.345Z","avatar_url":"https://github.com/tedg-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SPDX SBOM Merger\n\n**Merge SPDX dependency SBOMs into a comprehensive root SBOM with complete relationship preservation**\n\n[![CI/CD Pipeline](https://github.com/tedg-dev/merge_spdx_sboms/actions/workflows/ci.yml/badge.svg)](https://github.com/tedg-dev/merge_spdx_sboms/actions/workflows/ci.yml)\n[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA production-ready Python application for merging SPDX Software Bill of Materials (SBOMs) from dependencies into a comprehensive root SBOM, maintaining complete relationship hierarchies and generating unique deterministic IDs.\n\n---\n\n## Features\n\n✅ **Deterministic SPDX ID Generation** - Creates unique, reproducible IDs for all packages  \n✅ **Hierarchical Relationship Merging** - Preserves complete transitive dependency graphs  \n✅ **SPDX 2.3 Validation** - Ensures spec compliance with detailed validation reports  \n✅ **Package Deduplication** - Automatically removes duplicate packages across SBOMs  \n✅ **GitHub Integration** - Optional push to GitHub repositories  \n✅ **Comprehensive Reports** - Detailed merge statistics and validation results  \n✅ **96%+ Test Coverage** - Thoroughly tested with pytest  \n✅ **CI/CD Pipeline** - GitHub Actions with automated testing and security scanning  \n\n---\n\n## Quick Start\n\n### Setup Environment\n\n```bash\n# Setup and install\n./setup_environment.sh\n\n# Setup and run tests\n./setup_environment.sh --test\n\n# Setup and view coverage\n./setup_environment.sh --coverage\n```\n\n### Basic Usage\n\n```bash\n# Merge SBOMs from dependencies directory\npython -m sbom_merger.cli \\\n  --dependencies-dir /path/to/sboms/project_name/dependencies \\\n  --verbose\n\n# Merge and push to GitHub\npython -m sbom_merger.cli \\\n  --dependencies-dir /path/to/sboms/project_name/dependencies \\\n  --push-to-github \\\n  --github-owner tedg-dev \\\n  --github-repo my-project \\\n  --account tedg-dev\n```\n\n---\n\n## How It Works\n\n### Input Structure\n\nThe tool expects the directory structure created by `fetch_sbom`:\n\n```\nsboms/\n  sbom_export_2025-12-10_09.37.18/\n    CiscoSecurityServices_corona-sdk/\n      CiscoSecurityServices_corona-sdk_root.json  ← Root SBOM\n      dependencies/                                ← Input directory\n        psf_requests_main.json\n        pytest-dev_pytest_main.json\n        ...\n```\n\n### Merge Process\n\n1. **Discover Files** - Automatically finds root SBOM and all dependency SBOMs\n2. **Parse \u0026 Validate** - Validates SPDX 2.3 format and version compatibility\n3. **Generate New IDs** - Creates deterministic SPDXRef IDs for uniqueness\n4. **Merge Packages** - Combines all packages (no deduplication)\n5. **Preserve Relationships** - Maintains hierarchical DEPENDS_ON relationships\n6. **Create Report** - Generates detailed merge statistics\n\n### SPDX ID Generation\n\nUses industry best practice: **deterministic ID generation**\n\n```python\nSPDXRef-{ecosystem}-{sanitized-name}-{hash}\n\nExamples:\n- SPDXRef-pypi-requests-abc123\n- SPDXRef-npm-lodash-def456\n- SPDXRef-githubactions-actions-checkout-789xyz\n```\n\n**Why deterministic?**\n- Guarantees uniqueness within merged document\n- Reproducible across merges\n- No collision risk from different source SBOMs\n\n### Relationship Strategy\n\n**Hierarchical with full transitive dependency preservation:**\n\n```\nRoot SBOM (DESCRIBES)\n  └─ Main Project\n      ├─ DEPENDS_ON → pytest\n      │   └─ DEPENDS_ON → pytest-cov\n      │       └─ DEPENDS_ON → coverage\n      └─ DEPENDS_ON → requests\n          └─ DEPENDS_ON → urllib3\n```\n\nAll relationships from dependency SBOMs are preserved, creating a complete dependency graph.\n\n---\n\n## Installation\n\n### Prerequisites\n\n- Python 3.12 or later\n- Git\n\n### Using setup_environment.sh (Recommended)\n\n```bash\ngit clone https://github.com/tedg-dev/merge_spdx_sboms.git\ncd merge_spdx_sboms\n./setup_environment.sh\nsource venv/bin/activate\n```\n\n### Manual Installation\n\n```bash\npython3.12 -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\npip install -e .\n```\n\n---\n\n## Configuration\n\n### GitHub Authentication\n\nCreate `keys.json` for GitHub push functionality:\n\n```json\n{\n  \"accounts\": [\n    {\n      \"username\": \"your-github-username\",\n      \"token\": \"ghp_yourPersonalAccessToken\"\n    },\n    {\n      \"username\": \"your-work-account\",\n      \"token\": \"ghp_yourWorkAccessToken\"\n    }\n  ]\n}\n```\n\n**Token Requirements:**\n- **Classic PAT**: `repo` scope\n- **Fine-grained PAT**: Contents (Read/Write) permission\n\n**Security:**\n- Use `keys.sample.json` as template\n- `keys.json` is gitignored by default\n- Rotate tokens regularly\n\n---\n\n## Command-Line Interface\n\n### Required Options\n\n```bash\n--dependencies-dir PATH    Path to dependencies directory\n```\n\n### Optional Options\n\n```bash\n--output-dir PATH          Output directory (default: same as root SBOM)\n--key-file PATH            Path to keys.json (default: keys.json)\n--account USERNAME         GitHub account from keys.json\n--verbose                  Enable verbose output\n```\n\n### GitHub Push Options\n\n```bash\n--push-to-github           Push merged SBOM to GitHub\n--github-owner OWNER       Repository owner (required with --push-to-github)\n--github-repo REPO         Repository name (required with --push-to-github)\n--github-path PATH         Target path in repo (default: sboms/merged_sbom.json)\n--github-branch BRANCH     Target branch (default: main)\n```\n\n### Examples\n\n**Basic merge:**\n```bash\npython -m sbom_merger.cli \\\n  --dependencies-dir ~/sboms/export/my-project/dependencies\n```\n\n**Verbose with custom output:**\n```bash\npython -m sbom_merger.cli \\\n  --dependencies-dir ~/sboms/export/my-project/dependencies \\\n  --output-dir ./output \\\n  --verbose\n```\n\n**Push to GitHub:**\n```bash\npython -m sbom_merger.cli \\\n  --dependencies-dir ~/sboms/export/my-project/dependencies \\\n  --push-to-github \\\n  --github-owner tedg-dev \\\n  --github-repo my-project \\\n  --github-branch main \\\n  --account tedg-dev \\\n  --verbose\n```\n\n---\n\n## Output\n\n### Merged SBOM\n\n**Format:** SPDX 2.3 JSON  \n**Location:** Same directory as root SBOM (or --output-dir)  \n**Naming:** `{project}_merged.json`\n\n```json\n{\n  \"sbom\": {\n    \"spdxVersion\": \"SPDX-2.3\",\n    \"name\": \"Merged SBOM: com.github.owner/repo\",\n    \"packages\": [...],\n    \"relationships\": [...]\n  }\n}\n```\n\n### Merge Report\n\n**Format:** Markdown  \n**Location:** `{merged_sbom}_merge_report.md`\n\n**Contents:**\n- Merge statistics (packages, relationships, processing time)\n- Validation results (errors and warnings)\n- Document details\n- Package source breakdown\n\n---\n\n## Testing\n\n### Run Tests\n\n```bash\n# All tests with coverage\n./setup_environment.sh --test\n\n# Manual testing\npytest --cov=src/sbom_merger --cov-report=term-missing -v\n\n# Specific test file\npytest tests/test_merger.py -v\n\n# With HTML coverage report\npytest --cov=src/sbom_merger --cov-report=html\n```\n\n### Coverage Requirements\n\n- **Minimum:** 96% code coverage\n- **Target:** 98%+ coverage\n- Tests run automatically in CI/CD pipeline\n\n---\n\n## Architecture\n\n### Project Structure\n\n```\nmerge_spdx_sboms/\n├── src/sbom_merger/\n│   ├── domain/\n│   │   └── models.py              # Data models\n│   ├── services/\n│   │   ├── merger.py              # Core merge logic\n│   │   ├── parser.py              # SPDX parsing\n│   │   ├── id_generator.py       # Deterministic ID generation\n│   │   ├── validator.py           # SPDX validation\n│   │   └── reporter.py            # Report generation\n│   ├── infrastructure/\n│   │   ├── config.py              # Configuration \u0026 auth\n│   │   ├── file_handler.py       # File operations\n│   │   └── github_client.py      # GitHub API\n│   └── cli.py                     # Command-line interface\n├── tests/                         # Comprehensive test suite\n├── .github/workflows/             # CI/CD pipelines\n└── setup_environment.sh           # Environment setup script\n```\n\n### Design Principles\n\n- **SPDX 2.3 Spec Compliance** - Strict adherence to SPDX standards\n- **Deterministic Operations** - Reproducible merges\n- **No Data Loss** - All packages and relationships preserved\n- **Validation First** - Validate before and after merge\n- **Extensible Design** - Placeholder support for YAML, RDF formats\n\n---\n\n## CI/CD Pipeline\n\n### Automated Testing\n\n**On Push/PR:**\n- ✅ Unit tests (Python 3.12)\n- ✅ Code coverage (96%+ required)\n- ✅ Linting (Black, Flake8, MyPy)\n- ✅ Security scanning (Bandit, Safety)\n- ✅ Package build verification\n\n**On Release:**\n- ✅ PyPI publishing\n- ✅ Docker image build\n- ✅ GitHub release creation\n\n### GitHub Actions Workflows\n\n- **ci.yml** - Test, lint, build on every push\n- **release.yml** - Publish to PyPI on release\n- **codeql.yml** - Security analysis (weekly + on push)\n\n---\n\n## Development\n\n### Setup Development Environment\n\n```bash\n./setup_environment.sh\nsource venv/bin/activate\npip install -r requirements-dev.txt\n```\n\n### Code Quality Tools\n\n```bash\n# Format code\nblack src/ tests/\n\n# Lint\nflake8 src/ tests/\n\n# Type checking\nmypy src/sbom_merger\n\n# Security scan\nbandit -r src/\n```\n\n### Running Tests Locally\n\n**Before committing:**\n```bash\n./setup_environment.sh --test\n```\n\n**Ensure:**\n- All tests pass ✅\n- Coverage ≥ 96% ✅\n- No linting errors ✅\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n**\"No root SBOM found\"**\n- Ensure path ends with `/dependencies`\n- Root SBOM must match `*_root.json` pattern\n- Check parent directory for root file\n\n**\"Multiple root SBOMs found\"**\n- Only one `*_root.json` file allowed\n- Remove duplicate root SBOMs\n\n**\"Failed to push to GitHub\"**\n- Verify token has correct permissions\n- Check repository exists\n- Ensure branch name is correct\n\n**\"Validation errors\"**\n- All SBOMs must be SPDX-2.3 format\n- Check SPDX version compatibility\n- Review validation report for details\n\n---\n\n## Comparison with Alternatives\n\n| Feature | merge-spdx-sboms | Manual Merge | Other Tools |\n|---------|------------------|--------------|-------------|\n| SPDX 2.3 Support | ✅ Full | ❌ Error-prone | ⚠️ Varies |\n| Transitive Dependencies | ✅ Preserved | ❌ Lost | ⚠️ Limited |\n| Deterministic IDs | ✅ Yes | ❌ No | ❌ No |\n| Validation | ✅ Built-in | ❌ Manual | ⚠️ Basic |\n| GitHub Integration | ✅ Native | ❌ Manual | ❌ No |\n| Test Coverage | ✅ 96%+ | N/A | ⚠️ Unknown |\n\n---\n\n## Roadmap\n\n### Future Enhancements\n\n- [ ] SPDX 3.0 support (placeholder exists)\n- [ ] YAML output format (placeholder exists)\n- [ ] RDF output format (placeholder exists)\n- [ ] Deduplication option (configurable)\n- [ ] Multiple output formats simultaneously\n- [ ] License compatibility checking\n- [ ] Vulnerability correlation\n\n---\n\n## Contributing\n\nContributions welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure 96%+ coverage maintained\n5. Run `./setup_environment.sh --test`\n6. Submit a pull request\n\n---\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details\n\n---\n\n## Documentation\n\n- **[Architecture](docs/ARCHITECTURE.md)** - System design and component details\n- **[Features](docs/FEATURES.md)** - Comprehensive feature documentation\n- **[API Reference](docs/API.md)** - Python API and CLI documentation\n- **[Testing Guide](docs/TESTING.md)** - Testing procedures and coverage\n- **[GitHub Setup](docs/GITHUB_SETUP.md)** - Repository configuration and CI/CD\n- **[Versioning Guide](docs/VERSIONING.md)** - Release process and semantic versioning\n- **[Usage Examples](USAGE.md)** - Quick start examples and workflows\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/tedg-dev/merge_spdx_sboms/issues)\n- **Documentation**: See `docs/` directory\n- **CI/CD**: GitHub Actions workflows\n\n---\n\n## Acknowledgments\n\n- SPDX Working Group for the SPDX specification\n- Python spdx-tools library maintainers\n- GitHub for SBOM API and infrastructure\n\n---\n\n**Built with ❤️ for secure software supply chains**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftedg-dev%2Fmerge_spdx_sboms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftedg-dev%2Fmerge_spdx_sboms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftedg-dev%2Fmerge_spdx_sboms/lists"}