GoogleService-Info.plist : Copy bundle resources or not - xcode

I user flutter flavors (dev and prod) and my respective GoogleServices-Info.plist file is present in a Firebase/dev Firebase/prod folders respectively
I use a "Build Phases" script to copy the file to Runner/ directory at build-time with the below script
if [ "${CONFIGURATION}" == "Debug-prod" ] || [ "${CONFIGURATION}" == "Release-prod" ] || [ "${CONFIGURATION}" == "Release" ]; then
cp -r "${PROJECT_DIR}/Firebase/prod/GoogleService-Info.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
echo "Production plist copied"
elif [ "${CONFIGURATION}" == "Debug-dev" ] || [ "${CONFIGURATION}" == "Release-dev" ] || [ "${CONFIGURATION}" == "Debug" ]; then
cp -r "${PROJECT_DIR}/Firebase/dev/GoogleService-Info.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
echo "Development plist copied"
fi
Was all working OK, till I tried to use CI/CD with codemagic.
(1) First I got this error from codemagic build(But worked fine locally)
error: Build input file cannot be found: >'/Users/builder/clone/ios/Runner/GoogleService-Info.plist'
(2) I then removed the file from "Copy bundle resources" from my Xcode Target. Now I get below error(Both locally as well as with codemagic):
error: Could not get GOOGLE_APP_ID in Google Services file from build environment
What is the correct setting I should keep to get the build working both locally as well as in codemagic?
Update: After a bit of pondering, looks like (1) is the correct setting. > GoogleServices-Info.plist should be part of the copy bundle resources. >ADDITIONALLY, Runner/GoogleServices-Info.plist MUST exist before build >starts. So I placed a default plist file in the directory and it worked. >My Build Phases script will override this default plist file to >appropriate file based on the flavor

After a bit of pondering, looks like (1) is the correct setting. GoogleServices-Info.plist should be part of the copy bundle resources.
ADDITIONALLY, Runner/GoogleServices-Info.plist MUST exist before build starts. So I placed a default plist file in the directory and it worked. My Build Phases script will override this default plist file to >appropriate file based on the flavor

Related

How to rewrite file to file using bash?

I create builds using AppCenter.ms. But My project has many CustomAndroidManifest.xml files. It places on UserApp/UserApp.Android/Properties/
AppCenter automatically increments version code. But AppCenter changes it in AndroidManifest.xml.
Task: I need to rewrite CustomAndroidManifest.xml to AndroidManifest.xml before AppCenter will change build number.
Why I have many CustomAndroidManifests... because My App has many Configurations.
I've created appcenter-post-clone.sh file and put it in Droid folder. Please look at the my script:
#!/usr/bin/env bash
if [ "$APPCENTER_XAMARIN_CONFIGURATION" == "Conf1" ];
then
cp -R $APPCENTER_SOURCE_DIRECTORY/UserApp/UserApp.Android/Properties/Conf1AndroidManifest.xml/. $APPCENTER_SOURCE_DIRECTORY/UserApp/UserApp.Android/Properties/AndroidManifest.xml/
if [ "$APPCENTER_XAMARIN_CONFIGURATION" == "Conf2" ];
then
cp -R $APPCENTER_SOURCE_DIRECTORY/UserApp/UserApp.Android/Properties/Conf2AndroidManifest.xml/. $APPCENTER_SOURCE_DIRECTORY/UserApp/UserApp.Android/Properties/AndroidManifest.xml/
fi
Main Idea is change first file to second. Thank you.
EDIT! Problem is that CustomAndroidManifest.xml dos not rewrite to AndroidManifest.xml.
Question: How can I rewrite one file to second using bash?

Update Info.plist values in archive

