This guide explains how to use the upload_to_artifactory.sh script to upload entire directories to JFrog Artifactory while maintaining the original directory structure.

Prerequisites

  • Bash shell environment (Linux, macOS, or Windows with WSL/Git Bash)
  • curl command installed
  • JFrog Artifactory credentials

Setup Instructions

  1. Save the script

    Create a file named upload_to_artifactory.sh with the following content:

    #!/bin/bash
     
    # Usage: ./upload_to_artifactory.sh <local_directory> <target_directory>
    # Example: ./upload_to_artifactory.sh ./my_terraform_modules terraform/modules
     
    # Check if required arguments are provided
    if [ $# -lt 2 ]; then
        echo "Usage: $0 <local_directory> <target_directory>"
        exit 1
    fi
     
    # Set variables
    LOCAL_DIR=$1
    TARGET_DIR=$2
    USERNAME="mark.kpamy"
    ARTIFACTORY_URL="https://artifacts.my-nx.com/artifactory/nx-common-terraform-dev-internal"
     
    # Ask for password (avoid storing in script)
    read -s -p "Enter Artifactory password: " PASSWORD
    echo ""
     
    # Check if directory exists
    if [ ! -d "$LOCAL_DIR" ]; then
        echo "Error: Directory $LOCAL_DIR does not exist"
        exit 1
    fi
     
    # Function to upload files
    upload_files() {
        local dir=$1
        local target=$2
        
        # Process all files in the directory
        find "$dir" -type f | while read file; do
            # Get relative path
            rel_path=$(realpath --relative-to="$LOCAL_DIR" "$file")
            
            # Construct target path
            if [ -z "$target" ]; then
                target_path="$rel_path"
            else
                target_path="$target/$rel_path"
            fi
            
            echo "Uploading: $file to $ARTIFACTORY_URL/$target_path"
            
            # Upload file
            curl -u "$USERNAME:$PASSWORD" \
                 -T "$file" \
                 "$ARTIFACTORY_URL/$target_path" \
                 --fail --silent --show-error
            
            # Check if upload was successful
            if [ $? -eq 0 ]; then
                echo "Success: $file uploaded"
            else
                echo "Error: Failed to upload $file"
            fi
        done
    }
     
    echo "Starting upload from $LOCAL_DIR to $ARTIFACTORY_URL/$TARGET_DIR"
    upload_files "$LOCAL_DIR" "$TARGET_DIR"
    echo "Upload completed"
  2. Make the script executable

    chmod +x upload_to_artifactory.sh
  3. Customize the script

    Edit the script to update:

    • USERNAME with your Artifactory username
    • ARTIFACTORY_URL with your Artifactory URL and repository path

Usage

  1. Basic Usage

    ./upload_to_artifactory.sh <local_directory> <target_directory>

    For example:

    ./upload_to_artifactory.sh ./terraform_modules terraform/modules/v1
  2. Password

    The script will prompt for your password when executed. This avoids storing sensitive information in the script.

How It Works

The script:

  1. Takes two parameters: the local directory to upload and the target directory in Artifactory
  2. Finds all files in the local directory (including subdirectories)
  3. Preserves the relative paths when uploading to maintain the exact directory structure
  4. Uploads each file individually using curl and the Artifactory REST API
  5. Reports success or failure for each upload

Directory Structure Example

If your local directory has this structure:

my_local_folder/
├── main.tf
├── variables.tf
├── modules/
│   ├── networking/
│   │   ├── main.tf
│   │   └── variables.tf
│   └── compute/
│       ├── main.tf
│       └── variables.tf
└── environments/
    ├── dev/
    │   └── terraform.tfvars
    └── prod/
        └── terraform.tfvars

After running:

./upload_to_artifactory.sh ./my_local_folder my_target_folder

Your Artifactory will have this structure:

nx-common-terraform-dev-internal/my_target_folder/
├── main.tf
├── variables.tf
├── modules/
│   ├── networking/
│   │   ├── main.tf
│   │   └── variables.tf
│   └── compute/
│       ├── main.tf
│       └── variables.tf
└── environments/
    ├── dev/
    │   └── terraform.tfvars
    └── prod/
        └── terraform.tfvars

Troubleshooting

  • Permission Denied: Make sure the script is executable (chmod +x upload_to_artifactory.sh)
  • Authentication Failed: Verify your username and password are correct
  • Path Not Found: Ensure the local directory exists and the target path is valid in Artifactory
  • Upload Failed: Check if you have write permissions to the target repository

Advanced Modifications

To filter file types, add a condition to the find command:

find "$dir" -type f -name "*.tf" | while read file; do

To add a debug mode, add a flag and debug prints:

if [ "$DEBUG" = "true" ]; then
    echo "Debug: Command executed: curl -u "$USERNAME:****" -T "$file" "$ARTIFACTORY_URL/$target_path""
fi

Security Notes

  • The script prompts for your password rather than storing it in plain text
  • Consider using API keys or tokens instead of passwords for better security
  • For automation, consider using environment variables for credentials

Additional Resources