diff --git a/.experimenter.yaml b/.experimenter.yaml deleted file mode 100644 index 1c06b15e392e..000000000000 --- a/.experimenter.yaml +++ /dev/null @@ -1,236 +0,0 @@ ---- -address-autofill-feature: - description: This property defines the address card autofill feature - hasExposure: true - exposureDescription: "" - variables: - status: - type: boolean - description: "Variable description\n" -contextual-hint-feature: - description: This set holds all features pertaining to contextual hints. - hasExposure: true - exposureDescription: "" - variables: - features-enabled: - type: json - description: "This property provides a lookup table of whether specific contextual hints are enabled.\n" -credential-autofill-coordinator-refactor: - description: "This feature manages the roll out of the credential autofill coordinator as part of the coordinator refactor.\n" - hasExposure: true - exposureDescription: "" - variables: - enabled: - type: boolean - description: "Enables the feature\n" -credit-card-autofill: - description: This property defines the credit card autofill feature - hasExposure: true - exposureDescription: "" - variables: - credit-card-autofill-status: - type: boolean - description: "If true, we will allow user to use the credit autofill feature" -firefox-suggest-feature: - description: Configuration for the Firefox Suggest feature. - hasExposure: true - exposureDescription: "" - variables: - status: - type: boolean - description: "Whether the feature is enabled. When Firefox Suggest is enabled, Firefox will download and store new search suggestions in the background, and show additional Search settings to control which suggestions appear in the awesomebar. When Firefox Suggest is disabled, Firefox will not download new suggestions, and hide the additional Search settings.\n" -general-app-features: - description: The feature that contains feature flags for the entire application - hasExposure: true - exposureDescription: "" - variables: - report-site-issue: - type: json - description: This property defines whether or not the feature is enabled -homescreenFeature: - description: The homescreen that the user goes to when they press home or new tab. - hasExposure: true - exposureDescription: "" - variables: - pocket-sponsored-stories: - type: boolean - description: "This property defines whether pocket sponsored stories appear on the homepage.\n" - sections-enabled: - type: json - description: "This property provides a lookup table of whether or not the given section should be enabled. If the section is enabled, it should be toggleable in the settings screen, and on by default.\n" -library-coordinator-refactor: - description: "This feature is for managing the roll out of the library coordinator code as part of the changes on the navigation in the app\n" - hasExposure: true - exposureDescription: "" - variables: - enabled: - type: boolean - description: "Enables the feature\n" -messaging: - description: "The in-app messaging system\n" - hasExposure: true - exposureDescription: "" - variables: - actions: - type: json - description: A growable map of action URLs. - message-under-experiment: - type: string - description: "Deprecated. Please use \"experiment\": \"{experiment}\" instead." - messages: - type: json - description: "A growable collection of messages, where the Key is the message identifier and the value is its associated MessageData.\n" - on-control: - type: string - description: What should be displayed when a control message is selected. - enum: - - show-next-message - - show-none - styles: - type: json - description: "A map of styles to configure message appearance.\n" - triggers: - type: json - description: "A collection of out the box trigger expressions. Each entry maps to a valid JEXL expression.\n" -onboarding-framework-feature: - description: "The new onboarding framework feature that will allow onboarding to be experimentable through initial experiments.\n" - hasExposure: true - exposureDescription: "" - variables: - cards: - type: json - description: "The list of available cards for onboarding.\n" - conditions: - type: json - description: "A collection of out the box conditional expressions to be used in determining whether a card should show or not. Each entry maps to a valid JEXL expression.\n" - dismissable: - type: boolean - description: "Whether or not the entire onboarding is dismissable by pressing an X at the top right corner of the screen.\n" -private-browsing: - description: Private Browsing Mode - hasExposure: true - exposureDescription: "" - variables: - felt-privacy-enabled: - type: boolean - description: "If true, enable felt privacy related UI" -qr-code-coordinator-refactor: - description: "The feature for managing the roll out of the qrCode coordinator.\n" - hasExposure: true - exposureDescription: "" - variables: - enabled: - type: boolean - description: "Enables the feature\n" -redux-integration-feature: - description: "This feature is for managing the roll out of the Redux integration feature\n" - hasExposure: true - exposureDescription: "" - variables: - enabled: - type: boolean - description: "Enables the feature\n" -search: - description: "Configuring the functionality to do with search. This will be separated into smaller sub-features in later releases.\n" - hasExposure: true - exposureDescription: "" - variables: - awesome-bar: - type: json - description: Configuring the awesome bar. -search-term-groups-feature: - description: The feature that controls whether or not search term groups are enabled. - hasExposure: true - exposureDescription: "" - variables: - grouping-enabled: - type: json - description: This property provides a lookup table of whether or not the given grouping should be enabled. -share-extension-coordinator-refactor: - description: "This feature is for managing the roll out of the share extension coordinator as part of the changes to the navigation in the app\n" - hasExposure: true - exposureDescription: "" - variables: - enabled: - type: boolean - description: "Enables the feature\n" -share-sheet: - description: This feature define the redesign of the share sheet - hasExposure: true - exposureDescription: "" - variables: - move-actions: - type: boolean - description: If true copy and send to device are moved to share sheet - toolbar-changes: - type: boolean - description: If true share option is shown on the toolbar -shopping2023: - description: "The configuration setting for the status of the Fakespot feature\n" - hasExposure: true - exposureDescription: "" - variables: - config: - type: json - description: "A Map of website configurations\n" - product-recommendations: - type: boolean - description: "If true, recommended products feature is enabled\n to be shown to the user based on their preference.\n" - relay: - type: string - description: "Configurable relay URL for production environment\n" - status: - type: boolean - description: "Whether the Fakespot feature is enabled or disabled\n" -spotlight-search: - description: Add pages as items findable with Spotlight. - hasExposure: true - exposureDescription: "" - variables: - enabled: - type: boolean - description: "If this is true, then on each page load adds a new item to Spotlight." - icon-type: - type: string - description: "The icon that is displayed next to the item in the search results. If this is `null`, then no icon is displayed.\n" - keep-for-days: - type: int - description: "Number of days to keep the item before automatic deletion. If this is left `null`, then it is left to iOS's default.\n" - searchable-content: - type: string - description: "The text content that is made searchable. If this is `null` then no additional content is used, and only the title and URL will be used.\n" -tab-tray-refactor-feature: - description: "This feature is for managing the roll out of the Tab Tray refactor feature\n" - hasExposure: true - exposureDescription: "" - variables: - enabled: - type: boolean - description: "Enables the feature\n" -tabTrayFeature: - description: The tab tray screen that the user goes to when they open the tab tray. - hasExposure: true - exposureDescription: "" - variables: - sections-enabled: - type: json - description: "This property provides a lookup table of whether or not the given section should be enabled. If the section is enabled, it should be toggleable in the settings screen, and on by default." -wallpaper-feature: - description: This property defines the configuration for the wallpaper feature - hasExposure: true - exposureDescription: "" - variables: - configuration: - type: json - description: This property defines the configuration for the wallpaper feature - onboarding-sheet: - type: boolean - description: This property defines whether the wallpaper onboarding is shown or not -zoom-feature: - description: "The configuration for the status of the zoom feature\n" - hasExposure: true - exposureDescription: "" - variables: - status: - type: boolean - description: "Whether the page zoom feature is enabled or not\n" diff --git a/.gitignore b/.gitignore index eefa0647ab65..5ae85bb16c85 100644 --- a/.gitignore +++ b/.gitignore @@ -113,4 +113,8 @@ nimbus-fml/ *config.py # tmp files -/test-fixtures/tmp/* \ No newline at end of file +/test-fixtures/tmp/* + +# Nimbus build artifacts. +bin/nimbus-fml-configuration.local.sh +bin/nimbus-fml.sh diff --git a/Client.xcodeproj/project.pbxproj b/Client.xcodeproj/project.pbxproj index 0312e69674f6..9756f1d13aab 100644 --- a/Client.xcodeproj/project.pbxproj +++ b/Client.xcodeproj/project.pbxproj @@ -11953,14 +11953,14 @@ }; 5FA2232C27F6FA69005B3D87 /* Nimbus Feature Manifest Generator Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 12; files = ( ); inputFileListPaths = ( ); inputPaths = ( - "$(SRCROOT)/nimbus.fml.yaml", - "$(SRCROOT)/bin/nimbus-fml.sh", + "$(SOURCE_ROOT)/nimbus.fml.yaml", ); name = "Nimbus Feature Manifest Generator Script"; outputFileListPaths = ( @@ -11970,7 +11970,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ $ACTION != \"indexbuild\" ]; then\n bash $PWD/bin/nimbus-fml.sh --verbose\nfi\n"; + shellScript = "if [ $ACTION != \"indexbuild\" ]; then\n bash $SOURCE_ROOT/bin/nimbus-fml.sh --verbose\nfi\n"; }; 871F34442AD0A291006E34EE /* ShellScript */ = { isa = PBXShellScriptBuildPhase; diff --git a/bin/nimbus-fml-configuration.sh b/bin/nimbus-fml-configuration.sh index b2639431a6cd..d68d0938a141 100644 --- a/bin/nimbus-fml-configuration.sh +++ b/bin/nimbus-fml-configuration.sh @@ -36,7 +36,7 @@ fml_file=nimbus.fml.yaml ## Set the list of directories to scan for *.fml.yaml files. ## This can have individual files, but are relative to SOURCE_ROOT ## Default: $PROJECT -export MODULES=$fml_file +export MODULES="$PROJECT $fml_file" ## Set the directory where the generated files are placed. ## This is relative to SOURCE_ROOT. diff --git a/bin/nimbus-fml.sh b/bin/nimbus-fml.sh deleted file mode 100755 index 243363f4a0e6..000000000000 --- a/bin/nimbus-fml.sh +++ /dev/null @@ -1,268 +0,0 @@ -#!/bin/bash -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Nimbus Feature Manifest Language Generator -# -# For more infomration, check out https://experimenter.info/fml-spec -# -# This script generates Swift definitions for all the experimentable features supported by Nimbus. -# It generates Swift code to be included in the final build. -# -# To use it in a Swift project, follow these steps: -# 1. Import the `nimbus-fml.sh` script into your project. -# 2. Edit the `nimbus-fml-configuration.sh` file to suit your project. -# 3. Add a `.fml.yaml` feature manifest file. Check out https://experimenter.info/fml-spec for the spec. -# 4. Test the new file by running this file from SOURCE_ROOT. -# 5. Add a new "Run Script" build step and set the command to `bash $PWD/nimbus-fml.sh`. -# 6. Run the build. -# 7. Add the "FML.swift" file in the `Generated` folder to your project. -# 8. Add the same "FML.swift" from the `Generated` folder as Output Files of the newly created "Run Script" step. -# 9. Start using the generated feature code. - -DIRNAME=$(dirname "$0") - -# CMDNAME is used in the usage text below. -# shellcheck disable=SC2034 -CMDNAME=$(basename "$0") -USAGE=$(cat < Version or reference of nimbus-fml to use. Default is v${AS_VERSION}. - -F, --fresh Re-download the nimbus-fml binary. - -h, --help display this help message. -HEREDOC -) - -helptext() { - echo "$USAGE" -} - -if [ -z "$CONFIGURATION" ] ; then - echo "Error: No \$CONFIGURATION defined." - echo "Execute this script as a build step in Xcode." - exit 2 -fi - -if [ -z "$SOURCE_ROOT" ] ; then - echo "Error: No \$SOURCE_ROOT defined." - echo "Execute this script as a build step in Xcode." - exit 2 -fi - -if [ -z "$PROJECT" ]; then - echo "Error: No \$PROJECT defined." - echo "Execute this script as a build step in Xcode." - exit 2 -fi - -# We can derive the version we need by looking at the project file. -number_string=$(grep -A 3 $'https://github.com/mozilla/rust-components-swift' "$SOURCE_ROOT/$PROJECT.xcodeproj/project.pbxproj" | grep -E -o "\d+\.\d+\.\d+") - -if [ -z "$number_string" ]; then - # If there is no rust-components then perhaps we're building with a local versions of rust_components, using rust_components_local.sh . - # We try to resolve that, and find the version from the Package.swift file in that local directory. - # https://github.com/mozilla-mobile/firefox-ios/issues/12243 - rust_components_path=$(grep -A 3 $'XCRemoteSwiftPackageReference "rust-components-swift"' "$SOURCE_ROOT/$PROJECT.xcodeproj/project.pbxproj" | grep 'repositoryURL = "file://' | grep -o -E '/\w[^"]+') - number_string=$(grep 'let version =' "$rust_components_path/Package.swift" | grep -E -o "\d+\.0.\d+") - - if [ -z "$number_string" ]; then - echo "Error: No https://github.com/mozilla/rust-components-swift package was detected." - echo "The package must be added as a project dependency." - exit 2 - fi -fi - -AS_VERSION=$(echo "$number_string" | sed 's/\.0\./\./g') # rust-component-swift tags have a middle `.0.` to force it to align with spm. We remove it -FRESHEN_FML= -NIMBUS_DIR="$SOURCE_ROOT/build/nimbus" - -export CACHE_DIR="$NIMBUS_DIR/fml-cache" -export APP_FML_FILE="$PROJECT/nimbus.fml.yaml" -export GENERATED_SRC_DIR= -export MOZ_APPSERVICES_MODULE=MozillaAppServices -export MODULES=$PROJECT -export EXPERIMENTER_MANIFEST=".experimenter.yaml" - -# shellcheck disable=SC1091 -source "$DIRNAME/nimbus-fml-configuration.sh" - -local_config="$DIRNAME/nimbus-fml-configuration.local.sh" -if [ -f "$local_config" ] ; then - # shellcheck disable=SC1090 - source "$local_config" -fi - -while (( "$#" )); do - case "$1" in - -o|--output) - GENERATED_SRC_DIR=$2 - shift 2 - ;; - -h|--help) - helptext - exit 0 - ;; - -a|--use-fml-version) - AS_VERSION=$2 - FRESHEN_FML="true" - shift 2 - ;; - -F|--fresh) - FRESHEN_FML="true" - shift 2 - ;; - --verbose) - set -x - shift 1 - ;; - --) # end argument parsing - shift - break - ;; - --*=|-*) # unsupported flags - echo "Error: Unsupported flag $1" >&2 - exit 1 - ;; - *) # preserve positional arguments - APP_FML_FILE=$1 - shift - ;; - esac -done - -if [ -z "$APP_FML_FILE" ]; then - if [ -z "$SCRIPT_INPUT_FILE_COUNT" ] || [ "$SCRIPT_INPUT_FILE_COUNT" -eq 0 ]; then - echo "Error: No input files provided for the Nimbus Feature Manifest." - exit 2 - fi - APP_FML_FILE=$SCRIPT_INPUT_FILE_0 -fi - -if [ -n "$MOZ_APPSERVICES_LOCAL" ] ; then - # If we've specified where app-services lives, perhaps we can run from a local copy. - LOCAL_FML_DIR="$MOZ_APPSERVICES_LOCAL/components/support/nimbus-fml" - export BINARY_PATH="$HOME/.cargo/bin/cargo run --manifest-path $LOCAL_FML_DIR/Cargo.toml --" -else - # Otherwise, we should download a pre-built copy - AS_DOWNLOAD_URL="https://archive.mozilla.org/pub/app-services/releases/$AS_VERSION" - CHECKSUM_URL="$AS_DOWNLOAD_URL/nimbus-fml.sha256" - FML_URL="$AS_DOWNLOAD_URL/nimbus-fml.zip" - RELEASE_STATUS_CODE=$(curl -L --write-out '%{http_code}' --silent --output /dev/null "$CHECKSUM_URL") - if [ $RELEASE_STATUS_CODE != 200 ]; then - AS_DOWNLOAD_URL="https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.application-services.v2.nimbus-fml.$AS_VERSION/artifacts/public%2Fbuild%2F" - CHECKSUM_URL="${AS_DOWNLOAD_URL}nimbus-fml.sha256" - FML_URL="${AS_DOWNLOAD_URL}nimbus-fml.zip" - fi - FML_DIR="$NIMBUS_DIR/bin" - export BINARY_PATH="$FML_DIR/nimbus-fml" - # Check whether the cached copy is still the right one to use. - if [[ -f $FML_DIR/nimbus-fml.sha256 ]]; then - echo "Checking if we need to redownload the FML" - NEW_CHECKSUM=$(curl -L "$CHECKSUM_URL") - OLD_CHECKSUM=$(cat "$FML_DIR/nimbus-fml.sha256") - if [ ! "$OLD_CHECKSUM" == "$NEW_CHECKSUM" ]; then - FRESHEN_FML="true" - echo "The checksums don't match, redownloading the new FML" - fi - fi - - if [ -n "$FRESHEN_FML" ]; then - rm -Rf "$FML_DIR" - fi - mkdir -p "$FML_DIR" - if [[ ! -f "$FML_DIR/nimbus-fml.zip" ]] ; then - # We now download the nimbus-fml from the github release - curl -L "$FML_URL" --output "$FML_DIR/nimbus-fml.zip" - # We also download the checksum - curl -L "$CHECKSUM_URL" --output "$FML_DIR/nimbus-fml.sha256" - pushd "${FML_DIR}" - shasum --check nimbus-fml.sha256 - popd - fi - - ## We definitely have a zip file on disk, but we might already have done the work of unzipping it. - if [[ ! -f "$BINARY_PATH" ]] ; then - ## So we've looked and there's no executable file of that name - ## Now work out what arch version of the executable we want. - ARCH=$(uname -m) - if [[ "$ARCH" == 'x86_64' ]] - then - EXE_ARCH=x86_64-apple-darwin - elif [[ "$ARCH" == 'arm64' ]] - then - EXE_ARCH=aarch64-apple-darwin - else - echo "Error: Unsupported architecture. This script can only run on Mac devices running x86_64 or arm64" - exit 2 - fi - # -o overwrites a file (if the file existed but isn't executable) - # -j junks the path, so we don't have to have $EXE_ARCH/release/ in our directory - # -d outputs to the directory of our choice. - unzip -o -j "$FML_DIR/nimbus-fml.zip" $EXE_ARCH/release/nimbus-fml -d "$FML_DIR" - fi -fi - -echo "SOURCE_ROOT=$SOURCE_ROOT" -pushd "${SOURCE_ROOT}" > /dev/null -# We're going to assemble the repo args from the repo files that -repo_args= -for repo_file in $REPO_FILES ; do - repo_args="$repo_args --repo-file $repo_file" -done - -# Now generate the YAML that the `experimenter` server will use to keep up to date. -# This file, `.experimenter.yaml` **must** be checked into source control, and kept up-to-date. -# Experimenter will download it regularly/nightly. -CMD="$BINARY_PATH generate-experimenter $repo_args --channel $CHANNEL --cache-dir $CACHE_DIR $APP_FML_FILE $EXPERIMENTER_MANIFEST" -display=${CMD//"$SOURCE_ROOT"/\$SOURCE_ROOT} -echo "$display" -$CMD -if [ $? != 0 ] ; then - exit 1 -fi - -# We'll generate the command, and output some nice copy/pastable version of the command to the Build console… -for module in $MODULES ; do - output_dir="" - input_pattern="$module" - if [ -z "$GENERATED_SRC_DIR" ] ; then - output_dir="${module}/Generated" - else - output_dir="$GENERATED_SRC_DIR" - fi - if [ ! -f "$input_pattern" ] ; then - mkdir -p "$output_dir" - else - output_dir="$PROJECT/Generated" - fi - CMD="$BINARY_PATH generate $repo_args --channel $CHANNEL --language swift --cache-dir $CACHE_DIR $input_pattern $output_dir" - # …truncating the absolute paths into something easier to read. - display=${CMD//"$SOURCE_ROOT"/\$SOURCE_ROOT} - echo "$display" - $CMD - if [ $? != 0 ] ; then - exit 1 - fi -done -popd > /dev/null diff --git a/bootstrap.sh b/bootstrap.sh index 8dd621762f12..89a9633114e3 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -37,5 +37,9 @@ if [ "$1" == "--importLocales" ]; then exit 0 fi +# Download the nimbus-fml.sh script from application-services. +NIMBUS_FML_FILE=./nimbus.fml.yaml +curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/mozilla/application-services/main/components/nimbus/ios/scripts/bootstrap.sh | bash -s -- $NIMBUS_FML_FILE + # Run and update content blocker ./content_blocker_update.sh diff --git a/nimbus-features/messagingFeature.yaml b/nimbus-features/messagingFeature.yaml index cd70cd8a3b1f..6d67f38d0980 100644 --- a/nimbus-features/messagingFeature.yaml +++ b/nimbus-features/messagingFeature.yaml @@ -2,6 +2,23 @@ features: messaging: description: > The in-app messaging system + meta-bug: ~ + documentation: + - name: User documentation + url: https://experimenter.info/messaging/mobile-messaging + contacts: + # Nimbus team + - jhugman@mozilla.com + - brennie@mozilla.com + # iOS team + - gbuciu@mozilla.com + - wteichmann@mozilla.com + events: + - https://dictionary.telemetry.mozilla.org/apps/firefox_ios/metrics/messaging_shown + - https://dictionary.telemetry.mozilla.org/apps/firefox_ios/metrics/messaging_clicked + - https://dictionary.telemetry.mozilla.org/apps/firefox_ios/metrics/messaging_expired + - https://dictionary.telemetry.mozilla.org/apps/firefox_ios/metrics/messaging_dismissed + - https://dictionary.telemetry.mozilla.org/apps/firefox_ios/metrics/messaging_malformed # Allow the feature to be enrolled in more than one experiment at the same time. allow-coenrollment: true