Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8888b67
RTECO-1574 - RTECO-1574 - Implementation of Nuget Support for client -
bhanurp Jul 24, 2026
1330b5a
Fix NuGet FlexPack CLI wiring and pin dependencies to pushed commits
bhanurp Jul 29, 2026
b870955
Add NuGet FlexPack native test suite and fix --scan flag leak
bhanurp Aug 6, 2026
0d50f82
Point build-info-go/jfrog-cli-artifactory replace directives at pushe…
bhanurp Aug 6, 2026
485add2
Merge branch 'master' into RTECO-1574
bhanurp Aug 7, 2026
10fd916
Fix cli.go import conflict from master merge, bump fork replace direc…
bhanurp Aug 7, 2026
7958796
Merge branch 'master' into RTECO-1574
bhanurp Aug 8, 2026
642bbd6
Fix Go-Sec/Static Check findings in nuget_native_test.go
bhanurp Aug 8, 2026
6ac876b
Bump jfrog-cli's own build-info-go replace to match jfrog-cli-artifac…
bhanurp Aug 8, 2026
f976e15
Bump build-info-go/jfrog-cli-artifactory replace directives (Go-Sec f…
bhanurp Aug 8, 2026
b3fa315
Merge branch 'master' into RTECO-1574
bhanurp Aug 10, 2026
a33ab2b
Regenerate go.sum after merging master
bhanurp Aug 10, 2026
1bc0c18
Update TestNugetResolve assertions for FlexPack RequestedBy shape
bhanurp Aug 10, 2026
77e2b75
Fix unparam lint: drop unused moduleName param from Nuget dependency …
bhanurp Aug 10, 2026
6948835
Gate NuGet/Dotnet FlexPack routing on absence of a legacy config file
bhanurp Aug 10, 2026
f6e9d6c
Strip --insecure-tls in legacy NugetCmd/DotnetCmd too
bhanurp Aug 10, 2026
d5a9a40
Revert "Strip --insecure-tls in legacy NugetCmd/DotnetCmd too"
bhanurp Aug 10, 2026
addafd3
Use --allow-insecure-connections in legacy-config-based NuGet/Dotnet …
bhanurp Aug 10, 2026
0f36415
Give nuget_native_test.go its own insecure-connection helper
bhanurp Aug 10, 2026
63e1dc5
Skip build-scan NuGet tests when Xray is not enabled
bhanurp Aug 10, 2026
13af163
Fix project creation auth and skip release-bundle test without Lifecycle
bhanurp Aug 11, 2026
91dbc26
Point NuGet CI job at the platform router so Lifecycle endpoints resolve
bhanurp Aug 11, 2026
8ef3353
Scope the platform-router URL fix to the release-bundle test only
bhanurp Aug 11, 2026
c98cf47
Merge remote-tracking branch 'upstream/master' into RTECO-1574
bhanurp Aug 12, 2026
ca0e555
Route project-creation Access calls through the platform router too; …
bhanurp Aug 12, 2026
d1c91a9
Fix Windows-only failure in TestNugetFlexPackDependencyRangeResolvesC…
bhanurp Aug 12, 2026
ab33d4e
Merge remote-tracking branch 'upstream/master' into RTECO-1574
bhanurp Aug 12, 2026
2acb8ba
Add missing allow-unsafe-pr-checkout to aptTests.yml
bhanurp Aug 13, 2026
c9162ee
Merge branch 'master' into RTECO-1574
bhanurp Aug 13, 2026
b958f5d
RTECO-0000 - Ran go mod tidy
bhanurp Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/aptTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}
# Safe: this workflow only runs after human approval via the build-gate environment.
allow-unsafe-pr-checkout: true

