From 23c2fae2fb5a5cc24ab0eec766087d813bddf4e5 Mon Sep 17 00:00:00 2001 From: TheRealToxicDev Date: Sun, 25 Jan 2026 17:23:55 -0700 Subject: [PATCH 1/3] fix: more artifacts stuff and updated changelog --- CHANGELOG.md | 19 +++++++++++++++++++ internal/services/artifacts.go | 10 +++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b82207d..0d85f59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [0.1.1] - Unreleased + +### Added +- **Full version string for hosting panels** - Added `FullVersion` field to artifact entries + - Format: `{version}-{hash}` (e.g., `24769-315823736cfbc085104ca0d32779311cd2f1a5a8`) + - Compatible with Pterodactyl, Pelican, and similar hosting panel egg configurations + +### Fixed +- **Pagination total count** - Fixed incorrect total count in pagination metadata + - Previously returned count of paginated results instead of total filtered results + - Created `ArtifactsResult` struct to properly track total count after filtering but before pagination + - `hasMore` now correctly indicates if more pages are available + +### Changed +- Updated all artifact handlers to use new `ArtifactsResult` return type +- Refactored `generateFullVersion()` helper to accept hash parameter + +--- + ## [0.1.0] - 2026-01-25 ### Added diff --git a/internal/services/artifacts.go b/internal/services/artifacts.go index 1ee57f2..bb337b1 100644 --- a/internal/services/artifacts.go +++ b/internal/services/artifacts.go @@ -392,7 +392,7 @@ func (s *ArtifactsService) GetArtifacts(query ArtifactsQuery) (*ArtifactsResult, for version, artifact := range processedData.Windows { artifacts = append(artifacts, ArtifactEntry{ Version: version, - FullVersion: s.generateFullVersion(version), + FullVersion: s.generateFullVersion(version, artifact.Hash), Hash: artifact.Hash, Platform: Windows, Date: artifact.Date, @@ -404,7 +404,7 @@ func (s *ArtifactsService) GetArtifacts(query ArtifactsQuery) (*ArtifactsResult, for version, artifact := range processedData.Linux { artifacts = append(artifacts, ArtifactEntry{ Version: version, - FullVersion: s.generateFullVersion(version), + FullVersion: s.generateFullVersion(version, artifact.Hash), Hash: artifact.Hash, Platform: Linux, Date: artifact.Date, @@ -464,9 +464,9 @@ func (s *ArtifactsService) determineSupportStatus(version int) SupportStatus { } // generateFullVersion creates the full version string for hosting panels like Pterodactyl -// Format: v1.0.0.{build_number} (e.g., v1.0.0.12345) -func (s *ArtifactsService) generateFullVersion(version string) string { - return fmt.Sprintf("v1.0.0.%s", version) +// Format: {version}-{hash} (e.g., 24769-315823736cfbc085104ca0d32779311cd2f1a5a8) +func (s *ArtifactsService) generateFullVersion(version string, hash string) string { + return fmt.Sprintf("%s-%s", version, hash) } func (s *ArtifactsService) estimateSize(version string, platform string) int64 { From 2696cb1d19cba75da25eaf43028bb472ecb2f951 Mon Sep 17 00:00:00 2001 From: TheRealToxicDev Date: Sun, 25 Jan 2026 17:32:57 -0700 Subject: [PATCH 2/3] fix: even more stuff yes --- CHANGELOG.md | 6 ++++++ internal/handlers/artifacts.go | 8 ++++++++ internal/services/artifacts.go | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d85f59..5e79efb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Format: `{version}-{hash}` (e.g., `24769-315823736cfbc085104ca0d32779311cd2f1a5a8`) - Compatible with Pterodactyl, Pelican, and similar hosting panel egg configurations +- **Artifact statistics in API response** - Added `stats` object to metadata + - Includes counts for: `total`, `recommended`, `latest`, `active`, `deprecated`, `eol` + - Calculated from filtered results before pagination + - Enables frontend to show accurate totals regardless of current page + ### Fixed - **Pagination total count** - Fixed incorrect total count in pagination metadata - Previously returned count of paginated results instead of total filtered results @@ -41,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Updated all artifact handlers to use new `ArtifactsResult` return type - Refactored `generateFullVersion()` helper to accept hash parameter +- Added `ArtifactStats` struct and `calculateStats()` helper function --- diff --git a/internal/handlers/artifacts.go b/internal/handlers/artifacts.go index cfcdd64..fe8298a 100644 --- a/internal/handlers/artifacts.go +++ b/internal/handlers/artifacts.go @@ -91,6 +91,14 @@ func GetArtifacts(c *fiber.Ctx) error { "hasMore": offset+len(artifacts) < totalFiltered, "platforms": platforms, "supportStatuses": statuses, + "stats": fiber.Map{ + "total": result.Stats.Total, + "recommended": result.Stats.Recommended, + "latest": result.Stats.Latest, + "active": result.Stats.Active, + "deprecated": result.Stats.Deprecated, + "eol": result.Stats.EOL, + }, "query": fiber.Map{ "platform": query.Platform, "version": query.Version, diff --git a/internal/services/artifacts.go b/internal/services/artifacts.go index bb337b1..ab8f95e 100644 --- a/internal/services/artifacts.go +++ b/internal/services/artifacts.go @@ -88,10 +88,21 @@ type ArtifactEntry struct { Size int64 } +// ArtifactStats holds counts by support status +type ArtifactStats struct { + Total int `json:"total"` + Recommended int `json:"recommended"` + Latest int `json:"latest"` + Active int `json:"active"` + Deprecated int `json:"deprecated"` + EOL int `json:"eol"` +} + // ArtifactsResult holds paginated results with metadata type ArtifactsResult struct { Data []ArtifactEntry Total int + Stats ArtifactStats FilteredBy string } @@ -420,6 +431,9 @@ func (s *ArtifactsService) GetArtifacts(query ArtifactsQuery) (*ArtifactsResult, // Store total count after filtering but before pagination totalFiltered := len(filtered) + // Calculate stats from filtered results (before pagination) + stats := s.calculateStats(filtered) + // Apply sorting sorted := s.SortArtifacts(filtered, query.SortBy, query.SortOrder) @@ -432,6 +446,7 @@ func (s *ArtifactsService) GetArtifacts(query ArtifactsQuery) (*ArtifactsResult, return &ArtifactsResult{ Data: paginated, Total: totalFiltered, + Stats: stats, }, nil } @@ -469,6 +484,28 @@ func (s *ArtifactsService) generateFullVersion(version string, hash string) stri return fmt.Sprintf("%s-%s", version, hash) } +// calculateStats calculates artifact counts by support status +func (s *ArtifactsService) calculateStats(artifacts []ArtifactEntry) ArtifactStats { + stats := ArtifactStats{ + Total: len(artifacts), + } + for _, artifact := range artifacts { + switch artifact.SupportStatus { + case Recommended: + stats.Recommended++ + case Latest: + stats.Latest++ + case Active: + stats.Active++ + case Deprecated: + stats.Deprecated++ + case EOL: + stats.EOL++ + } + } + return stats +} + func (s *ArtifactsService) estimateSize(version string, platform string) int64 { // Rough estimates in MB if platform == "windows" { From 0784df88e3652a42f4a114c154997813da14705f Mon Sep 17 00:00:00 2001 From: TheRealToxicDev Date: Sun, 25 Jan 2026 17:47:24 -0700 Subject: [PATCH 3/3] fix: artifact support logic and updated changelog --- CHANGELOG.md | 14 +++++++++++++- internal/handlers/artifacts.go | 2 +- internal/services/artifacts.go | 33 ++++++++++++++++++++++++--------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e79efb..afe240e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- -## [0.1.1] - Unreleased +## [0.2.0] - 2026-01-25 ### Added - **Full version string for hosting panels** - Added `FullVersion` field to artifact entries @@ -43,10 +43,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Created `ArtifactsResult` struct to properly track total count after filtering but before pagination - `hasMore` now correctly indicates if more pages are available +- **Latest vs Recommended logic** - Fixed support status assignment per CFX EOL policy + - **Latest** = Single newest version (for testing/bleeding edge) + - **Recommended** = Next 3 versions after Latest (stable for production) + - Support status now dynamically assigned based on version position, not hardcoded thresholds + - See https://aka.cfx.re/eol for CFX official policy + +- **EOL filter default** - Changed `includeEol` default from `true` to `false` + - EOL artifacts are now excluded by default for safety + - Users must explicitly opt-in to see end-of-life versions + ### Changed - Updated all artifact handlers to use new `ArtifactsResult` return type - Refactored `generateFullVersion()` helper to accept hash parameter - Added `ArtifactStats` struct and `calculateStats()` helper function +- Refactored `ProcessGitHubTags` to dynamically assign Latest/Recommended based on sorted position +- Simplified `determineSupportStatus()` to only handle Active/Deprecated/EOL thresholds --- diff --git a/internal/handlers/artifacts.go b/internal/handlers/artifacts.go index fe8298a..57a0b0b 100644 --- a/internal/handlers/artifacts.go +++ b/internal/handlers/artifacts.go @@ -37,7 +37,7 @@ func GetArtifacts(c *fiber.Ctx) error { Status: services.SupportStatus(c.Query("status", "")), SortBy: c.Query("sortBy", "version"), SortOrder: c.Query("sortOrder", "desc"), - IncludeEOL: c.QueryBool("includeEol", true), + IncludeEOL: c.QueryBool("includeEol", false), } // Parse limit and offset diff --git a/internal/services/artifacts.go b/internal/services/artifacts.go index ab8f95e..2d3d0d9 100644 --- a/internal/services/artifacts.go +++ b/internal/services/artifacts.go @@ -239,7 +239,7 @@ func (s *ArtifactsService) ProcessGitHubTags(tags []GitHubTag) ArtifactData { } } - // Sort by version number (descending) + // Sort by version number (descending) - highest version first sort.Slice(artifactTags, func(i, j int) bool { versionA := s.extractVersionNumber(artifactTags[i].Name) versionB := s.extractVersionNumber(artifactTags[j].Name) @@ -248,15 +248,28 @@ func (s *ArtifactsService) ProcessGitHubTags(tags []GitHubTag) ArtifactData { now := time.Now().UTC().Format(time.RFC3339) - for _, tag := range artifactTags { + for idx, tag := range artifactTags { versionNumber := s.extractVersionNumber(tag.Name) version := strconv.Itoa(versionNumber) + // Determine support status based on position in sorted list + // Position 0 = Latest (newest single version) + // Position 1-3 = Recommended (stable versions) + // Rest based on version thresholds + var status SupportStatus + if idx == 0 { + status = Latest + } else if idx <= 3 { + status = Recommended + } else { + status = s.determineSupportStatus(versionNumber) + } + baseEntry := Artifact{ Version: version, Hash: tag.Commit.SHA, Date: now, - SupportStatus: s.determineSupportStatus(versionNumber), + SupportStatus: status, } // Windows artifact @@ -464,14 +477,16 @@ func (s *ArtifactsService) extractVersionNumber(tagName string) int { } func (s *ArtifactsService) determineSupportStatus(version int) SupportStatus { + // Based on CFX EOL policy: https://aka.cfx.re/eol + // This is used for versions beyond the top 4 (Latest + 3 Recommended) + // which are dynamically assigned in ProcessGitHubTags + // Active = still supported but older + // Deprecated = support ending soon + // EOL = no longer supported switch { - case version >= 24500: - return Recommended - case version >= 24000: - return Latest - case version >= 23000: + case version >= 23000: // Still actively supported return Active - case version >= 20000: + case version >= 20000: // Support ending return Deprecated default: return EOL