Maven의 mvn deploy:deploy-file 명령어는 보안상의 이유로 명령줄 인자(CLI)에서 직접 아이디/비밀번호를 받는 기능을 공식적으로 권장하지 않습니다. 보통 settings.xml에 서버 정보를 등록해야 작동합니다.
하지만 스크립트 실행 시 임시 settings.xml 파일을 생성하여 인증 정보를 주입하고, 실행 후 삭제하는 방식으로 로그인 정보를 포함한 완전 자동화 스크립트를 구현할 수 있습니다.
아래는 인증 정보(ID/PW)를 입력받아 처리하는 개선된 스크립트입니다.
1. 인증 포함 완전 자동화 Bash 스크립트 (권장)
이 스크립트는 실행 시에만 유효한 임시 설정 파일을 만들어 인증을 처리하므로, 전역 settings.xml을 수정할 필요가 없습니다.
#!/bin/bash
# upload-maven-interactive.sh
# 1. 인자 확인 (비밀번호 제외)
NEXUS_URL=$1
NEXUS_USER=$2
if [[ -z "$NEXUS_URL" ]] || [[ -z "$NEXUS_USER" ]]; then
echo "사용법: ./upload-maven-interactive.sh <nexus-url> <username>"
echo "예시: ./upload-maven-interactive.sh http://10.150.100.207/nexus/repository/gjf-temp/ admin"
exit 1
fi
# 2. 비밀번호 안전하게 입력 받기 (화면에 표시되지 않음)
echo -n "Nexus 비밀번호를 입력하세요: "
read -s NEXUS_PASSWORD
echo "" # 줄바꿈
if [[ -z "$NEXUS_PASSWORD" ]]; then
echo "비밀번호가 입력되지 않았습니다."
exit 1
fi
M2_REPO="${HOME}/.m2/repository"
TEMP_SETTINGS="temp-settings-$(date +%s).xml"
REPO_ID="temp-nexus-repo"
# 3. XML 특수문자 처리 (비밀번호에 <, >, &, ", ' 가 있을 경우 대비)
# sed를 사용하여 XML 엔티티로 변환
ESCAPED_PASSWORD=$(echo "$NEXUS_PASSWORD" | sed 's/&/\&/g; s/</\</g; s/>/\>/g; s/"/\"/g; s/'"'"'/\'/g')
if [[ ! -d "$M2_REPO" ]]; then
echo "Maven 저장소 디렉토리 없음: $M2_REPO"
exit 1
fi
# 4. 임시 settings.xml 생성
echo ">> 인증용 임시 설정 파일 생성 중..."
cat <<EOF > "$TEMP_SETTINGS"
<settings>
<servers>
<server>
<id>$REPO_ID</id>
<username>$NEXUS_USER</username>
<password>$ESCAPED_PASSWORD</password>
</server>
</servers>
</settings>
EOF
# 5. 업로드 시작
echo ">> 검색 시작: $M2_REPO"
find "$M2_REPO" -type f -name "*.jar" | while read jar_file; do
dir_path=$(dirname "$jar_file")
version=$(basename "$dir_path")
artifact_dir=$(dirname "$dir_path")
artifact_id=$(basename "$artifact_dir")
file_name=$(basename "$jar_file")
# 메인 아티팩트 체크
expected_jar_name="${artifact_id}-${version}.jar"
if [[ "$file_name" != "$expected_jar_name" ]]; then
continue
fi
# GroupId 추출
full_group_path=$(dirname "$artifact_dir")
rel_group_path=$(realpath --relative-to="$M2_REPO" "$full_group_path")
group_id=$(echo "$rel_group_path" | tr '/' '.')
# POM 파일 체크
pom_file="${dir_path}/${artifact_id}-${version}.pom"
pom_param=""
if [[ -f "$pom_file" ]]; then
pom_param="-DpomFile=$pom_file"
generate_pom="false"
else
pom_param="-DgeneratePom=true"
generate_pom="true"
fi
echo ">> 업로드: $group_id:$artifact_id:$version"
mvn deploy:deploy-file \
-s "$TEMP_SETTINGS" \
-DgroupId="$group_id" \
-DartifactId="$artifact_id" \
-Dversion="$version" \
-Dpackaging=jar \
$pom_param \
-DrepositoryId="$REPO_ID" \
-Durl="$NEXUS_URL" \
-Dfile="$jar_file" \
-DgeneratePom="$generate_pom" \
-B > /dev/null
if [[ $? -ne 0 ]]; then
echo " [실패] 로그 확인 필요"
else
echo " [성공]"
fi
done
# 6. 임시 파일 삭제
rm "$TEMP_SETTINGS"
echo ">> 작업 완료."
실행 방법
이제 비밀번호를 명령줄에 쓰지 말고, 아래와 같이 실행하세요.
# 1. 실행 권한 부여
chmod +x upload-maven-interactive.sh
# 2. 스크립트 실행 (비밀번호 인자 없이)
./upload-maven-auth.sh http://my-nexus:8081/repository/maven-releases/ admin admin
실행 후:
Nexus 비밀번호를 입력하세요: <-- 여기에 비밀번호 입력 (화면엔 안 보임)
2. (참고) Gradle Task 방식 (인증 포함)

