37322e4212
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
PR RC Release / Build RC Release (pull_request) Successful in 22s
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Add release_stream_map table for explicitly assigning releases to update streams. When a mapping exists, it overrides automatic tag detection. When absent, falls back to tag name/suffix matching. New model: ReleaseStreamMap with SetReleaseStream, GetReleaseStream, ResolveReleaseStream (manual first, auto fallback). UI: stream selector dropdown on release create/edit page, shown when licensing is enabled. Options: auto-detect (default) or any configured stream (stable, release-candidate, beta, etc.). All three feed generators (Joomla, Dolibarr, WordPress) now use ResolveReleaseStream instead of MatchStreamFromTag. Migration v340 updated with release_stream_map table creation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
89 lines
2.9 KiB
Go
89 lines
2.9 KiB
Go
// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package licenses
|
|
|
|
import (
|
|
"context"
|
|
|
|
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db"
|
|
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/timeutil"
|
|
)
|
|
|
|
func init() {
|
|
db.RegisterModel(new(ReleaseStreamMap))
|
|
}
|
|
|
|
// ReleaseStreamMap manually assigns a release to an update stream.
|
|
// When present, overrides automatic stream detection from tag names.
|
|
type ReleaseStreamMap struct {
|
|
ID int64 `xorm:"pk autoincr"`
|
|
ReleaseID int64 `xorm:"UNIQUE NOT NULL INDEX"` // FK to release
|
|
RepoID int64 `xorm:"NOT NULL INDEX"` // for fast repo-scoped queries
|
|
StreamName string `xorm:"NOT NULL"` // e.g. "stable", "release-candidate"
|
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
|
}
|
|
|
|
func (ReleaseStreamMap) TableName() string {
|
|
return "release_stream_map"
|
|
}
|
|
|
|
// SetReleaseStream assigns or updates the stream for a release.
|
|
func SetReleaseStream(ctx context.Context, releaseID, repoID int64, streamName string) error {
|
|
existing := new(ReleaseStreamMap)
|
|
has, err := db.GetEngine(ctx).Where("release_id = ?", releaseID).Get(existing)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if has {
|
|
existing.StreamName = streamName
|
|
_, err = db.GetEngine(ctx).ID(existing.ID).Cols("stream_name").Update(existing)
|
|
return err
|
|
}
|
|
|
|
_, err = db.GetEngine(ctx).Insert(&ReleaseStreamMap{
|
|
ReleaseID: releaseID,
|
|
RepoID: repoID,
|
|
StreamName: streamName,
|
|
})
|
|
return err
|
|
}
|
|
|
|
// GetReleaseStream returns the manually assigned stream for a release, or empty string.
|
|
func GetReleaseStream(ctx context.Context, releaseID int64) string {
|
|
m := new(ReleaseStreamMap)
|
|
has, err := db.GetEngine(ctx).Where("release_id = ?", releaseID).Get(m)
|
|
if err != nil || !has {
|
|
return ""
|
|
}
|
|
return m.StreamName
|
|
}
|
|
|
|
// GetStreamMapForRepo returns all manual stream assignments for a repo.
|
|
func GetStreamMapForRepo(ctx context.Context, repoID int64) (map[int64]string, error) {
|
|
var maps []ReleaseStreamMap
|
|
if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&maps); err != nil {
|
|
return nil, err
|
|
}
|
|
result := make(map[int64]string, len(maps))
|
|
for _, m := range maps {
|
|
result[m.ReleaseID] = m.StreamName
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// ResolveReleaseStream returns the stream for a release: manual mapping first, auto-detect fallback.
|
|
func ResolveReleaseStream(ctx context.Context, releaseID int64, tagName string, isPrerelease bool, streams []StreamDef) string {
|
|
if manual := GetReleaseStream(ctx, releaseID); manual != "" {
|
|
return manual
|
|
}
|
|
return MatchStreamFromTag(tagName, isPrerelease, streams)
|
|
}
|
|
|
|
// DeleteReleaseStream removes the manual stream assignment for a release.
|
|
func DeleteReleaseStream(ctx context.Context, releaseID int64) error {
|
|
_, err := db.GetEngine(ctx).Where("release_id = ?", releaseID).Delete(new(ReleaseStreamMap))
|
|
return err
|
|
}
|