varios una subdirectorios por para mover listar directorios crear copiar consola como comandos comando carpeta archivos xcode4 archive ipa

xcode4 - subdirectorios - Genera xcarchive en una carpeta específica desde la línea de comando



mover archivos en linux (7)

A partir de Xcode 4 Preview 5, hay tres variables de entorno a las que se puede acceder en las acciones posteriores del archivo de esquema.

ARCHIVE_PATH: The path to the archive. ARCHIVE_PRODUCTS_PATH: The installation location for the archived product. ARCHIVE_DSYMS_PATH: The path to the product’s dSYM files.

Podrías mover / copiar el archivo aquí. Quería tener un poco más de control sobre el proceso en un script de CI, así que guardé un archivo temporal que podría obtenerse fácilmente en mi script de CI que contenía estos valores.

BUILD_DIR=$PROJECT_DIR/build echo "ARCHIVE_PATH=/"$ARCHIVE_PATH/"" > $BUILD_DIR/archive_paths.sh echo "ARCHIVE_PRODUCTS_PATH=/"$ARCHIVE_PRODUCTS_PATH/"" >> $BUILD_DIR/archive_paths.sh echo "ARCHIVE_DSYMS_PATH=/"$ARCHIVE_DSYMS_PATH/"" >> $BUILD_DIR/archive_paths.sh echo "INFOPLIST_PATH=/"$INFOPLIST_PATH/"" >> $BUILD_DIR/archive_paths.sh

Luego en mi script de CI puedo ejecutar lo siguiente:

xcodebuild -alltargets -scheme [Scheme Name] -configuration [Config Name] clean archive source build/archive_paths.sh ARCHIVE_NAME=AppName-$APP_VERSION-$APP_BUILD.xcarchive cp -r "$ARCHIVE_PATH" "$BUILD_DIR/$ARCHIVE_NAME"

Para propósitos de CI, necesito poder generar un XCARCHIVE y un archivo IPA en nuestra compilación nocturna. El IPA es para nuestros probadores, que se debe firmar con nuestras claves ad-hoc, y XCARCHIVE se envía al cliente para que pueda importarlo a Xcode y enviarlo a la tienda de aplicaciones cuando estén contentos con él.

Generar el IPA es bastante simple con un poco de Google, sin embargo, cómo se genera el archivo .XCARCHIVE es lo que me elude. Lo más cerca que he encontrado es:

xcodebuild -scheme myscheme archive

Sin embargo, esto almacena el .xcarchive en alguna carpeta difícil de encontrar, por ejemplo:

/Users/me/Library/Developer/Xcode/Archives/2011-12-14/MyApp 14-12-11 11.42 AM.xcarchive

¿Hay alguna manera de controlar dónde se coloca el archivo, cómo se llama y cómo evitar tener que volver a compilarlo? Supongo que el mejor resultado posible sería generar el xcarchive de la DSYM y la APLICACIÓN que se generan cuando haces una ''construcción xcodebuild'' - ¿es esto posible?


Acabo de resolver este: simplemente agregue el argumento -archivePath a su línea de comando de construcción xcode, dada la pregunta inicial que significaría:

xcodebuild -scheme myscheme archive

se convierte ...

xcodebuild -scheme myscheme archive -archivePath Build/Archive

(Nota: las rutas son relativas, envío mi compilación a $PWD/Build )

Esto colocará su carpeta .app en:

Build/Archive.xarchive/Products/Application

Si su objetivo de compilación ya tiene su certificado de firma y su perfil de aprovisionamiento, puede crear su archivo IPA sin volver a firmar con el siguiente comando:

xcrun -v -sdk iphoneos PackageApplication -v `pwd`''/Build/Archive.xarchive/Products/Application/my.app'' -o `pwd`''/myapp.ipa''

(Nota: xcrun no le gusta los caminos relativos, por lo tanto, el pwd )

El archivo -v arroja mucha información útil - este comando puede no firmar correctamente y todavía salir con el código 0, suspiro!

Si descubre que no puede ejecutar el .ipa incorporado, es probable que sea un problema de firma que puede hacer doble control utilizando:

codesign --verify -vvvv myapp.app

Si se firma correctamente y no se modifica la salida, esto se tendrá en:

myapp.app: valid on disk myapp.app: satisfies its Designated Requirement

Si no, verás algo similar a esto:

Codesign check fails : /blahpath/myapp.app: a sealed resource is missing or invalid file modified: /blahpath/ls-ios-develop.app/Assets.car

... lo que generalmente significa que está intentando usar un directorio de salida intermedio en lugar del archivo adecuado.


En Xcode 4.6, es posible especificar una acción posterior a la compilación para que el esquema se compile en xcarchive:

