chore: update moby/buildkit to v0.20.1 (#519)
**Description:** This PR updates the `moby/buildkit` dependency to `v0.20.1` in order to remain compatible with recent changes required by GitHub Actions (GHA) caching. During the upgrade, several upstream behavioral changes required forking and restoring legacy logic to maintain compatibility: - Introduced `containsGithubToken` to replicate logic that was previously in `buildflags.ParseCacheEntry`, which is now removed. This check ensures we return `nil` instead of a zero-value object. - Forked the previous implementation of `ParseExports`, as its upstream logic changed significantly. This ensures short-term compatibility for release before the GHA deprecation deadline. - A follow-up issue will be created to improve this forked logic and align more closely with upstream behavior. 🚨 **Fixes critical issue:** This change addresses a high-priority issue where GitHub Actions cache will stop working due to the upcoming deprecation of the legacy caching service (effective **April 15, 2025**). Recent build failures showed errors like: > *"This legacy service is shutting down, effective April 15, 2025. Migrate to the new service ASAP. For more information: https://gh.io/gha-cache-sunset"* Root cause was identified in #515, where using `buildx >= 0.21.0` is required. This repo was previously using `buildx 0.18.0`. Closes: #515
This commit is contained in:
@@ -472,7 +472,23 @@ func (c CacheFrom) validate(preview bool) (*controllerapi.CacheOptionsEntry, err
|
||||
// environment variables set. Ignore the cacheFrom entry in this case.
|
||||
return nil, nil
|
||||
}
|
||||
return parsed[0], nil
|
||||
|
||||
pb := parsed[0].ToPB()
|
||||
if !containsGithubToken(pb) {
|
||||
pb = nil
|
||||
}
|
||||
|
||||
return pb, nil
|
||||
}
|
||||
|
||||
// containsGithubToken checks if the GitHub token is set in the cache entry.
|
||||
// If it is not a GHA cache entry, it will return true.
|
||||
// This is to maintain backwards compatibility with the old buildx behaviour.
|
||||
func containsGithubToken(ci *controllerapi.CacheOptionsEntry) bool {
|
||||
if ci.Type != "gha" {
|
||||
return true
|
||||
}
|
||||
return ci.Attrs["token"] != "" && ci.Attrs["url"] != ""
|
||||
}
|
||||
|
||||
// CacheToInline embeds cache information directly into an image.
|
||||
@@ -680,7 +696,13 @@ func (c CacheTo) validate(preview bool) (*controllerapi.CacheOptionsEntry, error
|
||||
// environment variables set. Ignore the cacheTo entry in this case.
|
||||
return nil, nil
|
||||
}
|
||||
return parsed[0], nil
|
||||
|
||||
pb := parsed[0].ToPB()
|
||||
if !containsGithubToken(pb) {
|
||||
pb = nil
|
||||
}
|
||||
|
||||
return pb, nil
|
||||
}
|
||||
|
||||
// CacheMode controls the complexity of exported cache manifests.
|
||||
|
||||
@@ -218,7 +218,7 @@ func (c *cli) Build(
|
||||
|
||||
Session: []session.Attachable{
|
||||
ssh,
|
||||
authprovider.NewDockerAuthProvider(c.ConfigFile(), nil),
|
||||
authprovider.NewDockerAuthProvider(authprovider.DockerAuthProviderConfig{ConfigFile: c.ConfigFile()}),
|
||||
build.Secrets(),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -22,7 +22,8 @@ import (
|
||||
"strings"
|
||||
|
||||
controllerapi "github.com/docker/buildx/controller/pb"
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/tonistiigi/go-csvvalue"
|
||||
|
||||
"github.com/pulumi/pulumi-go-provider/infer"
|
||||
)
|
||||
@@ -109,7 +110,7 @@ func (e Export) String() string {
|
||||
// pushed returns true if the export would result in a registry push.
|
||||
func (e Export) pushed() bool {
|
||||
if e.Raw != "" {
|
||||
exp, err := buildflags.ParseExports([]string{e.Raw.String()})
|
||||
exp, err := parseExports([]string{e.Raw.String()})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -124,14 +125,86 @@ func (e Export) pushed() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// parseExports is forked from docker/buildx@v0.18.0 from util/buildflags/export.go
|
||||
// to maintain the old logic. This is to get a working version of the provider with
|
||||
// the latest buildx while maintaining the old behaviour.
|
||||
//
|
||||
// TODO: Remove this fork and update existing logic/tests.
|
||||
func parseExports(inp []string) ([]*controllerapi.ExportEntry, error) {
|
||||
if len(inp) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
outs := make([]*controllerapi.ExportEntry, 0, len(inp))
|
||||
|
||||
for _, s := range inp {
|
||||
fields, err := csvvalue.Fields(s, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := controllerapi.ExportEntry{
|
||||
Attrs: map[string]string{},
|
||||
}
|
||||
if len(fields) == 1 && fields[0] == s && !strings.HasPrefix(s, "type=") {
|
||||
if s != "-" {
|
||||
outs = append(outs, &controllerapi.ExportEntry{
|
||||
Type: client.ExporterLocal,
|
||||
Destination: s,
|
||||
})
|
||||
continue
|
||||
}
|
||||
out = controllerapi.ExportEntry{
|
||||
Type: client.ExporterTar,
|
||||
Destination: s,
|
||||
}
|
||||
}
|
||||
|
||||
if out.Type == "" {
|
||||
for _, field := range fields {
|
||||
parts := strings.SplitN(field, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("invalid value %s", field)
|
||||
}
|
||||
key := strings.TrimSpace(strings.ToLower(parts[0]))
|
||||
value := parts[1]
|
||||
switch key {
|
||||
case "type":
|
||||
out.Type = value
|
||||
default:
|
||||
out.Attrs[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
if out.Type == "" {
|
||||
return nil, errors.New("type is required for output")
|
||||
}
|
||||
|
||||
if out.Type == "registry" {
|
||||
out.Type = client.ExporterImage
|
||||
if _, ok := out.Attrs["push"]; !ok {
|
||||
out.Attrs["push"] = "true"
|
||||
}
|
||||
}
|
||||
|
||||
if dest, ok := out.Attrs["dest"]; ok {
|
||||
out.Destination = dest
|
||||
delete(out.Attrs, "dest")
|
||||
}
|
||||
|
||||
outs = append(outs, &out)
|
||||
}
|
||||
return outs, nil
|
||||
}
|
||||
|
||||
func (e Export) validate(preview bool, tags []string) (*controllerapi.ExportEntry, error) {
|
||||
if strings.Count(e.String(), "type=") > 1 {
|
||||
return nil, errors.New("exports should only specify one export type")
|
||||
}
|
||||
ee, err := buildflags.ParseExports([]string{e.String()})
|
||||
ee, err := parseExports([]string{e.String()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exp := ee[0]
|
||||
if len(tags) == 0 && isRegistryPush(exp) && exp.Attrs["name"] == "" {
|
||||
return nil, errors.New(
|
||||
|
||||
Reference in New Issue
Block a user