Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b3e3643
Added native helm commands support without buildinfo
naveenku-jfrog Nov 20, 2025
4722065
Added native helm commands docs
naveenku-jfrog Nov 20, 2025
063b709
Updated helm help doc
naveenku-jfrog Nov 21, 2025
e40633d
Addressing test failures
naveenku-jfrog Nov 21, 2025
b2d5ae9
Marked helm commands as hidden until its complete implementation is done
naveenku-jfrog Nov 26, 2025
94b1ade
Added support for helm package manager commands
naveenku-jfrog Nov 26, 2025
86965b3
Addressing git merge conflicts issues
naveenku-jfrog Nov 26, 2025
a99a87e
Addressing git merge conflicts
naveenku-jfrog Nov 26, 2025
92f23e6
Adjusting test params
naveenku-jfrog Nov 26, 2025
2f35edf
Adjusting tests conditions to be triggered
naveenku-jfrog Nov 26, 2025
51c4ea7
Added support for helm package manager commands
naveenku-jfrog Nov 26, 2025
11d1823
Refactored code
naveenku-jfrog Dec 4, 2025
d249a3e
Fixing test case
naveenku-jfrog Dec 4, 2025
1c045a4
Fixing test case
naveenku-jfrog Dec 4, 2025
08b771f
Fixing test case
naveenku-jfrog Dec 4, 2025
bfacc76
Fixing test case
naveenku-jfrog Dec 4, 2025
05bcb43
Updated test data for http or https
naveenku-jfrog Dec 4, 2025
26d22e0
Updated test data for kuberntes failure
naveenku-jfrog Dec 4, 2025
53cadbb
Updated test data for kuberntes failure
naveenku-jfrog Dec 4, 2025
bc17195
Updated test data for kuberntes failure
naveenku-jfrog Dec 4, 2025
0a724dc
Addressed comments
naveenku-jfrog Dec 8, 2025
e37d81e
Addressing static failures
naveenku-jfrog Dec 8, 2025
6705120
Updating jfrog-cli-artifactory tests
naveenku-jfrog Dec 9, 2025
c84de91
Updating jfrog-cli-artifactory version
naveenku-jfrog Dec 10, 2025
b59e478
Updating jfrog-cli-artifactory version
naveenku-jfrog Dec 10, 2025
72b57df
Updating integration test failures
naveenku-jfrog Dec 10, 2025
1209278
Updating integration test failures
naveenku-jfrog Dec 10, 2025
b842478
Updating integration test failures
naveenku-jfrog Dec 10, 2025
8836406
Adding more test for packageAndPushCommand 's BuildInfo
naveenku-jfrog Dec 10, 2025
4195682
Removing helm changes in artifactory workflow
naveenku-jfrog Dec 10, 2025
2fbb875
Merge branch 'master' into feature/Added-native-helm-commands-support
naveenku-jfrog Dec 10, 2025
49a706b
Merge branch 'master' into feature/Added-native-helm-commands-support
naveenku-jfrog Dec 10, 2025
958baa3
Addressing comments
naveenku-jfrog Dec 10, 2025
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
90 changes: 90 additions & 0 deletions .github/workflows/helmTests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Helm Tests
on:
workflow_dispatch:
push:
branches:
- "master"
# Triggers the workflow on PRs to master branch only.
pull_request_target:
types: [labeled]
branches:
- "master"

# Ensures that only the latest commit is running for each PR at a time.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
cancel-in-progress: true
permissions:
id-token: write
contents: read
jobs:
Helm-Tests:
name: Helm tests (${{ matrix.os.name }})
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'safe to test')
strategy:
fail-fast: false
matrix:
os:
- name: ubuntu
version: 24.04
- name: windows
version: 2022
- name: macos
version: 14
runs-on: ${{ matrix.os.name }}-${{ matrix.os.version }}
steps:
- name: Skip macOS - JGC-413
if: matrix.os.name == 'macos'
run: |
echo "::warning::JGC-413 - Skip until artifactory bootstrap in osx is fixed"
exit 0

- name: Checkout code
if: matrix.os.name != 'macos'
uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- name: Setup Go with cache
if: matrix.os.name != 'macos'
uses: jfrog/.github/actions/install-go-with-cache@main

- name: Install Helm
if: matrix.os.name != 'macos'
uses: azure/setup-helm@v4
with:
version: 'latest'

