Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
jfrog-ecosystem committed Jan 22, 2025
2 parents 6c0484d + 61ec6ac commit 022cb45
Show file tree
Hide file tree
Showing 23 changed files with 591 additions and 55 deletions.
4 changes: 3 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ body:
id: description
attributes:
label: Describe the bug
description: What is the problem? A clear and concise description of the bug.
description: |
What is the problem? A clear and concise description of the bug.
Note: Issues related to JFrog security features such as Xray, audit, scan, etc., should be opened on the [jfrog-cli-security repository](https://github.com/jfrog/jfrog-cli-security/issues/new?template=bug_report.yml).
validations:
required: true

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/mavenTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ jobs:
- name: Setup Go with cache
uses: jfrog/.github/actions/install-go-with-cache@main

- name: Setup Maven v3.8.8 for macOS
# Fixed Maven version to avoid updating to 3.9, which includes breaking changes.
- name: Setup Maven v3.8.8
uses: stCarolas/[email protected]
with:
maven-version: 3.8.8
if: runner.os == 'macOS'

- name: Install local Artifactory
uses: jfrog/.github/actions/install-local-artifactory@main
Expand Down
57 changes: 57 additions & 0 deletions .github/workflows/prepareDarwinBinariesForRelease.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Sign Darwin Binaries for Release
on:
workflow_dispatch:
inputs:
releaseVersion:
description: "Release version"
required: true
binaryFileName:
description: 'Binary file name'
required: true
env:
binaryFileName: ${{ github.event.inputs.binaryFileName }}
releaseVersion: ${{ github.event.inputs.releaseVersion }}
jobs:
# Builds, signs, notarize and uploads the macOS binaries
prepareBinary:
name: Prepare-Binary
runs-on: macos-latest
strategy:
matrix:
goarch: [ arm64, amd64 ]
steps:
# Setup
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: 1.23.x
cache: false

- name: Checkout Source
uses: actions/checkout@v4
with:
ref: v2

# Builds the executable and moves it inside the app template
- name: Build and Move Executable
run: |
./build/build.sh ${{ env.binaryFileName }}
mv ${{ env.binaryFileName }} ./build/apple_release/${{ env.binaryFileName }}.app/Contents/MacOS
- name: Sign & Notarize
env:
APPLE_CERT_DATA: ${{ secrets.APPLE_CERT_DATA }}
APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_ACCOUNT_ID: ${{ secrets.APPLE_ACCOUNT_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APP_TEMPLATE_PATH: ./build/apple_release/${{ env.binaryFileName }}.app
run: ./build/apple_release/scripts/darwin-sign-and-notarize.sh

- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.binaryFileName }}-darwin-v${{ env.releaseVersion }}-${{ matrix.goarch }}
path: ./${{ env.binaryFileName }}
retention-days: 1
if-no-files-found: error
49 changes: 46 additions & 3 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ node("docker-ubuntu20-xlarge") {
repo = 'jfrog-cli'
sh 'rm -rf temp'
sh 'mkdir temp'
def goRoot = tool 'go-1.23.3'
def goRoot = tool 'go-1.23.4'
env.GOROOT="$goRoot"
env.PATH+=":${goRoot}/bin:/tmp/node-${nodeVersion}-linux-x64/bin"
env.GO111MODULE="on"
Expand Down Expand Up @@ -105,6 +105,7 @@ def runRelease(architectures) {
version = getCliVersion(builderPath)
print "CLI version: $version"
}

configRepo21()

try {
Expand All @@ -118,6 +119,12 @@ def runRelease(architectures) {
}
}

// We sign darwin binaries throughout GitHub actions to use MacOS machine,
// the binaries will be uploaded to GitHub packages
stage('Prepare Signed MacOS binaries') {
triggerDarwinBinariesSigningWorkflow()
}

// We sign the binary also for the standalone Windows executable, and not just for Windows executable packaged inside Chocolaty.
downloadToolsCert()
print "Uploading version $version to Repo21"
Expand Down Expand Up @@ -257,7 +264,7 @@ def cleanupRepo21() {

def buildRpmAndDeb(version, architectures) {
boolean built = false
withCredentials([file(credentialsId: 'rpm-gpg-key2', variable: 'rpmGpgKeyFile'), string(credentialsId: 'rpm-sign-passphrase', variable: 'rpmSignPassphrase')]) {
withCredentials([file(credentialsId: 'rpm-gpg-key3', variable: 'rpmGpgKeyFile'), string(credentialsId: 'rpm-sign-passphrase', variable: 'rpmSignPassphrase')]) {
def dirPath = "${pwd()}/jfrog-cli/build/deb_rpm/${identifier}/pkg"
def gpgPassphraseFilePath = "$dirPath/RPM-GPG-PASSPHRASE-jfrog-cli"
writeFile(file: gpgPassphraseFilePath, text: "$rpmSignPassphrase")
Expand Down Expand Up @@ -314,7 +321,12 @@ def uploadCli(architectures) {
for (int i = 0; i < architectures.size(); i++) {
def currentBuild = architectures[i]
stage("Build and upload ${currentBuild.pkg}") {
buildAndUpload(currentBuild.goos, currentBuild.goarch, currentBuild.pkg, currentBuild.fileExtension)
// MacOS binaries should be downloaded from GitHub packages, as they are signed there.
if (currentBuild.goos == 'darwin') {
uploadSignedDarwinBinaries(currentBuild.goarch,currentBuild.pkg)
} else {
buildAndUpload(currentBuild.goos, currentBuild.goarch, currentBuild.pkg, currentBuild.fileExtension)
}
}
}
}
Expand Down Expand Up @@ -511,3 +523,34 @@ def dockerLogin(){
sh "echo $REPO21_PASSWORD | docker login $REPO_NAME_21 -u=$REPO21_USER --password-stdin"
}
}


/**
* Triggers Github action that signs and notarize the MacOS binaries.
* The artifacts will be uploaded to Github artifacts
*/
def triggerDarwinBinariesSigningWorkflow() {
withCredentials([string(credentialsId: 'jfrog-cli-packages-github-token', variable: "GITHUB_ACCESS_TOKEN")]) {
stage("Sign MacOS binaries") {
sh ('export GITHUB_ACCESS_TOKEN=$GITHUB_ACCESS_TOKEN')
sh """#!/bin/bash
chmod +x ${repo}/build/apple_release/scripts/trigger-sign-mac-OS-workflow.sh
bash ${repo}/build/apple_release/scripts/trigger-sign-mac-OS-workflow.sh ${cliExecutableName} ${releaseVersion}
"""
}
}
}

/**
* Uploads signed darwin binaries from Github artifacts and uploads to releases
*/
def uploadSignedDarwinBinaries(goarch,pkg) {
withCredentials([string(credentialsId: 'jfrog-cli-packages-github-token', variable: "GITHUB_ACCESS_TOKEN")]) {
sh('export GITHUB_ACCESS_TOKEN=$GITHUB_ACCESS_TOKEN')
sh """#!/bin/bash
chmod +x ${repo}/build/apple_release/scripts/download-signed-mac-OS-binaries.sh
${repo}/build/apple_release/scripts/download-signed-mac-OS-binaries.sh ${cliExecutableName} ${releaseVersion} ${goarch}
$builderPath rt u ./${cliExecutableName} ecosys-jfrog-cli/$identifier/$version/${pkg}/ --flat
"""
}
}
104 changes: 103 additions & 1 deletion artifactory/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ import (
buildinfocmd "github.com/jfrog/jfrog-client-go/artifactory/buildinfo"
"github.com/jfrog/jfrog-client-go/artifactory/services"
clientutils "github.com/jfrog/jfrog-client-go/utils"
utilsForLC "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/jszwec/csvutil"
Expand All @@ -133,6 +134,7 @@ const (
userCategory = "User Management"
transferCategory = "Transfer Between Artifactory Instances"
otherCategory = "Other"
releaseBundlesV2 = "release-bundles-v2"
)

func GetCommands() []cli.Command {
Expand Down Expand Up @@ -1269,14 +1271,17 @@ func prepareDownloadCommand(c *cli.Context) (*spec.SpecFiles, error) {

var downloadSpec *spec.SpecFiles
var err error

if c.IsSet("spec") {
downloadSpec, err = cliutils.GetSpec(c, true, true)
} else {
downloadSpec, err = createDefaultDownloadSpec(c)
}

if err != nil {
return nil, err
}

setTransitiveInDownloadSpec(downloadSpec)
err = spec.ValidateSpec(downloadSpec.Files, false, true)
if err != nil {
Expand All @@ -1290,6 +1295,7 @@ func downloadCmd(c *cli.Context) error {
if err != nil {
return err
}

fixWinPathsForDownloadCmd(downloadSpec, c)
configuration, err := cliutils.CreateDownloadConfiguration(c)
if err != nil {
Expand Down Expand Up @@ -1330,6 +1336,54 @@ func downloadCmd(c *cli.Context) error {
return cliutils.GetCliError(err, result.SuccessCount(), result.FailCount(), cliutils.IsFailNoOp(c))
}

func checkRbExistenceInV2(c *cli.Context) (bool, error) {
bundleNameAndVersion := c.String("bundle")
parts := strings.Split(bundleNameAndVersion, "/")
rbName := parts[0]
rbVersion := parts[1]

lcDetails, err := createLifecycleDetailsByFlags(c)
if err != nil {
return false, err
}

lcServicesManager, err := utils.CreateLifecycleServiceManager(lcDetails, false)
if err != nil {
return false, err
}

return lcServicesManager.IsReleaseBundleExist(rbName, rbVersion, c.String("project"))
}

func createLifecycleDetailsByFlags(c *cli.Context) (*coreConfig.ServerDetails, error) {
lcDetails, err := cliutils.CreateServerDetailsWithConfigOffer(c, true, commonCliUtils.Platform)
if err != nil {
return nil, err
}
if lcDetails.Url == "" {
return nil, errors.New("platform URL is mandatory for lifecycle commands")
}
PlatformToLifecycleUrls(lcDetails)
return lcDetails, nil
}

func PlatformToLifecycleUrls(lcDetails *coreConfig.ServerDetails) {
// For tests only. in prod - this "if" will always return false
if strings.Contains(lcDetails.Url, "artifactory/") {
lcDetails.ArtifactoryUrl = utilsForLC.AddTrailingSlashIfNeeded(lcDetails.Url)
lcDetails.LifecycleUrl = strings.Replace(
utilsForLC.AddTrailingSlashIfNeeded(lcDetails.Url),
"artifactory/",
"lifecycle/",
1,
)
} else {
lcDetails.ArtifactoryUrl = utilsForLC.AddTrailingSlashIfNeeded(lcDetails.Url) + "artifactory/"
lcDetails.LifecycleUrl = utilsForLC.AddTrailingSlashIfNeeded(lcDetails.Url) + "lifecycle/"
}
lcDetails.Url = ""
}

func uploadCmd(c *cli.Context) (err error) {
if c.NArg() > 0 && c.IsSet("spec") {
return cliutils.PrintHelpAndReturnError("No arguments should be sent when the spec option is used.", c)
Expand Down Expand Up @@ -2648,8 +2702,9 @@ func createDefaultDownloadSpec(c *cli.Context) (*spec.SpecFiles, error) {
if err != nil {
return nil, err
}

return spec.NewBuilder().
Pattern(strings.TrimPrefix(c.Args().Get(0), "/")).
Pattern(getSourcePattern(c)).
Props(c.String("props")).
ExcludeProps(c.String("exclude-props")).
Build(c.String("build")).
Expand All @@ -2674,6 +2729,53 @@ func createDefaultDownloadSpec(c *cli.Context) (*spec.SpecFiles, error) {
BuildSpec(), nil
}

func getSourcePattern(c *cli.Context) string {
var source string
var isRbv2 bool
var err error

if c.IsSet("bundle") {
// If the bundle flag is set, we need to check if the bundle exists in rbv2
isRbv2, err = checkRbExistenceInV2(c)
if err != nil {
log.Error("Error occurred while checking if the bundle exists in rbv2:", err.Error())
}
}

if isRbv2 {
// RB2 will be downloaded like a regular artifact, path: projectKey-release-bundles-v2/rbName/rbVersion
source, err = buildSourceForRbv2(c)
if err != nil {
log.Error("Error occurred while building source path for rbv2:", err.Error())
return ""
}
} else {
source = strings.TrimPrefix(c.Args().Get(0), "/")
}

return source
}

func buildSourceForRbv2(c *cli.Context) (string, error) {
bundleNameAndVersion := c.String("bundle")
projectKey := c.String("project")
source := projectKey

// Reset bundle flag
err := c.Set("bundle", "")
if err != nil {
return "", err
}

// If projectKey is not empty, append "-" to it
if projectKey != "" {
source += "-"
}
// Build RB path: projectKey-release-bundles-v2/rbName/rbVersion/
source += releaseBundlesV2 + "/" + bundleNameAndVersion + "/"
return source, nil
}

func setTransitiveInDownloadSpec(downloadSpec *spec.SpecFiles) {
transitive := os.Getenv(coreutils.TransitiveDownload)
if transitive == "" {
Expand Down
Loading

0 comments on commit 022cb45

Please sign in to comment.