From efe10d0b2f1c9ef952ef2334a8d2998e3f3b8791 Mon Sep 17 00:00:00 2001 From: agrasth Date: Tue, 11 Nov 2025 14:24:45 +0530 Subject: [PATCH 1/3] Fix poetry publish bug in traditional flow --- go.mod | 2 +- go.sum | 4 +- poetry_test.go | 209 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f00bd677f..a709c48a6 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/jfrog/build-info-go v1.12.2 github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-cli-application v1.0.1 - github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251110084008-a7b8b1961aa8 + github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251111084708-c04b9d04d9ea github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251028101519-8c79bb06de65 github.com/jfrog/jfrog-cli-evidence v0.8.2 github.com/jfrog/jfrog-cli-platform-services v1.10.0 diff --git a/go.sum b/go.sum index b68fddcdd..8e6021ba6 100644 --- a/go.sum +++ b/go.sum @@ -1159,8 +1159,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-application v1.0.1 h1:PiiSVKFFs8VLAwjCe2JrIKlX7LmARFt+r8BLTupWIDc= github.com/jfrog/jfrog-cli-application v1.0.1/go.mod h1:gjV6Q2hhoMe3FF77GFiTyIRLSHokpDrkVj0GvYM+1Y4= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251110084008-a7b8b1961aa8 h1:rWrGzqSJWa2accXyNL2V+ePoMmyZ0gsxIEgLZEfVEa0= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251110084008-a7b8b1961aa8/go.mod h1:l9orAXG293Sx8pyk8nwZyHtnMXmPoVehUKZATIAy14U= +github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251111084708-c04b9d04d9ea h1:Nv/AzqsVax+PRt0H+xNEx07slHW6oKEHfBj43qCRrUI= +github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251111084708-c04b9d04d9ea/go.mod h1:l9orAXG293Sx8pyk8nwZyHtnMXmPoVehUKZATIAy14U= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251028101519-8c79bb06de65 h1:9HDaoQXzP2EcSL7JML3j6qQ18tDvpKRuonFe1DEKvb8= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251028101519-8c79bb06de65/go.mod h1:qGHIijD2doUdFaRFRhudtCmlt0ENDaBvM3dnUClpmHc= github.com/jfrog/jfrog-cli-evidence v0.8.2 h1:GQi2BjIruGzTWJ9AJM59frRgiPQoLLDo4IVfwiye0tc= diff --git a/poetry_test.go b/poetry_test.go index 6e0077c2d..849094c5e 100644 --- a/poetry_test.go +++ b/poetry_test.go @@ -237,6 +237,215 @@ func validatePoetryPublishProperties(t *testing.T, repo, buildName, buildNumber verifyExistInArtifactoryByProps([]string{}, repo+"/*", expectedProps, t) } +// TestPoetryPublishTraditionalFlowWithBuildInfo tests the traditional flow with build-info flags +// Ensures traditional flow publishes artifacts when --build-name and --build-number are provided +// This validates the fix for bug introduced in v2.79.0 where FlexPack code caused early return +func TestPoetryPublishTraditionalFlowWithBuildInfo(t *testing.T) { + initPoetryTest(t) + + // Populate cli config with 'default' server + oldHomeDir, newHomeDir := prepareHomeDir(t) + defer func() { + clientTestUtils.SetEnvAndAssert(t, coreutils.HomeDir, oldHomeDir) + clientTestUtils.RemoveAllAndAssert(t, newHomeDir) + }() + + // Ensure JFROG_RUN_NATIVE is NOT set (test traditional flow) + os.Unsetenv("JFROG_RUN_NATIVE") + + buildName := "poetry-traditional-buildinfo-test" + buildNumber := "1" + projectPath := createPoetryProject(t, "traditional-buildinfo-test", "poetryproject") + + // Change to project directory + wd, err := os.Getwd() + assert.NoError(t, err) + chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, projectPath) + defer chdirCallback() + + // Build the package + buildCmd := exec.Command("poetry", "build") + buildCmd.Dir = projectPath + assert.NoError(t, buildCmd.Run(), "Failed to build Poetry package") + + // Publish with build-info flags (this would fail in v2.79.0-v2.82.0) + args := []string{ + "poetry", "publish", + "--build-name=" + buildName, + "--build-number=" + buildNumber, + "--repository=" + tests.PoetryLocalRepo, + } + + jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "") + assert.NoError(t, jfrogCli.Exec(args...)) + + // Publish build info + assert.NoError(t, artifactoryCli.Exec("bp", buildName, buildNumber)) + + // CRITICAL: Validate artifacts were uploaded + // In buggy versions (v2.79.0-v2.82.0), this would fail with 0 artifacts + validatePoetryPublishProperties(t, tests.PoetryLocalRepo, buildName, buildNumber) + + // Validate build info has artifacts + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "build info was expected to be found") + + // Validate 2 artifacts exist (.whl and .tar.gz) + assert.Len(t, publishedBuildInfo.BuildInfo.Modules, 1) + assert.Len(t, publishedBuildInfo.BuildInfo.Modules[0].Artifacts, 2, + "Expected 2 artifacts (.whl and .tar.gz), validates fix for v2.79.0-v2.82.0 bug") + + // Clean up + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) +} + +// TestPoetryPublishFlexPackFlow tests the FlexPack flow for poetry publish +// Ensures FlexPack flow continues to work correctly with JFROG_RUN_NATIVE=true +func TestPoetryPublishFlexPackFlow(t *testing.T) { + initPoetryTest(t) + + // Set JFROG_RUN_NATIVE=true for FlexPack flow + setEnvCallback := clientTestUtils.SetEnvWithCallbackAndAssert(t, "JFROG_RUN_NATIVE", "true") + defer setEnvCallback() + + // Populate cli config with 'default' server + oldHomeDir, newHomeDir := prepareHomeDir(t) + defer func() { + clientTestUtils.SetEnvAndAssert(t, coreutils.HomeDir, oldHomeDir) + clientTestUtils.RemoveAllAndAssert(t, newHomeDir) + }() + + buildName := "poetry-flexpack-test" + buildNumber := "1" + projectPath := createPoetryProject(t, "flexpack-test", "poetryproject") + + // Change to project directory + wd, err := os.Getwd() + assert.NoError(t, err) + chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, projectPath) + defer chdirCallback() + + // Build the package + buildCmd := exec.Command("poetry", "build") + buildCmd.Dir = projectPath + assert.NoError(t, buildCmd.Run(), "Failed to build Poetry package") + + // Publish with FlexPack flow + args := []string{ + "poetry", "publish", + "--build-name=" + buildName, + "--build-number=" + buildNumber, + "--repository=" + tests.PoetryLocalRepo, + } + + jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "") + assert.NoError(t, jfrogCli.Exec(args...)) + + // Publish build info + assert.NoError(t, artifactoryCli.Exec("bp", buildName, buildNumber)) + + // Validate artifacts were uploaded + validatePoetryPublishProperties(t, tests.PoetryLocalRepo, buildName, buildNumber) + + // Validate build info has artifacts + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "build info was expected to be found") + + // Validate 2 artifacts exist + assert.Len(t, publishedBuildInfo.BuildInfo.Modules, 1) + assert.Len(t, publishedBuildInfo.BuildInfo.Modules[0].Artifacts, 2, + "Expected 2 artifacts (.whl and .tar.gz) in FlexPack flow") + + // Clean up + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) +} + +// TestPoetryPublishBothFlowsComparison tests both traditional and FlexPack flows +// Ensures both flows produce the same results (feature parity) +func TestPoetryPublishBothFlowsComparison(t *testing.T) { + initPoetryTest(t) + + // Populate cli config with 'default' server + oldHomeDir, newHomeDir := prepareHomeDir(t) + defer func() { + clientTestUtils.SetEnvAndAssert(t, coreutils.HomeDir, oldHomeDir) + clientTestUtils.RemoveAllAndAssert(t, newHomeDir) + }() + + flows := []struct { + name string + useNative bool + buildName string + }{ + {"Traditional", false, "poetry-flow-traditional"}, + {"FlexPack", true, "poetry-flow-flexpack"}, + } + + for _, flow := range flows { + t.Run(flow.name, func(t *testing.T) { + // Set up environment for FlexPack if needed + if flow.useNative { + setEnvCallback := clientTestUtils.SetEnvWithCallbackAndAssert(t, "JFROG_RUN_NATIVE", "true") + defer setEnvCallback() + } else { + os.Unsetenv("JFROG_RUN_NATIVE") + } + + buildNumber := "1" + projectPath := createPoetryProject(t, "flow-comparison-"+flow.name, "poetryproject") + + // Change to project directory + wd, err := os.Getwd() + assert.NoError(t, err) + chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, projectPath) + defer chdirCallback() + + // Build the package + buildCmd := exec.Command("poetry", "build") + buildCmd.Dir = projectPath + assert.NoError(t, buildCmd.Run(), "Failed to build Poetry package") + + // Publish + args := []string{ + "poetry", "publish", + "--build-name=" + flow.buildName, + "--build-number=" + buildNumber, + "--repository=" + tests.PoetryLocalRepo, + } + + jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "") + assert.NoError(t, jfrogCli.Exec(args...)) + + // Publish build info + assert.NoError(t, artifactoryCli.Exec("bp", flow.buildName, buildNumber)) + + // Validate artifacts were uploaded (both flows should upload same artifacts) + validatePoetryPublishProperties(t, tests.PoetryLocalRepo, flow.buildName, buildNumber) + + // Validate build info + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, flow.buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "build info was expected to be found for %s flow", flow.name) + + // Both flows should produce 2 artifacts + assert.Len(t, publishedBuildInfo.BuildInfo.Modules, 1) + assert.Len(t, publishedBuildInfo.BuildInfo.Modules[0].Artifacts, 2, + "%s flow should upload 2 artifacts (.whl and .tar.gz)", flow.name) + + // Validate artifacts have checksums + for _, artifact := range publishedBuildInfo.BuildInfo.Modules[0].Artifacts { + assert.NotEmpty(t, artifact.Sha1, "SHA1 checksum should be present in %s flow", flow.name) + assert.NotEmpty(t, artifact.Sha256, "SHA256 checksum should be present in %s flow", flow.name) + } + + // Clean up + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, flow.buildName, artHttpDetails) + }) + } +} + func TestPoetryBuildInfoCollection(t *testing.T) { // Test the FlexPack build info collection functionality initPoetryTest(t) From c531613fd576715960afddd90ce08c7b7ee209b1 Mon Sep 17 00:00:00 2001 From: agrasth Date: Tue, 11 Nov 2025 14:38:01 +0530 Subject: [PATCH 2/3] Fix linter errors: check os.Unsetenv return values --- poetry_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry_test.go b/poetry_test.go index 849094c5e..2c871c660 100644 --- a/poetry_test.go +++ b/poetry_test.go @@ -251,7 +251,7 @@ func TestPoetryPublishTraditionalFlowWithBuildInfo(t *testing.T) { }() // Ensure JFROG_RUN_NATIVE is NOT set (test traditional flow) - os.Unsetenv("JFROG_RUN_NATIVE") + assert.NoError(t, os.Unsetenv("JFROG_RUN_NATIVE")) buildName := "poetry-traditional-buildinfo-test" buildNumber := "1" @@ -390,7 +390,7 @@ func TestPoetryPublishBothFlowsComparison(t *testing.T) { setEnvCallback := clientTestUtils.SetEnvWithCallbackAndAssert(t, "JFROG_RUN_NATIVE", "true") defer setEnvCallback() } else { - os.Unsetenv("JFROG_RUN_NATIVE") + assert.NoError(t, os.Unsetenv("JFROG_RUN_NATIVE")) } buildNumber := "1" From 76ee755485837966d7db9a8535f9014ff6d529c9 Mon Sep 17 00:00:00 2001 From: agrasth Date: Tue, 11 Nov 2025 16:03:56 +0530 Subject: [PATCH 3/3] Add Poetry to build tools test initialization --- main_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main_test.go b/main_test.go index 8feeee219..a16417ad7 100644 --- a/main_test.go +++ b/main_test.go @@ -59,7 +59,7 @@ func setupIntegrationTests() { if (*tests.TestArtifactory && !*tests.TestArtifactoryProxy) || *tests.TestArtifactoryProject { InitArtifactoryTests() } - if *tests.TestNpm || *tests.TestGradle || *tests.TestMaven || *tests.TestGo || *tests.TestNuget || *tests.TestPip || *tests.TestPipenv { + if *tests.TestNpm || *tests.TestGradle || *tests.TestMaven || *tests.TestGo || *tests.TestNuget || *tests.TestPip || *tests.TestPipenv || *tests.TestPoetry { InitBuildToolsTests() } if *tests.TestDocker || *tests.TestPodman || *tests.TestDockerScan { @@ -86,7 +86,7 @@ func tearDownIntegrationTests() { if (*tests.TestArtifactory && !*tests.TestArtifactoryProxy) || *tests.TestArtifactoryProject { CleanArtifactoryTests() } - if *tests.TestNpm || *tests.TestGradle || *tests.TestMaven || *tests.TestGo || *tests.TestNuget || *tests.TestPip || *tests.TestPipenv || *tests.TestDocker || *tests.TestPodman || *tests.TestDockerScan { + if *tests.TestNpm || *tests.TestGradle || *tests.TestMaven || *tests.TestGo || *tests.TestNuget || *tests.TestPip || *tests.TestPipenv || *tests.TestPoetry || *tests.TestDocker || *tests.TestPodman || *tests.TestDockerScan { CleanBuildToolsTests() } if *tests.TestDistribution {