Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
gets `{{.TIMESTAMP}}` and no longer a `{{.CHECKSUM}}` (which now renders as an
empty string), and neither variable is injected when the effective method is
`none` (#2924 by @vmaerten).
- Fixed `{{.TIMESTAMP}}` rendering as the Unix epoch (e.g. `1970-01-01 01:00:00
+0100 CET`) when a task's `sources` matched no file. It now renders as an
empty string, instead of a date that looks genuine and carries the machine's
time zone (#2960 by @vmaerten).

## v3.52.0 - 2026-07-02

Expand Down
6 changes: 5 additions & 1 deletion internal/fingerprint/sources_timestamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,12 @@ func (checker *TimestampChecker) Value(t *ast.Task) (any, error) {
return time.Now(), err
}

// No source matched, so there is no modification time to report. Returning
// the Unix epoch here would render as a real date in templates, e.g.
// "1970-01-01 01:00:00 +0100 CET", which reads as a genuine timestamp and
// carries a machine-dependent zone.
if sourcesMaxTime.IsZero() {
return time.Unix(0, 0), nil
return "", nil
}

return sourcesMaxTime, nil
Expand Down
44 changes: 44 additions & 0 deletions internal/fingerprint/sources_timestamp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package fingerprint

import (
"os"
"path/filepath"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/go-task/task/v3/taskfile/ast"
)

func TestTimestampCheckerValue(t *testing.T) {
t.Parallel()

dir := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(dir, "source.txt"), []byte("content"), 0o644))
checker := NewTimestampChecker(t.TempDir(), true)

t.Run("reports the newest source modification time", func(t *testing.T) {
t.Parallel()

value, err := checker.Value(&ast.Task{
Dir: dir,
Sources: []*ast.Glob{{Glob: "source.txt"}},
})
require.NoError(t, err)
assert.IsType(t, time.Time{}, value)
assert.False(t, value.(time.Time).IsZero())
})

t.Run("reports no value when no source matches", func(t *testing.T) {
t.Parallel()

value, err := checker.Value(&ast.Task{
Dir: dir,
Sources: []*ast.Glob{{Glob: "gen/**/*.go"}},
})
require.NoError(t, err)
assert.Equal(t, "", value)
})
}