만약 Gradle 환경(build.gradle)에서 실행하고 싶다면, 아래 Task를 프로젝트에 추가하여 실행하세요. Gradle은 exec 내부에서 환경변수나 임시 파일을 다루기 까다롭기 때문에, 직접 Maven 명령어를 조립하여 인증 정보를 처리합니다.
Groovy
// build.gradle
task uploadMavenLocalCache {
doLast {
def nexusUrl = "http://my-nexus:8081/repository/maven-releases/"
def nexusUser = "admin"
def nexusPassword = "password123" // 보안상 gradle.properties로 빼는 것을 추천
def m2Repo = new File(System.getProperty("user.home"), ".m2/repository")
def tempSettingsFile = new File(project.buildDir, "temp-settings.xml")
def repoId = "temp-upload-repo"
// 1. 임시 settings.xml 생성
tempSettingsFile.parentFile.mkdirs()
tempSettingsFile.text = """
<settings>
<servers>
<server>
<id>${repoId}</id>
<username>${nexusUser}</username>
<password>${nexusPassword}</password>
</server>
</servers>
</settings>
"""
// 2. 파일 순회 및 업로드
m2Repo.traverse(type: groovy.io.FileType.FILES, nameFilter: ~/.*\.jar$/) { file ->
def versionDir = file.parentFile
def artifactDir = versionDir.parentFile
def groupDir = artifactDir.parentFile
def version = versionDir.name
def artifactId = artifactDir.name
// 메인 JAR 파일만 대상 (sources, javadoc 제외)
if (file.name == "${artifactId}-${version}.jar") {
// GroupId 추출 logic
def relativeGroupPath = groupDir.absolutePath.replace(m2Repo.absolutePath, "")
if (relativeGroupPath.startsWith(File.separator)) relativeGroupPath = relativeGroupPath.substring(1)
def groupId = relativeGroupPath.replace(File.separator, ".")
def pomFile = new File(versionDir, "${artifactId}-${version}.pom")
def hasPom = pomFile.exists()
println "업로드 중: ${groupId}:${artifactId}:${version}"
exec {
// Maven 명령 실행 (Windows 호환)
executable System.getProperty("os.name").toLowerCase().contains("win") ? "mvn.cmd" : "mvn"
args 'deploy:deploy-file',
"-s", tempSettingsFile.absolutePath, // 임시 설정 파일 사용
"-Durl=${nexusUrl}",
"-DrepositoryId=${repoId}",
"-DgroupId=${groupId}",
"-DartifactId=${artifactId}",
"-Dversion=${version}",
"-Dpackaging=jar",
"-Dfile=${file.absolutePath}"
if (hasPom) {
args "-DpomFile=${pomFile.absolutePath}", "-DgeneratePom=false"
} else {
args "-DgeneratePom=true"
}
}
}
}
// 3. 임시 파일 정리
tempSettingsFile.delete()
println "완료"
}
}
요약: 변경된 핵심 로직
-
임시 settings.xml 생성: 스크립트 시작 부분에 REPO_ID, USERNAME, PASSWORD가 담긴 XML 파일을 동적으로 생성합니다.
-
Maven 옵션 추가: mvn deploy 명령어에 -s temp-settings.xml 옵션을 주어, 방금 만든 임시 파일의 인증 정보를 사용하여 Nexus에 접근하게 합니다.
-
파일 정리: 스크립트 종료 전 rm 명령어로 임시 파일을 삭제하여 보안을 유지합니다.