I need to be able to set a couple custom values in the Info.plist during the Xcode ARCHIVE process. This is for Xcode 6 and Xcode 7.
I already have a script in place that successfully updates these values as a post-action on the BUILD process. It works great when deploying to the simulator or to a phone from Xcode 6.
However, the Info.plist doesn't seem to be available from within the directory structures during the ARCHIVE process. After a BUILD, I can find the results under .../Build/Products in $CONFIGURATION-iphoneos and $CONFIGURATION-iphonesimulator. But after the ARCHIVE, there isn't anything there and I only find the compiled binaries under .../Build/Intermediates.
Certainly, I can see the Info.plist in the IPA itself. Yet any attempts to update and replace this file after the fact are unsuccessful; the IPA is no longer valid, I assume due to checksum changes or something.
I don't want to update these values in the source Info.plist (e.g., using a pre-action) as it will always make the source dirty every time I archive.
Figured this out. The process is nearly identical to the build -- use a post-action for the build, use a post-action for the archive -- just the path is different (all listed below) for where to find the Info.plist.
Below is my build script where I've used tokens for the "name" and the "value" to be updated in Info.plist. I just copied this script and renamed it for use with the archive post-action. Note that this script also has an example of extracting a value from Info.plist as I am deriving the web services version from the client version.
The path to the build Info.plist is either of:
"$BUILD_DIR/$CONFIGURATION-iphoneos/$PRODUCT_NAME.app/Info.plist"
"$BUILD_DIR/$CONFIGURATION-iphonesimulator/$PRODUCT_NAME.app/Info.plist"
NOTE: Both targets are being updated for a build since I've not figured out a way to identify which build it is doing.
The path to the archive Info.plist is:
"$ARCHIVE_PRODUCTS_PATH/Applications/$PRODUCT_NAME.app/Info.plist"
Build post-action:
$SRCROOT/post_build.sh <value> ~/xcode_build_$PRODUCT_NAME.out
Build script:
#!/bin/bash
# post_build.sh
#
# This script is intended for use by Xcode build process as a post-action.
# It expects the only argument is the value to be updated in Info.plist. It
# derives the WS version for the URL from the version found in Info.plist.
printf "Running $0 using scheme '$SCHEME_NAME' as '$USER'\n"
# If this is a clean operation, just leave
if [ $COPY_PHASE_STRIP == "YES" ]
then
printf "Doing a clean; exiting.\n"
exit 1
fi
# Confirm that PlistBuddy is available
PLIST_BUDDY=/usr/libexec/PlistBuddy
if ![-f "$PLIST_BUDDY"]
then
printf "Unable to access $PLIST_BUDDY\n"
exit 1
else
printf "PLIST_BUDDY=$PLIST_BUDDY\n"
fi
# Function to perform the changes
updatePlist()
{
PLIST_FILE=$1
if [ -f "$PLIST_FILE" ]
then
printf "Determing WS version...\n"
if [[ $SCHEME_NAME == *"Local"* ]]
then
WS_VER=""
else
# Determine the services version
BUILD_VER=$(${PLIST_BUDDY} -c "Print CFBundleShortVersionString" "$PLIST_FILE")
WS_VER=$(printf $BUILD_VER | sed 's/\(.*\)\..*/\1/' | sed 's/\./_/g')
fi
# Update the plist
${PLIST_BUDDY} -c "Set <name> <value>" "$PLIST_FILE"
printf "Updated plist $PLIST_FILE\n"
else
printf "Skipping -- no plist: $PLIST_FILE\n"
fi
}
# Retrieve the supplied URL
BASE_URL=$1
printf "BASE_URL=$BASE_URL\n\n"
# Record the environment settings
printenv | sort > ~/xcode_build_$PRODUCT_NAME.env
# Locate the plist in the device build
printf "Checking device build...\n"
updatePlist "$BUILD_DIR/$CONFIGURATION-iphoneos/$PRODUCT_NAME.app/Info.plist"
printf "\n"
# Locate the plist in the simulator build
printf "Checking simulator build...\n"
updatePlist "$BUILD_DIR/$CONFIGURATION-iphonesimulator/$PRODUCT_NAME.app/Info.plist"
printf "\n"

How to generate a indeterminate number of WAR files using Maven?

