测试jenkins上传

This commit is contained in:
zhang hongbo 2026-05-09 11:45:40 +08:00
parent 1ebf5228ff
commit b24135b02c
3 changed files with 220 additions and 78 deletions

View File

@ -1,89 +1,113 @@
"""APK upload helper used by the Jenkins shared library.
All configuration is provided via environment variables so the Groovy caller
does not have to deal with shell-quoting on Windows agents.
Required environment variables:
APK_UPLOAD_URL Full upload endpoint URL.
APK_UPLOAD_TOKEN Value of the X-Apk-Upload-Token header.
APK_UPLOAD_ENV Form field "env" (dev / prod / stable).
APK_UPLOAD_PACKAGE_TYPE Form field "packageType" (with_sdk / without_sdk).
APK_UPLOAD_FILE Absolute path to the APK file to upload.
Optional environment variables:
APK_UPLOAD_VERSION Form field "version".
APK_UPLOAD_TIMEOUT Request timeout in seconds (default 300).
"""
import argparse
import os
import sys
from pathlib import Path
try:
import requests
except ImportError:
sys.stderr.write(
"Python package 'requests' is not installed on this Jenkins agent.\n"
DEFAULT_TOKEN_FILE = Path(r"d:\Github\devops\access_token.txt")
DEFAULT_TIMEOUT = 300
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="Upload APK to the Byway server.")
parser.add_argument("--upload-url", required=True, help="APK upload endpoint URL.")
parser.add_argument("--apk-path", required=True, type=Path, help="Path to the APK file.")
parser.add_argument("--env", dest="upload_env", required=True, help="Environment value sent as the env form field.")
parser.add_argument(
"--package-type",
dest="package_type",
required=True,
choices=["with_sdk", "without_sdk"],
help="Package type sent as the packageType form field.",
)
sys.exit(2)
parser.add_argument("--version", default="", help="Optional version form field.")
parser.add_argument("--token", default="", help="Upload token. Defaults to APK_UPLOAD_TOKEN or token file.")
parser.add_argument(
"--token-file",
type=Path,
default=DEFAULT_TOKEN_FILE,
help="Fallback file path used when no token argument or environment variable is provided.",
)
parser.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT, help="Request timeout in seconds.")
return parser
def _require_env(name: str) -> str:
value = os.environ.get(name, "").strip()
if not value:
sys.stderr.write(f"Missing required environment variable: {name}\n")
sys.exit(2)
return value
def load_upload_token(cli_token: str, token_file: Path) -> str:
direct_token = cli_token.strip()
if direct_token:
return direct_token
env_token = os.getenv("APK_UPLOAD_TOKEN", "").strip()
if env_token:
return env_token
if token_file.exists():
file_token = token_file.read_text(encoding="utf-8").strip()
if file_token:
return file_token
raise ValueError(
"未找到上传 token。请通过 --token、环境变量 APK_UPLOAD_TOKEN或 token 文件提供 token。"
)
def main() -> int:
upload_url = _require_env("APK_UPLOAD_URL")
upload_token = _require_env("APK_UPLOAD_TOKEN")
upload_env = _require_env("APK_UPLOAD_ENV")
package_type = _require_env("APK_UPLOAD_PACKAGE_TYPE")
apk_path = Path(_require_env("APK_UPLOAD_FILE"))
def main(argv: list[str] | None = None) -> int:
parser = build_parser()
args = parser.parse_args(argv)
version = os.environ.get("APK_UPLOAD_VERSION", "").strip()
timeout = int(os.environ.get("APK_UPLOAD_TIMEOUT", "300"))
try:
import requests
except ImportError:
sys.stderr.write("Python package 'requests' is not installed.\n")
return 2
if not apk_path.exists():
sys.stderr.write(f"APK file not found: {apk_path}\n")
try:
upload_token = load_upload_token(args.token, args.token_file)
except ValueError as exc:
sys.stderr.write(f"{exc}\n")
return 2
if not args.apk_path.exists():
sys.stderr.write(f"APK 文件不存在: {args.apk_path}\n")
return 2
form_data = {
"env": upload_env,
"packageType": package_type,
"env": args.upload_env,
"packageType": args.package_type,
}
if version:
form_data["version"] = version
if args.version:
form_data["version"] = args.version
print(f"Uploading {apk_path.name} to {upload_url}")
print(f" env={upload_env} packageType={package_type} version={version or '<none>'}")
print(f"Uploading {args.apk_path.name} to {args.upload_url}")
print(
f" env={args.upload_env} packageType={args.package_type} version={args.version or '<none>'}"
)
with apk_path.open("rb") as apk_file:
response = requests.post(
upload_url,
headers={"X-Apk-Upload-Token": upload_token},
data=form_data,
files={
"file": (
apk_path.name,
apk_file,
"application/vnd.android.package-archive",
)
},
timeout=timeout,
)
try:
with args.apk_path.open("rb") as apk_file:
response = requests.post(
args.upload_url,
headers={"X-Apk-Upload-Token": upload_token},
data=form_data,
files={
"file": (
args.apk_path.name,
apk_file,
"application/vnd.android.package-archive",
)
},
timeout=args.timeout,
)
except requests.RequestException as exc:
sys.stderr.write(f"APK upload request failed: {exc}\n")
return 1
print(f"status_code: {response.status_code}")
print("status_code:", response.status_code)
try:
print(response.json())
except ValueError:
print(response.text)
if not response.ok:
return 1
return 0
return 0 if response.ok else 1
if __name__ == "__main__":