echo "ARCHIVE_PATH=/"$ARCHIVE_PATH/"" > $PROJECT_DIR/archive_paths.sh

Se puede usar un script de compilación para verificar si $ ARCHIVE_PATH se define después de ejecutar xcodebuild y, si este es el caso, el xcarchive de salida se puede mover a una carpeta designada.

Este método no es muy fácil de mantener si los objetivos en el proyecto son un gran número, ya que para cada uno es necesario etiquetar el esquema correspondiente como ''compartido'' y agregar la acción posterior a la construcción.

Para solucionar este problema, he creado una secuencia de comandos de compilación que genera la ruta de archivo mediante programación extrayendo la última compilación que coincide con el nombre de destino en el día actual. Este método funciona de manera confiable siempre que no haya compilaciones múltiples con el mismo nombre de destino ejecutándose en la máquina (esto puede ser un problema en entornos de producción donde se ejecutan múltiples compilaciones simultáneas).

#!/bin/bash # # Script to archive an existing xcode project to a target location. # The script checks for a post-build action that defines the $ARCHIVE_PATH as follows: # echo "ARCHIVE_PATH=/"$ARCHIVE_PATH/"" > $PROJECT_DIR/archive_paths.sh # If such post-build action does not exist or sourcing it doesn''t define the $ARCHIVE_PATH # variable, the script tries to generate it programmatically by finding the latest build # in the expected archiving folder # post_build_script=archive_paths.sh build_errors_file=build_errors.log OUTPUT=output/ XCODEBUILD_CMD=''/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild'' TARGET_SDK=iphoneos function archive() { echo "Archiving target ''$1''" # Delete $post_build_script if it already exists as it should be generated by a # post-build action rm -f $post_build_script # Use custom provisioning profile and code sign identity if specified, otherwise # default to project settings # Note: xcodebuild always returns 0 even if the build failed. We look for failure in # the stderr output instead if [[ ! -z "$2" ]] && [[ ! -z "$3" ]]; then ${XCODEBUILD_CMD} clean archive -scheme $1 -sdk "${TARGET_SDK}" / "CODE_SIGN_IDENTITY=$3" "PROVISIONING_PROFILE=$2" 2>$build_errors_file else ${XCODEBUILD_CMD} clean archive -scheme $1 -sdk "${TARGET_SDK}" 2>$build_errors_file fi errors=`grep -wc "The following build commands failed" $build_errors_file` if [ "$errors" != "0" ] then echo "BUILD FAILED. Error Log:" cat $build_errors_file rm $build_errors_file exit 1 fi rm $build_errors_file # Check if archive_paths.sh exists if [ -f "$post_build_script" ]; then source "$post_build_script" if [ -z "$ARCHIVE_PATH" ]; then echo "''$post_build_script'' exists but ARCHIVE_PATH was not set. Enabling auto-detection" fi fi if [ -z "$ARCHIVE_PATH" ]; then # This is the format of the xcarchive path: # /Users/$USER/Library/Developer/Xcode/Archives/`date +%Y-%m-%d`/$1/ # `date +%d-%m-%Y/ %H.%M`.xcarchive # In order to avoid mismatches with the hour/minute of creation of the archive and # the current time, we list all archives with the correct target that have been # built in the current day (this may fail if the build wraps around midnight) and # fetch the correct file with a combination of ls and grep. # This script can break only if there are multiple targets with exactly the same # name running at the same time. EXTRACTED_LINE=$(ls -lrt /Users/$USER/Library/Developer/Xcode/Archives/`date +%Y-%m-%d`/ | grep $1/ `date +%d-%m-%Y` | tail -n 1) if [ "$EXTRACTED_LINE" == "" ]; then echo "Error: couldn''t fetch archive path" exit 1 fi # ls -lrt prints lines with the following format # drwxr-xr-x 5 mario 1306712193 170 25 Jul 17:17 ArchiveTest 25-07-2013 # 17.17.xcarchive # We can split this line with the " " separator and take the latest bit: # 17.17.xcarchive FILE_NAME_SUFFIX=$(echo $EXTRACTED_LINE | awk ''{split($0,a," "); print a[11]}'') if [ "$FILE_NAME_SUFFIX" == "" ]; then echo "Error: couldn''t fetch archive path" exit 1 fi # Finally, we can put everything together to generate the path to the xcarchive ARCHIVE_PATH="/Users/$USER/Library/Developer/Xcode/Archives/`date +%Y-%m-%d`/$1 `date +%d-%m-%Y` $FILE_NAME_SUFFIX/" fi # Create output folder if it doesn''t already exist mkdir -p "$OUTPUT" # Move archived xcarchive build to designated output folder mv -v "$ARCHIVE_PATH" "$OUTPUT" } # Check number of command line args if [ $# -lt 1 ]; then echo "Syntax: `basename $0` <target name> [/path/to/provisioning-profile] [<code sign identity]" exit 1 fi if [ ! -z "$2" ]; then PROVISIONING_PROFILE="$2" fi if [ ! -z "$3" ]; then SIGN_PROVISIONING_PROFILE="$3" else if [ ! -z "$PROVISIONING_PROFILE" ]; then SIGN_PROVISIONING_PROFILE=$(cat "$PROVISIONING_PROFILE" | egrep -a -o ''[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}'') fi fi archive "$1" "$PROVISIONING_PROFILE" "$SIGN_PROVISIONING_PROFILE"

