diff --git a/CHANGELOG.md b/CHANGELOG.md index d67a714e..8796f492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,8 @@ reports exit code `124`. Callers that join a `run: once` or `when_changed` task already running now honor their own `timeout`, and inherit that task's failure instead of being told it succeeded (#1569, #2898 by @vmaerten). +- Fixed a pinned `checksum:` not being verified when a remote Taskfile came from + the cache (#2980 by @vmaerten). ## v3.52.0 - 2026-07-02 diff --git a/taskfile/reader.go b/taskfile/reader.go index 1b8556c1..d5f5e663 100644 --- a/taskfile/reader.go +++ b/taskfile/reader.go @@ -457,7 +457,10 @@ func (r *Reader) readNodeContent(ctx context.Context, node Node) ([]byte, error) return nil, err } - // If the given checksum doesn't match the sum pinned in the Taskfile + return verifyPinnedChecksum(node, b) +} + +func verifyPinnedChecksum(node Node, b []byte) ([]byte, error) { checksum := checksum(b) if !node.Verify(checksum) { return nil, &errors.TaskfileDoesNotMatchChecksum{ @@ -466,7 +469,6 @@ func (r *Reader) readNodeContent(ctx context.Context, node Node) ([]byte, error) ActualChecksum: checksum, } } - return b, nil } @@ -475,7 +477,7 @@ func (r *Reader) readRemoteNodeContent(ctx context.Context, node RemoteNode) ([] now := time.Now().UTC() timestamp := cache.ReadTimestamp() expiry := timestamp.Add(r.cacheExpiryDuration) - cacheValid := now.Before(expiry) + cacheValid := !timestamp.After(now) && now.Before(expiry) var cacheFound bool r.debugf("checking cache for %q in %q\n", node.Location(), cache.Location()) @@ -498,7 +500,7 @@ func (r *Reader) readRemoteNodeContent(ctx context.Context, node RemoteNode) ([] // If we can't fetch a fresh copy, we should use the cache anyway if r.offline { r.debugf("in offline mode, using expired cache\n") - return cachedBytes, nil + return verifyPinnedChecksum(node, cachedBytes) } // Some other error @@ -510,7 +512,7 @@ func (r *Reader) readRemoteNodeContent(ctx context.Context, node RemoteNode) ([] r.debugf("cache found\n") // Not being forced to redownload, return cache if !r.download { - return cachedBytes, nil + return verifyPinnedChecksum(node, cachedBytes) } cacheFound = true } @@ -526,7 +528,7 @@ func (r *Reader) readRemoteNodeContent(ctx context.Context, node RemoteNode) ([] } else { r.debugf("failed to fetch remote file: %s: using expired cache\n", ctx.Err().Error()) } - return cachedBytes, nil + return verifyPinnedChecksum(node, cachedBytes) } return nil, err }