114
upload.py Normal file
View File

@ -0,0 +1,114 @@
import argparse
import os
import sys
from pathlib import Path
DEFAULT_TOKEN_FILE = Path(r"d:\Github\devops\access_token.txt")
DEFAULT_TIMEOUT = 300
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="Upload APK to the Byway server.")
parser.add_argument("--upload-url", required=True, help="APK upload endpoint URL.")
parser.add_argument("--apk-path", required=True, type=Path, help="Path to the APK file.")
parser.add_argument("--env", dest="upload_env", required=True, help="Environment value sent as the env form field.")
parser.add_argument(
"--package-type",
dest="package_type",
required=True,
choices=["with_sdk", "without_sdk"],
help="Package type sent as the packageType form field.",
)
parser.add_argument("--version", default="", help="Optional version form field.")
parser.add_argument("--token", default="", help="Upload token. Defaults to APK_UPLOAD_TOKEN or token file.")
parser.add_argument(
"--token-file",
type=Path,
default=DEFAULT_TOKEN_FILE,
help="Fallback file path used when no token argument or environment variable is provided.",
)
parser.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT, help="Request timeout in seconds.")
return parser
def load_upload_token(cli_token: str, token_file: Path) -> str:
direct_token = cli_token.strip()
if direct_token:
return direct_token
env_token = os.getenv("APK_UPLOAD_TOKEN", "").strip()
if env_token:
return env_token
if token_file.exists():
file_token = token_file.read_text(encoding="utf-8").strip()
if file_token:
return file_token
raise ValueError(
"未找到上传 token。请通过 --token、环境变量 APK_UPLOAD_TOKEN或 token 文件提供 token。"
)
def main(argv: list[str] | None = None) -> int:
parser = build_parser()
args = parser.parse_args(argv)
try:
import requests
except ImportError:
sys.stderr.write("Python package 'requests' is not installed.\n")
return 2
try:
upload_token = load_upload_token(args.token, args.token_file)
except ValueError as exc:
sys.stderr.write(f"{exc}\n")
return 2
if not args.apk_path.exists():
sys.stderr.write(f"APK 文件不存在: {args.apk_path}\n")
return 2
form_data = {
"env": args.upload_env,
"packageType": args.package_type,
}
if args.version:
form_data["version"] = args.version
print(f"Uploading {args.apk_path.name} to {args.upload_url}")
print(
f" env={args.upload_env} packageType={args.package_type} version={args.version or '<none>'}"
)
try:
with args.apk_path.open("rb") as apk_file:
response = requests.post(
args.upload_url,
headers={"X-Apk-Upload-Token": upload_token},
data=form_data,
files={
"file": (
args.apk_path.name,
apk_file,
"application/vnd.android.package-archive",
)
},
timeout=args.timeout,
)
except requests.RequestException as exc:
sys.stderr.write(f"APK upload request failed: {exc}\n")
return 1
print("status_code:", response.status_code)
try:
print(response.json())
except ValueError:
print(response.text)
return 0 if response.ok else 1
if __name__ == "__main__":
sys.exit(main())

View File

@ -41,22 +41,26 @@ def call(Map config)
echo "Multiple APKs found, uploading newest file: ${apkName}"
}
def scriptRelativePath = '.jenkins-upload-apk.py'
def scriptRelativePath = 'upload.py'
writeFile file: scriptRelativePath, text: libraryResource('uploadApk.py')
withEnv([
"APK_UPLOAD_URL=${uploadUrl}",
"APK_UPLOAD_ENV=${uploadEnv}",
"APK_UPLOAD_PACKAGE_TYPE=${packageType}",
"APK_UPLOAD_FILE=${apkPath}",
"APK_UPLOAD_VERSION=${version ?: ''}"
]) {
withCredentials([string(credentialsId: uploadTokenCredentialsId, variable: 'APK_UPLOAD_TOKEN')]) {
bat(
label: 'Upload APK to server',
script: "@echo off\r\npython \"${scriptRelativePath}\""
)
}
def pythonArgs = [
"python \"${scriptRelativePath}\"",
" --upload-url \"${uploadUrl}\"",
" --apk-path \"${apkPath}\"",
" --env \"${uploadEnv}\"",
" --package-type \"${packageType}\""
]
if (version) {
pythonArgs << " --version \"${version}\""
}
withCredentials([string(credentialsId: uploadTokenCredentialsId, variable: 'APK_UPLOAD_TOKEN')]) {
bat(
label: 'Upload APK to server',
script: "@echo off\r\n" + pythonArgs.join(" ^\r\n")
)
}
return [
@ -76,4 +80,4 @@ def extractVersionFromFileName(String fileName)
}
return ''
}
}