Replace the vendor/oci-distribution dependency with a custom implementation
that directly follows the OCI Distribution Specification using hyper for HTTP.
Key improvements:
- Direct HTTP implementation using hyper, hyper-util, and hyper-tls
- Support for Bearer token, Basic auth, and Anonymous authentication
- Cross-registry blob copying for layered images
- Multi-platform manifest list support
- Better error handling and redirect support
- Reduced dependency footprint
Technical changes:
- Remove vendor/oci-distribution dependency
- Add hyper ecosystem dependencies for HTTP client
- Implement OCI types: OciDescriptor, OciImageManifest, OciImageIndex
- Add ImageReference parsing with registry/repository/tag/digest support
- Implement registry authentication flows (Bearer token requests)
- Add blob upload/download with redirect handling
- Support manifest pulling with image index resolution
- Fix manifest size validation for Docker compatibility
- Update integration tests to use new registry auth types
- Handle docker.io redirect to registry-1.docker.io correctly
This enables more flexible authentication handling and reduces external
dependencies while maintaining full OCI compliance.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Resolves GitHub issue #28 by implementing proper layered image building
that preserves base image properties and handles cross-registry scenarios.
Changes:
- Enhanced push_layered_image() to detect cross-registry pushes and copy base layers
- Implemented automatic blob copying from source registry to destination registry
- Always use layered approach instead of falling back to single-layer builds
- Added verification tests to ensure base image environment and files are preserved
- Consolidated unit tests into module files for better organization
This fixes "MANIFEST_BLOB_UNKNOWN" errors when pushing layered images that
reference base image blobs from different registries (e.g., cgr.dev → ttl.sh).
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Only run make run-built-image on ubuntu-latest (x86_64) runners
- ARM64 runners cannot cross-compile for x86_64 due to linker architecture mismatch
- Prevents 'file in wrong format' errors when ARM64 musl-gcc tries to link x86_64 objects
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Change from x86_64-linux-musl-gcc to musl-gcc (provided by musl-tools package)
- Keep aarch64-linux-gnu-gcc for ARM64 cross-compilation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move cross-compilation setup to CI workflow for better portability
- Remove local .cargo/config.toml to avoid conflicts
- Add cross-compilation config directly in CI test matrix
- Re-enable make run-built-image in main test job
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Restore integration job with CI-compatible linker configuration
- Use aarch64-linux-gnu-gcc instead of aarch64-linux-musl-gcc for CI
- Enable make run-built-image test in dedicated ubuntu-latest environment
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Temporarily enable run-built-image in CI to see what specific
cross-compilation tools are missing in the ubuntu environment.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The CI environment provides musl-gcc instead of x86_64-linux-musl-gcc.
Update cargo config to use the available linker to resolve the
"linker not found" error during cross-compilation.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update cargo config to use aarch64-linux-gnu-gcc instead of
aarch64-linux-musl-gcc, which matches what's available in CI.
This resolves the "linker not found" error in CI builds.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update Makefile to use --verbose flag by default for build and test targets
- Simplify CI workflow to use standard make targets instead of verbose variants
- Improve debugging visibility in CI by showing detailed cargo output
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add matrix testing across ubuntu-latest and ubuntu-24.04-arm
- Test both stable and beta Rust toolchains
- Add comprehensive caching for cargo registry, index, and build
- Include cross-compilation verification steps
- Use make targets for consistent build and test execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove complex cross-compilation setup that was causing linker
errors. The simplified approach should work with the available
system linkers and musl-tools package.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Restore support for the --image flag that was accidentally removed
in the previous refactoring. This ensures all existing tests and
workflows continue to work while maintaining the digest-only approach.
- Restore image reference parsing with tag/digest stripping
- Maintain backward compatibility with existing CLI interface
- All integration tests now pass
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Platform-specific images are now pushed without any tags, only by digest.
This ensures no platform tags like :platform-linux-amd64 are created in
the registry, addressing the core requirement of issue #27.
- Added push_image_by_digest() method to registry client
- Platform images use digest-only references for manifest list
- Only manifest lists can receive explicit tags via --tag flag
- Eliminates all unwanted platform-specific tags from registry
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Images are now pushed by digest only by default, with optional tagging
via the new --tag flag. This addresses issue #27 by ensuring:
- No automatic :latest tags are applied during build
- Platform-specific images are never tagged for external use
- Only manifest lists can receive tags when explicitly requested
- Default behavior outputs digest-only references for reproducibility
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove the custom keychain implementation and keep only the simple wrapper
around oci-distribution's built-in auth. This change:
- Removes 300+ lines of duplicate authentication code
- Leverages well-tested oci-distribution auth functionality
- Simplifies the codebase and reduces maintenance burden
- Maintains full backward compatibility
The custom keychain implementation was never used in production code,
only the simple resolve_auth function was called. All tests have been
updated and are passing.
Fixes#17🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added `use_chunked_uploads` field to ClientConfig (default: true)
- Modified push_blob to respect the chunked upload configuration
- Configured krust to disable chunked uploads for better registry compatibility
- Added comprehensive tests for the new configuration option
This allows callers to control whether chunked/multi-part uploads are used,
which improves compatibility with registries that may not support them well.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Registry Authentication section documenting Docker config support
- Add documentation for Docker credential helpers
- Update development section to show Makefile targets
- Explain single-threaded test execution
- Add automatic authentication to key features
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add setup-cross-compile target to create cargo config
- Add verify-cross-compile target to check setup
- Update CI to use make verify-cross-compile
- Simplifies CI workflow and centralizes cross-compile logic
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add TEST_FLAGS variable for single-threaded test execution
- Create verbose targets for CI usage
- Update pre-commit hooks to use make targets
- Update CI workflow to use make targets
- This ensures consistency between local and CI test execution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update pre-commit hooks to use --test-threads=1
- Update CI workflow to run tests single-threaded
- This prevents test failures due to concurrent environment variable modifications
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Clear HOME env var to avoid ~/.docker/config.json
- Clear XDG_RUNTIME_DIR to avoid containers/auth.json
- Add debug output for failed auth resolution
- Tests should now pass in CI environments
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Clear REGISTRY_AUTH_FILE in all credential helper tests to avoid conflicts
- Apply rustfmt formatting
- Tests pass reliably when run sequentially (cargo test -- --test-threads=1)
- Note: Tests may fail when run in parallel due to env var mutations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>