- name: Debug macOS Environment and Set Timeout
if: runner.os == 'macOS'
run: |
echo "=== macOS Debug Information ==="
echo "Architecture: $(uname -m)"
echo "macOS Version: $(sw_vers -productVersion)"
echo "macOS Build: $(sw_vers -buildVersion)"
echo "Available memory: $(system_profiler SPHardwareDataType | grep Memory || echo 'Memory info not available')"
echo "Available disk space: $(df -h)"
echo "Java version: $(java -version 2>&1 || echo 'Java not found')"
echo "Go version: $(go version)"
echo "Setting RT_CONNECTION_TIMEOUT_SECONDS to 2400 for macOS"
echo "RT_CONNECTION_TIMEOUT_SECONDS=2400" >> $GITHUB_ENV

- name: Install local Artifactory
if: matrix.os.name != 'macos'
uses: jfrog/.github/actions/install-local-artifactory@main
with:
RTLIC: ${{ secrets.RTLIC }}
RT_CONNECTION_TIMEOUT_SECONDS: ${{ env.RT_CONNECTION_TIMEOUT_SECONDS || '1200' }}

- name: Get ID Token and Exchange Token
if: matrix.os.name != 'macos'
shell: bash
run: |
ID_TOKEN=$(curl -sLS -H "User-Agent: actions/oidc-client" -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq .value | tr -d '"')
echo "JFROG_CLI_OIDC_EXCHANGE_TOKEN_ID=${ID_TOKEN}" >> $GITHUB_ENV

- name: Run Helm tests
if: matrix.os.name != 'macos'
run: go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.helm --jfrog.url=http://127.0.0.1:8082 --jfrog.adminToken=${{ env.JFROG_TESTS_LOCAL_ACCESS_TOKEN }}

117 changes: 117 additions & 0 deletions buildtools/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
"github.com/jfrog/jfrog-cli-core/v2/utils/ioutils"
"github.com/jfrog/jfrog-cli-security/utils/techutils"
"github.com/jfrog/jfrog-cli/docs/buildtools/helmcommand"
"github.com/jfrog/jfrog-cli/docs/buildtools/rubyconfig"
setupdocs "github.com/jfrog/jfrog-cli/docs/buildtools/setup"