I would like to generate multiple WAR files, during the build cycle of my project. I already know how to add multiple dest-file, and other configuration with the maven-war-plugin. But I want to know if there is way to generate an indeterminate number of war during the build cycle, without writing configuration for each WAR.
I want to generate a build for each clients, I have the following directory structure in my project:
| pom.xml
+ src
+ main
+ clients
+ client1
+ client2
+ client3
+ ...
+ clientn
I would like to know how to generate a WAR for each client directory. I just want to create a Maven configuration, then just care about adding a new folder then mvn package and get n WAR packages.
Is it possible?
Seems like Maven cannot do that by itself, so I ended up creating a script that invoke Maven for each folder found in src/main/clients.
In Unix
#!/bin/bash
clear
###
# Check for Apache Maven home environment variable.
###
M2_HOME=`$M2_HOME`
if [ -z "$M2_HOME" ]; then
echo "Error: M2_HOME variable not set. Please set Apache Maven home."
exit
fi
###
# Build all client packages.
###
echo "Build start."
for f in $0/src/main/clients/*
do echo Building: %f
$M2_HOME/bin/mvn package -Dclient.id=`basename $f` -Dclient.path=$f -DskipTests
done;
echo "Build end."
In Windows
#ECHO off
SET M2_HOME=%M2_HOME%
CD %~p0
ECHO Build start.
FOR /r /d %%G in (src\main\client\*) DO (
ECHO Building: %%~nG
%M2_HOME%\bin\mvn package -Dclient.id=%%~nG -Dclient.path=%%G -DskipTests
)
ECHO Build end.

Look for a file in parent dir if it is not in current dir

I'm trying to make a shell function that looks for a file existence in the current dir. If the file doesn't exists if the current dir, it should try the parent dir, and go up to the root of the filesystem (going up to ~ should be more than enough).
What I'm trying to achieve is display the current ruby on rails version used for a project on my prompt. The easy way is to call bundle show rails and parse the string, but it is quite slow; so I want to parse the file that contains the versions informations, Gemfile.lock. What I have currently only works when I'm in the root of the project (where the Gemfile.lock lives).
This could also be used to parse a git config file, though git config is pretty fast.
Thanks for your time
like this?
#!/bin/zsh
# the function
findfile_parent() {
FILE=$1
while [ ! -e "${FILE}" ]; do
if [ "$(pwd)" = "/" ]; then
return
fi
cd ..
done
echo "$(pwd)/${FILE}"
}
# usage example
SEARCHFILE=foo.pyl
UPFILE=$(findfile_parent ${SEARCHFILE})
if [ "x${UPFILE}" != "x" ]; then
echo "found file ${SEARCHFILE} as ${UPFILE}"
else
echo "couldn't find file ${SEARCHFILE}"
fi
Refer the below two helpful links to find out your solution.
Get parent directory of current directory in Ruby
How to check for file existence
):

How to include file as resource in Xcode programmatically during build?

I have a file that is created by a script that is run during a build phase. Consequently, the file does not exist until build time.
How can I add the file to the app/project so that my code can access it at run time?
I know what the filename will be.
Normally, if I created the file by hand, I would just drag/drop it into Xcode, and I can instantly access it by using the filename in code. Since I am generating the file during build, I want to know how I can add it to my project.
EDIT: The file that I am adding is an Image file, that is created by a script during a build phase. I want to be able to access this file at runtime in my product.
I ended up using build references.
You could create the file and add it to the project and then during the build phase, your script could replace the existing file with the generated one....
The other option is to try manipulating the project file itself but that's quite complicated. Here are some resources on the subject...
You can copy the generated file to the build output using a script like this one I use to copy a plist with values maintained outside version control, as anything copied to "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/" is available using NSBundle APIs.
SECRETS="${SRCROOT}/../../secrets/Secrets.plist"
APP="${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/Secrets.plist"
if [ -f "$SECRETS" ]; then
cp -f "$SECRETS" "$APP"
echo "copied Secrets.plist: $APP"
else
echo "Secrets.plist not found at $SECRETS, all secrets will be 'MISSING'"
fi
For instance, that plist of secrets is defined as the Decodable struct SecretsFile and loaded with
private static var file: SecretsFile? = {
guard let url = Bundle.main.url(forResource: "Secrets", withExtension: "plist"),
let data = try? Data(contentsOf: url) else { return nil }
return try? PropertyListDecoder().decode(SecretsFile.self, from: data)
}()

Resources