El código fuente completo con un ejemplo de proyecto Xcode se puede encontrar aquí:

https://github.com/bizz84/Xcode-xcarchive-command


He aquí algunos detalles que he creado para nuestro sistema Jenkins CI. Estos comandos se deben ejecutar en una secuencia de comandos inmediatamente después de que xcodebuild archive comando de xcodebuild archive .

BUILD_DIR="${WORKSPACE}/build" XCODE_SCHEME="myscheme" # Common path and partial filename ARCHIVE_BASEPATH="${HOME}/Library/Developer/Xcode/Archives/$(date +%Y-%m-%d)/${XCODE_SCHEME}" # Find the latest .xcarchive for the given scheme NEW_ARCHIVE=$(ls -td "${ARCHIVE_BASEPATH}"* | head -n 1) # Zip it up so non-Apple systems won''t treat it as a dir pushd "${NEW_ARCHIVE%/*}" zip -r "${BUILD_DIR}/${NEW_ARCHIVE##*/}.zip" "${NEW_ARCHIVE##*/}" popd # Optional, disk cleanup rm -rf "${NEW_ARCHIVE}"

El BUILD_DIR se usa para recolectar artefactos para que sea fácil archivarlos desde Jenkins con un glob como build/*.ipa,build/*.zip


Mi solución actual es cambiar el nombre de la carpeta de archivos existente del usuario, ejecutar la compilación y hacer una búsqueda para copiar los archivos que desee, luego eliminar la carpeta de archivos y cambiar el nombre de la carpeta anterior tal como estaba, con un código como este en mi script de construcción de ruby:

# Move the existing archives out of the way system(''mv ~/Library/Developer/Xcode/Archives ~/Library/Developer/Xcode/OldArchivesTemp'') # Build the .app, the .DSYM, and the .xcarchive system("xcodebuild -scheme /"#{scheme}/" clean build archive CONFIGURATION_BUILD_DIR=/"#{build_destination_folder}/"") # Find the xcarchive wherever it was placed and copy it where i want it system("find ~/Library/Developer/Xcode/Archives -name *.xcarchive -exec cp -r {} /"#{build_destination_folder}/" /";/"") # Delete the new archives folder with this new xcarchive system(''rm -rf ~/Library/Developer/Xcode/Archives'') # Put the old archives back system(''mv ~/Library/Developer/Xcode/OldArchivesTemp ~/Library/Developer/Xcode/Archives'')

Es un poco hacky pero no veo una mejor solución actualmente. Al menos preserva la carpeta ''archivos'' del usuario y todos sus archivos preexistentes.

--¡Nota IMPORTANTE!--

Desde que descubrí que la línea de código donde encuentro el archivo y lo copio en la carpeta que quiero no copia los enlaces simbólicos dentro del archivo correctamente, rompiendo así la firma del código en la aplicación. Querrá reemplazar eso con un ''mv'' o algo que mantenga enlaces simbólicos. ¡Aclamaciones!


Similar a los otros, pero tal vez un poco más simple ya que trato de registrar la .xcarchive archivo .xcarchive . (Tampoco muevo la carpeta de archivos, así que esto funcionará mejor si estás haciendo varias compilaciones al mismo tiempo).

La secuencia de comandos de compilación de llamada genera un nuevo archivo de temp y establece su ruta a una variable de entorno llamada XCARCHIVE_PATH_TMPFILE . Esta variable de entorno está disponible en la secuencia de comandos del shell post-acción Archive de mi esquema, que luego escribe la ruta de .xcarchive a ese archivo. La secuencia de comandos de compilación que luego puede leer ese archivo después de llamar a xcodebuild archive .

script de shell post-acción

echo $ARCHIVE_PATH > "$XCARCHIVE_PATH_TMPFILE"


Xcode 5 ahora es compatible con una opción -archivePath :

xcodebuild -scheme myscheme archive -archivePath /path/to/AppName.xcarchive

También puede exportar una IPA firmada desde el archivo que acaba de crear:

xcodebuild -exportArchive -exportFormat IPA -exportProvisioningProfile my_profile_name -archivePath /path/to/AppName.xcarchive -exportPath /path/to/AppName.ipa