"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/container"
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/dotnet"
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/golang"
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/gradle"
helmcmd "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/helm"
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/mvn"
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/npm"
containerutils "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/ocicontainer"
Expand Down Expand Up @@ -340,6 +342,19 @@ func GetCommands() []cli.Command {
Category: buildToolsCategory,
Action: PoetryCmd,
},
{
Name: "helm",
Flags: cliutils.GetCommandFlags(cliutils.Helm),
Usage: helmcommand.GetDescription(),
HelpName: corecommon.CreateUsage("helm", helmcommand.GetDescription(), helmcommand.Usage),
UsageText: helmcommand.GetArguments(),
ArgsUsage: common.CreateEnvVars(),
SkipFlagParsing: true,
HideHelp: true,
BashComplete: corecommon.CreateBashCompletionFunc(),
Category: buildToolsCategory,
Action: HelmCmd,
},
{
Name: "conan",
Flags: cliutils.GetCommandFlags(cliutils.Conan),
Expand Down Expand Up @@ -1356,6 +1371,108 @@ func PoetryCmd(c *cli.Context) error {
return pythonCmd(c, project.Poetry)
}

// HelmCmd executes Helm commands with build info collection support
func HelmCmd(c *cli.Context) error {
if show, err := cliutils.ShowCmdHelpIfNeeded(c, c.Args()); show || err != nil {
return err
}
if c.NArg() < 1 {
return cliutils.WrongNumberOfArgumentsHandler(c)
}

args := cliutils.ExtractCommand(c)
cmdName, helmArgs := getCommandName(args)

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

helmArgs, serverDetails, err := extractHelmServerDetails(helmArgs)
if err != nil {
return err
}

helmArgs, repositoryCachePath := extractRepositoryCacheFromArgs(helmArgs)

restoreEnv, err := setHelmRepositoryCache(repositoryCachePath)
if err != nil {
return err
}
defer restoreEnv()

workingDir, err := os.Getwd()
if err != nil {
return fmt.Errorf("failed to get working directory: %w", err)
}

helmCmd := helmcmd.NewHelmCommand().
SetHelmArgs(helmArgs).
SetBuildConfiguration(buildConfiguration).
SetServerDetails(serverDetails).
SetWorkingDirectory(workingDir).
SetHelmCmdName(cmdName)

return commands.Exec(helmCmd)
}

// extractRepositoryCacheFromArgs extracts the --repository-cache flag value from Helm command arguments
func extractRepositoryCacheFromArgs(args []string) ([]string, string) {
cleanedArgs, repositoryCachePath, err := coreutils.ExtractStringOptionFromArgs(args, "repository-cache")
if err != nil {
return args, ""
}
return cleanedArgs, repositoryCachePath
}

// extractHelmServerDetails extracts server ID from arguments and retrieves server details.
func extractHelmServerDetails(args []string) ([]string, *coreConfig.ServerDetails, error) {
cleanedArgs, serverID, err := coreutils.ExtractServerIdFromCommand(args)
if err != nil {
return nil, nil, fmt.Errorf("failed to extract server ID: %w", err)
}

if serverID == "" {
serverDetails, err := coreConfig.GetDefaultServerConf()
if err != nil {
return cleanedArgs, nil, err
}
return cleanedArgs, serverDetails, nil
}

serverDetails, err := coreConfig.GetSpecificConfig(serverID, true, true)
if err != nil {
return nil, nil, fmt.Errorf("failed to get server configuration for ID '%s': %w", serverID, err)
}

return cleanedArgs, serverDetails, nil
}

// setHelmRepositoryCache sets or unsets HELM_REPOSITORY_CACHE environment variable.
func setHelmRepositoryCache(cachePath string) (func(), error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are too many redundant new lines across the code please remove

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed it.

const envVarName = "HELM_REPOSITORY_CACHE"
originalValue := os.Getenv(envVarName)

if cachePath != "" {
if err := os.Setenv(envVarName, cachePath); err != nil {
return nil, fmt.Errorf("failed to set %s environment variable: %w", envVarName, err)
}
} else {
if err := os.Unsetenv(envVarName); err != nil {
return nil, fmt.Errorf("failed to unset %s environment variable: %w", envVarName, err)
}
}
restoreFunc := func() {
if originalValue != "" {
_ = os.Setenv(envVarName, originalValue)
} else {
_ = os.Unsetenv(envVarName)
}
}

return restoreFunc, nil
}

func ConanCmd(c *cli.Context) error {
if show, err := cliutils.ShowCmdHelpIfNeeded(c, c.Args()); show || err != nil {
return err
Expand Down
35 changes: 35 additions & 0 deletions docs/buildtools/helmcommand/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package helmcommand

var Usage = []string{"helm <helm arguments> [command options]"}

func GetDescription() string {
return "Run native Helm command"
}

func GetArguments() string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add examples on how to use it

return ` Examples:

$ jf helm push mychart-0.1.0.tgz oci://myrepo.jfrog.io/helm-local --build-name=my-build --build-number=1

$ jf helm package ./mychart --build-name=my-build --build-number=1

$ jf helm dependency update ./mychart --build-name=my-build --build-number=1

Commands:

install Install a chart.

upgrade Upgrade a release.

package Package a chart directory into a chart archive.

push Push a chart to remote.

pull Download a chart from remote.

repo Add, list, remove, update, and index chart repositories.

dependency Manage a chart's dependencies.

help, h Show help for any command.`
}
18 changes: 13 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ require (
github.com/docker/docker v28.5.2+incompatible
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1
github.com/jfrog/archiver/v3 v3.6.1
github.com/jfrog/build-info-go v1.12.5-0.20251209031413-f5f0e93dc8db
github.com/jfrog/build-info-go v1.12.5-0.20251209171349-eb030db986f9
github.com/jfrog/gofrog v1.7.6
github.com/jfrog/jfrog-cli-application v1.0.2-0.20251208114900-b3cc968c8e3d
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251210074251-c15fabe27f7f
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251210120128-176c677fed4c
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251210085744-f8481d179ac5
github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20251204144808-73fa744851c0
github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e
Expand All @@ -34,6 +34,7 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand All @@ -49,12 +50,13 @@ require (
cloud.google.com/go/storage v1.57.2 // indirect
dario.cat/mergo v1.0.2 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/CycloneDX/cyclonedx-go v0.9.3 // indirect
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.3 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.3.0 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
Expand All @@ -72,6 +74,8 @@ require (
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cncf/xds/go v0.0.0-20251110193048-8bfbf64dc13e // indirect
github.com/containerd/containerd v1.7.29 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect
Expand Down Expand Up @@ -177,7 +181,7 @@ require (
github.com/moby/sys/sequential v0.6.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/nwaples/rardecode v1.1.3 // indirect
github.com/oklog/run v1.0.0 // indirect
Expand Down Expand Up @@ -247,6 +251,7 @@ require (
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
go.opentelemetry.io/otel/trace v1.38.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/mod v0.30.0 // indirect
Expand All @@ -265,9 +270,12 @@ require (
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.2 // indirect
helm.sh/helm/v3 v3.19.2 // indirect
k8s.io/client-go v0.34.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
oras.land/oras-go/v2 v2.6.0 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)

replace github.com/docker/docker => github.com/docker/docker v27.5.1+incompatible
Expand Down
Loading
Loading