修复打包签名并支持 App Store IPA 上传
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import plistlib
|
||||
import time
|
||||
import shutil
|
||||
import tempfile
|
||||
@@ -17,6 +18,7 @@ from backend.services.build_service import (
|
||||
build_project,
|
||||
generate_config,
|
||||
_cleanup_old_builds,
|
||||
_resolve_provisioning_profile,
|
||||
)
|
||||
from backend.services.log_streamer import LogStreamer
|
||||
|
||||
@@ -233,7 +235,11 @@ async def test_generate_config(tmp_path, log_streamer):
|
||||
"schemes": {"1": {"name": "testScheme", "ossFloder": "test"}},
|
||||
}
|
||||
|
||||
with patch("backend.routers.config.load_config", return_value=mock_config):
|
||||
with patch("backend.routers.config.load_config", return_value=mock_config), \
|
||||
patch(
|
||||
"backend.services.build_service._resolve_provisioning_profile",
|
||||
return_value=("pro", "TEAM123"),
|
||||
):
|
||||
result = await generate_config("t1", task, build_dir)
|
||||
|
||||
assert result["APPID"] == "guid-123"
|
||||
@@ -241,6 +247,8 @@ async def test_generate_config(tmp_path, log_streamer):
|
||||
assert result["BUILD_TYPE"] == "Ad_Hoc"
|
||||
assert result["BUNDLE_ID"] == "com.test.app"
|
||||
assert result["CERTIFICATE"] == "cert"
|
||||
assert result["PROVISIONING_NAME"] == "pro"
|
||||
assert result["TEAM_ID"] == "TEAM123"
|
||||
|
||||
config_file = build_dir / "config_output.json"
|
||||
assert config_file.exists()
|
||||
@@ -248,6 +256,15 @@ async def test_generate_config(tmp_path, log_streamer):
|
||||
assert saved["APPID"] == "guid-123"
|
||||
|
||||
|
||||
def test_resolve_provisioning_profile_extracts_name_and_team(tmp_path):
|
||||
profile_path = tmp_path / "profile.mobileprovision"
|
||||
profile_path.write_bytes(b"signed profile")
|
||||
decoded = plistlib.dumps({"Name": "a4YX061_adHoc", "TeamIdentifier": ["MG4Z7FU83W"]})
|
||||
|
||||
with patch("backend.services.build_service.subprocess.check_output", return_value=decoded):
|
||||
assert _resolve_provisioning_profile(str(profile_path)) == ("a4YX061_adHoc", "MG4Z7FU83W")
|
||||
|
||||
|
||||
async def test_generate_config_uses_saved_version(tmp_path, log_streamer):
|
||||
"""从服务配置读取版本号,不依赖分支源码脚本"""
|
||||
build_dir = tmp_path / "build"
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
"""服务端分发产物生成测试。"""
|
||||
import plistlib
|
||||
from unittest.mock import patch
|
||||
|
||||
from backend.services.distribution import _write_distribution_files, _write_download_page, _write_manifest
|
||||
from backend.services.distribution import (
|
||||
_write_distribution_files,
|
||||
_write_download_page,
|
||||
_write_manifest,
|
||||
publish_ipa,
|
||||
)
|
||||
|
||||
|
||||
def test_distribution_files_use_current_service_config(tmp_path):
|
||||
@@ -20,3 +26,27 @@ def test_distribution_files_use_current_service_config(tmp_path):
|
||||
assert ipa_file.read_bytes() == b"ipa"
|
||||
assert plist["items"][0]["metadata"]["bundle-identifier"] == "com.example.test"
|
||||
assert "itms-services://" in html.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_app_store_distribution_uploads_only_ipa(tmp_path):
|
||||
ipa = tmp_path / "source.ipa"
|
||||
ipa.write_bytes(b"app-store-ipa")
|
||||
config = {
|
||||
"APPID": "100",
|
||||
"VERSION": "2.0.0",
|
||||
"BUILD_TYPE": "App_Store",
|
||||
"OSS_FLODER": "readoor",
|
||||
"_upload_config": {"mode": "oss", "oss": {}},
|
||||
}
|
||||
|
||||
with patch(
|
||||
"backend.services.distribution._upload_oss",
|
||||
return_value={".ipa": "https://files.example.com/readoor/iOS/100_2_0_0.ipa"},
|
||||
) as upload:
|
||||
download_url, qr_path = publish_ipa(config, ipa, tmp_path / "build")
|
||||
|
||||
uploaded_files = upload.call_args.args[1]
|
||||
assert len(uploaded_files) == 1
|
||||
assert uploaded_files[0][0].suffix == ".ipa"
|
||||
assert download_url.endswith("100_2_0_0.ipa")
|
||||
assert qr_path == ""
|
||||
|
||||
@@ -19,7 +19,9 @@ def test_apply_project_config_without_branch_autopacking(tmp_path):
|
||||
"PRODUCT_BUNDLE_IDENTIFIER = old.id;\nDEVELOPMENT_TEAM = OLD;\n"
|
||||
'"DEVELOPMENT_TEAM[sdk=iphoneos*]" = OLD;\n'
|
||||
"PROVISIONING_PROFILE_SPECIFIER = old;\n"
|
||||
'"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = old;\n',
|
||||
'"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = old;\n'
|
||||
'CODE_SIGN_IDENTITY = "iPhone Developer";\n'
|
||||
'"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
(swift / "RDAppConfiguration.swift").write_text(
|
||||
@@ -49,6 +51,10 @@ def test_apply_project_config_without_branch_autopacking(tmp_path):
|
||||
|
||||
assert "工程、签名、版本和分发配置已更新" in messages
|
||||
assert 'let RD_APP_GUID: String = "guid"' in (swift / "RDAppConfiguration.swift").read_text()
|
||||
assert "PRODUCT_BUNDLE_IDENTIFIER = com.example.test;" in (project / "project.pbxproj").read_text()
|
||||
project_content = (project / "project.pbxproj").read_text()
|
||||
assert "PRODUCT_BUNDLE_IDENTIFIER = com.example.test;" in project_content
|
||||
assert 'CODE_SIGN_IDENTITY = "iPhone Distribution";' in project_content
|
||||
assert '"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";' in project_content
|
||||
assert "iPhone Developer" not in project_content
|
||||
assert (build_dir / "exportOptions.plist").exists()
|
||||
assert (logo / "icon-1024.png").read_bytes() == b"icon"
|
||||
|
||||
Reference in New Issue
Block a user