XCode trying to locate service account file - ios

When I try to build my Project in XCode, I get the following dialog box:
It asks for a service account file which I am not sure of.
If I cancel it, I get the following error in upload-symbol-util.bash file:
# If the token will expire in the next sixty seconds (or already
# has), reload it.
if ! fcr_verify_tok_plist; then
xcdebug "Token is invalid. Refreshing..."
if ! fcr_verify_svc_plist; then
xcdebug "Service account information is invalid. Requesting reload..."
if [[ "$SERVICE_ACCOUNT_FILE" && -f "$SERVICE_ACCOUNT_FILE" ]]; then
xcdebug "Using $SERVICE_ACCOUNT_FILE for credentials."
else
SERVICE_ACCOUNT_FILE="$(/usr/bin/osascript -e 'the POSIX path of (choose file with prompt "Where is the service account file?" of type "public.json")' 2>/dev/null)"
fi
/usr/libexec/PlistBuddy "$SVC_PLIST" \
-c "Add :version integer 1"
if [[ "$SERVICE_ACCOUNT_FILE" && -f "$SERVICE_ACCOUNT_FILE" ]]; then
/usr/bin/plutil -replace "$APP_KEY" -json "$(/bin/cat "$SERVICE_ACCOUNT_FILE")" "$SVC_PLIST" || return 2
if fcr_verify_svc_plist; then
xcdebug "Installed service account file into $SVC_PLIST."
else
/usr/libexec/PlistBuddy "$SVC_PLIST" -c "Delete $APP_KEY" >/dev/null 2>&1
xcerror "Unable to parse service account file."
return 2
fi
else
xcerror "User cancelled symbol uploading." // Getting Error here
return 1
fi
fi
Please tell what is a Service Account file and where do I find it?

Related

How to handle appcenter login error in shell script?

I am using the below script for publishing the ipa to appcenter.
ipaPath=<PATH TO MY IPA FILE>
echo "Found ipa at $ipaPath"
if [[ -z ${ipaPath} ]]
then
echo "No ipas were found, skip publishing to App Center"
else
appcenter login
appcenter distribute release \
--group Collaborators \
--file "${ipaPath}" \
--release-notes 'App submission' \
--app <username_or_organization>/<application_identifier> \
--quiet
fi
I need to exit if the login is failed and don't want to run the distribute command. how to check the login status and handle the error?
You could use command substitution to capture the result of appcenter login into a variable, then search the variable contents for a specific string (or lack of). For example:
reply="$(appcenter login --token ${token})"
if [[ $reply == *"Error"* ]]; then
echo "A problem occurred! ${reply}"
else
appcenter distribute release
...
fi

Initiate an email based on script output or console output in Jenkins

