From d66ba847f6c0a172e3404acaf303afc3d422b7d2 Mon Sep 17 00:00:00 2001 From: Bhanu Reddy Date: Fri, 25 Sep 2026 21:50:08 +0530 Subject: [PATCH 1/7] RTECO-2003: fix the failing Chocolatey tests Twelve Chocolatey tests have been failing on master since #3708 merged and the suite first ran in CI. This addresses the three causes. Nine of them failed because jfrog-cli-artifactory refused a non-HTTPS Artifactory source for choco only, so CI's http://localhost:8081 was rejected. Fixed in jfrog-cli-artifactory#569, which also fixes the flag-only pass-through bug behind TestChocoPassThroughWithoutServerConfigured; pinned here. TestChocoCommandPropertyRedactsApiKey crashed rather than failed. chocoPushApiKey read serverDetails.User directly, but authenticate() sets User only for the user/password form and leaves it empty whenever an access token was supplied - which is how CI runs. Chocolatey rejected the resulting ':' as invalid credentials, fell back to an interactive prompt with no console attached, and died with 0xe0434352. Derive the user from the token via the existing credentialsForTestServer helper, and fail with a readable message if it cannot be. The Chocolatey OS gate job ran on ubuntu-24.04 and failed on 'dial tcp [::1]:8081: connect: connection refused': suite-level repository setup runs before -run narrows to the two gate tests, so it reached for an Artifactory the job deliberately does not provision. Chocolatey is Windows-only, so the job is removed rather than patched. The non-Windows refusal stays covered by TestChocoCommandNonWindowsFailsClearly in jfrog-cli-artifactory, which runs on Linux. Co-Authored-By: Claude Opus 5 --- .github/workflows/chocoTests.yml | 22 ------------------ choco_test.go | 14 +++++++---- go.mod | 20 ++++++++-------- go.sum | 40 ++++++++++++++++---------------- 4 files changed, 40 insertions(+), 56 deletions(-) diff --git a/.github/workflows/chocoTests.yml b/.github/workflows/chocoTests.yml index 93c5a58fc..6c3ea6ac9 100644 --- a/.github/workflows/chocoTests.yml +++ b/.github/workflows/chocoTests.yml @@ -51,25 +51,3 @@ jobs: run: >- go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.choco ${{ env.JFROG_TESTS_IS_EXTERNAL == 'true' && format('--jfrog.url={0} --jfrog.adminToken={1}', env.JFROG_TESTS_URL, env.JFROG_TESTS_LOCAL_ACCESS_TOKEN) || '' }} - - # The OS gate is the one behaviour that can only be observed where Chocolatey cannot run, so it - # needs a non-Windows job. Deliberately cheap: no Artifactory and no Chocolatey, just the two - # tests asserting that 'jf choco' refuses to run and that 'jf choco --help' still works anyway. - Choco-OS-Gate: - name: Chocolatey OS gate (linux) - runs-on: ubuntu-24.04 - steps: - - name: Checkout code - 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 Go with cache - uses: jfrog/.github/actions/install-go-with-cache@main - - - name: Assert jf choco refuses to run on a non-Windows host - run: >- - go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.choco - -run 'TestChocoNonWindowsGate|TestChocoHelpWorksOnAllPlatforms' diff --git a/choco_test.go b/choco_test.go index 405e862f1..dc9094600 100644 --- a/choco_test.go +++ b/choco_test.go @@ -460,12 +460,18 @@ func TestChocoCommandPropertyRedactsApiKey(t *testing.T) { // chocoPushApiKey builds the composite ':' key that Artifactory NuGet endpoints // expect for authenticated pushes. +// +// The user has to be derived from the access token rather than read off serverDetails: authenticate +// sets User only for the user/password form and leaves it empty whenever a token was supplied, which +// is how CI runs. Chocolatey rejects the resulting ":" as invalid credentials and falls back +// to an interactive prompt, which has no console attached in CI and crashes the process with +// 0xe0434352 instead of reporting an authentication failure. func chocoPushApiKey(t *testing.T) string { t.Helper() - if serverDetails.AccessToken != "" { - return serverDetails.User + ":" + serverDetails.AccessToken - } - return serverDetails.User + ":" + serverDetails.Password + user, password := credentialsForTestServer(t) + require.NotEmpty(t, password, "the test harness must be configured with a password or an access token") + require.NotEmpty(t, user, "could not determine a username for the Chocolatey API key; the configured access token carries no subject to derive one from") + return user + ":" + password } // TestSetupChocoConfiguresSource covers the 'jf setup choco' happy path: the machine-wide diff --git a/go.mod b/go.mod index 761eff7eb..af730f026 100644 --- a/go.mod +++ b/go.mod @@ -19,11 +19,11 @@ require ( github.com/buger/jsonparser v1.3.0 github.com/gocarina/gocsv v0.0.0-20260607070740-0735908c6461 github.com/jfrog/archiver/v3 v3.6.5 - github.com/jfrog/build-info-go v1.13.1-0.20260925051954-247bd658f6f3 + github.com/jfrog/build-info-go v1.13.1-0.20260925090031-f9d40441f262 github.com/jfrog/gofrog v1.7.7 github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a - github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925064758-7cd88de3fdfc - github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925052043-a665d6336433 + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925155336-ae6e6f3c0ebd + github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260618062042-6053ab368cab github.com/jfrog/jfrog-cli-security v1.37.0 @@ -221,14 +221,14 @@ require ( go.opentelemetry.io/otel/trace v1.45.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect - golang.org/x/crypto v0.56.0 // indirect - golang.org/x/mod v0.40.0 // indirect - golang.org/x/net v0.57.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/mod v0.41.0 // indirect + golang.org/x/net v0.58.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.22.0 // indirect - golang.org/x/sys v0.47.0 // indirect - golang.org/x/term v0.45.0 // indirect - golang.org/x/text v0.41.0 // indirect + golang.org/x/sync v0.23.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/term v0.46.0 // indirect + golang.org/x/text v0.42.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect diff --git a/go.sum b/go.sum index 175dbd1f9..43b95fd75 100644 --- a/go.sum +++ b/go.sum @@ -390,8 +390,8 @@ 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.5 h1:AiNXJoe8jYDOtyykfVuwh26aM4rk/ei+YzBpfBukdzU= github.com/jfrog/archiver/v3 v3.6.5/go.mod h1:5V9l+Fte30Y4qe9dUOAd3yNTf8lmtVNuhKNrvI8PMhg= -github.com/jfrog/build-info-go v1.13.1-0.20260925051954-247bd658f6f3 h1:vBkLakwu2fEOncEK73hog+QbG8KWEOp3iJnvuhpCVKQ= -github.com/jfrog/build-info-go v1.13.1-0.20260925051954-247bd658f6f3/go.mod h1:CYRUCvLKfyARjoJXLWAxce1qNUxTEtbRKAARkV42vpE= +github.com/jfrog/build-info-go v1.13.1-0.20260925090031-f9d40441f262 h1:xqy989W2i97ENJTmnRa2mJu0Q2dI9IJ2pnQsFnH8AVA= +github.com/jfrog/build-info-go v1.13.1-0.20260925090031-f9d40441f262/go.mod h1:PCfjSoigriSjUWupH0jffPtDq+fnMGIZxgM3Cgw9QIg= 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= @@ -402,10 +402,10 @@ 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.20260820134442-c8629258ff3a h1:7GhcPfi+k9oOAJdCsKWjymnqH0e7DQZ1soVhbneYnGY= github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a/go.mod h1:p8yLtbmCxxQucIbLZKnWu0F+EDtj6NLXbRQCEK/nb6o= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925064758-7cd88de3fdfc h1:FReKkyXUwckBfVvvzXEgpIlkLvtzMFQjK6eCH285CS8= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925064758-7cd88de3fdfc/go.mod h1:E8h+DVJH2qRyB+7t1RnSQ4tYYbog6sQeAN7plnJRlNA= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925052043-a665d6336433 h1:orO2tFOrCvzMVEsKcjiPf3GVUCbxN7VpngS3uKS97+4= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925052043-a665d6336433/go.mod h1:SwV+DNLBnWLxBeNeZpJk+xxAbqJ8ywq1va56up+AGu4= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925155336-ae6e6f3c0ebd h1:LIsaiTbLjvPcUoy+b0Tb0ayTKxUSZXgAfsthhQ2rAC0= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925155336-ae6e6f3c0ebd/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 h1:SNXwdC0MIjNC2dCf8lNaZvMNpy6CLWdsZllcIhC/atQ= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0/go.mod h1:SwV+DNLBnWLxBeNeZpJk+xxAbqJ8ywq1va56up+AGu4= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e h1:+QYbewvK+PZKbfPpxYmy0bewhqMFtJPk/tUbCICjf8U= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e/go.mod h1:I83k7IH/cmMh00LyZOp13jctj8/pPKVHSAlu7GMJgwI= github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260618062042-6053ab368cab h1:Zn/qB8LYhSu82YDtbqXwErN1RPHTHe/a3gQY6Ti/OBE= @@ -758,14 +758,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= -golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/exp v0.0.0-20260727155853-b88d891fe743 h1:ex206bKw+v3K0dm3andkrIF+ijyQKJG1pLgwQ2PYdQM= golang.org/x/exp v0.0.0-20260727155853-b88d891fe743/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= -golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= +golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c= +golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -776,8 +776,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -786,8 +786,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= -golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -817,16 +817,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= -golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= -golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= +golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE= +golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -834,8 +834,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= -golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From c8728f3b79828294e87e833425bf210cde8a2ec4 Mon Sep 17 00:00:00 2001 From: Bhanu Reddy Date: Fri, 25 Sep 2026 22:11:39 +0530 Subject: [PATCH 2/7] RTECO-2003: repin jfrog-cli-artifactory for the Chocolatey source credentials fix Picks up the fix that stores read credentials on the Chocolatey source, without which 'jf choco install' fails with HTTP 401 against an authenticated repository. Co-Authored-By: Claude Opus 5 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index af730f026..a0f8f670c 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/jfrog/build-info-go v1.13.1-0.20260925090031-f9d40441f262 github.com/jfrog/gofrog v1.7.7 github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a - github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925155336-ae6e6f3c0ebd + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925163910-5a2a7456346b github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260618062042-6053ab368cab diff --git a/go.sum b/go.sum index 43b95fd75..56deade44 100644 --- a/go.sum +++ b/go.sum @@ -402,8 +402,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.2-0.20260820134442-c8629258ff3a h1:7GhcPfi+k9oOAJdCsKWjymnqH0e7DQZ1soVhbneYnGY= github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a/go.mod h1:p8yLtbmCxxQucIbLZKnWu0F+EDtj6NLXbRQCEK/nb6o= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925155336-ae6e6f3c0ebd h1:LIsaiTbLjvPcUoy+b0Tb0ayTKxUSZXgAfsthhQ2rAC0= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925155336-ae6e6f3c0ebd/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925163910-5a2a7456346b h1:NxftV6M3fejAQ9sG7Yv9Mk3d/w8mi3aG9jaaPU9EM6c= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925163910-5a2a7456346b/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 h1:SNXwdC0MIjNC2dCf8lNaZvMNpy6CLWdsZllcIhC/atQ= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0/go.mod h1:SwV+DNLBnWLxBeNeZpJk+xxAbqJ8ywq1va56up+AGu4= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e h1:+QYbewvK+PZKbfPpxYmy0bewhqMFtJPk/tUbCICjf8U= From 2719b09951a812e16570701c6879d3d468cd5ae7 Mon Sep 17 00:00:00 2001 From: Bhanu Reddy Date: Fri, 25 Sep 2026 22:33:47 +0530 Subject: [PATCH 3/7] RTECO-2003: drop the unreachable Chocolatey OS-gate test The only remaining --test.choco job is windows-2022, and TestChocoNonWindowsGate skipped itself on Windows, so its body could no longer run anywhere. The gate's rejection message is asserted by TestChocoCommandNonWindowsFailsClearly in jfrog-cli-artifactory, which stubs the platform check and therefore runs on Linux in that repo's normal suite. Fold the single-caller initChocoTestAnyPlatform helper into TestChocoHelpWorksOnAllPlatforms. Re-pin jfrog-cli-artifactory to pick up the Chocolatey setup cleanup. Co-Authored-By: Claude Opus 5 --- choco_test.go | 32 ++++++-------------------------- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/choco_test.go b/choco_test.go index dc9094600..d11dbe9d4 100644 --- a/choco_test.go +++ b/choco_test.go @@ -655,35 +655,15 @@ func TestChocoInstallRecordsVersionFromInstalledPackage(t *testing.T) { // Pass-through, statelessness and the platform gate. // --------------------------------------------------------------------------------------------- -// initChocoTestAnyPlatform gates only on the feature flag, for the two scenarios that must be -// observed where Chocolatey cannot run. It deliberately configures no JFrog server: the OS gate -// fires before any server interaction, and requiring one here would hide a regression that moved -// the gate behind server resolution. -func initChocoTestAnyPlatform(t *testing.T) { - t.Helper() +// TestChocoHelpWorksOnAllPlatforms asserts the gate lives in the command's Run(), not in its +// registration, so help stays reachable on the machines that cannot run the tool. It deliberately +// configures no JFrog server: help must not need one. The gate's rejection message is asserted by +// TestChocoCommandNonWindowsFailsClearly in jfrog-cli-artifactory, which stubs the platform check +// and so runs on every OS - this suite only ever runs on Windows. +func TestChocoHelpWorksOnAllPlatforms(t *testing.T) { if !*tests.TestChoco { t.Skip("Skipping Chocolatey test. To run Choco test add the '-test.choco=true' option.") } -} - -// TestChocoNonWindowsGate asserts the command refuses to run off Windows, naming the detected OS -// instead of surfacing a bare "choco: executable file not found". -func TestChocoNonWindowsGate(t *testing.T) { - initChocoTestAnyPlatform(t) - if runtime.GOOS == "windows" { - t.Skip("The OS gate only rejects non-Windows hosts; nothing to assert on Windows.") - } - - err := runChoco(t, "choco", "install", "some-package") - require.Error(t, err, "'jf choco' must refuse to run on a non-Windows host") - assert.Contains(t, err.Error(), "Windows only") - assert.Containsf(t, err.Error(), runtime.GOOS, "the error must name the detected OS (%s)", runtime.GOOS) -} - -// TestChocoHelpWorksOnAllPlatforms asserts the gate lives in the command's Run(), not in its -// registration, so help stays reachable on the machines that cannot run the tool. -func TestChocoHelpWorksOnAllPlatforms(t *testing.T) { - initChocoTestAnyPlatform(t) assert.NoError(t, runChoco(t, "choco", "--help"), "'jf choco --help' must work on every OS") } diff --git a/go.mod b/go.mod index a0f8f670c..311ab5e97 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/jfrog/build-info-go v1.13.1-0.20260925090031-f9d40441f262 github.com/jfrog/gofrog v1.7.7 github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a - github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925163910-5a2a7456346b + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925170204-48d93b52bc9d github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260618062042-6053ab368cab diff --git a/go.sum b/go.sum index 56deade44..ca6e7ba77 100644 --- a/go.sum +++ b/go.sum @@ -402,8 +402,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.2-0.20260820134442-c8629258ff3a h1:7GhcPfi+k9oOAJdCsKWjymnqH0e7DQZ1soVhbneYnGY= github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a/go.mod h1:p8yLtbmCxxQucIbLZKnWu0F+EDtj6NLXbRQCEK/nb6o= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925163910-5a2a7456346b h1:NxftV6M3fejAQ9sG7Yv9Mk3d/w8mi3aG9jaaPU9EM6c= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925163910-5a2a7456346b/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925170204-48d93b52bc9d h1:77p4ztj5mStrIStM7Tq7k9AE9n8PF+u26C9WvfHJIQs= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925170204-48d93b52bc9d/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 h1:SNXwdC0MIjNC2dCf8lNaZvMNpy6CLWdsZllcIhC/atQ= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0/go.mod h1:SwV+DNLBnWLxBeNeZpJk+xxAbqJ8ywq1va56up+AGu4= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e h1:+QYbewvK+PZKbfPpxYmy0bewhqMFtJPk/tUbCICjf8U= From eec572bd805fe19d9536aa04e1152e0640cbbf51 Mon Sep 17 00:00:00 2001 From: Bhanu Reddy Date: Fri, 25 Sep 2026 22:50:49 +0530 Subject: [PATCH 4/7] RTECO-2003: re-pin jfrog-cli-artifactory for the Chocolatey credential fix Picks up the username requirement and the source read credentials, so 'choco install' authenticates against an Artifactory NuGet feed instead of returning HTTP 401. Co-Authored-By: Claude Opus 5 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 311ab5e97..3e50ab8c9 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/jfrog/build-info-go v1.13.1-0.20260925090031-f9d40441f262 github.com/jfrog/gofrog v1.7.7 github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a - github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925170204-48d93b52bc9d + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925171759-b35d1f469e0d github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260618062042-6053ab368cab diff --git a/go.sum b/go.sum index ca6e7ba77..638c0ed38 100644 --- a/go.sum +++ b/go.sum @@ -402,8 +402,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.2-0.20260820134442-c8629258ff3a h1:7GhcPfi+k9oOAJdCsKWjymnqH0e7DQZ1soVhbneYnGY= github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a/go.mod h1:p8yLtbmCxxQucIbLZKnWu0F+EDtj6NLXbRQCEK/nb6o= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925170204-48d93b52bc9d h1:77p4ztj5mStrIStM7Tq7k9AE9n8PF+u26C9WvfHJIQs= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925170204-48d93b52bc9d/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925171759-b35d1f469e0d h1:Aymi84i0Z/fdrLuV0yPGa4hPZnusVVGd3df8OOvXQU8= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925171759-b35d1f469e0d/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 h1:SNXwdC0MIjNC2dCf8lNaZvMNpy6CLWdsZllcIhC/atQ= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0/go.mod h1:SwV+DNLBnWLxBeNeZpJk+xxAbqJ8ywq1va56up+AGu4= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e h1:+QYbewvK+PZKbfPpxYmy0bewhqMFtJPk/tUbCICjf8U= From 27e169eaebabfa6cd8854ac11d91a5cc640e3752 Mon Sep 17 00:00:00 2001 From: Bhanu Reddy Date: Fri, 25 Sep 2026 23:19:36 +0530 Subject: [PATCH 5/7] Assert the choco resolution repo on the collected build info TestChocoInstallCollectsDependencies asserted dependency.Repository on the build info read back from Artifactory after "jf rt bp". A dependency's Repository is a client-side field that Artifactory does not store - the same way entities.Artifact.OriginalDeploymentRepo is documented as internal-only - so the assertion could only ever have tested Artifactory's serialization, and it came back empty. The assertion had never executed before now: every earlier run of this test failed on the HTTP 401 that the credential fix resolved. Assert --repo-resolve where the value actually lives instead, by reading the partial build-info files off disk before the publish. The coverage is kept and now exercises the wiring it was written for. Co-Authored-By: Claude Opus 5 --- choco_test.go | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/choco_test.go b/choco_test.go index d11dbe9d4..987b11c6b 100644 --- a/choco_test.go +++ b/choco_test.go @@ -13,6 +13,7 @@ import ( "time" buildInfo "github.com/jfrog/build-info-go/entities" + coreBuild "github.com/jfrog/jfrog-cli-core/v2/common/build" "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" coreTests "github.com/jfrog/jfrog-cli-core/v2/utils/tests" "github.com/jfrog/jfrog-cli/inttestutils" @@ -514,6 +515,9 @@ func TestChocoInstallCollectsDependencies(t *testing.T) { cleanupChocoInstalledPackage(t, id) requireChocoInstall(t, id, version, sourceName, buildName, buildNumber) + // Asserted before the publish below, and against the locally collected build info: Artifactory + // does not persist per-dependency repository fields, so the value is gone after a round trip. + requireChocoResolutionRepoCollected(t, buildName, buildNumber, tests.NugetLocalRepo) installBuildInfo := getPublishedChocoBuildInfo(t, buildName, buildNumber) require.Len(t, installBuildInfo.Modules, 1) @@ -523,11 +527,29 @@ func TestChocoInstallCollectsDependencies(t *testing.T) { dependency := module.Dependencies[0] assert.Equal(t, id+":"+version, dependency.Id) assert.Equal(t, "nupkg", dependency.Type) - assert.Equal(t, tests.NugetLocalRepo, dependency.Repository, - "--repo-resolve should be recorded as the resolution repository") assert.Contains(t, getChocoCommandProperty(t, module), "install") } +// requireChocoResolutionRepoCollected asserts that --repo-resolve reached the collected +// dependencies. It reads the partial build-info files straight off disk, and so must run before +// 'jf rt bp': a dependency's Repository is a client-side field that Artifactory does not store, +// the same way entities.Artifact.OriginalDeploymentRepo is documented as internal-only. Asserting +// it on published build info would only ever test Artifactory's serialization. +func requireChocoResolutionRepoCollected(t *testing.T, buildName, buildNumber, expectedRepo string) { + t.Helper() + partials, err := coreBuild.ReadPartialBuildInfoFiles(buildName, buildNumber, "") + require.NoError(t, err) + var dependencies []buildInfo.Dependency + for _, partial := range partials { + dependencies = append(dependencies, partial.Dependencies...) + } + require.NotEmpty(t, dependencies, "the installed package must be collected as a dependency") + for _, dependency := range dependencies { + assert.Equal(t, expectedRepo, dependency.Repository, + "--repo-resolve should be recorded as the resolution repository of %s", dependency.Id) + } +} + // requireChocoInstall runs 'jf choco install' with a short retry, because a freshly pushed // package is not immediately searchable through the NuGet endpoint. func requireChocoInstall(t *testing.T, id, version, sourceName, buildName, buildNumber string) { From 21389fb802cd9e318b51835b1654c65634cb35e7 Mon Sep 17 00:00:00 2001 From: Bhanu Reddy Date: Fri, 25 Sep 2026 23:39:20 +0530 Subject: [PATCH 6/7] Read the saved choco build info with the right reader The previous commit read the collected dependencies with ReadPartialBuildInfoFiles, which found nothing: 'jf choco' persists a whole build-info file through Build.SaveBuildInfo rather than per-module partials, so the partials directory is empty. Read it with GetGeneratedBuildsInfo instead, the same call the conan tests use for locally saved build info, and walk the modules for their dependencies. Co-Authored-By: Claude Opus 5 --- choco_test.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/choco_test.go b/choco_test.go index 987b11c6b..45beacb0d 100644 --- a/choco_test.go +++ b/choco_test.go @@ -531,17 +531,20 @@ func TestChocoInstallCollectsDependencies(t *testing.T) { } // requireChocoResolutionRepoCollected asserts that --repo-resolve reached the collected -// dependencies. It reads the partial build-info files straight off disk, and so must run before -// 'jf rt bp': a dependency's Repository is a client-side field that Artifactory does not store, +// dependencies. It reads the build info that 'jf choco install' saved to disk, and so must run +// before 'jf rt bp': a dependency's Repository is a client-side field that Artifactory does not store, // the same way entities.Artifact.OriginalDeploymentRepo is documented as internal-only. Asserting // it on published build info would only ever test Artifactory's serialization. func requireChocoResolutionRepoCollected(t *testing.T, buildName, buildNumber, expectedRepo string) { t.Helper() - partials, err := coreBuild.ReadPartialBuildInfoFiles(buildName, buildNumber, "") + generatedBuilds, err := coreBuild.GetGeneratedBuildsInfo(buildName, buildNumber, "") require.NoError(t, err) + require.NotEmpty(t, generatedBuilds, "'jf choco install' should have saved build info locally") var dependencies []buildInfo.Dependency - for _, partial := range partials { - dependencies = append(dependencies, partial.Dependencies...) + for _, generatedBuild := range generatedBuilds { + for _, module := range generatedBuild.Modules { + dependencies = append(dependencies, module.Dependencies...) + } } require.NotEmpty(t, dependencies, "the installed package must be collected as a dependency") for _, dependency := range dependencies { From 11b62531aa751704275eebc9dfda12e923f3063f Mon Sep 17 00:00:00 2001 From: Bhanu Reddy Date: Fri, 25 Sep 2026 23:40:25 +0530 Subject: [PATCH 7/7] Bump jfrog-cli-artifactory to the gosec-clean commit Picks up 7443887, which annotates the fake reference token in the choco setup tests so the Go-Sec job passes. Co-Authored-By: Claude Opus 5 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3e50ab8c9..457c5cb33 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/jfrog/build-info-go v1.13.1-0.20260925090031-f9d40441f262 github.com/jfrog/gofrog v1.7.7 github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a - github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925171759-b35d1f469e0d + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925180054-7443887d736b github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260618062042-6053ab368cab diff --git a/go.sum b/go.sum index 638c0ed38..2bc133dce 100644 --- a/go.sum +++ b/go.sum @@ -402,8 +402,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.2-0.20260820134442-c8629258ff3a h1:7GhcPfi+k9oOAJdCsKWjymnqH0e7DQZ1soVhbneYnGY= github.com/jfrog/jfrog-cli-application v1.0.2-0.20260820134442-c8629258ff3a/go.mod h1:p8yLtbmCxxQucIbLZKnWu0F+EDtj6NLXbRQCEK/nb6o= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925171759-b35d1f469e0d h1:Aymi84i0Z/fdrLuV0yPGa4hPZnusVVGd3df8OOvXQU8= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925171759-b35d1f469e0d/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925180054-7443887d736b h1:ZhVUJM5ff7+a0lqpnBz9jswB8FpVoCRmYOEMxiJfwjs= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260925180054-7443887d736b/go.mod h1:VaMX/0GKExKszogM+G62260Krx15l4EV/MQ0ftgbBW0= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0 h1:SNXwdC0MIjNC2dCf8lNaZvMNpy6CLWdsZllcIhC/atQ= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260925084932-b47892ded3a0/go.mod h1:SwV+DNLBnWLxBeNeZpJk+xxAbqJ8ywq1va56up+AGu4= github.com/jfrog/jfrog-cli-evidence v0.11.1-0.20260824063609-79b735ec565e h1:+QYbewvK+PZKbfPpxYmy0bewhqMFtJPk/tUbCICjf8U=