- Replace 3 smoke tests with full pytest integration suite (~350 tests) - Tests run against deployed Kubernetes environment (feature/stage) - Skip @large and @slow tests in CI for reasonable run times - Production deployments use lightweight smoke tests only (no test data) - Add JUnit report artifacts for test results in GitLab
21 KiB
21 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Added
- Added comprehensive upload/download tests for size boundaries (1B to 1GB) (#38)
- Added concurrent upload/download tests (2, 5, 10 parallel operations) (#38)
- Added data integrity tests (binary, text, unicode, compressed content) (#38)
- Added chunk boundary tests for edge cases (#38)
- Added
@pytest.mark.largeand@pytest.mark.concurrenttest markers (#38) - Added
generate_content()andgenerate_content_with_hash()test helpers (#38) - Added
sized_contentfixture for generating test content of specific sizes (#38) - Added upload API tests: upload without tag, artifact creation verification, S3 object creation (#38)
- Added download API tests: tag: prefix resolution, 404 for nonexistent project/package/artifact (#38)
- Added download header tests: Content-Type, Content-Length, Content-Disposition, ETag, X-Checksum-SHA256 (#38)
- Added error handling tests: timeout behavior, checksum validation, resource cleanup, graceful error responses (#38)
- Added version API tests: version creation, auto-detection, listing, download by version prefix (#38)
- Added integrity verification tests: round-trip hash verification, client-side verification workflow, size variants (1KB-10MB) (#40)
- Added consistency check endpoint tests with response format validation (#40)
- Added corruption detection tests: bit flip, truncation, appended content, size mismatch, missing S3 objects (#40)
- Added Digest header tests (RFC 3230) and verification mode tests (#40)
- Added integrity verification documentation (
docs/integrity-verification.md) (#40) - Added conditional request support for downloads (If-None-Match, If-Modified-Since) returning 304 Not Modified (#42)
- Added caching headers to downloads: Cache-Control (immutable), Last-Modified (#42)
- Added 416 Range Not Satisfiable response for invalid range requests (#42)
- Added download completion logging with bytes transferred and throughput (#42)
- Added client disconnect handling during streaming downloads (#42)
- Added streaming download tests: range requests, conditional requests, caching headers, download resume (#42)
- Added upload duration and throughput metrics (
duration_ms,throughput_mbps) to upload response (#43) - Added upload progress logging for large files (hash computation and multipart upload phases) (#43)
- Added client disconnect handling during uploads with proper cleanup (#43)
- Added upload progress tracking endpoint
GET /upload/{upload_id}/progressfor resumable uploads (#43) - Added large file upload tests (10MB, 100MB, 1GB) with multipart upload verification (#43)
- Added upload cancellation and timeout handling tests (#43)
- Added comprehensive API documentation for upload endpoints with curl, Python, and JavaScript examples (#43)
- Added
package_versionstable for immutable version tracking separate from mutable tags (#56)- Versions are set at upload time via explicit
versionparameter or auto-detected from filename/metadata - Version detection priority: explicit parameter > package metadata > filename pattern
- Versions are immutable once created (unlike tags which can be moved)
- Versions are set at upload time via explicit
- Added version API endpoints (#56):
GET /api/v1/project/{project}/{package}/versions- List all versions for a packageGET /api/v1/project/{project}/{package}/versions/{version}- Get specific version detailsDELETE /api/v1/project/{project}/{package}/versions/{version}- Delete a version (admin only)
- Added version support to upload endpoint via
versionform parameter (#56) - Added
version:X.Y.Zprefix for explicit version resolution in download refs (#56) - Added version field to tag responses (shows which version the artifact has, if any) (#56)
- Added migration
007_package_versions.sqlwith ref_count triggers and data migration from semver tags (#56) - Added production deployment job triggered by semantic version tags (v1.0.0) with manual approval gate (#63)
- Added production Helm values file with persistence enabled (20Gi PostgreSQL, 100Gi MinIO) (#63)
- Added integration tests for production deployment (#63)
- Added GitLab CI pipeline for feature branch deployments to dev namespace (#51)
- Added
deploy_featurejob with dynamic hostnames and unique release names (#51) - Added
cleanup_featurejob withon_stopfor automatic cleanup on merge (#51) - Added
values-dev.yamlHelm values for lightweight ephemeral environments (#51) - Added main branch deployment to stage environment (#51)
- Added post-deployment integration tests (#51)
- Added internal proxy configuration for npm, pip, helm, and apt (#51)
Changed
- CI integration tests now run full pytest suite (~350 tests) against deployed environment instead of 3 smoke tests
- CI production deployment uses lightweight smoke tests only (no test data creation in prod)
- Updated download ref resolution to check versions before tags (version → tag → artifact ID) (#56)
- Deploy jobs now require all security scans to pass before deployment (added test_image, app_deps_scan, cve_scan, cve_sbom_analysis, app_sbom_analysis to dependencies) (#63)
- Increased deploy job timeout from 5m to 10m (#63)
- Added
--atomicflag to Helm deployments for automatic rollback on failure - Adjusted dark mode color palette to use lighter background tones for better readability and reduced eye strain (#52)
- Replaced project card grid with sortable data table on Home page for better handling of large project lists
- Replaced package card grid with sortable data table on Project page for consistency
- Replaced SortDropdown with table header sorting on Package page for consistency
- Enabled sorting on supported table columns (name, created, updated) via clickable headers
- Updated browser tab title to "Orchard" with custom favicon
- Improved pod naming: Orchard pods now named
orchard-{env}-server-*for clarity (#51)
Fixed
- Fixed Content-Disposition header encoding for non-ASCII filenames using RFC 5987 (#38)
- Fixed deploy jobs running even when tests or security scans fail (changed rules from
when: alwaystowhen: on_success) (#63) - Fixed python_tests job not using internal PyPI proxy (#63)
- Fixed
cleanup_featurejob failing when branch is deleted (GIT_STRATEGY: none) (#51) - Fixed gitleaks false positives with fingerprints for historical commits (#51)
- Fixed integration tests running when deploy fails (
when: on_success) (#51) - Fixed static file serving for favicon and other files in frontend dist root
- Fixed deploy jobs running when secrets scan fails (added
secretsto deploy dependencies) - Fixed dev environment memory requests to equal limits per cluster Kyverno policy
- Fixed init containers missing resource limits (Kyverno policy compliance)
- Fixed Python SyntaxWarning for invalid escape sequence in database migration regex pattern
Removed
- Removed unused
store_streaming()method from storage.py (#51)
[0.4.0] - 2026-01-12
Added
- Added user authentication system with session-based login (#50)
userstable with password hashing (bcrypt), admin flag, active statussessionstable for web login sessions (24-hour expiry)auth_settingstable for future OIDC configuration- Default admin user created on first boot (username: admin, password: admin)
- Added auth API endpoints (#50)
POST /api/v1/auth/login- Login with username/passwordPOST /api/v1/auth/logout- Logout and clear sessionGET /api/v1/auth/me- Get current user infoPOST /api/v1/auth/change-password- Change own password
- Added API key management with user ownership (#50)
POST /api/v1/auth/keys- Create API key (format:orch_<random>)GET /api/v1/auth/keys- List user's API keysDELETE /api/v1/auth/keys/{id}- Revoke API key- Added
owner_id,scopes,descriptioncolumns toapi_keystable
- Added admin user management endpoints (#50)
GET /api/v1/admin/users- List all usersPOST /api/v1/admin/users- Create userGET /api/v1/admin/users/{username}- Get user detailsPUT /api/v1/admin/users/{username}- Update user (admin/active status)POST /api/v1/admin/users/{username}/reset-password- Reset password
- Added
auth.pymodule with AuthService class and FastAPI dependencies (#50) - Added auth schemas: LoginRequest, LoginResponse, UserResponse, APIKeyResponse (#50)
- Added migration
006_auth_tables.sqlfor auth database tables (#50) - Added frontend Login page with session management (#50)
- Added frontend API Keys management page (#50)
- Added frontend Admin Users page (admin-only) (#50)
- Added AuthContext for frontend session state (#50)
- Added user menu to Layout header with login/logout (#50)
- Added 15 integration tests for auth system (#50)
- Added reusable
DragDropUploadcomponent for artifact uploads (#8)- Drag-and-drop file selection with visual feedback
- Click-to-browse fallback
- Multiple file upload support with queue management
- Real-time progress indicators with speed and ETA
- File type and size validation (configurable)
- Concurrent upload handling (configurable max concurrent)
- Automatic retry with exponential backoff for network errors
- Individual file status (pending, uploading, complete, failed)
- Retry and remove actions per file
- Auto-dismiss success messages after 5 seconds
- Integrated DragDropUpload into PackagePage replacing basic file input (#8)
- Added frontend testing infrastructure with Vitest and React Testing Library (#14)
- Configured Vitest for React/TypeScript with jsdom
- Added 24 unit tests for DragDropUpload component
- Tests cover: rendering, drag-drop events, file validation, upload queue, progress, errors
- Added chunked upload support for large files (#9)
- Files >100MB automatically use chunked upload API (10MB chunks)
- Client-side SHA256 hash computation via Web Crypto API
- localStorage persistence for resume after browser close
- Deduplication check at upload init phase
- Added offline detection and network resilience (#12)
- Automatic pause when browser goes offline
- Auto-resume when connection restored
- Offline banner UI with status message
- XHR abort on network loss to prevent hung requests
- Added download by artifact ID feature (#10)
- Direct artifact ID input field on package page
- Hex-only input validation with character count
- File size and filename displayed in tag list
- Added backend security tests (#15)
- Path traversal prevention tests for upload/download
- Malformed request handling tests
- Checksum validation tests
- 10 new security-focused integration tests
- Added download verification with
verifyandverify_modequery parameters (#26)?verify=true&verify_mode=pre- Pre-verification: verify before streaming (guaranteed no corrupt data)?verify=true&verify_mode=stream- Streaming verification: verify while streaming (logs error if mismatch)
- Added checksum response headers to all download endpoints (#27)
X-Checksum-SHA256- SHA256 hash of the artifactX-Content-Length- File size in bytesX-Checksum-MD5- MD5 hash (if available)ETag- Artifact ID (SHA256)Digest- RFC 3230 format sha-256 hash (base64)X-Verified- Verification status (true/false/pending)
- Added
checksum.pymodule with SHA256 utilities (#26)compute_sha256()andcompute_sha256_stream()functionsHashingStreamWrapperfor incremental hash computationVerifyingStreamWrapperfor stream verificationverify_checksum()andverify_checksum_strict()functionsChecksumMismatchErrorexception with context
- Added
get_verified()andget_stream_verified()methods to storage layer (#26) - Added
logging_config.pymodule with structured logging (#28)- JSON logging format for production
- Request ID tracking via context variables
- Verification failure logging with full context
- Added
log_levelandlog_formatsettings to configuration (#28) - Added 62 unit tests for checksum utilities and verification (#29)
- Added 17 integration tests for download verification API (#29)
- Added global artifacts endpoint
GET /api/v1/artifactswith project/package/tag/size/date filters (#18) - Added global tags endpoint
GET /api/v1/tagswith project/package/search/date filters (#18) - Added wildcard pattern matching (
*) for tag filters across all endpoints (#18) - Added comma-separated multi-value support for tag filters (#18)
- Added
searchparameter to/api/v1/uploadsfor filename search (#18) - Added
tagfilter to/api/v1/uploadsendpoint (#18) - Added
sortandorderparameters to/api/v1/uploadsendpoint (#18) - Added
min_sizeandmax_sizefilters to package artifacts endpoint (#18) - Added
sortandorderparameters to package artifacts endpoint (#18) - Added
fromandtodate filters to package tags endpoint (#18) - Added
GlobalArtifactResponseandGlobalTagResponseschemas (#18) - Added S3 object verification before database commit during upload (#19)
- Added S3 object cleanup on database commit failure (#19)
- Added upload duration tracking (
duration_msfield) (#19) - Added
User-Agentheader capture during uploads (#19) - Added
X-Checksum-SHA256header support for client-side checksum verification (#19) - Added
status,error_message,client_checksumcolumns to uploads table (#19) - Added
upload_lockstable for future concurrent upload conflict detection (#19) - Added consistency check endpoint
GET /api/v1/admin/consistency-check(#19) - Added
PUT /api/v1/projects/{project}endpoint for project updates with audit logging (#20) - Added
PUT /api/v1/project/{project}/packages/{package}endpoint for package updates with audit logging (#20) - Added
artifact.downloadaudit logging to download endpoint (#20) - Added
ProjectHistoryandPackageHistorymodels with database triggers (#20) - Added migration
004_history_tables.sqlfor project/package history (#20) - Added migration
005_upload_enhancements.sqlfor upload status tracking (#19) - Added 9 integration tests for global artifacts/tags endpoints (#18)
- Added global uploads query endpoint
GET /api/v1/uploadswith project/package/user/date filters (#18) - Added project-level uploads endpoint
GET /api/v1/project/{project}/uploads(#18) - Added
has_morefield to pagination metadata for easier pagination UI (#18) - Added
upload_id,content_type,original_name,created_atfields to upload response (#19) - Added audit log API endpoints with filtering and pagination (#20)
GET /api/v1/audit-logs- list all audit logs with action/resource/user/date filtersGET /api/v1/projects/{project}/audit-logs- project-scoped audit logsGET /api/v1/project/{project}/{package}/audit-logs- package-scoped audit logs
- Added upload history API endpoints (#20)
GET /api/v1/project/{project}/{package}/uploads- list upload events for a packageGET /api/v1/artifact/{id}/uploads- list all uploads of a specific artifact
- Added artifact provenance endpoint
GET /api/v1/artifact/{id}/history(#20)- Returns full artifact history including packages, tags, and upload events
- Added audit logging for project.create, package.create, tag.create, tag.update, artifact.upload actions (#20)
- Added
AuditLogResponse,UploadHistoryResponse,ArtifactProvenanceResponseschemas (#20) - Added
TagHistoryDetailResponseschema with artifact metadata (#20) - Added 31 integration tests for audit log, history, and upload query endpoints (#22)
Changed
- Standardized audit action naming to
{entity}.{action}pattern (project.delete, package.delete, tag.delete) (#20) - Added
StorageBackendprotocol/interface for backend-agnostic storage (#33) - Added
health_check()method to storage backend with/healthendpoint integration (#33) - Added
verify_integrity()method for post-upload hash validation (#33) - Added S3 configuration options:
s3_verify_ssl,s3_connect_timeout,s3_read_timeout,s3_max_retries(#33) - Added
S3StorageUnavailableErrorandHashCollisionErrorexception types (#33) - Added hash collision detection by comparing file sizes during deduplication (#33)
- Added garbage collection endpoint
POST /api/v1/admin/garbage-collectfor orphaned artifacts (#36) - Added orphaned artifacts listing endpoint
GET /api/v1/admin/orphaned-artifacts(#36) - Added global storage statistics endpoint
GET /api/v1/stats(#34) - Added storage breakdown endpoint
GET /api/v1/stats/storage(#34) - Added deduplication metrics endpoint
GET /api/v1/stats/deduplication(#34) - Added per-project statistics endpoint
GET /api/v1/projects/{project}/stats(#34) - Added per-package statistics endpoint
GET /api/v1/project/{project}/packages/{package}/stats(#34) - Added per-artifact statistics endpoint
GET /api/v1/artifact/{id}/stats(#34) - Added cross-project deduplication endpoint
GET /api/v1/stats/cross-project(#34) - Added timeline statistics endpoint
GET /api/v1/stats/timelinewith daily/weekly/monthly periods (#34) - Added stats export endpoint
GET /api/v1/stats/exportwith JSON/CSV formats (#34) - Added summary report endpoint
GET /api/v1/stats/reportwith markdown/JSON formats (#34) - Added Dashboard page at
/dashboardwith storage and deduplication visualizations (#34) - Added pytest infrastructure with mock S3 client for unit testing (#35)
- Added unit tests for SHA256 hash calculation (#35)
- Added unit tests for duplicate detection and deduplication behavior (#35)
- Added integration tests for upload scenarios and ref_count management (#35)
- Added integration tests for S3 verification and failure cleanup (#35)
- Added integration tests for all stats endpoints (#35)
- Added integration tests for cascade deletion ref_count behavior (package/project delete) (#35)
- Added integration tests for tag update ref_count adjustments (#35)
- Added integration tests for garbage collection endpoints (#35)
- Added integration tests for file size validation (#35)
- Added test dependencies to requirements.txt (pytest, pytest-asyncio, pytest-cov, httpx, moto) (#35)
- Added
ORCHARD_MAX_FILE_SIZEconfig option (default: 10GB) for upload size limits (#37) - Added
ORCHARD_MIN_FILE_SIZEconfig option (default: 1 byte, rejects empty files) (#37) - Added file size validation to upload and resumable upload endpoints (#37)
- Added comprehensive deduplication design document (
docs/design/deduplication-design.md) (#37)
Fixed
- Fixed Helm chart
minio.ingressconflicting with Bitnami MinIO subchart by renaming tominioIngress(#48) - Fixed JSON report serialization error for Decimal types in
GET /api/v1/stats/report(#34) - Fixed resumable upload double-counting ref_count when tag provided (removed manual increment, SQL triggers handle it) (#35)
[0.3.0] - 2025-12-15
Changed
- Changed default download mode from
proxytopresignedfor better performance (#48)
Added
- Added presigned URL support for direct S3 downloads (#48)
- Added
ORCHARD_DOWNLOAD_MODEconfig option (presigned,redirect,proxy) (#48) - Added
ORCHARD_PRESIGNED_URL_EXPIRYconfig option (default: 3600 seconds) (#48) - Added
?mode=query parameter to override download mode per-request (#48) - Added
/api/v1/project/{project}/{package}/+/{ref}/urlendpoint for getting presigned URLs (#48) - Added
PresignedUrlResponseschema with URL, expiry, checksums, and artifact metadata (#48) - Added MinIO ingress support in Helm chart for presigned URL access (#48)
- Added
orchard.download.modeandorchard.download.presignedUrlExpiryHelm values (#48) - Added integrity verification workflow design document (#24)
- Added
sha256field to API responses for clarity (alias ofid) (#25) - Added
checksum_sha1field to artifacts table for compatibility (#25) - Added
s3_etagfield to artifacts table for S3 verification (#25) - Compute and store MD5, SHA1, and S3 ETag alongside SHA256 during upload (#25)
- Added
Dockerfile.localanddocker-compose.local.ymlfor local development (#25) - Added migration script
003_checksum_fields.sqlfor existing databases (#25)
[0.2.0] - 2025-12-15
Added
- Added
formatandplatformfields to packages table (#16) - Added
checksum_md5andmetadataJSONB fields to artifacts table (#16) - Added
updated_atfield to tags table (#16) - Added
tag_name,user_agent,duration_ms,deduplicated,checksum_verifiedfields to uploads table (#16) - Added
change_typefield to tag_history table (#16) - Added composite indexes for common query patterns (#16)
- Added GIN indexes on JSONB fields for efficient JSON queries (#16)
- Added partial index for public projects (#16)
- Added database triggers for
updated_attimestamps (#16) - Added database triggers for maintaining artifact
ref_countaccuracy (#16) - Added CHECK constraints for data integrity (
size > 0,ref_count >= 0) (#16) - Added migration script
002_schema_enhancements.sqlfor existing databases (#16)
Changed
- Updated images to use internal container BSF proxy (#46)
[0.1.0] - 2025-12-12
Added
- Added Prosper docker template config (#45)
Changed
- Changed the Dockerfile npm build arg to use the deps.global.bsf.tools URL as the default registry (#45)