diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8d97ec4ef7f..9fbcac794fed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -390,6 +390,7 @@ jobs: run: | ./hack/images "${{ needs.release-base.outputs.tag }}" "$REPO_SLUG_TARGET" "${{ needs.release-base.outputs.push }}" env: + RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} TARGET: ${{ matrix.target-stage }} CACHE_FROM: type=gha,scope=${{ env.CACHE_GHA_SCOPE_CROSS }} type=gha,scope=image${{ matrix.target-stage }} CACHE_TO: type=gha,scope=image${{ matrix.target-stage }} @@ -419,6 +420,7 @@ jobs: run: | ./hack/release-tar "${{ needs.release-base.outputs.tag }}" release-out env: + RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} PLATFORMS: ${{ env.PLATFORMS }},darwin/amd64,darwin/arm64,windows/amd64,windows/arm64 CACHE_FROM: type=gha,scope=${{ env.CACHE_GHA_SCOPE_BINARIES }} type=gha,scope=${{ env.CACHE_GHA_SCOPE_CROSS }} - @@ -444,8 +446,8 @@ jobs: if: github.event_name != 'schedule' outputs: typ: ${{ steps.prep.outputs.typ }} - tag: ${{ steps.prep.outputs.tag }} push: ${{ steps.prep.outputs.push }} + matrix: ${{ steps.prep.outputs.matrix }} steps: - name: Prepare @@ -462,14 +464,30 @@ jobs: PUSH=push fi echo "typ=${TYP}" >>${GITHUB_OUTPUT} - echo "tag=${TAG}" >>${GITHUB_OUTPUT} echo "push=${PUSH}" >>${GITHUB_OUTPUT} + if [ "${TYP}" = "master" ]; then + echo "matrix=$(jq -cn --arg tag "$TAG" '[$tag, "labs"]')" >>${GITHUB_OUTPUT} + else + echo "matrix=$(jq -cn --arg tag "$TAG" '[$tag]')" >>${GITHUB_OUTPUT} + fi frontend-image: runs-on: ubuntu-20.04 if: github.event_name != 'schedule' needs: [frontend-base, test] + strategy: + fail-fast: false + matrix: + tag: ${{ fromJson(needs.frontend-base.outputs.matrix) }} steps: + - + name: Prepare + run: | + if [ "${{ matrix.tag }}" = "labs" ]; then + echo "CACHE_SCOPE=frontend-labs" >>${GITHUB_ENV} + else + echo "CACHE_SCOPE=frontend-mainline" >>${GITHUB_ENV} + fi - name: Checkout uses: actions/checkout@v3 @@ -494,18 +512,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build ${{ needs.frontend-base.outputs.typ }}/${{ needs.frontend-base.outputs.tag }} - run: | - ./frontend/dockerfile/cmd/dockerfile-frontend/hack/release "${{ needs.frontend-base.outputs.typ }}" "${{ needs.frontend-base.outputs.tag }}" "$DF_REPO_SLUG_TARGET" "${{ needs.frontend-base.outputs.push }}" - env: - PLATFORMS: ${{ env.PLATFORMS }},linux/mips,linux/mipsle,linux/mips64,linux/mips64le - CACHE_FROM: type=gha,scope=frontend-${{ needs.frontend-base.outputs.typ }} - CACHE_TO: type=gha,scope=frontend-${{ needs.frontend-base.outputs.typ }} - - - name: Build ${{ needs.frontend-base.outputs.typ }}/labs - if: needs.frontend-base.outputs.typ == 'master' + name: Build run: | - ./frontend/dockerfile/cmd/dockerfile-frontend/hack/release "${{ needs.frontend-base.outputs.typ }}" labs "$DF_REPO_SLUG_TARGET" "${{ needs.frontend-base.outputs.push }}" + ./frontend/dockerfile/cmd/dockerfile-frontend/hack/release "${{ needs.frontend-base.outputs.typ }}" "${{ matrix.tag }}" "$DF_REPO_SLUG_TARGET" "${{ needs.frontend-base.outputs.push }}" env: - PLATFORMS: ${{ env.PLATFORMS }},linux/mips,linux/mipsle,linux/mips64,linux/mips64le - CACHE_FROM: type=gha,scope=frontend-${{ needs.frontend-base.outputs.typ }} + RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} + PLATFORMS: ${{ env.PLATFORMS }},linux/386,linux/mips,linux/mipsle,linux/mips64,linux/mips64le + CACHE_FROM: type=gha,scope=${{ env.CACHE_SCOPE }} + CACHE_TO: type=gha,scope=${{ env.CACHE_SCOPE }} diff --git a/cache/manager.go b/cache/manager.go index 983f7cd5295f..d579a6007ba0 100644 --- a/cache/manager.go +++ b/cache/manager.go @@ -222,10 +222,8 @@ func (cm *cacheManager) GetByBlob(ctx context.Context, desc ocispecs.Descriptor, id := identity.NewID() snapshotID := chainID.String() - blobOnly := true if link != nil { snapshotID = link.getSnapshotID() - blobOnly = link.getBlobOnly() go link.Release(context.TODO()) } @@ -289,7 +287,7 @@ func (cm *cacheManager) GetByBlob(ctx context.Context, desc ocispecs.Descriptor, rec.queueChainID(chainID) rec.queueBlobChainID(blobChainID) rec.queueSnapshotID(snapshotID) - rec.queueBlobOnly(blobOnly) + rec.queueBlobOnly(true) rec.queueMediaType(desc.MediaType) rec.queueBlobSize(desc.Size) rec.appendURLs(desc.URLs) diff --git a/cache/metadata.go b/cache/metadata.go index d6410fd554db..82209a93c0f9 100644 --- a/cache/metadata.go +++ b/cache/metadata.go @@ -251,7 +251,13 @@ func (md *cacheMetadata) queueMediaType(str string) error { } func (md *cacheMetadata) getSnapshotID() string { - return md.GetString(keySnapshot) + sid := md.GetString(keySnapshot) + // Note that historic buildkit releases did not always set the snapshot ID. + // Fallback to record ID is needed for old build cache compatibility. + if sid == "" { + return md.ID() + } + return sid } func (md *cacheMetadata) queueSnapshotID(str string) error { diff --git a/cache/remotecache/gha/gha.go b/cache/remotecache/gha/gha.go index 45cacb5b8332..f36693d3b08d 100644 --- a/cache/remotecache/gha/gha.go +++ b/cache/remotecache/gha/gha.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "io" "os" "sync" "time" @@ -371,6 +372,13 @@ type readerAt struct { desc ocispecs.Descriptor } +func (r *readerAt) ReadAt(p []byte, off int64) (int, error) { + if off >= r.desc.Size { + return 0, io.EOF + } + return r.ReaderAtCloser.ReadAt(p, off) +} + func (r *readerAt) Size() int64 { return r.desc.Size } diff --git a/client/client_test.go b/client/client_test.go index c1f87dc7d4b9..0fca38e23a70 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -62,6 +62,7 @@ import ( digest "github.com/opencontainers/go-digest" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" + spdx "github.com/spdx/tools-golang/spdx/v2_3" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh/agent" "golang.org/x/sync/errgroup" @@ -189,6 +190,7 @@ func TestIntegration(t *testing.T) { testAttestationBundle, testSBOMScan, testSBOMScanSingleRef, + testSBOMSupplements, testMultipleCacheExports, testMountStubsDirectory, testMountStubsTimestamp, @@ -1137,9 +1139,9 @@ func testSecretMounts(t *testing.T, sb integration.Sandbox) { }, nil) require.NoError(t, err) - // test optional + // test optional, mount should not exist when secret not present in SolveOpt st = llb.Image("busybox:latest"). - Run(llb.Shlex(`echo secret2`), llb.AddSecret("/run/secrets/mysecret2", llb.SecretOptional)) + Run(llb.Shlex(`test ! -f /run/secrets/mysecret2`), llb.AddSecret("/run/secrets/mysecret2", llb.SecretOptional)) def, err = st.Marshal(sb.Context()) require.NoError(t, err) @@ -1176,6 +1178,20 @@ func testSecretMounts(t *testing.T, sb integration.Sandbox) { })}, }, nil) require.NoError(t, err) + + // test empty cert still creates secret file + st = llb.Image("busybox:latest"). + Run(llb.Shlex(`test -f /run/secrets/mysecret5`), llb.AddSecret("/run/secrets/mysecret5", llb.SecretID("mysecret"))) + + def, err = st.Marshal(sb.Context()) + require.NoError(t, err) + + _, err = c.Solve(sb.Context(), def, SolveOpt{ + Session: []session.Attachable{secretsprovider.FromMap(map[string][]byte{ + "mysecret": []byte(""), + })}, + }, nil) + require.NoError(t, err) } func testSecretEnv(t *testing.T, sb integration.Sandbox) { @@ -8185,6 +8201,154 @@ EOF require.Subset(t, attest.Predicate, map[string]interface{}{"name": "fallback"}) } +func testSBOMSupplements(t *testing.T, sb integration.Sandbox) { + integration.CheckFeatureCompat(t, sb, integration.FeatureDirectPush, integration.FeatureSBOM) + requiresLinux(t) + c, err := New(sb.Context(), sb.Address()) + require.NoError(t, err) + + registry, err := sb.NewRegistry() + if errors.Is(err, integration.ErrRequirements) { + t.Skip(err.Error()) + } + + p := platforms.MustParse("linux/amd64") + pk := platforms.Format(p) + + frontend := func(ctx context.Context, c gateway.Client) (*gateway.Result, error) { + res := gateway.NewResult() + + // build image + st := llb.Scratch().File( + llb.Mkfile("/foo", 0600, []byte{}), + ) + def, err := st.Marshal(ctx) + if err != nil { + return nil, err + } + r, err := c.Solve(ctx, gateway.SolveRequest{ + Definition: def.ToPB(), + }) + if err != nil { + return nil, err + } + ref, err := r.SingleRef() + if err != nil { + return nil, err + } + _, err = ref.ToState() + if err != nil { + return nil, err + } + res.AddRef(pk, ref) + + expPlatforms := &exptypes.Platforms{ + Platforms: []exptypes.Platform{{ID: pk, Platform: p}}, + } + dt, err := json.Marshal(expPlatforms) + if err != nil { + return nil, err + } + res.AddMeta(exptypes.ExporterPlatformsKey, dt) + + // build attestations + doc := spdx.Document{ + SPDXIdentifier: "DOCUMENT", + Files: []*spdx.File{ + { + // foo exists... + FileSPDXIdentifier: "SPDXRef-File-foo", + FileName: "/foo", + }, + { + // ...but bar doesn't + FileSPDXIdentifier: "SPDXRef-File-bar", + FileName: "/bar", + }, + }, + } + docBytes, err := json.Marshal(doc) + if err != nil { + return nil, err + } + st = llb.Scratch(). + File(llb.Mkfile("/result.spdx", 0600, docBytes)) + def, err = st.Marshal(ctx) + if err != nil { + return nil, err + } + r, err = c.Solve(ctx, gateway.SolveRequest{ + Definition: def.ToPB(), + }) + if err != nil { + return nil, err + } + refAttest, err := r.SingleRef() + if err != nil { + return nil, err + } + _, err = ref.ToState() + if err != nil { + return nil, err + } + + res.AddAttestation(pk, gateway.Attestation{ + Kind: gatewaypb.AttestationKindInToto, + Ref: refAttest, + Path: "/result.spdx", + InToto: result.InTotoAttestation{ + PredicateType: intoto.PredicateSPDX, + }, + Metadata: map[string][]byte{ + result.AttestationSBOMCore: []byte("result"), + }, + }) + + return res, nil + } + + // test the default fallback scanner + target := registry + "/buildkit/testsbom:latest" + _, err = c.Build(sb.Context(), SolveOpt{ + FrontendAttrs: map[string]string{ + "attest:sbom": "", + }, + Exports: []ExportEntry{ + { + Type: ExporterImage, + Attrs: map[string]string{ + "name": target, + "push": "true", + }, + }, + }, + }, "", frontend, nil) + require.NoError(t, err) + + desc, provider, err := contentutil.ProviderFromRef(target) + require.NoError(t, err) + + imgs, err := testutil.ReadImages(sb.Context(), provider, desc) + require.NoError(t, err) + require.Equal(t, 2, len(imgs.Images)) + + att := imgs.Find("unknown/unknown") + attest := struct { + intoto.StatementHeader + Predicate spdx.Document + }{} + require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest)) + require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type) + require.Equal(t, intoto.PredicateSPDX, attest.PredicateType) + + require.Equal(t, "DOCUMENT", string(attest.Predicate.SPDXIdentifier)) + require.Len(t, attest.Predicate.Files, 2) + require.Equal(t, attest.Predicate.Files[0].FileName, "/foo") + require.Regexp(t, "^layerID: sha256:", attest.Predicate.Files[0].FileComment) + require.Equal(t, attest.Predicate.Files[1].FileName, "/bar") + require.Empty(t, attest.Predicate.Files[1].FileComment) +} + func testMultipleCacheExports(t *testing.T, sb integration.Sandbox) { integration.CheckFeatureCompat(t, sb, integration.FeatureMultiCacheExport) c, err := New(sb.Context(), sb.Address()) diff --git a/exporter/containerimage/attestations.go b/exporter/containerimage/attestations.go index 782c18733035..a41c6039f0ba 100644 --- a/exporter/containerimage/attestations.go +++ b/exporter/containerimage/attestations.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "io/fs" + "path/filepath" "strings" intoto "github.com/in-toto/in-toto-golang/in_toto" @@ -30,6 +31,9 @@ var intotoPlatform ocispecs.Platform = ocispecs.Platform{ // supplementSBOM modifies SPDX attestations to include the file layers func supplementSBOM(ctx context.Context, s session.Group, target cache.ImmutableRef, targetRemote *solver.Remote, att exporter.Attestation) (exporter.Attestation, error) { + if target == nil { + return att, nil + } if att.Kind != gatewaypb.AttestationKindInToto { return att, nil } @@ -40,7 +44,7 @@ func supplementSBOM(ctx context.Context, s session.Group, target cache.Immutable if !ok { return att, nil } - if n, _, _ := strings.Cut(att.Path, "."); n != string(name) { + if n, _, _ := strings.Cut(filepath.Base(att.Path), "."); n != string(name) { return att, nil } @@ -172,6 +176,8 @@ func newFileLayerFinder(target cache.ImmutableRef, remote *solver.Remote) (fileL // // find is not concurrency-safe. func (c *fileLayerFinder) find(ctx context.Context, s session.Group, filename string) (cache.ImmutableRef, *ocispecs.Descriptor, error) { + filename = filepath.Join("/", filename) + // return immediately if we've already found the layer containing filename if cache, ok := c.cache[filename]; ok { return cache.ref, &cache.desc, nil @@ -188,7 +194,9 @@ func (c *fileLayerFinder) find(ctx context.Context, s session.Group, filename st found := false for _, f := range files { - if strings.HasPrefix(f, ".wh.") { + f = filepath.Join("/", f) + + if strings.HasPrefix(filepath.Base(f), ".wh.") { // skip whiteout files, we only care about file creations continue } diff --git a/exporter/util/epoch/parse.go b/exporter/util/epoch/parse.go index 9d581ed9136c..63f806e1b76a 100644 --- a/exporter/util/epoch/parse.go +++ b/exporter/util/epoch/parse.go @@ -60,6 +60,6 @@ func parseTime(key, value string) (*time.Time, error) { if err != nil { return nil, errors.Wrapf(err, "invalid %s: %s", key, err) } - tm := time.Unix(sde, 0) + tm := time.Unix(sde, 0).UTC() return &tm, nil } diff --git a/frontend/attestations/sbom/sbom.go b/frontend/attestations/sbom/sbom.go index b4446aed45f0..113797b2139c 100644 --- a/frontend/attestations/sbom/sbom.go +++ b/frontend/attestations/sbom/sbom.go @@ -78,6 +78,8 @@ func CreateSBOMScanner(ctx context.Context, resolver llb.ImageMetaResolver, scan } runscan := llb.Image(scanner).Run(runOpts...) + runscan.AddMount("/tmp", llb.Scratch(), llb.Tmpfs()) + runscan.AddMount(path.Join(srcDir, "core", CoreSBOMName), ref, llb.Readonly) for k, extra := range extras { runscan.AddMount(path.Join(srcDir, "extras", ExtraSBOMPrefix+k), extra, llb.Readonly) diff --git a/frontend/dockerfile/builder/build.go b/frontend/dockerfile/builder/build.go index f9dd3643cd63..aafd9c9a73f3 100644 --- a/frontend/dockerfile/builder/build.go +++ b/frontend/dockerfile/builder/build.go @@ -1133,6 +1133,6 @@ func parseSourceDateEpoch(v string) (*time.Time, error) { if err != nil { return nil, errors.Wrapf(err, "invalid SOURCE_DATE_EPOCH: %s", v) } - tm := time.Unix(sde, 0) + tm := time.Unix(sde, 0).UTC() return &tm, nil } diff --git a/frontend/dockerfile/cmd/dockerfile-frontend/hack/release b/frontend/dockerfile/cmd/dockerfile-frontend/hack/release index 4de0c9c6b27f..8d71f83e8def 100755 --- a/frontend/dockerfile/cmd/dockerfile-frontend/hack/release +++ b/frontend/dockerfile/cmd/dockerfile-frontend/hack/release @@ -1,10 +1,11 @@ #!/usr/bin/env bash . $(dirname $0)/../../../../../hack/util -set -e +set -eu -: ${PLATFORMS=} -: ${DAILY_TARGETS=} +: "${RELEASE=false}" +: "${PLATFORMS=}" +: "${DAILY_TARGETS=}" usage() { echo "$0 (master|tag|daily) (tag|channel) [push]" @@ -23,7 +24,7 @@ parseTag() { fi local suffix=$(echo $1 | awk -F- '{print $NF}') local tagf=./frontend/dockerfile/release/$suffix/tags - if [ "$sufffix" == "$1" ] || [ ! -f $tagf ]; then + if [ "$suffix" == "$1" ] || [ ! -f $tagf ]; then suffix="mainline" fi @@ -70,6 +71,11 @@ if [ "$PUSH" = "push" ]; then pushFlag="push=true" fi +nocacheFilterFlag="" +if [[ "$RELEASE" = "true" ]] && [[ "$GITHUB_ACTIONS" = "true" ]]; then + nocacheFilterFlag="--no-cache-filter=base" +fi + case $TYP in "master") tagf=./frontend/dockerfile/release/$TAG/tags @@ -84,7 +90,7 @@ case $TYP in pushTag=${pushTag}-$TAG fi - buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags $(buildAttestFlags) \ + buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags $nocacheFilterFlag $(buildAttestFlags) \ --build-arg "CHANNEL=$TAG" \ --build-arg "BUILDTAGS=$buildTags" \ --output "type=image,name=$REPO:$pushTag,buildinfo-attrs=true,$pushFlag" \ @@ -101,7 +107,7 @@ case $TYP in fi buildTags=$(cat $tagf) - buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags $(buildAttestFlags) \ + buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags $nocacheFilterFlag $(buildAttestFlags) \ --build-arg "CHANNEL=$TAG" \ --build-arg "BUILDTAGS=$buildTags" \ --output "type=image,\"name=$publishedNames\",buildinfo-attrs=true,$pushFlag" \ @@ -127,7 +133,7 @@ case $TYP in tmp=$(mktemp -d -t buildid.XXXXXXXXXX) dt=$(date +%Y%m%d) - buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags \ + buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags $nocacheFilterFlag \ --target "buildid" \ --build-arg "CHANNEL=$TAG" \ --build-arg "BUILDTAGS=$buildTags" \ @@ -141,7 +147,7 @@ case $TYP in buildid=$(cat $tmp/buildid) echo "buildid: $buildid" - buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags $(buildAttestFlags) \ + buildxCmd build $platformFlag $cacheFromFlags $cacheToFlags $nocacheFilterFlag $(buildAttestFlags) \ --build-arg "CHANNEL=$TAG" \ --build-arg "BUILDTAGS=$buildTags" \ --output "type=image,name=$REPO:$dt-$TAG,buildinfo-attrs=true,$pushFlag" \ diff --git a/frontend/dockerfile/docs/reference.md b/frontend/dockerfile/docs/reference.md index e6d2809f30cc..0065a59eb062 100644 --- a/frontend/dockerfile/docs/reference.md +++ b/frontend/dockerfile/docs/reference.md @@ -1323,7 +1323,7 @@ ADD [--keep-git-dir=] ``` ```dockerfile -# syntax=docker/dockerfile-upstream:master-labs +# syntax=docker/dockerfile:1-labs FROM alpine ADD --keep-git-dir=true https://github.com/moby/buildkit.git#v0.10.1 /buildkit ``` @@ -1331,9 +1331,11 @@ ADD --keep-git-dir=true https://github.com/moby/buildkit.git#v0.10.1 /buildkit The `--keep-git-dir=true` flag adds the `.git` directory. This flag defaults to false. ### Adding a private git repository + To add a private repo via SSH, create a Dockerfile with the following form: + ```dockerfile -# syntax = docker/dockerfile-upstream:master-labs +# syntax=docker/dockerfile:1-labs FROM alpine ADD git@git.example.com:foo/bar.git /bar ``` diff --git a/hack/images b/hack/images index 8c4564caa27e..cbaf0eb16f2c 100755 --- a/hack/images +++ b/hack/images @@ -7,6 +7,7 @@ PUSH=$3 . $(dirname $0)/util set -eu -o pipefail +: ${RELEASE=false} : ${PLATFORMS=} : ${TARGET=} @@ -39,12 +40,15 @@ if [[ "$TAG" == "local" ]]; then fi fi +attestFlags="$(buildAttestFlags)" + outputFlag="--output=type=image,push=false" if [ "$PUSH" = "push" ]; then outputFlag="--output=type=image,buildinfo-attrs=true,push=true" fi if [ -n "$localmode" ]; then outputFlag="--output=type=docker,buildinfo-attrs=true" + attestFlags="" fi targetFlag="" @@ -88,5 +92,10 @@ for tagName in $tagNames; do tagFlags="$tagFlags--tag=$tagName " done -buildxCmd build $platformFlag $targetFlag $importCacheFlags $exportCacheFlags $tagFlags $outputFlag $(buildAttestFlags) \ +nocacheFilterFlag="" +if [[ "$RELEASE" = "true" ]] && [[ "$GITHUB_ACTIONS" = "true" ]]; then + nocacheFilterFlag="--no-cache-filter=git,buildkit-export,gobuild-base" +fi + +buildxCmd build $platformFlag $targetFlag $importCacheFlags $exportCacheFlags $tagFlags $outputFlag $nocacheFilterFlag $attestFlags \ $currentcontext diff --git a/hack/release-tar b/hack/release-tar index 549fe5f3f2c6..308243f72096 100755 --- a/hack/release-tar +++ b/hack/release-tar @@ -6,6 +6,7 @@ OUT=$2 . $(dirname $0)/util set -eu -o pipefail +: ${RELEASE=false} : ${PLATFORMS=} usage() { @@ -22,9 +23,14 @@ if [ -n "$PLATFORMS" ]; then platformFlag="--platform=$PLATFORMS" fi +nocacheFilterFlag="" +if [[ "$RELEASE" = "true" ]] && [[ "$GITHUB_ACTIONS" = "true" ]]; then + nocacheFilterFlag="--no-cache-filter=git,gobuild-base" +fi + output=$(mktemp -d -t buildkit-output.XXXXXXXXXX) -buildxCmd build $platformFlag $cacheFromFlags $(buildAttestFlags) \ +buildxCmd build $platformFlag $cacheFromFlags $nocacheFilterFlag $(buildAttestFlags) \ --build-arg "BUILDKIT_MULTI_PLATFORM=true" \ --target release \ --output "type=local,dest=$output" \ diff --git a/solver/llbsolver/mounts/mount.go b/solver/llbsolver/mounts/mount.go index 37bc8a602d71..2cfeaae7a213 100644 --- a/solver/llbsolver/mounts/mount.go +++ b/solver/llbsolver/mounts/mount.go @@ -251,14 +251,14 @@ func (mm *MountManager) getSecretMountable(ctx context.Context, m *pb.Mount, g s err = mm.sm.Any(ctx, g, func(ctx context.Context, _ string, caller session.Caller) error { dt, err = secrets.GetSecret(ctx, caller, id) if err != nil { - if errors.Is(err, secrets.ErrNotFound) && m.SecretOpt.Optional { - return nil - } return err } return nil }) if err != nil { + if errors.Is(err, secrets.ErrNotFound) && m.SecretOpt.Optional { + return nil, nil + } return nil, err } return &secretMount{mount: m, data: dt, idmap: mm.cm.IdentityMapping()}, nil diff --git a/util/progress/progressui/init.go b/util/progress/progressui/init.go index f21072214825..75f0cb83d1de 100644 --- a/util/progress/progressui/init.go +++ b/util/progress/progressui/init.go @@ -14,7 +14,7 @@ var colorError aec.ANSI func init() { // As recommended on https://no-color.org/ - if _, ok := os.LookupEnv("NO_COLOR"); ok { + if v := os.Getenv("NO_COLOR"); v != "" { // nil values will result in no ANSI color codes being emitted. return } else if runtime.GOOS == "windows" {