feat: implement Live/Remix filtering and add CI/CD pipeline
Some checks failed
Build and Push Docker Image / build (pull_request) Failing after 38s

This commit includes:

1. Live/Remix Filtering Feature:
   - Added ignore_live and ignore_remix columns to artist_settings table (migration 010)
   - Updated ArtistSettings struct with IgnoreLive and IgnoreRemix fields
   - Modified SaveArtistSettings and UpdateArtistSettings to handle new fields
   - Extended FilterOptions struct with IgnoreLive and IgnoreRemix
   - Updated ApplyTypeToggles and ApplyTypeTogglesToReleaseGroups to filter Live/Remix types
   - Added toggleIgnoreLive and toggleIgnoreRemix handlers in web layer
   - Updated ArtistData view model and artist.html template with new toggle UI
   - Comprehensive test coverage for all new functionality

2. CI/CD Pipeline with Gitea Actions:
   - Added .gitea/workflows/docker-build.yml for automated Docker builds
   - Workflow triggers on pushes to main/master and tags, plus PRs
   - Runs Go tests before building
   - Builds and pushes multi-architecture Docker images to gitea.mrixs.me
   - Includes caching for faster subsequent builds
   - Proper tagging strategy (branch, semver, SHA)
   - CI-CD-GUIDE.md documentation

3. Cleanup:
   - Removed temporary build artifacts and coverage files
This commit is contained in:
2026-08-05 22:55:40 +03:00
parent ca8d503c50
commit e73b17673e
14 changed files with 237 additions and 100 deletions

View File

@@ -4,6 +4,7 @@ import (
"testing"
"naviwatcher/internal/database"
"naviwatcher/internal/musicbrainz"
)
func TestSimilarity(t *testing.T) {
@@ -202,7 +203,7 @@ func TestFindMissingReleases(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := FindMissingReleases(tt.local, tt.external, threshold, TypeFilter{})
got := FindMissingReleases(tt.local, tt.external, threshold, musicbrainz.FilterOptions{})
gotRGIDs := make([]string, 0, len(got))
for _, m := range got {
@@ -225,7 +226,7 @@ func TestFindMissingReleases(t *testing.T) {
}
}
func TestFindMissingReleases_TypeFilter(t *testing.T) {
func TestFindMissingReleases_FilterOptions(t *testing.T) {
const threshold = 0.85
artist := "artist-a"
@@ -238,27 +239,27 @@ func TestFindMissingReleases_TypeFilter(t *testing.T) {
tests := []struct {
name string
filter TypeFilter
filter musicbrainz.FilterOptions
want []string
}{
{
name: "no filter reports all",
filter: TypeFilter{},
filter: musicbrainz.FilterOptions{},
want: []string{"rg-album", "rg-single", "rg-comp", "rg-comp-sec"},
},
{
name: "ignore singles drops Single primary type",
filter: TypeFilter{IgnoreSingles: true},
filter: musicbrainz.FilterOptions{IgnoreSingles: true},
want: []string{"rg-album", "rg-comp", "rg-comp-sec"},
},
{
name: "ignore compilations drops Compilation primary and secondary type",
filter: TypeFilter{IgnoreCompilations: true},
filter: musicbrainz.FilterOptions{IgnoreCompilations: true},
want: []string{"rg-album", "rg-single"},
},
{
name: "both toggles drop singles and compilations",
filter: TypeFilter{IgnoreSingles: true, IgnoreCompilations: true},
filter: musicbrainz.FilterOptions{IgnoreSingles: true, IgnoreCompilations: true},
want: []string{"rg-album"},
},
}
@@ -301,7 +302,7 @@ func TestFindMissingReleases_ThresholdBoundaryInclusive(t *testing.T) {
}
// With default threshold 0.85, "The Wall Live" does not match "The Wall";
// at a low threshold it would. Confirms threshold is honoured.
if len(FindMissingReleases(local, external, 0.85, TypeFilter{})) != 1 {
if len(FindMissingReleases(local, external, 0.85, musicbrainz.FilterOptions{})) != 1 {
t.Errorf("expected 1 missing at 0.85 threshold")
}
}