diff --git a/pkg/artifactcache/handler.go b/pkg/artifactcache/handler.go index ac4755e..b6600b6 100644 --- a/pkg/artifactcache/handler.go +++ b/pkg/artifactcache/handler.go @@ -311,10 +311,13 @@ func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprout db.Close() - if err := h.storage.Commit(cache.ID, cache.Size); err != nil { + size, err := h.storage.Commit(cache.ID, cache.Size) + if err != nil { h.responseJSON(w, r, 500, err) return } + // write real size back to cache, it may be different from the current value when the request doesn't specify it. + cache.Size = size db, err = h.openDB() if err != nil { diff --git a/pkg/artifactcache/model.go b/pkg/artifactcache/model.go index 5c28899..32b8ce5 100644 --- a/pkg/artifactcache/model.go +++ b/pkg/artifactcache/model.go @@ -15,11 +15,17 @@ func (c *Request) ToCache() *Cache { if c == nil { return nil } - return &Cache{ + ret := &Cache{ Key: c.Key, Version: c.Version, Size: c.Size, } + if c.Size == 0 { + // So the request comes from old versions of actions, like `actions/cache@v2`. + // It doesn't send cache size. Set it to -1 to indicate that. + ret.Size = -1 + } + return ret } type Cache struct { diff --git a/pkg/artifactcache/storage.go b/pkg/artifactcache/storage.go index a49c94e..9a2609a 100644 --- a/pkg/artifactcache/storage.go +++ b/pkg/artifactcache/storage.go @@ -46,7 +46,7 @@ func (s *Storage) Write(id uint64, offset int64, reader io.Reader) error { return err } -func (s *Storage) Commit(id uint64, size int64) error { +func (s *Storage) Commit(id uint64, size int64) (int64, error) { defer func() { _ = os.RemoveAll(s.tempDir(id)) }() @@ -54,15 +54,15 @@ func (s *Storage) Commit(id uint64, size int64) error { name := s.filename(id) tempNames, err := s.tempNames(id) if err != nil { - return err + return 0, err } if err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil { - return err + return 0, err } file, err := os.Create(name) if err != nil { - return err + return 0, err } defer file.Close() @@ -70,22 +70,26 @@ func (s *Storage) Commit(id uint64, size int64) error { for _, v := range tempNames { f, err := os.Open(v) if err != nil { - return err + return 0, err } n, err := io.Copy(file, f) _ = f.Close() if err != nil { - return err + return 0, err } written += n } - if written != size { + // If size is less than 0, it means the size is unknown. + // We can't check the size of the file, just skip the check. + // It happens when the request comes from old versions of actions, like `actions/cache@v2`. + if size >= 0 && written != size { _ = file.Close() _ = os.Remove(name) - return fmt.Errorf("broken file: %v != %v", written, size) + return 0, fmt.Errorf("broken file: %v != %v", written, size) } - return nil + + return written, nil } func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) {