diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml
new file mode 100644
index 000000000..07eff39ab
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml
@@ -0,0 +1,88 @@
+name: 🐞 Bug
+description: File a bug/issue
+title: "[BUG]
"
+labels: ["bug", "needs-triage"]
+body:
+- type: checkboxes
+ attributes:
+ label: Is there an existing issue for this?
+ description: Please search to see if an issue already exists for the bug you encountered.
+ options:
+ - label: I have searched the existing issues
+ required: true
+- type: textarea
+ attributes:
+ label: SDK Version
+ description: Version of the SDK in use?
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: iOS Version
+ description: Version of iOS in use?
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Current Behavior
+ description: A concise description of what you're experiencing.
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Expected Behavior
+ description: A concise description of what you expected to happen.
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Steps To Reproduce
+ description: Steps to reproduce the behavior.
+ placeholder: |
+ 1. In this environment...
+ 1. With this config...
+ 1. Run '...'
+ 1. See error...
+ validations:
+ required: true
+- type: textarea
+ attributes:
+ label: Link
+ description: Link to code demonstrating the problem.
+ validations:
+ required: false
+- type: textarea
+ attributes:
+ label: Logs / Stacktraces
+ description: Logs/stack traces related to the problem (⚠️do not include sensitive information).
+ validations:
+ required: false
+- type: dropdown
+ attributes:
+ label: Severity
+ description: What is the severity of the problem?
+ multiple: true
+ options:
+ - Blocking development
+ - Affecting users
+ - Minor issue
+ validations:
+ required: false
+- type: textarea
+ attributes:
+ label: Workaround/Solution
+ description: Do you have any workaround or solution in mind for the problem?
+ validations:
+ required: false
+- type: textarea
+ attributes:
+ label: "Recent Change"
+ description: Has this issue started happening after an update or experiment change?
+ validations:
+ required: false
+- type: textarea
+ attributes:
+ label: Conflicts
+ description: Are there other libraries/dependencies potentially in conflict?
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/ENHANCEMENT.yml b/.github/ISSUE_TEMPLATE/ENHANCEMENT.yml
new file mode 100644
index 000000000..79c53247b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/ENHANCEMENT.yml
@@ -0,0 +1,45 @@
+name: ✨Enhancement
+description: Create a new ticket for a Enhancement/Tech-initiative for the benefit of the SDK which would be considered for a minor version update.
+title: "[ENHANCEMENT] "
+labels: ["enhancement"]
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: "Description"
+ description: Briefly describe the enhancement in a few sentences.
+ placeholder: Short description...
+ validations:
+ required: true
+ - type: textarea
+ id: benefits
+ attributes:
+ label: "Benefits"
+ description: How would the enhancement benefit to your product or usage?
+ placeholder: Benefits...
+ validations:
+ required: true
+ - type: textarea
+ id: detail
+ attributes:
+ label: "Detail"
+ description: How would you like the enhancement to work? Please provide as much detail as possible
+ placeholder: Detailed description...
+ validations:
+ required: false
+ - type: textarea
+ id: examples
+ attributes:
+ label: "Examples"
+ description: Are there any examples of this enhancement in other products/services? If so, please provide links or references.
+ placeholder: Links/References...
+ validations:
+ required: false
+ - type: textarea
+ id: risks
+ attributes:
+ label: "Risks/Downsides"
+ description: Do you think this enhancement could have any potential downsides or risks?
+ placeholder: Risks/Downsides...
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.md
new file mode 100644
index 000000000..a061f3356
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.md
@@ -0,0 +1,4 @@
+
+## Feedback requesting a new feature can be shared [here.](https://feedback.optimizely.com/)
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..d28ef3dd4
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+ - name: 💡Feature Requests
+ url: https://feedback.optimizely.com/
+ about: Feedback requesting a new feature can be shared here.
\ No newline at end of file
diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml
new file mode 100644
index 000000000..181fcbf4e
--- /dev/null
+++ b/.github/workflows/integration_tests.yml
@@ -0,0 +1,50 @@
+name: Reusable action of Integration tests
+
+on:
+ workflow_call:
+ secrets:
+ CI_USER_TOKEN:
+ required: true
+ TRAVIS_COM_TOKEN:
+ required: true
+
+jobs:
+ integration_tests:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ # You should create a personal access token and store it in your repository
+ token: ${{ secrets.CI_USER_TOKEN }}
+ repository: 'optimizely/travisci-tools'
+ path: 'home/runner/travisci-tools'
+ ref: 'master'
+ - name: set SDK Branch if PR
+ if: ${{ github.event_name == 'pull_request' }}
+ run: |
+ echo "SDK_BRANCH=${{ github.head_ref }}" >> $GITHUB_ENV
+ - name: set SDK Branch if not pull request
+ if: ${{ github.event_name != 'pull_request' }}
+ run: |
+ echo "SDK_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
+ echo "TRAVIS_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
+ - name: Trigger build
+ env:
+ SDK: swift
+ TESTAPP_TAG: master
+ BUILD_NUMBER: ${{ github.run_id }}
+ TESTAPP_BRANCH: master
+ GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }}
+ EVENT_TYPE: ${{ github.event_name }}
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ #REPO_SLUG: ${{ github.repository }}
+ PULL_REQUEST_SLUG: ${{ github.repository }}
+ UPSTREAM_REPO: ${{ github.repository }}
+ PULL_REQUEST_SHA: ${{ github.event.pull_request.head.sha }}
+ PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+ UPSTREAM_SHA: ${{ github.sha }}
+ TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
+ EVENT_MESSAGE: ${{ github.event.message }}
+ HOME: 'home/runner'
+ run: |
+ home/runner/travisci-tools/trigger-script-with-status-update.sh
diff --git a/.github/workflows/lint_markdown.yml b/.github/workflows/lint_markdown.yml
new file mode 100644
index 000000000..e3e903143
--- /dev/null
+++ b/.github/workflows/lint_markdown.yml
@@ -0,0 +1,19 @@
+name: Reusable action of linting markdown files
+
+on: [workflow_call]
+
+jobs:
+ lint_markdown:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '2.6'
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
+ - name: Install gem and Run tests
+ run: |
+ cd ../../
+ gem install awesome_bot
+ find . -type f -name '*.md' -exec awesome_bot {} \;
diff --git a/.github/workflows/source_clear_cron.yml b/.github/workflows/source_clear_cron.yml
new file mode 100644
index 000000000..ca1a715b8
--- /dev/null
+++ b/.github/workflows/source_clear_cron.yml
@@ -0,0 +1,20 @@
+name: Source clear
+
+on:
+ push:
+ branches: [ master ]
+ schedule:
+ # Runs "weekly"
+ - cron: '0 0 * * 0'
+
+jobs:
+ source_clear:
+ runs-on: macos-12
+ steps:
+ - uses: actions/checkout@v3
+ - name: Source clear scan
+ env:
+ SRCCLR_API_TOKEN: ${{ secrets.SRCCLR_API_TOKEN }}
+ run: |
+ gem install cocoapods -v '1.9.3'
+ curl -sSL https://download.sourceclear.com/ci.sh | bash -s - scan
diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml
new file mode 100644
index 000000000..086a9832c
--- /dev/null
+++ b/.github/workflows/swift.yml
@@ -0,0 +1,116 @@
+name: Swift
+
+on:
+ push:
+ branches: [ 'master' ]
+ pull_request:
+ branches: [ '*' ]
+ workflow_dispatch:
+ inputs:
+ PREP:
+ required: false
+ type: boolean
+ description: prepare to release
+ RELEASE:
+ required: false
+ type: boolean
+ description: release
+
+env:
+ VERSION: 3.10.5
+
+jobs:
+
+ lint_markdown_files:
+ uses: optimizely/swift-sdk/.github/workflows/lint_markdown.yml@master
+
+ integration_tests:
+ if: "${{ github.event.inputs.PREP == '' && github.event.inputs.RELEASE == '' }}"
+ uses: optimizely/swift-sdk/.github/workflows/integration_tests.yml@master
+ secrets:
+ CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
+ TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
+
+ lint:
+ runs-on: macos-12
+ steps:
+ - uses: actions/checkout@v3
+ - uses: maxim-lobanov/setup-xcode@v1
+ with:
+ xcode-version: 14.1.0
+ - env:
+ SRCCLR_API_TOKEN: ${{ secrets.SRCCLR_API_TOKEN }}
+ run: |
+ gem install cocoapods -v '1.9.3'
+ pod spec lint --quick
+ curl -sSL https://download.sourceclear.com/ci.sh | bash
+
+ unittests:
+ if: "${{ github.event.inputs.PREP == '' && github.event.inputs.RELEASE == '' }}"
+ uses: optimizely/swift-sdk/.github/workflows/unit_tests.yml@master
+
+ prepare_for_release:
+ runs-on: macos-12
+ if: "${{ github.event.inputs.PREP == 'true' && github.event_name == 'workflow_dispatch' }}"
+ steps:
+ - uses: actions/checkout@v3
+ - uses: maxim-lobanov/setup-xcode@v1
+ with:
+ xcode-version: 14.1.0
+ - name: Install Homebrew
+ run: |
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+
+ - name: Install Hub
+ run: |
+ brew install hub
+
+ - name: Verify Hub Installation
+ run: |
+ hub version
+ - id: prepare_for_release
+ name: Prepare for release
+ env:
+ HOME: 'home/runner'
+ REPO_SLUG: ${{ github.repository }}
+ BRANCH: ${{ github.ref_name }}
+ GITHUB_USER: optibot
+ GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }}
+ COCOAPODS_VERSION: '1.12.1'
+ run: |
+ gem install cocoapods -v $COCOAPODS_VERSION
+ Scripts/run_prep.sh
+ - name: Check prepare for release failure
+ if: steps.prepare_for_release.conclusion == 'failure'
+ run: cat /tmp/build.out
+
+ release:
+ if: "${{github.event.inputs.RELEASE == 'true' && github.event_name == 'workflow_dispatch' }}"
+ runs-on: macos-12
+ steps:
+ - uses: actions/checkout@v3
+ - uses: maxim-lobanov/setup-xcode@v1
+ with:
+ xcode-version: 14.1.0
+ - name: Install Homebrew
+ run: |
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+
+ - name: Install Hub
+ run: |
+ brew install hub
+
+ - name: Verify Hub Installation
+ run: |
+ hub version
+ - name: Push to cocoapods.org
+ env:
+ HOME: 'home/runner'
+ REPO_SLUG: ${{ github.repository }}
+ BRANCH: ${{ github.ref_name }}
+ GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }}
+ COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
+ COCOAPODS_VERSION: '1.12.1'
+ run: |
+ gem install cocoapods -v $COCOAPODS_VERSION
+ Scripts/run_release.sh
diff --git a/.github/workflows/ticket_reference_check.yml b/.github/workflows/ticket_reference_check.yml
new file mode 100644
index 000000000..b7d52780f
--- /dev/null
+++ b/.github/workflows/ticket_reference_check.yml
@@ -0,0 +1,16 @@
+name: Jira ticket reference check
+
+on:
+ pull_request:
+ types: [opened, edited, reopened, synchronize]
+
+jobs:
+
+ jira_ticket_reference_check:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check for Jira ticket reference
+ uses: optimizely/github-action-ticket-reference-checker-public@master
+ with:
+ bodyRegex: 'FSSDK-(?\d+)'
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
new file mode 100644
index 000000000..3fd6ddfdd
--- /dev/null
+++ b/.github/workflows/unit_tests.yml
@@ -0,0 +1,113 @@
+name: Reusable action of Unit tests
+
+on: [workflow_call]
+
+env:
+ COVERAGE_DIR: ./COVERAGE
+
+jobs:
+ unittests:
+ runs-on: macos-12
+ strategy:
+ fail-fast: false
+ matrix:
+ # github actions are very poor in supporting iOS simulators:
+ # - multiple Xcode versions are pre installed (not all versions and they change supported xcode versions frequently)
+ # - each xcode version has own simulator os versions.
+ # - so to run tests with the target simulator, we have to find a proper xcode version pre-installed and support the target simulator os version.
+ # also, the xcode version (simulator_xcode_version) and simulator os versions (os) are moving target. We have to change these time to time.
+ # - see "https://github.com/actions/runner-images/blob/main/images/macos/macos-11-Readme.md" for installed macOS, xcode and simulator versions.
+ include:
+ - os: 16.1
+ device: "iPhone 12"
+ scheme: "OptimizelySwiftSDK-iOS"
+ test_sdk: "iphonesimulator"
+ platform: "iOS Simulator"
+ os_type: "iOS"
+ simulator_xcode_version: 14.1
+ - os: 15.5
+ device: "iPhone 12"
+ scheme: "OptimizelySwiftSDK-iOS"
+ test_sdk: "iphonesimulator"
+ platform: "iOS Simulator"
+ os_type: "iOS"
+ simulator_xcode_version: 13.4.1
+ - os: 15.5
+ # good to have tests with older OS versions, but it looks like this is min OS+xcode versions supported by github actions
+ device: "iPad Air (4th generation)"
+ scheme: "OptimizelySwiftSDK-iOS"
+ test_sdk: "iphonesimulator"
+ platform: "iOS Simulator"
+ os_type: "iOS"
+ simulator_xcode_version: 13.4.1
+ - os: 16.1
+ device: "Apple TV"
+ scheme: "OptimizelySwiftSDK-tvOS"
+ test_sdk: "appletvsimulator"
+ platform: "tvOS Simulator"
+ os_type: "tvOS"
+ simulator_xcode_version: 14.1
+ steps:
+ - uses: actions/checkout@v3
+ - uses: maxim-lobanov/setup-xcode@v1
+ with:
+ # macos version and supported simulator_xcode_versions are all related to this xcode_version, so be careful when you upgrade this.
+ xcode-version: 14.1
+ - name: set SDK Branch if PR
+ if: ${{ github.event_name == 'pull_request' }}
+ run: |
+ echo "BRANCH=${{ github.base_ref }}" >> $GITHUB_ENV
+ - name: set SDK Branch if not pull request
+ if: ${{ github.event_name != 'pull_request' }}
+ run: |
+ echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
+ - id: unit_tests
+ env:
+ SCHEME: ${{ matrix.scheme }}
+ TEST_SDK: ${{ matrix.test_sdk }}
+ PLATFORM: ${{ matrix.platform }}
+ OS: ${{ matrix.os }}
+ OS_TYPE: ${{ matrix.os_type }}
+ SIMULATOR_XCODE_VERSION: ${{ matrix.simulator_xcode_version }}
+ NAME: ${{ matrix.device }}
+ run: |
+ gem install coveralls-lcov
+ gem install cocoapods -v '1.11.3'
+ pod repo update
+ pod install
+ HOMEBREW_NO_INSTALL_CLEANUP=true brew update && brew install jq
+
+ # github actions are very poor in supporting iOS simulators:
+ # - to find pre-installed xcode version, run this:
+ ##ls /Applications/
+ # - to find supported simulator os versions, run this (and find simulator with non-error "datapath")
+ ##xcrun simctl list --json devices
+
+ # switch to the target xcode version
+ sudo xcode-select -switch /Applications/Xcode_$SIMULATOR_XCODE_VERSION.app
+
+ Scripts/prepare_simulator.sh
+ Scripts/run_unit_tests.sh
+ - name: Check on failures (Archive Test Results)
+ uses: actions/upload-artifact@v3
+ if: steps.unit_tests.outcome != 'success'
+ with:
+ name: build-logs-${{ matrix.device }}-${{ matrix.os }}
+ path: build/Logs
+ - # - report coverage for PR and iPhone 11 only (avoid redundant ones)
+ # - use Xcode12.4+ (older Xcode reports a wrong number)
+ name: Check on success
+ id: coveralls
+ if: ${{ steps.unit_tests.outcome == 'success' && env.BRANCH == 'master' && env.PLATFORM == 'iOS Simulator' && env.NAME == 'iPhone 11' }}
+ env:
+ PLATFORM: ${{ matrix.platform }}
+ NAME: ${{ matrix.device }}
+ run: |
+ Scripts/prepare_coveralls_report.sh
+ sleep 5
+ - name: Upload coveralls report
+ if: steps.coveralls.outcome == 'success'
+ uses: coverallsapp/github-action@master
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ path-to-lcov: ./xccov2lcov/lcov.info
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 83c87e49a..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,136 +0,0 @@
-language: minimal
-os: linux
-
-# Integration tests need to run first to reset the PR build status to pending
-stages:
- - name: 'Source Clear'
- - name: 'Lint markdown files'
- - name: 'Trigger Integration Tests'
- if: env(RUN_COMPAT_SUITE) = true and env(PREP) IS NOT present and env(RELEASE) IS NOT present
- - name: 'Lint'
- - name: 'Unit Tests'
- if: env(PREP) IS NOT present and env(RELEASE) IS NOT present
- - name: 'Prepare for release'
- if: env(PREP) = true and type = api
- - name: 'Release'
- if: env(RELEASE) = true and type = api
-
-jobs:
- include:
- - stage: 'Lint markdown files'
- os: linux
- language: generic
- install: gem install awesome_bot
- script:
- - find . -type f -name '*.md' -exec awesome_bot {} \;
- notifications:
- email: false
-
- - stage: 'Trigger Integration Tests'
- language: minimal
- os: linux
- env:
- - SDK=swift
- - BUILD_NUMBER=${TRAVIS_JOB_NUMBER/.}
- - TESTAPP_TAG=master
- - SDK_BRANCH=$TRAVIS_PULL_REQUEST_BRANCH
-
- cache: false
- install:
- - mkdir $HOME/travisci-tools && pushd $HOME/travisci-tools && git init && git pull https://$CI_USER_TOKEN@github.com/optimizely/travisci-tools.git && popd
- script:
- - $HOME/travisci-tools/trigger-script-with-status-update.sh
-
- - stage: 'Lint'
- language: swift
- os: osx
- osx_image: xcode12.4
- install:
- - gem install cocoapods -v '1.9.3'
- script:
- - pod spec lint --quick
- after_script:
- - curl -sSL https://download.sourceclear.com/ci.sh | bash
-
- - stage: 'Source Clear'
- if: type = cron
- addons:
- srcclr: true
- before_install: skip
- install: skip
- before_script: skip
- script: skip
- after_success: skip
-
- - &unittests
- stage: 'Unit Tests'
- language: swift
- os: osx
- osx_image: xcode12.4
- branches:
- only:
- - master
- env: COVERAGE_DIR=./COVERAGE SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=14.4 NAME='iPhone 11'
- name: PLATFORM='iOS Simulator' OS=14.4 NAME='iPhone 11'
- install:
- #- gem install slather --no-document --quiet
- - gem install coveralls-lcov
- #
- - gem install cocoapods -v '1.9.3'
- - pod repo update
- - pod install
- # install jq without cleaning up
- - HOMEBREW_NO_INSTALL_CLEANUP=true brew update && brew install jq
- # preload simulator
- - Scripts/start_simulator.sh
- script:
- - Scripts/run_unit_tests.sh
- after_success:
- - Scripts/upload_coveralls.sh
- - sleep 5 # https://github.com/travis-ci/travis-ci/issues/4725
- after_failure:
- # install travis artifacts uploader
- - sudo curl -sL https://raw.githubusercontent.com/travis-ci/artifacts/master/install | bash
- - artifacts upload --target-paths "/${TRAVIS_REPO_SLUG}/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/xcodebuild_logs" $(find /Users/travis/Library/Developer/Xcode/ -name *.xcresult -o -name *.log)
- - artifacts upload --target-paths "/${TRAVIS_REPO_SLUG}/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/buildoutput" "$TRAVIS_BUILD_DIR/buildoutput"
- - <<: *unittests
- env: COVERAGE_DIR=./COVERAGE SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=13.3 NAME='iPhone 8'
- name: PLATFORM='iOS Simulator' OS=13.3 NAME='iPhone 8'
- - <<: *unittests
- env: COVERAGE_DIR=./COVERAGE SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=11.4 NAME='iPad Air'
- name: PLATFORM='iOS Simulator' OS=11.4 NAME='iPad Air'
- - <<: *unittests
- env: COVERAGE_DIR=./COVERAGE SCHEME=OptimizelySwiftSDK-tvOS TEST_SDK=appletvsimulator PLATFORM='tvOS Simulator' OS=12.1 NAME='Apple TV 4K'
- name: PLATFORM='tvOS Simulator' OS=12.1 NAME='Apple TV 4K'
-
- - stage: 'Prepare for release'
- name: Prepare for release
- language: swift
- os: osx
- osx_image: xcode12.4
- env:
- - VERSION=3.10.1
- install:
- # install hub
- - wget https://github.com/github/hub/releases/download/v2.11.2/hub-darwin-amd64-2.11.2.tgz -O /tmp/hub-darwin-amd64-2.11.2.tgz && tar -xvf /tmp/hub-darwin-amd64-2.11.2.tgz -C /usr/local/opt && ln -s /usr/local/opt/hub-darwin-amd64-2.11.2/bin/hub /usr/local/bin/hub
- # upgrade cocoapods
- - gem install cocoapods -v '1.9.3'
- script:
- - Scripts/run_prep.sh
- after_failure:
- - cat /tmp/build.out
-
- - stage: 'Release'
- name: Push to cocoapods.org
- language: minimal
- os: osx
- osx_image: xcode12.4
- env:
- - VERSION=3.10.1
- install:
- # install hub
- - wget https://github.com/github/hub/releases/download/v2.11.2/hub-darwin-amd64-2.11.2.tgz -O /tmp/hub-darwin-amd64-2.11.2.tgz && tar -xvf /tmp/hub-darwin-amd64-2.11.2.tgz -C /usr/local/opt && ln -s /usr/local/opt/hub-darwin-amd64-2.11.2/bin/hub /usr/local/bin/hub
- # upgrade cocoapods
- - gem install cocoapods -v '1.9.3'
- script:
- - Scripts/run_release.sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9a0417dca..f6038dd22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,33 @@
# Optimizely Swift SDK Changelog
+## 3.10.5
+Jan 19, 2024
+
+### Bug Fixes
+* Value for required reason API fixed at privacy manifest file. ([#541](https://github.com/optimizely/swift-sdk/pull/541))
+* Add coccoapods support to bundle privacy manifest file. ([#542](https://github.com/optimizely/swift-sdk/pull/542))
+* Add SPM support to bundle privacy manifest file. ([#544](https://github.com/optimizely/swift-sdk/pull/544))
+
+## 3.10.4
+December 8, 2023
+
+### Enhancement
+* Add privacy manifest file ([#522](https://github.com/optimizely/swift-sdk/pull/522/)).
+
+## 3.10.3
+December 7, 2023
+
+### Bug Fixes
+* Remove redundant post request body in upload task. ([#521](https://github.com/optimizely/swift-sdk/pull/521/)).
+
+### Enhancement
+* Handle duplicate keys in experiment ([#523](https://github.com/optimizely/swift-sdk/pull/523/)).
+
+## 3.10.2
+March 14, 2023
+
+* We updated our README.md and other non-functional code to reflect that this SDK supports both Optimizely Feature Experimentation and Optimizely Full Stack. ([#479](https://github.com/optimizely/swift-sdk/pull/479)).
+
## 3.10.1
April 8, 2022
diff --git a/OptimizelySwiftSDK.podspec b/OptimizelySwiftSDK.podspec
index da440c498..e0b08a57b 100644
--- a/OptimizelySwiftSDK.podspec
+++ b/OptimizelySwiftSDK.podspec
@@ -1,9 +1,9 @@
Pod::Spec.new do |s|
s.name = "OptimizelySwiftSDK"
s.module_name = "Optimizely"
- s.version = "3.10.1"
+ s.version = "3.10.5"
s.summary = "Optimizely experiment framework for iOS/tvOS/watchOS"
- s.homepage = "https://docs.developers.optimizely.com/full-stack/docs"
+ s.homepage = "https://docs.developers.optimizely.com/experimentation/v4.0.0-full-stack/docs"
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" }
s.author = { "Optimizely" => "support@optimizely.com" }
s.ios.deployment_target = "10.0"
@@ -15,6 +15,7 @@ Pod::Spec.new do |s|
:tag => "v"+s.version.to_s
}
s.source_files = "Sources/**/*.swift"
+ s.resource_bundles = { 'OptimizelySwiftSDK' => ['Sources/Supporting Files/PrivacyInfo.xcprivacy'] }
s.swift_version = ["5.0", "5.1"]
s.framework = "Foundation"
s.requires_arc = true
diff --git a/OptimizelySwiftSDK.xcodeproj/project.pbxproj b/OptimizelySwiftSDK.xcodeproj/project.pbxproj
index ceb2e999a..3267c2e1d 100644
--- a/OptimizelySwiftSDK.xcodeproj/project.pbxproj
+++ b/OptimizelySwiftSDK.xcodeproj/project.pbxproj
@@ -1739,6 +1739,10 @@
84E7ABC827D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E7ABBA27D2A1F100447CAE /* ThreadSafeLogger.swift */; };
84E7ABC927D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E7ABBA27D2A1F100447CAE /* ThreadSafeLogger.swift */; };
84E7ABCA27D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E7ABBA27D2A1F100447CAE /* ThreadSafeLogger.swift */; };
+ 98D47DAB2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 98D47DAA2B224627001D38AC /* PrivacyInfo.xcprivacy */; };
+ 98D47DAC2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 98D47DAA2B224627001D38AC /* PrivacyInfo.xcprivacy */; };
+ 98D47DAD2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 98D47DAA2B224627001D38AC /* PrivacyInfo.xcprivacy */; };
+ 98D47DAE2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 98D47DAA2B224627001D38AC /* PrivacyInfo.xcprivacy */; };
BD1C3E8524E4399C0084B4DA /* SemanticVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B97DD93249D327F003DE606 /* SemanticVersion.swift */; };
BD64853C2491474500F30986 /* Optimizely.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E75167A22C520D400B2B157 /* Optimizely.h */; settings = {ATTRIBUTES = (Public, ); }; };
BD64853E2491474500F30986 /* Audience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E75169822C520D400B2B157 /* Audience.swift */; };
@@ -2149,6 +2153,7 @@
75C719BB25E4519B0084187E /* Optimizely.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Optimizely.framework; sourceTree = BUILT_PRODUCTS_DIR; };
75C71C3825E45A2B0084187E /* WatchBackgroundNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchBackgroundNotifier.swift; sourceTree = ""; };
84E7ABBA27D2A1F100447CAE /* ThreadSafeLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreadSafeLogger.swift; sourceTree = ""; };
+ 98D47DAA2B224627001D38AC /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; };
BD6485812491474500F30986 /* Optimizely.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Optimizely.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C78CAF572445AD8D009FE876 /* OptimizelyJSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyJSON.swift; sourceTree = ""; };
C78CAF652446DB91009FE876 /* OptimizelyClientTests_OptimizelyJSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyClientTests_OptimizelyJSON.swift; sourceTree = ""; };
@@ -2455,6 +2460,7 @@
6E75167922C520D400B2B157 /* Supporting Files */ = {
isa = PBXGroup;
children = (
+ 98D47DAA2B224627001D38AC /* PrivacyInfo.xcprivacy */,
6E75167A22C520D400B2B157 /* Optimizely.h */,
6E75167B22C520D400B2B157 /* Info.plist */,
);
@@ -3292,6 +3298,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 98D47DAC2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3657,6 +3664,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 98D47DAB2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3703,6 +3711,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 98D47DAE2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3710,6 +3719,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 98D47DAD2B224627001D38AC /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Package.swift b/Package.swift
index ab02c5309..22653f4ee 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,4 +1,8 @@
-// swift-tools-version:5.0
+// swift-tools-version:5.3
+// The Swift tools version declares the version of the PackageDescription library,
+// the minimum version of the Swift tools and Swift language compatibility version to process the manifest,
+// and the minimum version of the Swift tools that are needed to use the Swift package.
+
import PackageDescription
let package = Package(
@@ -14,7 +18,11 @@ let package = Package(
targets: ["Optimizely"])
],
targets: [
- .target(name: "Optimizely", path: "Sources")
+ .target(
+ name: "Optimizely",
+ path: "Sources",
+ resources: [.copy("Supporting Files/PrivacyInfo.xcprivacy")]
+ )
],
- swiftLanguageVersions: [.v5]
+ swiftLanguageVersions: [.v5, .version("5.9")]
)
diff --git a/README.md b/README.md
index 01b50fc8d..573451918 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# SWIFT SDK
+# Optimizely Swift SDK
[](http://www.apache.org/licenses/LICENSE-2.0)
[](https://github.com/carthage/carthage)
[](https://travis-ci.com/optimizely/swift-sdk)
@@ -6,25 +6,24 @@
[](https://img.shields.io/cocoapods/p/OptimizelySwiftSDK.svg)
[](https://cocoapods.org/pods/OptimizelySwiftSDK)
-This repository houses the Swift SDK for use with Optimizely Full Stack and Optimizely Rollouts for Mobile and OTT.
+This repository houses the Swift SDK for use with Optimizely Feature Experimentation and Optimizely Full Stack (legacy) for Mobile and OTT.
-Optimizely Full Stack is A/B testing and feature flag management for product development teams. Experiment in any application. Make every feature on your roadmap an opportunity to learn. Learn more at https://www.optimizely.com/platform/full-stack/, or see the [documentation](https://docs.developers.optimizely.com/experimentation/v4.0.0-full-stack/docs/welcome).
+Optimizely Feature Experimentation is an A/B testing and feature management tool for product development teams, enabling you to experiment at every step. Using Optimizely Feature Experimentation allows for every feature on your roadmap to be an opportunity to discover hidden insights. Learn more at [Optimizely.com](https://www.optimizely.com/products/experiment/feature-experimentation/), or see the [developer documentation](https://docs.developers.optimizely.com/experimentation/v4.0.0-full-stack/docs/welcome).
-Optimizely Rollouts is free feature flags for development teams. Easily roll out and roll back features in any application without code deploys. Mitigate risk for every feature on your roadmap. Learn more at https://www.optimizely.com/rollouts/, or see the [documentation](https://docs.developers.optimizely.com/experimentation/v3.1.0-full-stack/docs/introduction-to-rollouts).
+Optimizely Rollouts is [free feature flags](https://www.optimizely.com/free-feature-flagging/) for development teams. You can easily roll out and roll back features in any application without code deploys, mitigating risk for every feature on your roadmap.
-## Getting Started
+## Get started
-### Using the SDK
+### Use the Swift SDK
-See the [Swift SDK developer documentation](https://docs.developers.optimizely.com/experimentation/v4.0.0-full-stack/docs/swift-sdk) to learn how to set
-up an Optimizely project and start using the SDK.
+Refer to the [Swift SDK's developer documentation](https://docs.developers.optimizely.com/experimentation/v4.0.0-full-stack/docs/swift-sdk) for detailed instructions on getting started with using the SDK.
### Requirements
* iOS 10.0+ / tvOS 10.0+ / watchOS 3.0+
* Swift 5+
-### Installing the SDK
+### Install the SDK
Please note below that _\_ is used to represent the platform on which you are building your app. Currently, we support ```iOS```, ```tvOS```, and ```watchOS``` platforms.
@@ -38,7 +37,7 @@ Add the dependency on the Optimizely Swift SDK with Swift Package Manager in `Xc
#### CocoaPods
1. Add the following lines to the _Podfile_:
```use_frameworks!```
-```pod 'OptimizelySwiftSDK', '~> 3.10.1'```
+```pod 'OptimizelySwiftSDK', '~> 3.10.5'```
2. Run the following command: ``` pod install ```
@@ -46,7 +45,7 @@ Add the dependency on the Optimizely Swift SDK with Swift Package Manager in `Xc
Further installation instructions for Cocoapods: https://guides.cocoapods.org/using/getting-started.html
#### Carthage
-1. Add the following lines to the _Cartfile_:```github "optimizely/swift-sdk" ~> 3.10.1```
+1. Add the following lines to the _Cartfile_:```github "optimizely/swift-sdk" ~> 3.10.5```
2. Run the following command:```carthage update```
@@ -63,6 +62,12 @@ Further installation instructions for Cocoapods: https://guides.cocoapods.org/us
Futher installation instructions for Carthage: https://github.com/Carthage/Carthage
+### Feature Management Access
+
+To access the Feature Management configuration in the Optimizely dashboard, please contact your Optimizely customer success manager.
+
+## Use the Swift SDK
+
### Samples
A sample code for SDK initialization and experiments:
@@ -80,6 +85,8 @@ optimizely.start{ result in
}
```
+See the Optimizely Feature Experimentation [developer documentation](https://docs.developers.optimizely.com/experimentation/v4.0-full-stack/docs/swift-sdk) to learn how to set up your first Swift project and use the SDK.
+
### Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md).
@@ -90,12 +97,34 @@ First-party code (under OptimizelySwiftSDK is copyright Optimizely, Inc. and con
### Additional Code
-This software incorporates code from the following open source repo:
+This software incorporates code from the following open source projects:
-For the SDK:
MurmurHash3:https://github.com/jpedrosa/sua/blob/master/Sources/murmurhash3.swift License (Apache 2.0):https://github.com/jpedrosa/sua/blob/master/LICENSE.txt
Ported to Swift4.
SwiftLint:https://github.com/realm/SwiftLint License (MIT):https://github.com/realm/SwiftLint/blob/master/LICENSE
Used to enforce Swift style and conventions.
+### Other Optimizely SDKs
+
+- Agent - https://github.com/optimizely/agent
+
+- Android - https://github.com/optimizely/android-sdk
+
+- C# - https://github.com/optimizely/csharp-sdk
+
+- Flutter - https://github.com/optimizely/optimizely-flutter-sdk
+
+- Go - https://github.com/optimizely/go-sdk
+
+- Java - https://github.com/optimizely/java-sdk
+
+- JavaScript - https://github.com/optimizely/javascript-sdk
+
+- PHP - https://github.com/optimizely/php-sdk
+
+- Python - https://github.com/optimizely/python-sdk
+
+- React - https://github.com/optimizely/react-sdk
+
+- Ruby - https://github.com/optimizely/ruby-sdk
diff --git a/Scripts/build_all.sh b/Scripts/build_all.sh
index d5e7b9605..f1fc8bdd0 100755
--- a/Scripts/build_all.sh
+++ b/Scripts/build_all.sh
@@ -32,7 +32,8 @@ main() {
xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-iOS -configuration Release "${action}"
xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-tvOS -configuration Release "${action}"
+ xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-macOS -configuration Release "${action}"
+ xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-watchOS -configuration Release "${action}"
}
main
-
diff --git a/Scripts/prepare_coveralls_report.sh b/Scripts/prepare_coveralls_report.sh
new file mode 100755
index 000000000..adfb0eba0
--- /dev/null
+++ b/Scripts/prepare_coveralls_report.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -e
+
+# prepare_coveralls_report.sh
+#
+# Usage:
+# $ ./prepare_coveralls_report.sh
+#
+
+# [coveralls]
+# - exclude coverage for Test codes by setting OptimizelySwiftSDK-iOS scheme > Test > Options > Gather coverage for selected targets
+mkdir xccov2lcov && cd xccov2lcov && git init && git fetch --depth=1 https://github.com/trax-retail/xccov2lcov.git && git checkout FETCH_HEAD
+xcrun xccov view --report --json ../$COVERAGE_DIR/Logs/Test/*.xcresult > coverage.json
+swift run xccov2lcov coverage.json > lcov.info
+cd ..
diff --git a/Scripts/prepare_simulator.sh b/Scripts/prepare_simulator.sh
new file mode 100755
index 000000000..29da056dc
--- /dev/null
+++ b/Scripts/prepare_simulator.sh
@@ -0,0 +1,48 @@
+#!/bin/bash -e
+set -eou pipefail
+
+# expects the following environment variables defined
+# PLATFORM (eg. iOS Simulator)
+# OS (eg. 12.0)
+# NAME (eg. iPad Air)
+# OS_TYPE (eg. iOS)
+# SIMULATOR_XCODE_VERSION (Which Xcode's simulator to use)
+# Since github actions only provides limit simulators with each xcode, we need to link simulators from other versions of xcode to be used by current xcode.
+# We must use old simulators with current xcode since older xcode versions do not support swift 5 which is required by Swift SDK.
+# More about XCode and its compatible simulators can be found here: https://github.com/actions/virtual-environments/blob/main/images/macos/macos-10.15-Readme.md
+# https://github.com/actions/virtual-environments/issues/551
+
+# Older than Xcode 12 (12.4?) has different paths
+MAJOR_SIMULATOR_XCODE_VERSION=$(echo $SIMULATOR_XCODE_VERSION | cut -d. -f1)
+if [ "$MAJOR_SIMULATOR_XCODE_VERSION" -lt 12 ]; then
+ os_folder="iPhoneOS"
+ os="${OS/./-}"
+ name="${NAME//[ ()]/-}"
+
+ sudo mkdir -p /Library/Developer/CoreSimulator/Profiles/Runtimes
+
+ # Check if device is Apple tv, update os_folder for linking purposes
+ if [[ "$NAME" = "Apple TV"* ]]
+ then
+ name="${name}-1080p"
+ os_folder="AppleTVOS"
+ fi
+
+ # update os_folder as per xcode version
+ if [ "$SIMULATOR_XCODE_VERSION" == 10.3 ]
+ then
+ os_folder="${os_folder}.platform/Developer/Library"
+ else
+ os_folder="${os_folder}.platform/Library/Developer"
+ fi
+
+ # Link and create simulators from older xcode versions which are not part of the current xcode version
+ sudo ln -s /Applications/Xcode_$SIMULATOR_XCODE_VERSION.app/Contents/Developer/Platforms/$os_folder/CoreSimulator/Profiles/Runtimes/$OS_TYPE.simruntime /Library/Developer/CoreSimulator/Profiles/Runtimes/$OS_TYPE\ $OS.simruntime
+ xcrun simctl create "custom-device" "com.apple.CoreSimulator.SimDeviceType.$name" "com.apple.CoreSimulator.SimRuntime.$OS_TYPE-$os"
+ CUSTOM_SIMULATOR="$(instruments -s devices | grep -m 1 'custom-device' | awk -F'[][]' '{print $2}')"
+else
+ echo ".devices.\"com.apple.CoreSimulator.SimRuntime.${PLATFORM/ Simulator/}-${OS/./-}\"" > /tmp/jq_file
+ CUSTOM_SIMULATOR=$( xcrun simctl list --json devices | jq -f /tmp/jq_file | jq -r '.[] | select(.name==env.NAME) | .udid' )
+fi
+xcrun simctl boot $CUSTOM_SIMULATOR && sleep 30
+xcrun simctl list | grep Booted
diff --git a/Scripts/run_prep.sh b/Scripts/run_prep.sh
index 7209e9caa..dace39b25 100755
--- a/Scripts/run_prep.sh
+++ b/Scripts/run_prep.sh
@@ -1,19 +1,16 @@
-#!/usr/bin/env bash
-set -e
+#!/bin/bash -e
-# Because `hub` is used, this script expects the following environment variables defined in travis job settings:
+# Because `hub` is used, this script expects the following environment variables:
# GITHUB_TOKEN - github api token with repo permissions (display value in build log setting: OFF)
# GITHUB_USER - github username that GITHUB_TOKEN is associated with (display value in build log setting: ON)
# Additionally, it needs the following environment variables:
-# VERSION - defined in .travis.yml
-
-# Variables starting with TRAVIS_ are default environment variables available to all Travis CI builds
+# VERSION - defined in swift.yml
COLOR_RESET='\033[0m'
COLOR_MAGENTA='\033[0;35m'
COLOR_CYAN='\033[0;36m'
-MYREPO=${HOME}/workdir/${TRAVIS_REPO_SLUG}
+MYREPO=${HOME}/workdir/${REPO_SLUG}
AUTOBRANCH=${GITHUB_USER}/prepareRelease${VERSION}
BUILD_OUTPUT=/tmp/build.out
touch $BUILD_OUTPUT
@@ -21,7 +18,7 @@ touch $BUILD_OUTPUT
function prep_workspace {
rm -rf ${MYREPO}
mkdir -p ${MYREPO}
- git clone -b ${TRAVIS_BRANCH} https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG} ${MYREPO}
+ git clone -b ${BRANCH} https://${GITHUB_TOKEN}@github.com/${REPO_SLUG} ${MYREPO}
cd ${MYREPO}
git checkout -b ${AUTOBRANCH}
}
@@ -38,16 +35,27 @@ function error_handler() {
}
function do_stuff {
- # keepalive for Travis
while :; do sleep 10; echo -n .; done &
trap "kill $!" EXIT
trap 'error_handler' ERR
# we need pod install or test_all.sh fails
- pod repo update
- pod install
+
+ # we skip "test_all.sh" until we have a good reason to repeat it heere
+ # 1. this test takes long and also flaky tests can interrupt release process
+ # 2. this "test_all.sh" is supposed to pass before starting pre-release
+ # 3. prep auto PRs will be tested in CI/CD before starting release process.
+
+ # - cocoapods requires ENV['HOME'] with absolute path
+ #
+ # HOME=$(pwd)
+ # gem install cocoapods -v $COCOAPODS_VERSION
+ # pod _${COCOAPODS_VERSION}_ repo update
+ # pod _${COCOAPODS_VERSION}_ install
+ #
+ # myscripts=( "update_version.sh ${VERSION}" "build_all.sh" "test_all.sh" )
+ myscripts=( "update_version.sh ${VERSION}" "build_all.sh" )
- myscripts=( "update_version.sh ${VERSION}" "build_all.sh" "test_all.sh" )
for i in "${myscripts[@]}"; do
echo -n "${i} "
echo "===== ${i} =====" >> $BUILD_OUTPUT
@@ -60,11 +68,23 @@ function do_stuff {
}
function push_changes {
+
+
git config user.email "optibot@users.noreply.github.com"
git config user.name "${GITHUB_USER}"
git add --all
- # this is like a try/catch
- git commit -m "ci(travis): auto release prep for $VERSION" ||
+
+ TITLE="ci(git-action): auto release prep for $VERSION"
+ # an empty line required between title and description
+ # a dummy ref (FSSDK-1234) for required FSSDK checking
+ MESSAGE=$(cat </dev/null | jq -r '.assets[] | select(.browser_download_url | contains("windows-amd64")) | .browser_download_url')
+ echo "$WINDOWS_URL"
+ curl -fsSLO "$WINDOWS_URL"
+ unzip "$(basename "$WINDOWS_URL")" bin/hub.exe
+ rm -f "$(basename "$WINDOWS_URL")"
+ ;;
+ darwin )
+ DARWIN_URL=$(curl -u $GITHUB_USER:$GITHUB_TOKEN https://api.github.com/repos/$1/$2/releases/latest 2>/dev/null | jq -r '.assets[] | select(.browser_download_url | contains("darwin-amd64")) | .browser_download_url')
+ curl -fsSL "$DARWIN_URL" -o - | tar xz --strip-components=1 '*/bin/hub'
+ ;;
+ * )
+ LINUX_URL=$(curl -u $GITHUB_USER:$GITHUB_TOKEN https://api.github.com/repos/$1/$2/releases/latest 2>/dev/null | jq -r '.assets[] | select(.browser_download_url | contains("linux-amd64")) | .browser_download_url')
+ curl -fsSL "$LINUX_URL" | tar xz --strip-components=1 --wildcards '*/bin/hub'
+ ;;
+ esac
+}
+
+function install_binary {
+ mkdir -p ~/bin
+
+ # https://code-maven.com/create-temporary-directory-on-linux-using-bash
+ tmp_dir=$(mktemp -d -t ci-XXXXXXXXXX)
+
+ cd $tmp_dir
+
+ download $1 $2
+
+ if [ ! -f "$tmp_dir/bin/hub${windows:+.exe}" ]; then
+ echo "Failed to obtain $tmp_dir/bin/hub${windows:+.exe}"
+ exit 1
+ fi
+ mkdir -p ~/bin/
+ mv $tmp_dir/bin/hub${windows:+.exe} ~/bin/
+
+ chmod +x ~/bin/hub${windows:+.exe}
+ pwd
+ # verify
+ ~/bin/hub${windows:+.exe} version
+
+ # cleanup
+ rm -rf $tmp_dir
+ echo "hub installed"
+ # cp ~/bin/hub .
+}
+
+function prep_workspace {
+ rm -rf ${MYREPO}
+ mkdir -p ${MYREPO}
+ git clone -b ${BRANCH} https://${GITHUB_TOKEN}@github.com/${REPO_SLUG} ${MYREPO}
+ cd ${MYREPO}
+}
+
function release_github {
+ LAST_RELEASE=$(git describe --abbrev=0 --tags)
+
+ if [[ ${LAST_RELEASE} == "v${VERSION}" ]]; then
+ echo "${LAST_RELEASE} tag exists already (probably created while in the current release process). Skipping..."
+ return
+ fi
+
CHANGELOG="CHANGELOG.md"
# check that CHANGELOG.md has been updated
@@ -21,12 +93,15 @@ function release_github {
LAST_VERSION=$(grep '^## \d\+\.\d\+.\d\+' ${CHANGELOG} | awk 'NR==2')
DESCRIPTION=$(awk "/^${NEW_VERSION}$/,/^${LAST_VERSION:-nothingmatched}$/" ${CHANGELOG} | grep -v "^${LAST_VERSION:-nothingmatched}$")
-
- hub release create v${VERSION} -m "Release ${VERSION}" -m "${DESCRIPTION}" -t "${TRAVIS_BRANCH}"
-
+ hub version
+ hub release create v${VERSION} -m "Release ${VERSION}" -m "${DESCRIPTION}" -t "${BRANCH}"
}
function release_cocoapods {
+
+ # - cocoapods requires ENV['HOME'] with absolute path
+ HOME=$(pwd)
+ gem install cocoapods -v $COCOAPODS_VERSION
# ---- Optimizely's pods ----
pods=(OptimizelySwiftSDK);
@@ -39,13 +114,14 @@ function release_cocoapods {
do
podname=${pods[i]};
printf "Pushing the ${podname} pod to COCOAPODS.ORG .\n"
- pod trunk push --allow-warnings ${podname}.podspec
- pod update
+ pod _${COCOAPODS_VERSION}_ trunk push --allow-warnings ${podname}.podspec
+ pod _${COCOAPODS_VERSION}_ update
done
}
function main {
+ prep_workspace
release_github
release_cocoapods
}
diff --git a/Scripts/run_unit_tests.sh b/Scripts/run_unit_tests.sh
index bea414251..dd99210a2 100755
--- a/Scripts/run_unit_tests.sh
+++ b/Scripts/run_unit_tests.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
# run xcode unit tests
#
@@ -7,7 +7,7 @@
#
# unit tests for PR only
-if [[ "$TRAVIS_BRANCH" == "master" ]]
-then
+# if [[ "$BRANCH" == "master" ]]
+# then
xcodebuild test -derivedDataPath $COVERAGE_DIR -workspace OptimizelySwiftSDK.xcworkspace -scheme $SCHEME -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -sdk $TEST_SDK -destination "platform=$PLATFORM,OS=$OS,name=$NAME" ONLY_ACTIVE_ARCH=YES | tee buildoutput | xcpretty && test ${PIPESTATUS[0]} -eq 0
-fi
+# fi
diff --git a/Scripts/start_simulator.sh b/Scripts/start_simulator.sh
deleted file mode 100755
index 7cbc9bc09..000000000
--- a/Scripts/start_simulator.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-set -eou pipefail
-
-# expects the following environment variables defined
-# PLATFORM (eg. iOS Simulator)
-# OS (eg. 12.0)
-# NAME (eg. iPad Air)
-
-# prep jq arg because it doesnt allow parameter expansion within its single quotes
-echo ".devices.\"com.apple.CoreSimulator.SimRuntime.${PLATFORM/ Simulator/}-${OS/./-}\"" > /tmp/jq_file
-
-simulator=$( xcrun simctl list --json devices | jq -f /tmp/jq_file | jq -r '.[] | select(.name==env.NAME) | .udid' )
-if [ -z $simulator ]; then
- echo "The requested simulator ($PLATFORM $OS $NAME) cannot be found."
- #xcrun instruments -s device
- xcrun xctrace list devices
- sleep 3
- exit 1
-fi
-
-xcrun simctl boot $simulator && sleep 30
-xcrun simctl list | grep Booted
diff --git a/Scripts/test_all.sh b/Scripts/test_all.sh
index 36e12d960..1833f8227 100755
--- a/Scripts/test_all.sh
+++ b/Scripts/test_all.sh
@@ -1,13 +1,25 @@
-echo 'Testing OptimizelySwiftSDK-iOS (iPhone 8,OS=12.1)'
-xcrun xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-iOS -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8,OS=12.1' test
-echo 'Testing OptimizelySwiftSDK-iOS (iPhone SE,OS=11.1)'
-xcrun xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-iOS -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone SE,OS=11.1' test
-echo 'Testing OptimizelySwiftSDK-iOS (iPhone XS,OS=13.2)'
-xcrun xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-iOS -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone XS,OS=13.2' test
-echo 'Testing OptimizelySwiftSDK-tvOS (Apple TV,OS=11.1)'
-xcrun xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-tvOS -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV,OS=11.1' test
-echo 'Testing OptimizelySwiftSDK-tvOS (Apple TV,OS=12.1)'
-xcrun xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-tvOS -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV,OS=12.1' test
-echo 'Testing OptimizelySwiftSDK-tvOS (Apple TV 4K,OS=13.2)'
-xcrun xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme OptimizelySwiftSDK-tvOS -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV 4K,OS=13.2' test
+#!/bin/bash -e
+# Since github actions only provides limit simulators with each xcode, we need to link simulators from other versions of xcode to be used by current xcode.
+# We must use old simulators with current xcode since older xcode versions do not support swift 5 which is required by Swift SDK.
+# More about XCode and its compatible simulators can be found here: https://github.com/actions/virtual-environments/blob/main/images/macos/macos-10.15-Readme.md
+# https://github.com/actions/virtual-environments/issues/551
+
+deviceModels=("iPhone 12" "iPhone 8" "iPad Air (4th generation)" "Apple TV")
+osVersions=("16.0" "14.4" "15.0" "16.0")
+xcodeVersions=("14.3" "14.3" "14.3" "14.3")
+platforms=("iOS" "iOS" "iOS" "tvOS")
+testSdks=("iphonesimulator" "iphonesimulator" "iphonesimulator" "appletvsimulator")
+
+for i in "${!deviceModels[@]}"; do
+ export PLATFORM="${platforms[$i]} Simulator"
+ export OS="${osVersions[$i]}"
+ export NAME="${deviceModels[$i]}"
+ export OS_TYPE="${platforms[$i]}"
+ export SIMULATOR_XCODE_VERSION="${xcodeVersions[$i]}"
+
+ Scripts/prepare_simulator.sh
+ echo "Testing OptimizelySwiftSDK-${platforms[$i]} (${deviceModels[$i]},OS=${osVersions[$i]})"
+
+ xcrun xcodebuild -workspace OptimizelySwiftSDK.xcworkspace -scheme "OptimizelySwiftSDK-${platforms[$i]}" -sdk "${testSdks[$i]}" -configuration Release -destination "platform=${platforms[$i]} Simulator,name=${deviceModels[$i]},OS=${osVersions[$i]}" test
+done
diff --git a/Scripts/upload_coveralls.sh b/Scripts/upload_coveralls.sh
deleted file mode 100755
index c74239c1f..000000000
--- a/Scripts/upload_coveralls.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-# upload_coveralls.sh
-#
-# Usage:
-# $ ./upload_coveralls.sh
-#
-
-# [coveralls]
-# - exclude coverage for Test codes by setting OptimizelySwiftSDK-iOS scheme > Test > Options > Gather coverage for selected targets
-# - report coverage for PR and iPhone 11 only (avoid redundant ones)
-# - use Xcode12.4+ (older Xcode reports a wrong number)
-if [[ "$TRAVIS_BRANCH" == "master" && "$PLATFORM" == "iOS Simulator" && "$NAME" == "iPhone 11" ]]
-then
- mkdir xccov2lcov && cd xccov2lcov && git init && git fetch --depth=1 https://github.com/trax-retail/xccov2lcov.git && git checkout FETCH_HEAD
- xcrun xccov view --report --json ../$COVERAGE_DIR/Logs/Test/*.xcresult > coverage.json
- swift run xccov2lcov coverage.json > lcov.info
-
- cd ..
- coveralls-lcov -v --repo-token $COVERALLS_TOKEN xccov2lcov/lcov.info
-fi
diff --git a/Sources/Customization/DefaultEventDispatcher.swift b/Sources/Customization/DefaultEventDispatcher.swift
index 68e93feae..0311f9d09 100644
--- a/Sources/Customization/DefaultEventDispatcher.swift
+++ b/Sources/Customization/DefaultEventDispatcher.swift
@@ -183,7 +183,6 @@ open class DefaultEventDispatcher: BackgroundingCallbacks, OPTEventDispatcher {
var request = URLRequest(url: event.url)
request.httpMethod = "POST"
- request.httpBody = event.body
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// send notification BEFORE sending event to the server
diff --git a/Sources/Optimizely/OptimizelyClient.swift b/Sources/Optimizely/OptimizelyClient.swift
index a88fd9de0..0c32c7eb0 100644
--- a/Sources/Optimizely/OptimizelyClient.swift
+++ b/Sources/Optimizely/OptimizelyClient.swift
@@ -745,7 +745,7 @@ open class OptimizelyClient: NSObject {
public func getOptimizelyConfig() throws -> OptimizelyConfig {
guard let config = self.config else { throw OptimizelyError.sdkNotReady }
- return OptimizelyConfigImp(projectConfig: config)
+ return OptimizelyConfigImp(projectConfig: config, logger: logger)
}
}
diff --git a/Sources/Optimizely/OptimizelyConfig.swift b/Sources/Optimizely/OptimizelyConfig.swift
index af590d31b..e04d3002c 100644
--- a/Sources/Optimizely/OptimizelyConfig.swift
+++ b/Sources/Optimizely/OptimizelyConfig.swift
@@ -95,8 +95,8 @@ struct OptimizelyConfigImp: OptimizelyConfig {
var attributes: [OptimizelyAttribute] = []
var audiences: [OptimizelyAudience] = []
var events: [OptimizelyEvent] = []
-
- init(projectConfig: ProjectConfig) {
+
+ init(projectConfig: ProjectConfig, logger: OPTLogger = DefaultLogger()) {
guard let project = projectConfig.project else { return }
self.environmentKey = project.environmentKey ?? ""
@@ -139,7 +139,7 @@ struct OptimizelyConfigImp: OptimizelyConfig {
return updatedRollout
}
- self.experimentsMap = makeExperimentsMap(project: project, experiments: updatedExperiments)
+ self.experimentsMap = makeExperimentsMap(project: project, experiments: updatedExperiments, logger: logger)
self.featuresMap = makeFeaturesMap(project: project, experiments: updatedExperiments, rollouts: updatedRollouts)
}
}
@@ -148,9 +148,12 @@ struct OptimizelyConfigImp: OptimizelyConfig {
extension OptimizelyConfigImp {
- func makeExperimentsMap(project: Project, experiments: [Experiment]) -> [String: Experiment] {
+ func makeExperimentsMap(project: Project, experiments: [Experiment], logger: OPTLogger) -> [String: Experiment] {
var map = [String: Experiment]()
experiments.forEach {
+ if map.keys.contains($0.key) {
+ logger.w("Duplicate experiment keys found in datafile: \($0.key)")
+ }
map[$0.key] = $0
}
return map
diff --git a/Sources/Supporting Files/PrivacyInfo.xcprivacy b/Sources/Supporting Files/PrivacyInfo.xcprivacy
new file mode 100644
index 000000000..8042b2096
--- /dev/null
+++ b/Sources/Supporting Files/PrivacyInfo.xcprivacy
@@ -0,0 +1,32 @@
+
+
+
+
+ NSPrivacyCollectedDataTypes
+
+
+ NSPrivacyCollectedDataType
+ NSPrivacyCollectedDataTypeProductInteraction
+ NSPrivacyCollectedDataTypeLinked
+
+ NSPrivacyCollectedDataTypeTracking
+
+ NSPrivacyCollectedDataTypePurposes
+
+ NSPrivacyCollectedDataTypePurposeAnalytics
+
+
+
+ NSPrivacyAccessedAPITypes
+
+
+ NSPrivacyAccessedAPIType
+ NSPrivacyAccessedAPICategoryUserDefaults
+ NSPrivacyAccessedAPITypeReasons
+
+ CA92.1
+
+
+
+
+
diff --git a/Sources/Utils/SDKVersion.swift b/Sources/Utils/SDKVersion.swift
index 2ef3b49b4..72afe1366 100644
--- a/Sources/Utils/SDKVersion.swift
+++ b/Sources/Utils/SDKVersion.swift
@@ -17,4 +17,4 @@
/// Do not edit this field.
/// - It is auto updated (Scripts/updated_version.sh) to reflect the current version
/// - Do not put underscores in the name (Swiftlint can modify unexpectedly)
-let OPTIMIZELYSDKVERSION = "3.10.1"
+let OPTIMIZELYSDKVERSION = "3.10.5"
diff --git a/Tests/OptimizelyTests-APIs/OptimizelyClientTests_OptimizelyConfig.swift b/Tests/OptimizelyTests-APIs/OptimizelyClientTests_OptimizelyConfig.swift
index 24880abfa..48891924d 100644
--- a/Tests/OptimizelyTests-APIs/OptimizelyClientTests_OptimizelyConfig.swift
+++ b/Tests/OptimizelyTests-APIs/OptimizelyClientTests_OptimizelyConfig.swift
@@ -263,6 +263,64 @@ class OptimizelyClientTests_OptimizelyConfig: XCTestCase {
let result = try? self.optimizely.getOptimizelyConfig()
XCTAssertNil(result)
}
+
+ func testOptimizelyConfigWithDuplicateKeys() {
+ let exp0: [String : Any] = [
+ "id": "10001",
+ "key": "duplicate_key",
+ "status": "Running",
+ "layerId": "22222",
+ "variations": [],
+ "trafficAllocation": [],
+ "audienceIds": ["33333"],
+ "audienceConditions": [],
+ "forcedVariations": ["12345": "1234567890"]
+ ]
+
+ let exp1: [String : Any] = [
+ "id": "10005",
+ "key": "duplicate_key",
+ "status": "Running",
+ "layerId": "22222",
+ "variations": [],
+ "trafficAllocation": [],
+ "audienceIds": ["33333"],
+ "audienceConditions": [],
+ "forcedVariations": ["12345": "1234567890"]
+ ]
+
+ var projectData: [String: Any] = [
+ "version": "4",
+ "projectId": "11111",
+ "experiments": [],
+ "audiences": [],
+ "groups": [],
+ "attributes": [],
+ "accountId": "1234567890",
+ "events": [],
+ "revision": "5",
+ "anonymizeIP": true,
+ "rollouts": [],
+ "typedAudiences": [],
+ "integrations": [],
+ "featureFlags": [],
+ "botFiltering": false,
+ "sendFlagDecisions": true
+ ]
+
+ projectData["experiments"] = [exp0, exp1]
+ let model: Project = try! OTUtils.model(from: projectData)
+ let projectConfig = ProjectConfig()
+ projectConfig.project = model
+
+ let logger = TestLogger()
+ let optiConfigImpl = OptimizelyConfigImp(projectConfig: projectConfig, logger: logger)
+ let optimizelyExpMap: [String: OptimizelyExperiment] = optiConfigImpl.experimentsMap
+ XCTAssertEqual(logger.getMessages(.warning), ["Duplicate experiment keys found in datafile: duplicate_key"])
+
+ XCTAssertEqual(optimizelyExpMap.count, 1)
+ XCTAssertEqual(optimizelyExpMap["duplicate_key"]?.id, "10005")
+ }
}
@@ -371,3 +429,41 @@ extension OptimizelyEvent {
}
}
+// MARK: - Mock Loggers
+
+fileprivate class TestLogger: OPTLogger {
+ private static var _logLevel: OptimizelyLogLevel?
+ public static var logLevel: OptimizelyLogLevel {
+ get {
+ return _logLevel ?? .info
+ }
+ set (newLevel) {
+ _logLevel = newLevel
+ }
+ }
+
+ required public init() {
+ clearMessages()
+ }
+
+ func log(level: OptimizelyLogLevel, message: String) {
+ logMessages[level.rawValue].append(message)
+ }
+
+ // Utils
+
+ var logMessages = [[String]]()
+
+ var logCount: Int {
+ return logMessages.reduce(0) { $0 + $1.count }
+ }
+
+ func getMessages(_ level: OptimizelyLogLevel) -> [String] {
+ return logMessages[level.rawValue]
+ }
+
+ func clearMessages() {
+ logMessages = [[String]](repeating: [], count: OptimizelyLogLevel.debug.rawValue + 1)
+ }
+
+}