- name: Setup FastCI
uses: jfrog-fastci/fastci@v1
Expand Down
116 changes: 113 additions & 3 deletions buildtools/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package buildtools
import (
"errors"
"fmt"

"io/fs"
"os"
"os/exec"
Expand All @@ -11,10 +12,12 @@ import (
"strconv"
"strings"

dotnetutils "github.com/jfrog/build-info-go/build/utils/dotnet"
alpinecommand "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/alpine"
aptcommand "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/apt"
conancommand "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/conan"
nixcommand "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/nix"
nugetcommand "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/nuget"

"github.com/BurntSushi/toml"
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/container/strategies"
Expand Down Expand Up @@ -1015,11 +1018,22 @@ func NugetCmd(c *cli.Context) error {
return cliutils.WrongNumberOfArgumentsHandler(c)
}

configFilePath, err := getProjectConfigPathOrThrow(project.Nuget, "nuget", "nuget-config")
configFilePath, configExists, err := project.GetProjectConfFilePath(project.Nuget)
if err != nil {
return err
}

// FlexPack bypasses all config file requirements (only when no config exists)
if artutils.ShouldRunNative(configFilePath) && !configExists {
return runNugetFlexPackCmd(c, dotnetutils.Nuget)
}

if !configExists {
if configFilePath, err = getProjectConfigPathOrThrow(project.Nuget, "nuget", "nuget-config"); err != nil {
return err
}
}

rtDetails, targetRepo, useNugetV2, err := getNugetAndDotnetConfigFields(configFilePath)
if err != nil {
return err
Expand Down Expand Up @@ -1059,12 +1073,22 @@ func DotnetCmd(c *cli.Context) error {
return cliutils.WrongNumberOfArgumentsHandler(c)
}

// Get configuration file path.
configFilePath, err := getProjectConfigPathOrThrow(project.Dotnet, "dotnet", "dotnet-config")
configFilePath, configExists, err := project.GetProjectConfFilePath(project.Dotnet)
if err != nil {
return err
}

// FlexPack bypasses all config file requirements (only when no config exists)
if artutils.ShouldRunNative(configFilePath) && !configExists {
return runNugetFlexPackCmd(c, dotnetutils.DotnetCore)
}

if !configExists {
if configFilePath, err = getProjectConfigPathOrThrow(project.Dotnet, "dotnet", "dotnet-config"); err != nil {
return err
}
}

rtDetails, targetRepo, useNugetV2, err := getNugetAndDotnetConfigFields(configFilePath)
if err != nil {
return err
Expand Down Expand Up @@ -2147,6 +2171,92 @@ func ConanCmd(c *cli.Context) error {
return commands.ExecWithPackageManager(conanCommand, project.Conan.String())
}

// runNugetFlexPackCmd handles NuGet/dotnet commands in FlexPack native mode.
// No project config file is required; server details come from --server-id or the default profile.
func runNugetFlexPackCmd(c *cli.Context, toolchainType dotnetutils.ToolchainType) error {
args := cliutils.ExtractCommand(c)

args, serverID, err := coreutils.ExtractServerIdFromCommand(args)
if err != nil {
return fmt.Errorf("extract server ID: %w", err)
}

filteredArgs, buildConfiguration, err := build.ExtractBuildDetailsFromArgs(args)
if err != nil {
return err
}

// Extract --repo-resolve and --repo flags.
var repoResolve, repoDeploy string
filteredArgs, repoResolve, err = coreutils.ExtractStringOptionFromArgs(filteredArgs, "repo-resolve")
if err != nil {
return fmt.Errorf("extract --repo-resolve: %w", err)
}
filteredArgs, repoDeploy, err = coreutils.ExtractStringOptionFromArgs(filteredArgs, "repo")
if err != nil {
return fmt.Errorf("extract --repo: %w", err)
}

useNugetV2, err := cliutils.ExtractBoolFlagFromArgs(&filteredArgs, "nuget-v2")
if err != nil {
return err
}
allowInsecure, err := cliutils.ExtractBoolFlagFromArgs(&filteredArgs, "insecure-tls")
if err != nil {
return err
}
// --scan isn't a native nuget.exe option; it must be consumed here or it leaks through and
// nuget.exe rejects it with "Unknown option". Conditional-upload Xray scanning (blocking the
// push itself on a critical vulnerability, as Maven's --scan does via
// commandsUtils.ConditionalUploadScanFunc) isn't wired for NuGet FlexPack yet - same
// documented gap as the curation hook (scenario 11) - so for now this only strips the flag
// rather than acting on it.
xrayScan, err := cliutils.ExtractBoolFlagFromArgs(&filteredArgs, "scan")
if err != nil {
return err
}
if xrayScan {
log.Debug("'--scan' was passed to 'jf nuget push' but conditional-upload Xray scanning is not yet wired for NuGet FlexPack; the flag is accepted and stripped, not acted on.")
}

cmdName, nugetArgs := getNugetCommandName(filteredArgs, toolchainType)
workingDir, err := filepath.Abs(".")
if err != nil {
return err
}

nugetCmd := nugetcommand.NewNuGetFlexPackCommand().
SetToolchainType(toolchainType).
SetSubCommand(cmdName).
SetArgs(nugetArgs).
SetRepoResolve(repoResolve).
SetRepoDeploy(repoDeploy).
SetUseNugetV2(useNugetV2).
SetAllowInsecureConnections(allowInsecure).
SetBuildConfiguration(buildConfiguration).
SetWorkingDir(workingDir)

if nugetCmd.RequiresServerDetails() {
serverDetails, err := coreConfig.GetSpecificConfig(serverID, true, false)
if err != nil {
return err
}
nugetCmd.SetServerDetails(serverDetails)
}

return commands.ExecWithPackageManager(nugetCmd, project.Nuget.String())
}

// getNugetCommandName parses the native NuGet command and handles dotnet's two-token
// "nuget push" subcommand without changing the argument list for any other command.
func getNugetCommandName(args []string, toolchainType dotnetutils.ToolchainType) (string, []string) {
commandName, commandArgs := getCommandName(args)
if toolchainType == dotnetutils.DotnetCore && commandName == "nuget" && len(commandArgs) > 0 && commandArgs[0] == "push" {
return "nuget push", commandArgs[1:]
}
return commandName, commandArgs
}

func NixCmd(c *cli.Context) error {
if show, err := cliutils.ShowCmdHelpIfNeeded(c, c.Args()); show || err != nil {
return err
Expand Down
48 changes: 48 additions & 0 deletions buildtools/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"testing"

dotnetutils "github.com/jfrog/build-info-go/build/utils/dotnet"
containerutils "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/ocicontainer"
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
securityDocs "github.com/jfrog/jfrog-cli-security/cli/docs"
Expand All @@ -13,6 +14,53 @@ import (
"github.com/urfave/cli"
)

func TestGetNugetCommandName(t *testing.T) {
tests := []struct {
name string
toolchainType dotnetutils.ToolchainType
args []string
expectedCommand string
expectedArgs []string
}{
{
name: "dotnet nuget push",
toolchainType: dotnetutils.DotnetCore,
args: []string{"nuget", "push", "Package.1.0.0.nupkg", "--skip-duplicate"},
expectedCommand: "nuget push",
expectedArgs: []string{"Package.1.0.0.nupkg", "--skip-duplicate"},
},
{
name: "dotnet restore",
toolchainType: dotnetutils.DotnetCore,
args: []string{"restore", "Project.csproj"},
expectedCommand: "restore",
expectedArgs: []string{"Project.csproj"},
},
{
name: "nuget push remains one token",
toolchainType: dotnetutils.Nuget,
args: []string{"push", "Package.1.0.0.nupkg"},
expectedCommand: "push",
expectedArgs: []string{"Package.1.0.0.nupkg"},
},
{
name: "dotnet nuget non-push passthrough",
toolchainType: dotnetutils.DotnetCore,
args: []string{"nuget", "locals", "all", "--clear"},
expectedCommand: "nuget",
expectedArgs: []string{"locals", "all", "--clear"},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actualCommand, actualArgs := getNugetCommandName(test.args, test.toolchainType)
assert.Equal(t, test.expectedCommand, actualCommand)
assert.Equal(t, test.expectedArgs, actualArgs)
})
}
}

func TestExtractDockerBuildOptionsFromArgs(t *testing.T) {
tests := []struct {
name string
Expand Down
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,8 @@ require (

// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.54.2-0.20251007084958-5eeaa42c31a6

replace github.com/jfrog/build-info-go => github.com/bhanurp/build-info-go v1.10.10-0.20260812084325-6352a2560238

replace github.com/jfrog/jfrog-cli-artifactory => github.com/bhanurp/jfrog-cli-artifactory v0.1.12-0.20260812084434-0f13480197bf

// replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260811155045-62401b3fa49b
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ github.com/beevik/etree v1.7.0 h1:xjBk9O4p4x7D1YajePjfLzdaFC4/uYUENA7P0pv6gXA=
github.com/beevik/etree v1.7.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bhanurp/build-info-go v1.10.10-0.20260812084325-6352a2560238 h1:XgtSnmVMgu8k0xe3l9GJ53lJ8iQFqj7z3JDsnu5Gna8=
github.com/bhanurp/build-info-go v1.10.10-0.20260812084325-6352a2560238/go.mod h1:CYRUCvLKfyARjoJXLWAxce1qNUxTEtbRKAARkV42vpE=
github.com/bhanurp/jfrog-cli-artifactory v0.1.12-0.20260812084434-0f13480197bf h1:JrngoXdG+OSoJ8jL2Ahrs65pidTA8FToS11BewhiAE0=
github.com/bhanurp/jfrog-cli-artifactory v0.1.12-0.20260812084434-0f13480197bf/go.mod h1:QhB5ztpF/hyrXxfEy3q1pWMPYD8a6Pn/nlWNxdDNIXw=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
Expand Down Expand Up @@ -390,8 +394,6 @@ github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP
github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4=
github.com/jfrog/archiver/v3 v3.6.4 h1:qHAWCLKwo3+ocHNNoWzGZ8ESl8QQk/lR3W09Pt+ROvE=
github.com/jfrog/archiver/v3 v3.6.4/go.mod h1:5V9l+Fte30Y4qe9dUOAd3yNTf8lmtVNuhKNrvI8PMhg=
github.com/jfrog/build-info-go v1.13.1-0.20260811071930-3b99d4a6c84b h1:2AdobqXAdCICOEpabSc0yJavJOtX1W14/6Le8ervBaQ=
github.com/jfrog/build-info-go v1.13.1-0.20260811071930-3b99d4a6c84b/go.mod h1:CYRUCvLKfyARjoJXLWAxce1qNUxTEtbRKAARkV42vpE=
github.com/jfrog/froggit-go v1.23.1 h1:4wmaHeuptxVINbovMaeITzVhi3+VQoc/FFIjF4axzu0=
github.com/jfrog/froggit-go v1.23.1/go.mod h1:wRDryqyp3oe+eHgME2mpnEQmO8XBECIPagFwj0nHmdI=
github.com/jfrog/go-mockhttp v0.3.1 h1:/wac8v4GMZx62viZmv4wazB5GNKs+GxawuS1u3maJH8=
Expand All @@ -402,8 +404,6 @@ 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.2-0.20260723152309-34eeb81e2847 h1:wahxu7URLrhdHtI3CVH3aE1Y3eeubDin13t+QVJBeW8=
github.com/jfrog/jfrog-cli-application v1.0.2-0.20260723152309-34eeb81e2847/go.mod h1:p8yLtbmCxxQucIbLZKnWu0F+EDtj6NLXbRQCEK/nb6o=
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260812053557-d311dd344da9 h1:6N87yf7y1Zce1DvqZ1zX1sWirdJ7lh04mFvjr1JhVL0=
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260812053557-d311dd344da9/go.mod h1:eYyYY+GMdddy75/rCWiKg8EydGp/jRY+9+30QkGpbGw=
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260811142039-2813ec601d92 h1:BAV1oTSRtviUCnANnOhqcSI+V9DbITtD+7FsMpzlB24=
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260811142039-2813ec601d92/go.mod h1:JMNqk+ojKSIOrUTDdVGtYejvCpYsVSZASWbSmU95Vng=
github.com/jfrog/jfrog-cli-evidence v0.10.0 h1:9wbdHOl+wcN3crNw5qtQtQ0N28NX+9QH/Yo3Ia+iYhc=
Expand Down
Loading
Loading