From 50454db3fb84e82fe50d87ee9c482992cacef8bd Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 30 May 2026 20:31:43 -0500 Subject: [PATCH] feat(updates): use full Joomla channel names in update feeds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the full Joomla convention for update stream tag names: - dev → development - rc → release-candidate - alpha, beta, stable unchanged Add NormalizeChannel() helper that maps shorthand names (dev, rc) to full names so license key allowed_channels work with either format. Applied in XML generation, JSON generation, and key validation. Co-Authored-By: Claude Opus 4.6 (1M context) --- routers/web/repo/updateserver.go | 4 ++ services/updateserver/dolibarr.go | 2 +- services/updateserver/joomla.go | 61 ++++++++++++++++++++++++------- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/routers/web/repo/updateserver.go b/routers/web/repo/updateserver.go index c3c040bcbf..957ecd60de 100644 --- a/routers/web/repo/updateserver.go +++ b/routers/web/repo/updateserver.go @@ -56,6 +56,10 @@ func validateUpdateKey(ctx *context.Context) (allowedChannels []string, ok bool) channels = parsed } } + // Normalize shorthand names to full Joomla convention. + for i := range channels { + channels[i] = updateserver.NormalizeChannel(channels[i]) + } return channels, true } diff --git a/services/updateserver/dolibarr.go b/services/updateserver/dolibarr.go index dc4c12d672..d434182344 100644 --- a/services/updateserver/dolibarr.go +++ b/services/updateserver/dolibarr.go @@ -69,7 +69,7 @@ func GenerateDolibarrJSON(ctx context.Context, repo *repo_model.Repository) (*Do } } - for _, ch := range []string{"stable", "rc", "beta", "alpha", "dev"} { + for _, ch := range AllChannels { rel, ok := bestByChannel[ch] if !ok { continue diff --git a/services/updateserver/joomla.go b/services/updateserver/joomla.go index 83a224027d..100d52e78b 100644 --- a/services/updateserver/joomla.go +++ b/services/updateserver/joomla.go @@ -64,22 +64,54 @@ type xmlTargetPlat struct { Version string `xml:"version,attr"` } +// channelFromTag maps a release tag name to a Joomla update channel. +// Joomla update stream names (full convention). +const ( + ChannelStable = "stable" + ChannelReleaseCandidate = "release-candidate" + ChannelBeta = "beta" + ChannelAlpha = "alpha" + ChannelDevelopment = "development" +) + +// AllChannels in display order (most stable first). +var AllChannels = []string{ChannelStable, ChannelReleaseCandidate, ChannelBeta, ChannelAlpha, ChannelDevelopment} + // channelFromTag maps a release tag name to a Joomla update channel. func channelFromTag(tagName string, isPrerelease bool) string { lower := strings.ToLower(tagName) switch { case strings.Contains(lower, "-dev") || strings.Contains(lower, "development"): - return "dev" - case strings.Contains(lower, "-alpha") || strings.Contains(lower, "alpha"): - return "alpha" - case strings.Contains(lower, "-beta") || strings.Contains(lower, "beta"): - return "beta" + return ChannelDevelopment + case strings.Contains(lower, "-alpha"): + return ChannelAlpha + case strings.Contains(lower, "-beta"): + return ChannelBeta case strings.Contains(lower, "-rc") || strings.Contains(lower, "release-candidate"): - return "rc" + return ChannelReleaseCandidate case isPrerelease: - return "rc" + return ChannelReleaseCandidate default: - return "stable" + return ChannelStable + } +} + +// NormalizeChannel maps shorthand channel names to the full Joomla convention. +// Accepts both "rc" and "release-candidate", "dev" and "development", etc. +func NormalizeChannel(ch string) string { + switch strings.ToLower(ch) { + case "rc", "release-candidate": + return ChannelReleaseCandidate + case "dev", "development": + return ChannelDevelopment + case "alpha": + return ChannelAlpha + case "beta": + return ChannelBeta + case "stable": + return ChannelStable + default: + return ch } } @@ -124,15 +156,16 @@ func GenerateJoomlaXML(ctx context.Context, repo *repo_model.Repository, allowed } // Build allowed channel set for filtering. + // Normalize shorthand names so both "rc" and "release-candidate" work. channelAllowed := make(map[string]bool) if len(allowedChannels) > 0 { for _, c := range allowedChannels { - channelAllowed[strings.ToLower(c)] = true + channelAllowed[NormalizeChannel(c)] = true } } var updates xmlUpdates - for _, ch := range []string{"stable", "rc", "beta", "alpha", "dev"} { + for _, ch := range AllChannels { // Skip channels not in the allowed set (when filtering is active). if len(channelAllowed) > 0 && !channelAllowed[ch] { continue @@ -223,13 +256,13 @@ func extractVersion(tagName string) string { // channelSuffix returns the version suffix for a channel. func channelSuffix(channel string) string { switch channel { - case "dev": + case ChannelDevelopment: return "-dev" - case "alpha": + case ChannelAlpha: return "-alpha" - case "beta": + case ChannelBeta: return "-beta" - case "rc": + case ChannelReleaseCandidate: return "-rc" default: return ""