I am currently building a CI/CD pipeline for a Flutter project. As you don’t want to share all your secret keys from Google, Apple and others to be shared with the world or other developers they are usually put in a variable. If it is a file it is usually base64 encoded and stored in GitHub or Codemagic.
For me this is inconvenient for two reasons:
- It is a little bit of a different approach for each service and does not work for my own machines. When I want to build the iOS version on a virtual Mac I need to collect half a dozen files and manually copy them.
- Updating all the individual pieces is quite tedious and error prone as you might have overlooked one of the files that you should have updated.
My solution to this is a super simple shell script that runs in all environments. By just calling
secrets.sh pack
it creates a secrets.zip and a secrets.b64 base64 encoded version of that zip file in the current directory. I then store the base64 content in an environment variable that gets dumped into secrets.zip and run
secrets.sh unpack
… and all the files land in the correct location.
This way creating a CI/CD is still painful but at least one task got a little easier.
#!/bin/bash
# --- Script: tools/secrets.sh ---
# Packs or unpacks secret files into a zip archive.
# --- Configuration ---
SECRETS_ZIP="secrets.zip"
# Define an array of secret files with their relative paths
SECRET_FILES=(
"google-services.json:android/app/google-services.json"
"GoogleService-Info.plist:ios/Runner/GoogleService-Info.plist"
"firebase.json:firebase.json"
"google-services-playstore.json:fastlane/google-services-playstore.json"
"release-key.jks:android/app/release-key.jks"
"key.properties:android/key.properties"
# Add all your files here ...
)
# --- Functions ---
# Function to pack secret files into a zip archive
pack_secrets() {
local files_to_pack=()
for file_info in "${SECRET_FILES[@]}"; do
local file=$(echo "$file_info" | cut -d ':' -f 1)
local path=$(echo "$file_info" | cut -d ':' -f 2)
if [ -f "$path" ]; then
files_to_pack+=("$path")
else
echo "Warning: $path not found, skipping..."
fi
done
if [ ${#files_to_pack[@]} -eq 0 ]; then
echo "No secret files found to pack."
exit 1
fi
zip -j "$SECRETS_ZIP" "${files_to_pack[@]}"
echo "Secrets packed into $SECRETS_ZIP"
base64 -w 0 secrets.zip > secrets.b64
echo "Secrets base64 encoded into secrets.b64"
}
# Function to unpack secret files from a zip archive
unpack_secrets() {
if [ ! -f "$SECRETS_ZIP" ]; then
echo "Error: $SECRETS_ZIP not found"
exit 1
fi
unzip -o "$SECRETS_ZIP"
for file_info in "${SECRET_FILES[@]}"; do
local file=$(echo "$file_info" | cut -d ':' -f 1)
local path=$(echo "$file_info" | cut -d ':' -f 2)
local dir=$(dirname "$path")
# Create directory if it doesn't exist
mkdir -p "$dir"
# Move the file to its correct location
if [ -f "$file" ]; then
mv "$file" "$path"
echo "Moved $file to $path"
else
echo "Warning: $file not found in zip, skipping..."
fi
done
echo "Secrets unpacked from $SECRETS_ZIP"
}
# --- Main Script ---
if [ "$1" == "pack" ]; then
pack_secrets
elif [ "$1" == "unpack" ]; then
unpack_secrets
else
echo "Usage: $0 [pack|unpack]"
exit 1
fi
Sei der Erste der einen Kommentar abgibt