Fastlane Scan: How to add '--screenshots' (xcpretty flag)? - testing

I need to add my screenshots to html-report after Fastlane Scan runs the tests, but here's the problem: --screenshots is xcpretty's flag, not xcodebuild's.
Scan has no such parameter, like xcpretty_args in Snapshot. So now I'm forced to run my tests without Scan but with next script:
set -o pipefail && env NSUnbufferedIO=YES xcodebuild -workspace ./MyProject.xcworkspace -scheme myScheme -destination 'platform=iOS Simulator,name=iPhone 7 Plus,OS=10.3.1' -derivedDataPath 'build'
-only-testing:myTarget/myTestSuite01 test-without-building| xcpretty -r html --screenshots -r junit
So, is it possible to do it any way with Scan?

Related

Pod Install fails when installing MuPDF

I'm developing a pdf viewer app and I'm using MuPdf library cocoapods. I created a new project, added a pod file and ran pod install. Following error occurred. Any help is appreciated to fix this. I have set automatically manage signing in the project.
Analyzing dependencies
Downloading dependencies
Installing MuPDF (1.10)
[!] /bin/bash -c
set -e
cd platform/ios
# release armv7 + arm64
xcodebuild -scheme MuPDF -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
# debug 64bit sim
xcodebuild -scheme MuPDF -configuration Release -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
cd ../../build/
for i in mupdf mupdfthird; do
LIB=lib${i}.a
lipo -create -output $LIB release-ios-i386-x86_64/$LIB release-ios-armv7-arm64/$LIB
done
# rename to avoid any conflict with the libmupdf.a that the pod generates
mv libmupdf.a libmupdfcore.a
# copy iOS headers into the general include directory, as
# cocoapods 1.0 insists that all headers are under the
# header_mappings_dir location
cd ..
cp platform/ios/Classes/*.h platform/ios/common.h include/mupdf/
cd platform/ios
# now fix the imports/includes to be mupdf/foo.h instead of foo.h
find . -name '*.[mh]' -print0 | xargs -0 perl -pi -e 's,#import "Mu,#import "mupdf/Mu,'
find . -name '*.[mh]' -print0 | xargs -0 perl -pi -e 's,#include "common.h",#include "mupdf/common.h",'
find . -name '*.[mh]' -print0 | xargs -0 perl -pi -e 's,#import "common.h",#import "mupdf/common.h",'
# the reference to memory.h in memento.h upsets xcode when
# building a module (fixed upstream for version after 1.9)
cd ../..
find . -name 'memento.h' -print0 | xargs -0 perl -pi -e 's,#include <memory.h>,#include <stdlib.h>,'
Command line invocation:
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -scheme MuPDF -configuration Release CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO
Build settings from command line:
CODE_SIGN_IDENTITY =
CODE_SIGNING_REQUIRED = NO
note: Using new build system
note: Building targets in parallel
note: Planning build
note: Constructing build description
error: An empty identity is not valid when signing a binary for the product type 'Application'. (in target 'MuPDF' from project 'MuPDF')
** BUILD FAILED **

Can xcodebuild delete the contents of the project's Build Folder?

Back in Xcode 9, there was a build option called "Clean Build Folder..." (⌥⇧⌘K), which deleted all files in the build folder, only leaving the folder behind with no contents. Since then, this behavior was removed, the menu item's title changed to "Clean Build Folder", and now behaving like the old "Clean" used to.
xcodebuild has a build option called clean which simply does the same thing as Xcode's "Clean Build Folder" (⌘⇧K), which leaves stuff around.
Is there any way to delete all files in the build folder via a scriptable command?
What I've tried so far:
xcodebuild clean -workspace "My Workspace.xcworkspace" -scheme "My Scheme"
This, as I said, doesn't actually clean everything up. For that, I added this bodge to my build script:
export IS_XCODE_CACHE_FOLDER_PRESENT="`ls -la ~/Library/Developer/ | grep -x "Xcode"`"
if [ 0 -ne "$IS_XCODE_CACHE_FOLDER_PRESENT" ]; then
echo "Xcode cache folder should not be present at build time! Attempting to delete..."
rm -rf "~/Library/Developer/Xcode"
RM_RESULT=$?
if [ 0 -ne "$RM_RESULT" ]; then
echo "FAILED to remove Xcode cache folder!"
exit $RM_RESULT
fi
fi
I faced a similar requirement. So after trying for several hours, I resolved to a custom script instead of using Xcode's run script.
So instead of using Xcode to run the app on the simulator I use my script which in turn first cleans the build folder, then builds the project, then installs and finally launches the app in the simulator.
Here is what I am using as a quick script:
# Delete Build directory
rm -rf ./build/Build
# pod install
pod install
# Build project
xcrun xcodebuild -scheme Example -workspace Example.xcworkspace -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 11 Pro Max,OS=13.1' -derivedDataPath build
# Install App
xcrun simctl install "iPhone 11 Pro Max" ./build/Build/Products/Debug-iphonesimulator/Example.app/
# Launch in Simulator
xcrun simctl launch "iPhone 11 Pro Max" com.ihak.arpatech.Example
Note: See this question I posted to know the issue I was facing.
You can add clean action.
xcodebuild clean build -workspace "My Workspace.xcworkspace" -scheme "My Scheme"
see more in man xcodebuild
action ...
Specify one or more actions to perform. Available actions are:
build Build the target in the build root (SYMROOT). This is the default action, and is used if no action is given.
build-for-testing Build the target and associated tests in the build root (SYMROOT). This will also produce an xctestrun file in the build root. This requires speci-
fying a scheme.
analyze Build and analyze a target or scheme from the build root (SYMROOT). This requires specifying a scheme.
archive Archive a scheme from the build root (SYMROOT). This requires specifying a scheme.
test Test a scheme from the build root (SYMROOT). This requires specifying a scheme and optionally a destination.
test-without-building Test compiled bundles. If a scheme is provided with -scheme then the command finds bundles in the build root (SRCROOT). If an xctestrun file is
provided with -xctestrun then the command finds bundles at paths specified in the xctestrun file.
installsrc Copy the source of the project to the source root (SRCROOT).
install Build the target and install it into the target's installation directory in the distribution root (DSTROOT).
clean Remove build products and intermediate files from the build root (SYMROOT).

How to use OCLint for the Cocoa Framework?

Run the following command in the folder with the project:
$ xcodebuild -target MyCocoaFramework -configuration Debug -scheme MyCocoaFramework clean build | tee xcodebuild.log
$ oclint-xcodebuild
$ oclint-json-compilation-database
$
Nothing is displayed.
This approach works fine for Cocoa Application.
$ xcodebuild -target MyCocoaApplication -configuration Debug -scheme MyCocoaApplication clean build | tee xcodebuild.log
$ oclint-xcodebuild
$ oclint-json-compilation-database
/a/b/c/d.m:181:5: redundant local variable P3
/a/b/c/d/e.m:193:5: redundant local variable P3
/a/b/c/d.m:104:1: long line P3 Line with 112 characters exceeds limit of 100
What should be changed to work for the Cocoa Framework?
OCLint can't support the arm64 architecture: https://github.com/oclint/oclint/issues/190
If your code targets iOS 7, then OCLint may fail silently.

xcodebuild far slower than Xcode?

Building from the command line with xcodebuild is orders of magnitude slower than building the same project, same scheme, same target from within Xcode. Does anyone know why this might be the case and how I might speed up my xcodebuild build?
I'm invoking xcodebuild as follows:
xcodebuild -scheme <SCHEME> -workspace <WORKSPACE> -configuration Debug -sdk iphonesimulator7.0 -jobs 12 build
for building on a 12-core Mac Pro. I guessed at the -jobs setting but it seems reasonable. Does anyone have any advice? Is there a way, by analyzing Xcode's build log, to tell what settings for xcodebuild most closely map to what Xcode itself is using? Thanks!
While this alone may not explain the slowness of xcodebuild compared to IDE, I've seen some improvements if I disable Spotlight indexing on ~/Library/Developer/Xcode/DerivedData directory.
When using xcodebuild test that will reboot the simulator each time. It is the main reason case the xcodebuild slowly. When you using xcode test directly, The simulator will not boot twice after booted.
You can try this:
xcodebuild -project Example.xcodeproj \
-scheme ExampleTests \
-disable-concurrent-destination-testing \
-destination 'platform=iOS Simulator,name=iPhone 13' \
-sdk iphonesimulator \
CODE_SIGNING_ALLOWED="NO" \
test
-disable-concurrent-destination-testing disable clone simulator in Xcode 14 and test in the same simulator
CODE_SIGNING_ALLOWED="NO" disable signing test target will faster

xcodebuild archive configuration not work

I want to use xcodebuild to archive one scheme with 3 different configurations, but the configuration is never changed with archive action.
Here is the content in .sh
xcodebuild -workspace myApp.xcodeproj/project.xcworkspace -sdk iphoneos -scheme myApp -configuration Distribution clean archive
xcodebuild -workspace myApp.xcodeproj/project.xcworkspace -sdk iphoneos -scheme myApp -configuration Inhouse clean archive
xcodebuild -workspace myApp.xcodeproj/project.xcworkspace -sdk iphoneos -scheme myApp -configuration Release clean archive
update: build action works fine
xcodebuild -workspace myApp.xcodeproj/project.xcworkspace -sdk iphoneos -scheme myApp -configuration Distribution clean build
xcodebuild -workspace myApp.xcodeproj/project.xcworkspace -sdk iphoneos -scheme myApp -configuration Inhouse clean build
xcodebuild -workspace myApp.xcodeproj/project.xcworkspace -sdk iphoneos -scheme myApp -configuration Release clean build
I am using Xcode4.5/iOS6.0, It works fine with build action(configuration changes each xcodebuild run), any solution?
The configuration for archive action has no effect, maybe it's a bug of xcodebuild.
In order to change the configuration of archive, I write a shell script change the configuration of scheme each time before run archive command.
May not be the best solution, but solve the problem.
Here is the code:
#! /bin/sh
# Define Scheme name
PACKAGE_PROJECT_NAME="MyApp"
PACKAGE_SCHEME_NAME="MyApp"
# Get Username
PACKAGE_USER_NAME="$(whoami)"
# Scheme Path
PACKAGE_SCHEME_DIR="$SRCROOT/${PACKAGE_PROJECT_NAME}.xcodeproj/xcuserdata/${PACKAGE_USER_NAME}.xcuserdatad/xcschemes"
PACKAGE_SCHEME_PATH="${PACKAGE_SCHEME_DIR}/${PACKAGE_SCHEME_NAME}.xcscheme"
echo "PACKAGE_SCHEME_PATH = ${PACKAGE_SCHEME_PATH}"
# Set Configuration
# WARNING: BACKUP_CONFIGURATION MUST be same with build configuration of archive action in MyApp scheme
BACKUP_CONFIGURATION="Distribution"
# WARNING: Archive name of archive action in MyApp scheme MUST be set explicitly.
# WARNING: BACKUP_ARCHIVENAME MUST be same with archive name of archive action in MyApp scheme
BACKUP_ARCHIVENAME="MyAppArchive"
echo "BACKUP_CONFIGURATION = ${BACKUP_CONFIGURATION}"
echo "BACKUP_ARCHIVENAME = ${BACKUP_ARCHIVENAME}"
# -------------------------------Archive Distribution---------------------------------------
# Set Configuration
OLD_CONFIGURATION="${BACKUP_CONFIGURATION}"
NEW_CONFIGURATION="Distribution"
OLD_ARCHIVENAME="${BACKUP_ARCHIVENAME}"
NEW_ARCHIVENAME="${PACKAGE_SCHEME_NAME}_${NEW_CONFIGURATION}"
# Clean
xcodebuild -workspace ${PACKAGE_PROJECT_NAME}.xcodeproj/project.xcworkspace -sdk iphoneos -scheme ${PACKAGE_SCHEME_NAME} -configuration ${NEW_CONFIGURATION} clean
# Change archive configuration
sed -i .bak "/<ArchiveAction/,/<\/ArchiveAction>/{s/\"${OLD_CONFIGURATION}\"/\"${NEW_CONFIGURATION}\"/;s/\"${OLD_ARCHIVENAME}\"/\"${NEW_ARCHIVENAME}\"/;}" ${PACKAGE_SCHEME_PATH}
# Archive
xcodebuild -workspace ${PACKAGE_PROJECT_NAME}.xcodeproj/project.xcworkspace -sdk iphoneos -scheme ${PACKAGE_SCHEME_NAME} archive
# -------------------------------Archive Inhouse------------------------------------------
# Set Configuration
OLD_CONFIGURATION="${NEW_CONFIGURATION}"
NEW_CONFIGURATION="Inhouse"
OLD_ARCHIVENAME="${NEW_ARCHIVENAME}"
NEW_ARCHIVENAME="${PACKAGE_SCHEME_NAME}_${NEW_CONFIGURATION}"
# Clean
xcodebuild -workspace ${PACKAGE_PROJECT_NAME}.xcodeproj/project.xcworkspace -sdk iphoneos -scheme ${PACKAGE_SCHEME_NAME} -configuration ${NEW_CONFIGURATION} clean
# Change archive configuration
sed -i .bak "/<ArchiveAction/,/<\/ArchiveAction>/{s/\"${OLD_CONFIGURATION}\"/\"${NEW_CONFIGURATION}\"/;s/\"${OLD_ARCHIVENAME}\"/\"${NEW_ARCHIVENAME}\"/;}" ${PACKAGE_SCHEME_PATH}
# Archive
xcodebuild -workspace ${PACKAGE_PROJECT_NAME}.xcodeproj/project.xcworkspace -sdk iphoneos -scheme ${PACKAGE_SCHEME_NAME} archive
# -------------------------------Archive Adhoc-------------------------------------------
# Set Configuration
OLD_CONFIGURATION="${NEW_CONFIGURATION}"
NEW_CONFIGURATION="Release"
OLD_ARCHIVENAME="${NEW_ARCHIVENAME}"
NEW_ARCHIVENAME="${PACKAGE_SCHEME_NAME}_${NEW_CONFIGURATION}"
# Clean
xcodebuild -workspace ${PACKAGE_PROJECT_NAME}.xcodeproj/project.xcworkspace -sdk iphoneos -scheme ${PACKAGE_SCHEME_NAME} -configuration ${NEW_CONFIGURATION} clean
# Change archive configuration
sed -i .bak "/<ArchiveAction/,/<\/ArchiveAction>/{s/\"${OLD_CONFIGURATION}\"/\"${NEW_CONFIGURATION}\"/;s/\"${OLD_ARCHIVENAME}\"/\"${NEW_ARCHIVENAME}\"/;}" ${PACKAGE_SCHEME_PATH}
# Archive
xcodebuild -workspace ${PACKAGE_PROJECT_NAME}.xcodeproj/project.xcworkspace -sdk iphoneos -scheme ${PACKAGE_SCHEME_NAME} archive
# ------------------------------Restore Configuration-------------------------------------
sed -i .bak "/<ArchiveAction/,/<\/ArchiveAction>/{s/\"${NEW_CONFIGURATION}\"/\"${BACKUP_CONFIGURATION}\"/;s/\"${NEW_ARCHIVENAME}\"/\"${BACKUP_ARCHIVENAME}\"/;}" ${PACKAGE_SCHEME_PATH}
When using the --scheme option, the configuration is overridden by the settings in the Scheme itself. You will need to create 3 different schemes and configure each to use the appropriate configuration for the Archive action:
Alternatively you can not bother with schemes at all, and use the --target and --configuration switches on the command line directly.