This is the entry point of all-things Ecosia. It contains info on the way we got the project structure, how we interface it with Firefox, how we release and keep localizations aligned.
The Ecosia Framework aims to be a wrapper of all our Ecosia isolated implementation and logic.
Some of the Ecosia codebase still lives under the main project Client/Ecosia but the goal is to bring as much codebase as possible as part of this dedicated framework.
We encourage you to participate in those open source projects. We love Pull Requests, Issue Reports, Feature Requests or any kind of positive contribution. Please read the Mozilla Community Participation Guidelines and our Contributing guidelines first.
- You can file a new issue or research existing bugs
If more information is required or you have any questions then we suggest reaching out to us via:
- Chat on Element channel #fx-ios and #focus-ios for general discussion, or write DMs to specific teammates for questions.
- Open a Github discussion which can be used for general questions.
Want to contribute on the codebase but don't know where to start? Here is a list of issues that are contributor friendly, but make sure to read the Contributing guidelines first.
To ensure consistency when commenting code in Firefox for Ecosia updates, you could document the following approach:
Commenting Guidelines for Ecosia Code in Firefox:
1. One-liner Comments:
Use // for introducing new code or brief explanations.
// Ecosia: Update appversion predicate
let appVersionPredicate = (appVersionString?.contains("Ecosia") ?? false) == true
2. Block Comments:
Use /* */ when commenting out existing Firefox code for easier readability and conflict resolution.
/* Ecosia: Update appversion predicate
let appVersionPredicate = (appVersionString?.contains("Firefox") ?? false) == true
*/
let appVersionPredicate = (appVersionString?.contains("Ecosia") ?? false) == true
This project uses custom Git hooks to enforce commit message formatting and other automated tasks.
To ensure that these hooks are installed correctly in your local .git/hooks directory, you need to run the provided setup script after cloning the repository.
- Navigate into the project directory
- Run the setup script to install the Git hooks:
./setup_hooks.sh
This script will copy all the necessary hooks (such as prepare-commit-msg) to your local .git/hooks directory, ensuring they are executable.
We use SwiftLint to enforce Swift style and conventions. Make sure to install it so that linting runs correctly when building.
brew install swiftlint- Install the latest Xcode developer tools from Apple.
- Install, Brew, Node, and a Python3 virtualenv for localization scripts:
brew update brew install node pip3 install virtualenv
- Clone the repository:
git clone https://github.com/ecosia/ios-browser
- Install Node.js dependencies, build user scripts and update content blocker:
cd ios-browser sh ./bootstrap.sh - Open
firefox-ios/Client.xcodeprojin Xcode. - Make sure to select the
Ecosiascheme in Xcode. - Select the destination device you want to build on.
- Run the app with
Cmd + Ror by pressing thebuild and runbutton.
- Xcode -> File -> Packages -> Reset Package Caches
- This will also require you to have a working github integration set up in xcode (see Settings > Accounts > Source Control Accounts)
User Scripts (JavaScript injected into the WKWebView) are compiled, concatenated, and minified using webpack. User Scripts to be aggregated are placed in the following directories:
/Client
|-- /Frontend
|-- /UserContent
|-- /UserScripts
|-- /AllFrames
| |-- /AtDocumentEnd
| |-- /AtDocumentStart
|-- /MainFrame
|-- /AtDocumentEnd
|-- /AtDocumentStart
This reduces the total possible number of User Scripts down to four. The compiled output from concatenating and minifying the User Scripts placed in these folders resides in /Client/Assets and are named accordingly:
AllFramesAtDocumentEnd.jsAllFramesAtDocumentStart.jsMainFrameAtDocumentEnd.jsMainFrameAtDocumentStart.js
To simplify the build process, these compiled files are checked-in to this repository. When adding or editing User Scripts, these files can be re-compiled with webpack manually. This requires Node.js to be installed, and all required npm packages can be installed by running npm install in the project's root directory. User Scripts can be compiled by running the following npm command in the root directory of the project:
npm run buildThe CURRENT_PROJECT_VERSION being set to 0 indicates that it is not being used for local testing. The outcoming build number is updated by the CI, matching the CI run number (e.g. 8023).
brew install fastlane
Our certs and profiles are managed centrally by fastlane match. Find the repo here
You might need to set up your Ruby stack:
sudo gem install bundler:2.3.4
bundle install
# you may need to link your ruby if you have a ruby from brew
echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc
# you may need to install a ruby <4
# https://formulae.brew.sh/formula/rbenv
brew install rbenv
echo 'eval "$(rbenv init -)"' >> ~/.zshrc
source ~/.zshrc
rbenv install 3.2.2
rbenv global 3.2.2
Run bundle exec fastlane match --readonly to add certs and profiles to your system. You can append -p "keychain password" to avoid keychain prompts during the process. The passphrase to decrypt the repo can be found in LastPass.
Command:
bundle exec fastlane match --readonlyExpected output:
[...]
[14:22:17]: Passphrase for Match storage: [get the password from the password manager]
To run the app on a new device, register it on the Apple Developer Portal and re-generate the provisioning profiles using fastlane match.
- Plug in your device and register it via the
register_devicesaction. You will be prompted for the device name and UDID:bundle exec fastlane run register_devices - Re-generate the provisioning profiles to include the new device by running
matchwith--force_for_new_devicesfor both development (for local development) and ad hoc (for Firebase releases):This flag makesbundle exec fastlane match development --force_for_new_devices bundle exec fastlane match adhoc --force_for_new_devices
matchcheck whether the device count has changed since the last run and automatically re-generate the provisioning profiles if necessary. See the fastlane match docs for more details. - Open Xcode, select the EcosiaBeta (or Ecosia) scheme, choose your device and run (
Cmd + R).
We are using Transifex for managing our translations.
curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash[https://www.transifex.com]
api_hostname = https://api.transifex.com
hostname = https://www.transifex.com
username = <vault secret>
password = <vault secret>
rest_hostname = https://rest.api.transifex.com
token = <vault secret>Pulling translation from the web
tx pull -fsTest and commit the new translations. There exists schemes for testing other languages in the simulator.
- Pull the source file
- Add the new strings to the English source file
Client/Ecosia/L10N/en.lproj/Ecosia.strings - Push it to Transifex
tx pull -fs
tx push -sWe do a rebrand of the Strings from Mozilla. Usually this step is only needed after an upgrade as we keep our changes in version control (as of opposite to Mozilla). Firefox already imports and versions their strings, which means they will have been added to our codebase once we rebase. After that, you can use the existing python script to update all strings on the folder containing the project file.
# brand all the files as they contain the term 'Firefox' a lot
python3 ecosify-strings.py firefox-iosFollow the instructions from our confluence page
Make sure that fastlane and transifex-cli is installed.
ℹ️ Updating the source file in the project and merging it into
mainwill automatically push it to Transifex as well since the Github integration is in place.
🔔 Make sure that an inflight version exists in AppStore Connect. If not, create one.
- Create a new branch off
mainand modify the English release notes here - Open a PR with the modified English release note text file against
mainbranch - Once approved, Squash and Merge the code to
main. (The transifex integration will pick up the push) - Transifex will create a PR and update it with the release notes in all available languages ⏳
- Squash and Merge the code to
mainvia a PR and a GitHubAction workflow will be triggered to upload the newly translated release notes
-
Make sure that all languages are translated in the transifex web interface and found their way to
main -
Verify the translations in the Transifex-made PR
-
Squash and Merge the PR
-
The GitHub Action Workflow
Upload release notes to AppStorewill take care of the upload
-
Push via the update translation via
deliverto the AppStorebundle exec fastlane deliver --app-version 8.2.0
- Run tests against
EcosiaBetascheme. With the standard CMD+U it picks the test plan (Xcode)
Check https://github.com/ecosia/mobile-acceptance-testing for details
We built our snapshot testing setup with SnapshotTestHelper to streamline UI checks. Here’s the gist:
-
Dynamic Setup: We create UI components on-the-fly for testing, ensuring they're set up with current data and state.
-
Config Flexibility: The tool handles multiple themes and devices, simulating how UI looks across different environments.
-
Localization: It supports testing in various languages by adjusting the app’s locale dynamically, crucial for ensuring the UI displays correctly in all supported languages.
-
Comparison: We capture snapshots of the UI and compare them to reference images to spot any unintended changes.
More details here