From 8677e49cf7626319ef71ba4c452f8fcfc3bbb937 Mon Sep 17 00:00:00 2001 From: ivanovac Date: Mon, 8 Dec 2025 15:47:27 +0200 Subject: [PATCH 1/3] Upgrade to switchblade v0.9.2 for CF API v3 compatibility --- go.mod | 2 +- go.sum | 4 ++-- scripts/.util/tools.sh | 9 ++++++++- src/nodejs/integration/override_test.go | 18 ++++++++++-------- .../switchblade/internal/cloudfoundry/stage.go | 15 +++++++++++++++ vendor/modules.txt | 2 +- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 2a9087511..1c926bac8 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Dynatrace/libbuildpack-dynatrace v1.8.0 github.com/Masterminds/semver v1.5.0 github.com/cloudfoundry/libbuildpack v0.0.0-20251203175254-7be530ec9fef - github.com/cloudfoundry/switchblade v0.9.1 + github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b github.com/golang/mock v1.6.0 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.36.2 diff --git a/go.sum b/go.sum index 3a7ce2225..2b7bb7a37 100644 --- a/go.sum +++ b/go.sum @@ -478,8 +478,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudfoundry/libbuildpack v0.0.0-20251203175254-7be530ec9fef h1:lrggsL5p4dr3bBK/x1xIu3sn/6PGYV71GQIe/mCNfFw= github.com/cloudfoundry/libbuildpack v0.0.0-20251203175254-7be530ec9fef/go.mod h1:kn4FHMwI8bTd9gT92wPGjXHzUvGcj8CkPxG8q3AGBAQ= -github.com/cloudfoundry/switchblade v0.9.1 h1:WHEUhSnkoqCJOkqJ1WD3XcmKztpYmagdIWT+GJf6Gfc= -github.com/cloudfoundry/switchblade v0.9.1/go.mod h1:hIEQdGAsuNnzlyQfsD5OIORt38weSBar6Wq5/JX6Omo= +github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b h1:BkOKz3IOwZyq3A3tc9iWiZENPUDyQRD2X5dchveYOEM= +github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b/go.mod h1:hIEQdGAsuNnzlyQfsD5OIORt38weSBar6Wq5/JX6Omo= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= diff --git a/scripts/.util/tools.sh b/scripts/.util/tools.sh index dc8a55776..3260ab8b2 100644 --- a/scripts/.util/tools.sh +++ b/scripts/.util/tools.sh @@ -148,10 +148,17 @@ function util::tools::cf::install() { exit 1 esac + # Check if cf is already available in PATH (e.g., from system/Docker image) + if command -v cf &> /dev/null; then + util::print::title "CF CLI already installed (using system version)" + cf version + return 0 + fi + if [[ ! -f "${dir}/cf" ]]; then util::print::title "Installing cf" - curl "https://packages.cloudfoundry.org/stable?release=${os}-binary&version=6.49.0&source=github-rel" \ + curl "https://packages.cloudfoundry.org/stable?release=${os}-binary&source=github-rel" \ --silent \ --location \ --output /tmp/cf.tar.gz diff --git a/src/nodejs/integration/override_test.go b/src/nodejs/integration/override_test.go index d11500f6f..dec2f894b 100644 --- a/src/nodejs/integration/override_test.go +++ b/src/nodejs/integration/override_test.go @@ -7,7 +7,6 @@ import ( "github.com/cloudfoundry/switchblade" "github.com/sclevine/spec" - . "github.com/cloudfoundry/switchblade/matchers" . "github.com/onsi/gomega" ) @@ -23,6 +22,7 @@ func testOverride(platform switchblade.Platform, fixtures string) func(*testing. var err error name, err = switchblade.RandomName() Expect(err).NotTo(HaveOccurred()) + println(name) }) it.After(func() { @@ -37,13 +37,15 @@ func testOverride(platform switchblade.Platform, fixtures string) func(*testing. ). Execute(name, filepath.Join(fixtures, "simple")) Expect(err).To(HaveOccurred()) - - Expect(logs.String()).To(SatisfyAll( - ContainLines(ContainSubstring("-----> OverrideYML Buildpack")), - ContainLines(ContainSubstring("-----> Installing node")), - ContainLines(MatchRegexp("Copy .*/node.tgz")), - ContainLines(ContainSubstring("Unable to install node: dependency sha256 mismatch: expected sha256 062d906c87839d03b243e2821e10653c89b4c92878bfe2bf995dec231e117bfc, actual sha256 b56b58ac21f9f42d032e1e4b8bf8b8823e69af5411caa15aee2b140bc756962f")), - )) + Expect(err).To(MatchError(ContainSubstring("App staging failed"))) + + // Switchblade now automatically captures staging logs in CF API v3 + // by fetching them using 'cf logs --recent' when staging fails + logsStr := logs.String() + Expect(logsStr).To(ContainSubstring("-----> OverrideYML Buildpack")) + Expect(logsStr).To(ContainSubstring("-----> Installing node")) + Expect(logsStr).To(MatchRegexp(`Copy .*/node.tgz`)) + Expect(logsStr).To(ContainSubstring("Unable to install node: dependency sha256 mismatch: expected sha256 062d906c87839d03b243e2821e10653c89b4c92878bfe2bf995dec231e117bfc, actual sha256 b56b58ac21f9f42d032e1e4b8bf8b8823e69af5411caa15aee2b140bc756962f")) }) } } diff --git a/vendor/github.com/cloudfoundry/switchblade/internal/cloudfoundry/stage.go b/vendor/github.com/cloudfoundry/switchblade/internal/cloudfoundry/stage.go index 912572fb9..cee76d1d9 100644 --- a/vendor/github.com/cloudfoundry/switchblade/internal/cloudfoundry/stage.go +++ b/vendor/github.com/cloudfoundry/switchblade/internal/cloudfoundry/stage.go @@ -35,6 +35,21 @@ func (s Stage) Run(logs io.Writer, home, name string) (string, error) { Env: env, }) if err != nil { + // In CF API v3, staging failure logs are not automatically captured in stdout/stderr + // We need to fetch them explicitly using 'cf logs --recent' + recentLogs := bytes.NewBuffer(nil) + logErr := s.cli.Execute(pexec.Execution{ + Args: []string{"logs", name, "--recent"}, + Stdout: recentLogs, + Stderr: recentLogs, + Env: env, + }) + if logErr == nil && recentLogs.Len() > 0 { + // Append recent logs to the main logs buffer + _, _ = logs.Write([]byte("\n--- Recent Logs (cf logs --recent) ---\n")) + _, _ = logs.Write(recentLogs.Bytes()) + } + return "", fmt.Errorf("failed to start: %w\n\nOutput:\n%s", err, logs) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 6126d2cb8..dca3001c2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -30,7 +30,7 @@ github.com/cloudfoundry/libbuildpack/cutlass github.com/cloudfoundry/libbuildpack/cutlass/docker github.com/cloudfoundry/libbuildpack/cutlass/glow github.com/cloudfoundry/libbuildpack/packager -# github.com/cloudfoundry/switchblade v0.9.1 +# github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b ## explicit; go 1.23.0 github.com/cloudfoundry/switchblade github.com/cloudfoundry/switchblade/internal/cloudfoundry From 82c9ba014c3bfbadba9eb4a7be17f1014b64d4fb Mon Sep 17 00:00:00 2001 From: ivanovac Date: Wed, 10 Dec 2025 14:45:41 +0200 Subject: [PATCH 2/3] adopt switchbladev0.9.2 --- go.mod | 2 +- go.sum | 4 ++-- vendor/github.com/cloudfoundry/switchblade/random_name.go | 4 ++++ vendor/modules.txt | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 1c926bac8..d25334225 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Dynatrace/libbuildpack-dynatrace v1.8.0 github.com/Masterminds/semver v1.5.0 github.com/cloudfoundry/libbuildpack v0.0.0-20251203175254-7be530ec9fef - github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b + github.com/cloudfoundry/switchblade v0.9.2 github.com/golang/mock v1.6.0 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.36.2 diff --git a/go.sum b/go.sum index 2b7bb7a37..cac3eed54 100644 --- a/go.sum +++ b/go.sum @@ -478,8 +478,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudfoundry/libbuildpack v0.0.0-20251203175254-7be530ec9fef h1:lrggsL5p4dr3bBK/x1xIu3sn/6PGYV71GQIe/mCNfFw= github.com/cloudfoundry/libbuildpack v0.0.0-20251203175254-7be530ec9fef/go.mod h1:kn4FHMwI8bTd9gT92wPGjXHzUvGcj8CkPxG8q3AGBAQ= -github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b h1:BkOKz3IOwZyq3A3tc9iWiZENPUDyQRD2X5dchveYOEM= -github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b/go.mod h1:hIEQdGAsuNnzlyQfsD5OIORt38weSBar6Wq5/JX6Omo= +github.com/cloudfoundry/switchblade v0.9.2 h1:b2lwxrAblg9uKncNQRKZ09/teuKdZIixcENKgrLQPjo= +github.com/cloudfoundry/switchblade v0.9.2/go.mod h1:hIEQdGAsuNnzlyQfsD5OIORt38weSBar6Wq5/JX6Omo= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= diff --git a/vendor/github.com/cloudfoundry/switchblade/random_name.go b/vendor/github.com/cloudfoundry/switchblade/random_name.go index b094449be..285f5cbff 100644 --- a/vendor/github.com/cloudfoundry/switchblade/random_name.go +++ b/vendor/github.com/cloudfoundry/switchblade/random_name.go @@ -13,5 +13,9 @@ func RandomName() (string, error) { return "", err } + // Replace underscores with hyphens to make the name DNS-safe + // Cloud Foundry uses app names in DNS URLs where underscores are not allowed + id = strings.ReplaceAll(id, "_", "-") + return strings.ToLower(fmt.Sprintf("switchblade-%s", id)), nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index dca3001c2..80adb9fc8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -30,7 +30,7 @@ github.com/cloudfoundry/libbuildpack/cutlass github.com/cloudfoundry/libbuildpack/cutlass/docker github.com/cloudfoundry/libbuildpack/cutlass/glow github.com/cloudfoundry/libbuildpack/packager -# github.com/cloudfoundry/switchblade v0.9.2-0.20251205151235-f452557fbc4b +# github.com/cloudfoundry/switchblade v0.9.2 ## explicit; go 1.23.0 github.com/cloudfoundry/switchblade github.com/cloudfoundry/switchblade/internal/cloudfoundry From 4374e30d0e29e7ad70f33e5fded845840208b2d5 Mon Sep 17 00:00:00 2001 From: ivanovac Date: Wed, 10 Dec 2025 16:48:39 +0200 Subject: [PATCH 3/3] revert meanless change --- src/nodejs/integration/override_test.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/nodejs/integration/override_test.go b/src/nodejs/integration/override_test.go index dec2f894b..0ec0c76cf 100644 --- a/src/nodejs/integration/override_test.go +++ b/src/nodejs/integration/override_test.go @@ -7,6 +7,7 @@ import ( "github.com/cloudfoundry/switchblade" "github.com/sclevine/spec" + . "github.com/cloudfoundry/switchblade/matchers" . "github.com/onsi/gomega" ) @@ -37,15 +38,13 @@ func testOverride(platform switchblade.Platform, fixtures string) func(*testing. ). Execute(name, filepath.Join(fixtures, "simple")) Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError(ContainSubstring("App staging failed"))) - - // Switchblade now automatically captures staging logs in CF API v3 - // by fetching them using 'cf logs --recent' when staging fails - logsStr := logs.String() - Expect(logsStr).To(ContainSubstring("-----> OverrideYML Buildpack")) - Expect(logsStr).To(ContainSubstring("-----> Installing node")) - Expect(logsStr).To(MatchRegexp(`Copy .*/node.tgz`)) - Expect(logsStr).To(ContainSubstring("Unable to install node: dependency sha256 mismatch: expected sha256 062d906c87839d03b243e2821e10653c89b4c92878bfe2bf995dec231e117bfc, actual sha256 b56b58ac21f9f42d032e1e4b8bf8b8823e69af5411caa15aee2b140bc756962f")) + + Expect(logs.String()).To(SatisfyAll( + ContainLines(ContainSubstring("-----> OverrideYML Buildpack")), + ContainLines(ContainSubstring("-----> Installing node")), + ContainLines(MatchRegexp("Copy .*/node.tgz")), + ContainLines(ContainSubstring("Unable to install node: dependency sha256 mismatch: expected sha256 062d906c87839d03b243e2821e10653c89b4c92878bfe2bf995dec231e117bfc, actual sha256 b56b58ac21f9f42d032e1e4b8bf8b8823e69af5411caa15aee2b140bc756962f")), + )) }) } }