diff --git a/.github/workflows/cocoapods.yaml b/.github/workflows/cocoapods.yaml new file mode 100644 index 0000000..40cf599 --- /dev/null +++ b/.github/workflows/cocoapods.yaml @@ -0,0 +1,38 @@ +name: CocoaPods + +on: + workflow_dispatch: + workflow_call: + release: + types: [published] + +jobs: + pod-lint: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + + - name: Install CocoaPods + run: gem install cocoapods + + - name: Lint Podspec + run: pod lib lint --allow-warnings + + pod-publish: + needs: pod-lint + if: github.event_name == 'release' + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + + - name: Install CocoaPods + run: gem install cocoapods + + - name: Update CocoaPods Trunk + env: + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} + run: | + # Ensure the version in podspec matches the release + ./scripts/update_podspec.sh + # Push the podspec to trunk + pod trunk push OpenFeature.podspec --allow-warnings --verbose diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml index cb3d923..3ec7673 100644 --- a/.github/workflows/release-please.yaml +++ b/.github/workflows/release-please.yaml @@ -24,9 +24,32 @@ jobs: run: | echo "$RELEASE_PLEASE_OUTPUT" + # Update podspec version when a release PR is created or updated + - name: Checkout code if PR is generated/updated + if: ${{ steps.release.outputs.pr }} + uses: actions/checkout@v3 + with: + ref: ${{ fromJSON(steps.release.outputs.pr).headBranchName }} + + - name: Update podspec version + if: ${{ steps.release.outputs.pr }} + run: | + ./scripts/update_podspec.sh + git config --global user.name "github-actions[bot]" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add OpenFeature.podspec + git commit -m "chore: update podspec version [skip ci]" || true + git push + # Outputs are namespaced by package when using a manifest in Release Please outputs: release_created: ${{ steps.release.outputs['OpenFeature--release_created'] }} # Version doesn't include `v` as a prefix. This is undocumented version: ${{ steps.release.outputs['OpenFeature--version'] }} upload_url: ${{ steps.release.outputs['OpenFeature--upload_url'] }} + + # Trigger the CocoaPods workflow when a release is created + cocoapods: + needs: release-please + if: ${{ needs.release-please.outputs.release_created == 'true' }} + uses: ./.github/workflows/cocoapods.yaml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b6a002..d27784b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,4 +23,19 @@ You can automatically format your code using: ```shell swift test -``` \ No newline at end of file +``` + +### Maintaining CocoaPods Integration + +The project includes CocoaPods support via the `OpenFeature.podspec` file. When making changes: + +1. The version in the podspec is automatically updated from `version.txt` during the release process +2. To validate the podspec locally, run: + ```shell + pod spec lint OpenFeature.podspec --allow-warnings + ``` +3. The CocoaPods validation and publishing is handled automatically via GitHub workflows on release + +#### Token Management + +For information on regenerating the CocoaPods trunk token used in CI/CD, see the "CocoaPods Release Token Management" section in [OWNERS.md](OWNERS.md). diff --git a/OWNERS.md b/OWNERS.md index cbffdc5..c4eb292 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -8,3 +8,32 @@ - Mattias Frånberg (mfranberg, Spotify) - Alina Andersone (alina-v1, Spotify) - Brian Hackett (Calibretto, Spotify) + +## CocoaPods Release Token Management + +The automated CocoaPods releases require a valid trunk token that expires every 128 days (~4 months). When the token expires, a core developer needs to update the `COCOAPODS_TRUNK_TOKEN` repository secret. + +### Getting a New Token + +1. Install CocoaPods if not already installed: + ```bash + gem install cocoapods + ``` + +2. Register with CocoaPods trunk to generate a new token: + ```bash + pod trunk register openfeature-core@groups.io 'OpenFeature' --description='OpenFeature Deployment User' + ``` + +3. Check your email and click the verification link (check https://groups.io/g/openfeature-core for the email) + +4. Extract the token from your local configuration: + ```bash + cat ~/.netrc + ``` + Look for the `password` field + +### Updating the GitHub Secret + +1. Go to the repository settings: `Settings` → `Secrets and variables` → `Actions` +2. Find the existing `COCOAPODS_TRUNK_TOKEN` secret and update it diff --git a/OpenFeature.podspec b/OpenFeature.podspec new file mode 100644 index 0000000..45ec073 --- /dev/null +++ b/OpenFeature.podspec @@ -0,0 +1,20 @@ +Pod::Spec.new do |s| + s.name = 'OpenFeature' + s.version = '0.3.0' + s.summary = 'OpenFeature iOS SDK' + s.description = <<-DESC +OpenFeature is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool or in-house solution. + DESC + s.homepage = 'https://github.com/open-feature/swift-sdk' + s.license = { :type => 'Apache-2.0', :file => 'LICENSE' } + s.author = { 'OpenFeature' => 'https://github.com/open-feature' } + s.source = { :git => 'https://github.com/open-feature/swift-sdk.git', :tag => s.version.to_s } + + s.ios.deployment_target = '14.0' + s.osx.deployment_target = '11.0' + s.swift_version = '5.5' + + s.source_files = 'Sources/OpenFeature/**/*' + + s.frameworks = 'Foundation' +end \ No newline at end of file diff --git a/README.md b/README.md index 96d40ae..8a5410f 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,20 @@ and in the target dependencies section add: .product(name: "OpenFeature", package: "swift-sdk"), ``` +#### CocoaPods + +If you manage dependencies through CocoaPods, add the following to your Podfile: + +```ruby +pod 'OpenFeature', '~> 0.3.0' +``` + +Then, run: + +```bash +pod install +``` + ### Usage ```swift @@ -194,7 +208,7 @@ A shutdown function is not yet available in the iOS SDK. ### Develop a provider To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency. -You’ll then need to write the provider by implementing the `FeatureProvider` interface exported by the OpenFeature SDK. +You'll then need to write the provider by implementing the `FeatureProvider` interface exported by the OpenFeature SDK. ```swift import OpenFeature diff --git a/scripts/update_podspec.sh b/scripts/update_podspec.sh new file mode 100755 index 0000000..7c373b8 --- /dev/null +++ b/scripts/update_podspec.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# Exit if any command fails +set -e + +# Get the version from version.txt +VERSION=$(cat version.txt | tr -d '\n') + +# Update the version in the podspec +sed -i '' "s/s.version.*=.*/s.version = '$VERSION'/g" OpenFeature.podspec + +echo "Updated OpenFeature.podspec to version $VERSION" \ No newline at end of file