如何通过Maven或TeamCity变量获取构件上传至Artifactory的完整仓库URL?
Great question—getting that exact deployment path can be tricky since neither the Maven Deploy Plugin nor TeamCity exposes it directly out of the box. Here are three solid approaches to solve this, ordered by reliability:
1. Construct the Path Manually Using Maven & TeamCity Variables
Since you already have access to core Maven variables (like maven.project.version and maven.project.name), you can build the full URL by combining these with your Artifactory repository details. The path follows a predictable structure:{artifactory-base-url}/{repo-key}/{group-path}/{artifact-name}/{version}/{artifact-name}-{version}.jar
Where:
{group-path}is your Maven group ID with dots replaced by slashes (e.g.,com.myteam.appbecomescom/myteam/app){repo-key}is your Artifactory repo key (likesnapshot-localfrom your log example)
How to implement this:
First, add a Maven step (before your deploy step) to generate the path and save it to a file. You can use the maven-antrun-plugin for this—either add it to your pom.xml or run it as a standalone command in TeamCity:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>validate</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <!-- Convert group ID dots to slashes --> <property name="group.id" value="${project.groupId}" /> <script language="javascript"> var groupPath = project.getProperty("group.id").replace(/\./g, "/"); project.setProperty("group.path", groupPath); </script> <!-- Write full path to a text file --> <echo file="artifactory-deploy-path.txt" message="http://artifactory.mycompany.com/snapshot-local/${group.path}/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}.jar" /> </tasks> </configuration> </execution> </executions> </plugin>
Then, add a script step (Bash/PowerShell) to read the file and set a TeamCity environment variable using TeamCity's service message format:
Bash example:
ARTIFACT_PATH=$(cat artifactory-deploy-path.txt) echo "##teamcity[setParameter name='env.ARTIFACT_DEPLOY_PATH' value='$ARTIFACT_PATH']"
Now you can reference %env.ARTIFACT_DEPLOY_PATH% in any subsequent TeamCity steps.
2. Fetch the Path via Artifactory REST API (Most Reliable)
If you want to guarantee you get the exact path as stored in Artifactory (even if your repository structure changes), use the Artifactory REST API to query the artifact after deployment.
Steps:
- Add a script step right after your Maven deploy step.
- Use the Artifactory search API to find your artifact by group ID, artifact ID, and version.
- Extract the download URL from the response and set it as a TeamCity variable.
Bash example (requires curl and jq on your agent):
# Replace these with your values ARTIFACTORY_BASE="http://artifactory.mycompany.com" ARTIFACTORY_USER="your-username" ARTIFACTORY_PASS="your-password" GROUP_ID="com.yourcompany" ARTIFACT_ID="%maven.project.name%" VERSION="%maven.project.version%" REPO_KEY="snapshot-local" # Query Artifactory for the artifact API_RESPONSE=$(curl -u "$ARTIFACTORY_USER:$ARTIFACTORY_PASS" \ "$ARTIFACTORY_BASE/api/search/artifact?name=$ARTIFACT_ID&repos=$REPO_KEY") # Extract the full download URL ARTIFACT_PATH=$(echo "$API_RESPONSE" | jq -r '.results[0].uri') FULL_URL="$ARTIFACTORY_BASE$ARTIFACT_PATH" # Set TeamCity variable echo "##teamcity[setParameter name='env.ARTIFACT_DEPLOY_PATH' value='$FULL_URL']"
This method is foolproof because it directly fetches the path from Artifactory itself.
3. Parse the TeamCity Build Log (Quick & Dirty, Less Reliable)
If you need a quick solution without modifying your pom.xml or using the API, you can parse the TeamCity build log to extract the URL. Note that this depends on the exact log message format, so it might break if TeamCity or Maven changes their log output.
Bash example:
# Extract the URL from the log line containing "上传..." ARTIFACT_PATH=$(grep -o "上传... http://artifactory.mycompany.com/.*\.jar" build.log | sed 's/上传... //') echo "##teamcity[setParameter name='env.ARTIFACT_DEPLOY_PATH' value='$ARTIFACT_PATH']"
内容的提问来源于stack exchange,提问作者Ishwar Jindal