I have a script which basically fetches the http response codes. I want to trigger an email for response code anything apart from 200. I do not want to trigger mail using script. Is there any way to send a mail in post build actions ?
Kindly assist.
#!/bin/bash
date
if [ $# -eq 0 ]; then
cat /home/ubuntu/check_kibana/lists.txt | while read output
do
RESP=$(curl -sL $output -w "%{http_code} \n" -o /dev/null)
if [ $RESP -eq 200 ]; then
echo "ResponseCode: $RESP, Service is active."
else
echo "ResponseCode: $RESP, $output is not active."
echo "ResponseCode: $RESP for $output. Please check as the service may be down or not listening to the designated port." | mail -s "Error triggered for unavailable kibana service" xxxxxxxxx#gmail.com
fi
done
fi
If you are running this as a build step then you need to add exit 1; in the else part of the response code check. This will mark the build step as a failure and then you can set up an email trigger using "Email Notification" as a post-build step. In case, If you want to have personalized email then you can use "Editable Email Notification" plugin.
So, your script should be something like this
#!/bin/bash
date
if [ $# -eq 0 ]; then
cat /home/ubuntu/check_kibana/lists.txt | while read output
do
RESP=$(curl -sL $output -w "%{http_code} \n" -o /dev/null)
if [ $RESP -eq 200 ]; then
echo "ResponseCode: $RESP, Service is active."
else
exit 1; # Any exit code except 0 will mark the build step as the failure
echo "ResponseCode: $RESP, $output is not active."
echo "ResponseCode: $RESP for $output. Please check as the service may be down or not listening to the designated port." | mail -s "Error triggered for unavailable kibana service" pruthvi.basagodu#gmail.com
fi
done
fi
To fix the above issue, we need to know that Jenkins will trigger the email notification only if the build fails or changes from failure to success. (depends on how you want to trigger an email via Jenkins).
I have found a way to solve the above issue. Instead of shell script, python would be right choice for me me as it is very flexible to play around with the various libraries and variables. So, those who want to trigger an email based on the loop conditions in the script, go with python or any OOP languages.
Shell script will only run the script and sets the build status. If I am wrong, I'd be happy receive the suggestions.

Best practice for using Fabric/Crashlytics with open-source app?

I have an iOS app that I'm about to open source. I don't want to include my key and secret in the Run Script code when the the app is live for everyone to look at, fork, download etc. for obvious reasons.
What is the best way to still use Fabric/Crashlytics but also keep those keys secure so that only those who can deploy the app have access to those credentials?
Here's a way:
1 - Store fabric keys in a local file.
<apiKey>
<secretKey>
2 - In your cocoa pods run script phase (under Build Phases in Xcode), have your script grab the api key and secret key from the local file.
apiKey=$(sed -n '1p' < localFile.txt)
secretKey=$(sed -n '2p' < localFile.txt)
3 - Use PlistBuddy in the cocoa pods run script phase to set the API Key into your Info.plist file. Something like this:
/usr/libexec/PlistBuddy -c "Set :Fabric:APIKey string $apiKey" $(PROJECT_DIR)/Info.plist
4 - Call the cocoa pods run command.
"${PODS_ROOT}/Fabric/run" $apiKey $secretKey
Edit: full script
apiKey=$(sed -n '1p' < localFile.txt)
secretKey=$(sed -n '2p' < localFile.txt)
/usr/libexec/PlistBuddy -c "Set :Fabric:APIKey string $apiKey" $(PROJECT_DIR)/Info.plist
"${PODS_ROOT}/Fabric/run" $apiKey $secretKey
NOTE -
$(PROJECT_DIR)/Info.plist may not be the correct path for your particular project.
Jake's answer didn't work for me. Apparently $(PROJECT_DIR)/Info.plist returns an incorrect path.
But here's a working example for a project that uses both Fabric and Google sign in. (This works perfectly in Xcode 9 as of July 2018)
FabricApiKey=$(sed -n '2p' < app_config.txt)
FabricSecretKey=$(sed -n '4p' < app_config.txt)
GoogleReversedClientId=$(sed -n '6p' < app_config.txt)
INFO_PLIST="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"
/usr/libexec/PlistBuddy -c "Set :Fabric:APIKey $FabricApiKey" "$INFO_PLIST"
/usr/libexec/PlistBuddy -c "Set :CFBundleURLTypes:0:CFBundleURLSchemes:0 $GoogleReversedClientId" "$INFO_PLIST"
"${PODS_ROOT}/Fabric/run" $FabricApiKey $FabricSecretKey
and here's the structure of app_config.txt file that must be present at the project root:
FabricApiKey:
your_key_here
FabricSecretKey:
your_secret_here
GoogleReversedClientId:
google_reversed_client_id_here
Excellent post by #Jake - thank-you! This is my variation which checks for the existence of the secrets file, and uses some environment variables provided by Xcode 9.4.
#1/usr/bin/env sh
secretsFile=$PROJECT_DIR/scripts/fabric.secrets
if [ ! -f $secretsFile ]; then
echo "warning: '$secretsFile' not found"
exit 0
fi
apiKey=$(sed -n '1p' < $secretsFile)
secretKey=$(sed -n '2p' < $secretsFile)
/usr/libexec/PlistBuddy -c "Set :Fabric:APIKey $apiKey" $PRODUCT_SETTINGS_PATH
$PROJECT_DIR/Fabric.framework/run $apiKey $secretKey
Note: the echo "warning: " part will be detected by Xcode, and put into the build log as a yellow warning.
Finally, here's a pre-commit git hook to check for a 40-character hex string accidentally being added to the Info.plist:
#!/usr/bin/env sh
files=$(ls */Info.plist)
git diff --cached --name-status | while read modificationtype thisfile; do
if [ "$modificationtype" == 'D' ]; then continue; fi
for file in $files
do
if [ ! "$thisfile" == "$file" ]; then continue; fi
if egrep '[0-9a-fA-F]{40}' $file ; then
echo "ERROR: API key in file: ${file}"
exit 1
fi
done
done || exit $?

How can I find my Apple Developer Team id and Team Agent Apple ID?

I am trying to transfer an app. I am having troubles finding my team agent apple id and my team id. I have found it before and I have searched for 30 min without any luck now that i need it.
The person trying to transfer the app to me gets to view in this image and I don't know where to find this info.
You can find your team id here:
https://developer.apple.com/account/#/membership
This will get you to your Membership Details, just scroll down to Team ID
If you're on OSX you can also find it your keychain. Your developer and distribution certificates have your Team ID in them.
Applications -> Utilities -> Keychain Access.
Under the 'login' Keychain, go into the 'Certificates' category.
Scroll to find your development or distribution certificate. They will read:
iPhone Distribution: Team Name (certificate id)
or
iPhone Developer: Team Name (certificate id)
Simply double-click on the item, and the
"Organizational Unit"
is the "Team ID"
Note that this is the only way to find your
"Personal team" ID
You can not find the "Personal team" ID on the Apple web interface.
For example, if you are automating a build from say Unity, during development you'll want it to appear in Xcode as your "Personal team" - this is the only way to get that value.
For personal teams
grep DEVELOPMENT_TEAM MyProject.xcodeproj/project.pbxproj
should give you the team ID
DEVELOPMENT_TEAM = ZU88ND8437;
You can find the Team ID via this link: https://developer.apple.com/membercenter/index.action#accountSummary
Apple has changed the interface.
The team ID could be found via this link:
https://developer.apple.com/account/#/membership
There are ways you can check even if you are not a paid user.
You can confirm TeamID from Xcode.
[Build setting] Displayed on tooltip of development team.
I wanted to get this from the command line (Terminal) so I came up with this bash script
Link to gist
#!/usr/bin/env bash
#requires openssl#3 from Homebrew
_openssl=$(brew --prefix openssl 2>/dev/null)/bin/openssl
[[ -x $_openssl ]] || { echo "missing openssl, try \`brew install openssl\`"; exit 1; }
#find development cert
id=$(security find-identity -v -p codesigning | head -1)
[[ -n $id ]] || exit 1
cn=$(sed -En 's/^.*Apple Development.*\((.*)\).*$/\1/p' <<<"$id")
sha1=$(sed -En 's/^.*([A-F0-9]{40}).*$/\1/p' <<<"$id")
[[ -n $cn && -n $sha1 ]] || { echo "could not find valid development cert"; exit 1; }
#make temp dir
outdir=$(mktemp -d /private/tmp/teamid.XXXXXX)
[[ -n $outdir ]] || { echo "error creating temp dir"; exit 1; }
#export cert
if ! security find-certificate -c "$cn" -Z -p >"${outdir}/${cn}.pem"; then
echo "error exporting cert from Keychain"
exit 1
fi
#check for hash match
certhash=$(awk -F: '/SHA-1 hash:/{sub(" ","",$2); print $2}' "${outdir}/${cn}.pem")
[[ "$certhash" == "$sha1" ]] || { echo "hash mismatch!"; exit 1; }
#output DEVELOPMENT_TEAM
$_openssl x509 -in "${outdir}/${cn}.pem" -subject -noout |
sed -En 's/.*OU = ([^,]+),.*$/\1/p'
#cleanup
rm -r "${outdir:?}"
It's now under Certificates, Identities & Profiles top right you have your name in the first line, and in the second your name again and right to it is the Team ID.
For a flutter project and personal team.
navigate to below address and search for DEVELOPMENT_TEAM
you should find some thing like this DEVELOPMENT_TEAM = 64F9WR9M48
ios/Runner.xcodeproj/project.pbxproj

Xcode Build Script (Build Phases->Run Script) Increment Build Version based on Username(User)

When compiling a project, this script should increment the Build Version of the Xcode project by one, when the system username matches. Keep in mind that these are just Unix commands in a script (not Applescript, Python, or Perl) inside Target->Build Phases->Run Script in Xcode.
I've done "echo $USER" in terminal. This prints the username of the logged-in user just fine, and it's the same string I placed in the conditional statement in the second block of code.
The first block of code works. The second, which adds the conditional statement, does not.
#!/bin/bash
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
#!/bin/bash
username=$USER
if [ username == "erik" ]; then
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
fi
Syntax concerns:
Parsing of $USER (case sensitive)
Semicolon right after closing bracket in if statement
Then statement on same line as if statement
You can see the script log in the Log Navigator, with your script i've got the following issue:
I believe the default comparison is case sensitive, to make it not sensitive you can change the username to uppercase/lowercase before comparison:
if [ `echo $USER | tr [:lower:] [:upper:]` = "USERNAME" ]; then
echo "Got user check"
fi
As you can see I moved $USER to the condition to avoid additional var usage and the script failure.
And the semicolon at if-then block is a normal thing, check the man page. then word might be moved to the new line if that is more convenient for you to read.

Resources