Merge branch 'master' into codex/ttml-lrc-lyrics

This commit is contained in:
Yuuta 2026-04-18 23:19:44 +03:00 committed by GitHub
commit f79fd1087d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 64 additions and 8 deletions

View File

@ -4,7 +4,7 @@
"dockerfile": "Dockerfile",
"args": {
// Update the VARIANT arg to pick a version of Go: 1, 1.15, 1.14
"VARIANT": "1.25",
"VARIANT": "1.26",
// Options
"INSTALL_NODE": "true",
"NODE_VERSION": "v24"

View File

@ -64,6 +64,10 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
@ -99,6 +103,10 @@ jobs:
- name: Check out code into the Go module directory
uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: Download dependencies
run: go mod download

View File

@ -43,7 +43,7 @@ COPY --from=ui /build /build
########################################################################################################################
### Build Navidrome binary for Docker image (dynamic musl, enables native libwebp via dlopen)
FROM --platform=$BUILDPLATFORM public.ecr.aws/docker/library/golang:1.25-alpine AS build-alpine
FROM --platform=$BUILDPLATFORM public.ecr.aws/docker/library/golang:1.26-alpine AS build-alpine
COPY --from=xx / /
ARG TARGETPLATFORM
@ -82,7 +82,7 @@ EOT
########################################################################################################################
### Build Navidrome binary for standalone distribution (static glibc, cross-compiled)
FROM --platform=$BUILDPLATFORM public.ecr.aws/docker/library/golang:1.25-trixie AS base
FROM --platform=$BUILDPLATFORM public.ecr.aws/docker/library/golang:1.26-trixie AS base
RUN apt-get update && apt-get install -y clang lld
COPY --from=xx / /
WORKDIR /workspace

4
context7.json Normal file
View File

@ -0,0 +1,4 @@
{
"url": "https://context7.com/navidrome/navidrome",
"public_key": "pk_WqzhKScNKWQ84J4n0oG0J"
}

View File

@ -7,12 +7,11 @@ import (
"image/jpeg"
"image/png"
"io"
"os"
"path/filepath"
"time"
_ "github.com/gen2brain/webp"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/conf/configtest"
"github.com/navidrome/navidrome/log"
@ -146,6 +145,51 @@ var _ = Describe("Artwork", func() {
Entry(nil, " embedded , front.* , cover.*,folder.*", "tests/fixtures/artist/an-album/test.mp3"),
)
})
Context("LastUpdated", func() {
// Regression test for #5377: LastUpdated feeds the HTTP Last-Modified header.
// It must return max(album.UpdatedAt, ImagesUpdatedAt) so browsers revalidate
// cached cover art when only the image file changes.
now := time.Now().Truncate(time.Second)
DescribeTable("returns the max of album.UpdatedAt and ImagesUpdatedAt",
func(albumUpdatedAt, imagesUpdatedAt, expected time.Time) {
album := model.Album{ID: "al1", UpdatedAt: albumUpdatedAt}
folderRepo.result = []model.Folder{{ImagesUpdatedAt: imagesUpdatedAt}}
ds.Album(ctx).(*tests.MockAlbumRepo).SetData(model.Albums{album})
ar, err := newAlbumArtworkReader(ctx, aw, album.CoverArtID(), nil)
Expect(err).ToNot(HaveOccurred())
Expect(ar.LastUpdated()).To(Equal(expected))
},
Entry("album newer than images", now, now.Add(-1*time.Hour), now),
Entry("images newer than album", now.Add(-24*time.Hour), now.Add(-1*time.Hour), now.Add(-1*time.Hour)),
Entry("equal timestamps", now, now, now),
)
})
})
Describe("discArtworkReader", func() {
Context("LastUpdated", func() {
// Regression test for #5377: same bug as albumArtworkReader — disc covers
// must also revalidate when the image file changes, not only when media files do.
now := time.Now().Truncate(time.Second)
DescribeTable("returns the max of album.UpdatedAt and ImagesUpdatedAt",
func(albumUpdatedAt, imagesUpdatedAt, expected time.Time) {
album := model.Album{ID: "al1", UpdatedAt: albumUpdatedAt}
folderRepo.result = []model.Folder{{ImagesUpdatedAt: imagesUpdatedAt}}
ds.Album(ctx).(*tests.MockAlbumRepo).SetData(model.Albums{album})
ds.MediaFile(ctx).(*tests.MockMediaFileRepo).SetData(model.MediaFiles{
{ID: "mf1", AlbumID: "al1", DiscNumber: 1, Path: "tests/fixtures/test.mp3"},
})
artID := model.NewArtworkID(model.KindDiscArtwork, model.DiscArtworkID("al1", 1), nil)
dr, err := newDiscArtworkReader(ctx, aw, artID)
Expect(err).ToNot(HaveOccurred())
Expect(dr.LastUpdated()).To(Equal(expected))
},
Entry("album newer than images", now, now.Add(-1*time.Hour), now),
Entry("images newer than album", now.Add(-24*time.Hour), now.Add(-1*time.Hour), now.Add(-1*time.Hour)),
Entry("equal timestamps", now, now, now),
)
})
})
Describe("artistArtworkReader", func() {
Context("Multiple covers", func() {

View File

@ -72,7 +72,7 @@ func (a *albumArtworkReader) Key() string {
)
}
func (a *albumArtworkReader) LastUpdated() time.Time {
return a.album.UpdatedAt
return a.lastUpdate
}
func (a *albumArtworkReader) Reader(ctx context.Context) (io.ReadCloser, string, error) {

View File

@ -116,7 +116,7 @@ func (d *discArtworkReader) Key() string {
}
func (d *discArtworkReader) LastUpdated() time.Time {
return d.album.UpdatedAt
return d.lastUpdate
}
func (d *discArtworkReader) Reader(ctx context.Context) (io.ReadCloser, string, error) {

2
go.mod
View File

@ -1,6 +1,6 @@
module github.com/navidrome/navidrome
go 1.25.0
go 1.26.0
// Fork to implement raw tags support
replace go.senan.xyz/taglib => github.com/deluan/go-taglib v0.0.0-20260407173416-cf47afbaa67a