feat: 服务端集成自动打包流程
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Xcode Run Script Phase (Post) for Archive obfuscation.
|
||||
# Add this as a late Build Phase (after Compile Sources / near end).
|
||||
# It restores original files backed up by archive_obfuscate_pre.sh.
|
||||
|
||||
if [[ "${ACTION:-}" != "install" || "${CONFIGURATION:-}" != "Release" ]]; then
|
||||
echo "[obf-post] Skip: ACTION=${ACTION:-}, CONFIGURATION=${CONFIGURATION:-}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
DERIVED_DIR="${DERIVED_FILE_DIR:-/tmp}"
|
||||
MARKER_FILE="${DERIVED_DIR}/rd_obf_marker_${TARGET_NAME:-app}.env"
|
||||
|
||||
if [[ ! -f "${MARKER_FILE}" ]]; then
|
||||
echo "[obf-post] No marker file found. Skip restore."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
source "${MARKER_FILE}"
|
||||
|
||||
if [[ -z "${BACKUP_DIR:-}" || -z "${ROOT:-}" ]]; then
|
||||
echo "[obf-post] Marker invalid, skip restore."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! -d "${BACKUP_DIR}" ]]; then
|
||||
echo "[obf-post] Backup dir missing: ${BACKUP_DIR}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[obf-post] Restoring source files from ${BACKUP_DIR}"
|
||||
cd "${ROOT}"
|
||||
|
||||
while IFS= read -r file; do
|
||||
rel="${file#${BACKUP_DIR}/}"
|
||||
mkdir -p "$(dirname "${ROOT}/$rel")"
|
||||
cp -f "$file" "${ROOT}/$rel"
|
||||
done < <(find "${BACKUP_DIR}" -type f)
|
||||
|
||||
rm -rf "${BACKUP_DIR}" "${MARKER_FILE}"
|
||||
echo "[obf-post] Done."
|
||||
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Xcode Run Script Phase (Pre) for Archive obfuscation.
|
||||
# Add this as an early Build Phase (before Compile Sources).
|
||||
# It only runs on Archive + Release, and obfuscates source in-place,
|
||||
# then the post phase restores original files from backup.
|
||||
|
||||
if [[ "${ACTION:-}" != "install" || "${CONFIGURATION:-}" != "Release" ]]; then
|
||||
echo "[obf-pre] Skip: ACTION=${ACTION:-}, CONFIGURATION=${CONFIGURATION:-}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Allow external driver (CI/script) to opt-out of running this phase
|
||||
if [[ "${SKIP_OBF_PHASE:-}" = "1" ]]; then
|
||||
echo "[obf-pre] SKIP_OBF_PHASE=1 set; skipping pre-archive obfuscation phase."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ROOT="${SRCROOT:-$(cd "$(dirname "$0")/../../.." && pwd)}"
|
||||
DERIVED_DIR="${DERIVED_FILE_DIR:-/tmp}"
|
||||
STAMP="$(date +%Y%m%d_%H%M%S)"
|
||||
BACKUP_DIR="${DERIVED_DIR}/rd_obf_backup_${STAMP}"
|
||||
MARKER_FILE="${DERIVED_DIR}/rd_obf_marker_${TARGET_NAME:-app}.env"
|
||||
MAP_DIR="${ROOT}/obfuscation_maps"
|
||||
MAP_PATH="${MAP_DIR}/${TARGET_NAME:-app}_${STAMP}.json"
|
||||
METHOD_MAP_PATH="${MAP_DIR}/method_map_${TARGET_NAME:-app}_${STAMP}.json"
|
||||
PRE_SUCCESS=0
|
||||
|
||||
restore_from_backup_dir() {
|
||||
local backup_dir="$1"
|
||||
if [[ ! -d "${backup_dir}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS= read -r file; do
|
||||
rel="${file#${backup_dir}/}"
|
||||
mkdir -p "$(dirname "${ROOT}/$rel")"
|
||||
cp -f "$file" "${ROOT}/$rel"
|
||||
done < <(find "${backup_dir}" -type f)
|
||||
|
||||
rm -rf "${backup_dir}"
|
||||
}
|
||||
|
||||
restore_stale_backup_if_needed() {
|
||||
if [[ ! -f "${MARKER_FILE}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "[obf-pre] Detected stale marker from previous build, restoring workspace first..."
|
||||
# shellcheck disable=SC1090
|
||||
source "${MARKER_FILE}"
|
||||
if [[ -n "${BACKUP_DIR:-}" && -n "${ROOT:-}" ]]; then
|
||||
restore_from_backup_dir "${BACKUP_DIR}"
|
||||
fi
|
||||
rm -f "${MARKER_FILE}"
|
||||
}
|
||||
|
||||
restore_on_error() {
|
||||
local exit_code=$?
|
||||
if [[ ${PRE_SUCCESS} -eq 1 ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "[obf-pre] Failed (exit=${exit_code}), restoring source files from backup..."
|
||||
restore_from_backup_dir "${BACKUP_DIR}"
|
||||
|
||||
rm -f "${MARKER_FILE}"
|
||||
echo "[obf-pre] Restore complete."
|
||||
exit ${exit_code}
|
||||
}
|
||||
|
||||
# Run repository self-check to ensure no residual obfuscated tokens remain.
|
||||
trap restore_on_error EXIT INT TERM
|
||||
|
||||
cd "${ROOT}"
|
||||
|
||||
restore_stale_backup_if_needed
|
||||
|
||||
echo "[obf-pre] Running repository self-check"
|
||||
# Self-check must run before creating backups to avoid restoring a pre-check backup on failure.
|
||||
bash "${ROOT}/AutoPacking/obfuscation/scripts/obfuscation_self_check.sh" "${ROOT}"
|
||||
|
||||
echo "[obf-pre] Generating dylib whitelist with HMAC"
|
||||
python3 "${ROOT}/AutoPacking/obfuscation/generate_image_whitelist.py"
|
||||
|
||||
mkdir -p "${BACKUP_DIR}" "${MAP_DIR}"
|
||||
|
||||
echo "[obf-pre] Backing up source files to ${BACKUP_DIR}"
|
||||
# Backup all source files that may be touched by obfuscation. Keep this for rollback safety.
|
||||
while IFS= read -r file; do
|
||||
rel="${file#./}"
|
||||
mkdir -p "${BACKUP_DIR}/$(dirname "$rel")"
|
||||
cp "$file" "${BACKUP_DIR}/$rel"
|
||||
done < <(
|
||||
find . \
|
||||
\( -path './Pods' -o -path './Pods/*' -o -path './.git' -o -path './.git/*' -o -path './build_output' -o -path './build_output/*' -o -path './DerivedData' -o -path './DerivedData/*' -o -path './readoorTests' -o -path './readoorTests/*' -o -name '*.framework' -o -name '*.xcframework' \) -prune -o \
|
||||
-type f \( -name '*.swift' -o -name '*.m' -o -name '*.mm' -o -name '*.h' -o -name '*.pch' \) -print
|
||||
)
|
||||
|
||||
echo "[obf-pre] Running obfuscation in archive mode (auto apply + type/method maps)..."
|
||||
OBF_TIMESTAMP="${STAMP}" python3 "${ROOT}/AutoPacking/obfuscation/obfuscate_symbols.py" --archive-mode
|
||||
|
||||
echo "BACKUP_DIR=${BACKUP_DIR}" > "${MARKER_FILE}"
|
||||
echo "ROOT=${ROOT}" >> "${MARKER_FILE}"
|
||||
|
||||
PRE_SUCCESS=1
|
||||
trap - EXIT INT TERM
|
||||
|
||||
echo "[obf-pre] Done. map=${MAP_PATH} method_map=${METHOD_MAP_PATH} marker=${MARKER_FILE}"
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Scan repository for residual obfuscated tokens like RdXXXXXX and fail if any found.
|
||||
# Exits 0 when clean, non-zero when tokens are present.
|
||||
|
||||
ROOT="${1:-$(cd "$(dirname "$0")/../../.." && pwd)}"
|
||||
|
||||
echo "[obf-check] Scanning for residual obfuscated tokens in ${ROOT}"
|
||||
|
||||
EXCLUDE=("./Pods" "./.git" "./obfuscation_maps" "./build_output" "./DerivedData" "./readoorTests")
|
||||
|
||||
GREP_EXCLUDE_ARGS=()
|
||||
for e in "${EXCLUDE[@]}"; do
|
||||
GREP_EXCLUDE_ARGS+=(--exclude-dir "${e#./}")
|
||||
done
|
||||
|
||||
FOUND=0
|
||||
TOKEN_SUFFIX_RE='(?:[a-f0-9]{6}|[a-f0-9]{8}|[a-f0-9]{10})'
|
||||
|
||||
echo "[obf-check] Looking for token pattern '\b(?:Rd|YMH)${TOKEN_SUFFIX_RE}\b' in source files..."
|
||||
if grep -R --line-number -E "\\b(?:Rd|YMH)${TOKEN_SUFFIX_RE}\\b" --include='*.swift' --include='*.m' --include='*.mm' --include='*.h' "${ROOT}" "${GREP_EXCLUDE_ARGS[@]}"; then
|
||||
FOUND=1
|
||||
fi
|
||||
|
||||
echo "[obf-check] Looking for obfuscated header imports like \"(Rd|YMH)XXXXXX.h\"..."
|
||||
if grep -R --line-number -E "#import\\s+\"(?:Rd|YMH)${TOKEN_SUFFIX_RE}\\.h\"" --include='*.pch' --include='*.h' --include='*.m' --include='*.mm' "${ROOT}" "${GREP_EXCLUDE_ARGS[@]}"; then
|
||||
FOUND=1
|
||||
fi
|
||||
|
||||
if [[ ${FOUND} -ne 0 ]]; then
|
||||
echo "[obf-check] ERROR: Found residual obfuscated tokens; aborting to avoid double-obfuscation."
|
||||
echo "[obf-check] Run: python3 AutoPacking/obfuscation/obfuscate_symbols.py --restore-source-from-map-dir obfuscation_maps or run the auto-restore tool before archiving."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "[obf-check] Clean: no residual obfuscated tokens found."
|
||||
exit 0
|
||||
Reference in New Issue
Block a user