Jenkins Pipeline推送Git仓库时URL端口错误排查求助
Jenkins Kubernetes Agent推送Git仓库时出现URL端口错误问题
报错信息
fatal: unable to access 'https://example.org/git/usernamerepo/devops-gitops-apps.git/': URL rejected: Port number was not a decimal number between 0 and 65535
Jenkinsfile相关代码片段
pipeline { agent { kubernetes { yaml ''' apiVersion: v1 kind: Pod metadata: labels: pod-name: jenkins-agent spec: containers: - name: git image: alpine/git command: - cat tty: true env: - name: http_proxy value: proxyvalue - name: https_proxy value: proxyvalue - name: no_proxy value: somevalues,othersvalue volumeMounts: - name: yq-bin mountPath: /yq-bin resources: requests: memory: "256Mi" cpu: "0.25" - name: jnlp image: jenkins/inbound-agent:latest args: ['$(JENKINS_SECRET)', '$(JENKINS_NAME)'] initContainers: - name: yq image: mikefarah/yq:4.43.1 command: ["sh", "-c", "cp /usr/bin/yq /yq-bin/yq"] volumeMounts: - name: yq-bin mountPath: /yq-bin volumes: - name: yq-bin emptyDir: {} ''' } } environment { HELM_HOME = "/usr/local/bin/helm" VALUES_FILE = "jenkins/values.yaml" GIT_REPO = "https://example.org/git/usernamerepo/devops-gitops-apps.git" GIT_BRANCH = "master" NEW_BRANCH = "jenkins-update" GIT_CREDENTIALS_ID = "giteaAccess" } stages { stage('Checkout') { steps { container('git') { git branch: "${env.GIT_BRANCH}", url: "${env.GIT_REPO}", credentialsId: "${env.GIT_CREDENTIALS_ID}" } } } stage('Debug YQ Path') { steps { container('git') { script { sh 'ls -l /yq-bin' sh '/yq-bin/yq --version' } } } } stage('Read Plugins') { steps { container('git') { script { def plugins = sh(script: "/yq-bin/yq e '.controller.installPlugins[]' ${env.VALUES_FILE}", returnStdout: true).trim().split("\n") env.PLUGINS = plugins.join(" ") } } } } stage('Update Plugins') { steps { container('git') { script { def pluginsList = env.PLUGINS.tokenize() sh "sed -i '/installPlugins:/,\$d' ${env.VALUES_FILE}" sh "echo 'controller:' >> ${env.VALUES_FILE}" sh "echo ' installPlugins:' >> ${env.VALUES_FILE}" pluginsList.each { plugin -> sh "echo ' - ${plugin}' >> ${env.VALUES_FILE}" } } } } } stage('Configure Git Safe Directory') { steps { container('git') { script { sh "git config --global --add safe.directory /home/jenkins/agent/workspace/jenkinsupdater" } } } } stage('Commit Changes') { steps { container('git') { script { withCredentials([usernamePassword(credentialsId: "${env.GIT_CREDENTIALS_ID}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh "git checkout -b ${env.NEW_BRANCH}" sh 'git config user.email "username@example.org"' sh 'git config user.name "${USERNAME}"' sh 'git add ${VALUES_FILE}' sh 'git commit -m "Automated update of Jenkins plugins"' sh ''' git remote set-url origin https://${USERNAME}:${PASSWORD}@example.org/git/usernamerepo/devops-gitops-apps.git git push -u origin ${NEW_BRANCH} ''' } } } } } stage('Create Pull Request') { steps { container('git') { script { withCredentials([usernamePassword(credentialsId: "${env.GIT_CREDENTIALS_ID}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh """ curl -X POST -H "Content-Type: application/json" -u ${USERNAME}:${PASSWORD} \ -d '{ "title": "Automated update of Jenkins plugins", "body": "This PR includes automated updates of Jenkins plugins", "head": "${NEW_BRANCH}", "base": "master" }' \ https://example.org/git/usernamerepo/devops-gitops-apps/pulls """ } } } } } } post { always { echo "Cleaning up and finalizing pipeline." cleanWs() } } }
问题背景
该流水线负责拉取仓库代码、更新values.yaml中的Jenkins插件列表、提交变更、推送新分支到远程仓库并创建PR。使用Jenkins withCredentials块管理凭证,但仍触发上述URL端口相关错误。
已排查操作:
- 确认
withCredentials对凭证的处理逻辑正确 - 尝试多种设置远程URL及推送变更的方式
- 检查代理配置无异常
原因分析
- 凭证特殊字符破坏URL结构:如果Git凭证(密码/用户名)包含
@、:等URL特殊字符,直接拼接进远程URL时会打乱URL格式,导致Git误将特殊字符后的内容解析为端口号,引发端口格式错误。 - Shell变量解析失败:多行
sh脚本使用单引号包裹时,Jenkins环境变量(如${USERNAME})无法被正确替换,可能生成无效URL。 - 代理配置间接干扰:
http_proxy/https_proxy环境变量若格式异常,或no_proxy未包含Git仓库域名,可能干扰Git对目标URL的解析逻辑。
解决建议
方案1:使用Git凭证助手替代URL拼接
避免手动拼接带凭证的URL,用Git凭证助手自动处理认证:
stage('Commit Changes') { steps { container('git') { script { withCredentials([usernamePassword(credentialsId: "${env.GIT_CREDENTIALS_ID}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh "git checkout -b ${env.NEW_BRANCH}" sh 'git config user.email "username@example.org"' sh "git config user.name '${USERNAME}'" sh "git add ${VALUES_FILE}" sh 'git commit -m "Automated update of Jenkins plugins"' // 配置临时凭证助手 sh "git config credential.helper '!f() { echo username=\$USERNAME; echo password=\$PASSWORD; }; f'" sh "git push -u origin ${NEW_BRANCH}" // 清理凭证配置 sh "git config --unset credential.helper" } } } } }
方案2:对凭证特殊字符进行URL编码
若必须拼接URL,需对用户名和密码中的特殊字符编码:
stage('Commit Changes') { steps { container('git') { script { withCredentials([usernamePassword(credentialsId: "${env.GIT_CREDENTIALS_ID}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { // URL编码特殊字符 def encodedUser = java.net.URLEncoder.encode(USERNAME, "UTF-8") def encodedPass = java.net.URLEncoder.encode(PASSWORD, "UTF-8") def gitUrl = "https://${encodedUser}:${encodedPass}@example.org/git/usernamerepo/devops-gitops-apps.git" sh "git checkout -b ${env.NEW_BRANCH}" sh 'git config user.email "username@example.org"' sh "git config user.name '${USERNAME}'" sh "git add ${VALUES_FILE}" sh 'git commit -m "Automated update of Jenkins plugins"' sh "git remote set-url origin ${gitUrl}" sh "git push -u origin ${NEW_BRANCH}" } } } } }
方案3:修正Shell变量解析问题
将多行sh脚本拆分为单行,或使用双引号保证变量替换:
// 替换原多行sh脚本为以下单行命令 sh "git remote set-url origin https://${USERNAME}:${PASSWORD}@example.org/git/usernamerepo/devops-gitops-apps.git" sh "git push -u origin ${NEW_BRANCH}"
方案4:优化代理配置
- 确认
no_proxy环境变量包含Git仓库域名example.org,避免代理解析内部域名 - 检查代理地址格式(如
http://proxy-host:port),确保无多余特殊字符
内容的提问来源于stack exchange,提问作者Andres Cabrera
相关产品推荐
相关产品推荐

