diff --git a/pull_request_template.md b/.github/pull_request_template.md similarity index 95% rename from pull_request_template.md rename to .github/pull_request_template.md index cf46729..9729fe6 100644 --- a/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,6 +22,5 @@ - [ ] Pull request title follows the format `RNMT-XXXX ` - [ ] Code follows the code style of this project -- [ ] CHANGELOG.md file is correctly updated - [ ] Changes require an update to the documentation - [ ] Documentation has been updated accordingly diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index f8047d5..532a9d6 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -25,7 +25,7 @@ jobs: run: brew link --overwrite swiftlint || brew install swiftlint - name: Set up XCode - run: sudo xcode-select --switch /Applications/Xcode_26.0.app + run: sudo xcode-select --switch /Applications/Xcode_26.1.1.app/Contents/Developer - name: Bundle Install run: bundle install @@ -42,8 +42,11 @@ jobs: - name: Setup sonarqube uses: warchant/setup-sonar-scanner@v8 + # TODO: Sonarcloud integration is failing, so continue-on-error: true was added + # to prevent blocking the pipeline. This should be revisited when we work on fixing this integration. - name: Send to Sonarcloud run: bundle exec fastlane sonarqube + continue-on-error: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONARCLOUD_KEY }} diff --git a/.github/workflows/prepare_release.yml b/.github/workflows/prepare_release.yml deleted file mode 100644 index 0bb0e48..0000000 --- a/.github/workflows/prepare_release.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Prepare Release - -on: - workflow_dispatch: - inputs: - versionBumpLevel: - description: 'Version bump level (patch, minor, major)' - required: true - type: choice - default: 'patch' - options: - - patch - - minor - - major - -jobs: - build-and-release: - if: github.ref == 'refs/heads/main' - runs-on: macos-15 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Link SwiftLint or install it - run: brew link --overwrite swiftlint || brew install swiftlint - - - name: Set up XCode - run: sudo xcode-select --switch /Applications/Xcode_26.0.app - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.3' - - - name: Bump version - run: ruby ./scripts/bump_versions.rb ${{ github.event.inputs.versionBumpLevel }} - - - name: Build XCFramework - run: ./scripts/build_framework.sh - - - name: Get new version - id: version - run: echo "VERSION=$(ruby -e 'puts File.read("./OSInAppBrowserLib.podspec").match(/spec.version.*=.*''(\d+\.\d+\.\d+)''/)[1]')" >> $GITHUB_ENV - - - name: Create new branch - run: | - git switch --create "prepare-new-release-${{ env.VERSION }}" - - - name: Move zip file to root and push changes - run: | - if [ -f OSInAppBrowserLib.zip ]; then - rm OSInAppBrowserLib.zip - else - echo "File does not exist." - fi - mv build/OSInAppBrowserLib.zip . - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - git add . - git commit -m "chore: Bump version to ${{ env.VERSION }}" - git push origin HEAD:prepare-new-release-${{ env.VERSION }} - - - name: Create pull request - id: create_pr - run: | - gh pr create -B main -H prepare-new-release-${{ env.VERSION }} --title 'Prepare `main` to Release `${{ env.VERSION }}`' --body 'Bumps version to `${{ env.VERSION }}`.<br/>Creates an updated and ready-to-be-released `OSInAppBrowserLib.zip`.' - PR_NUMBER=$(gh pr view --json number --jq '.number') - echo "PR_NUMBER=${PR_NUMBER}" >> $GITHUB_ENV - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Add label to the pull request - run: | - gh api \ - --method POST \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/${{ github.repository }}/issues/${{ env.PR_NUMBER }}/labels \ - -f "labels[]=release" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ce9a62e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: Release + +on: + workflow_dispatch: {} + +env: + XCODE_VERSION: 26.2 + NODE_VERSION: '24' + +permissions: + contents: write + packages: write + +jobs: + release: + runs-on: macos-15 + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + token: ${{ secrets.CAP_GH_RELEASE_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Install dependencies + run: | + npm i + + - name: Install CocoaPods + run: | + gem install cocoapods --no-document + + - name: Set Xcode version + run: | + sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app/Contents/Developer + + - name: Run semantic-release + env: + GITHUB_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} + run: | + npx semantic-release + + diff --git a/.github/workflows/release_and_publish.yml b/.github/workflows/release_and_publish.yml deleted file mode 100644 index 12122fb..0000000 --- a/.github/workflows/release_and_publish.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Release and Publish - -on: - pull_request: - types: [closed] - branches: - - 'main' - -jobs: - post-merge: - if: contains(github.event.pull_request.labels.*.name, 'release') && github.event.pull_request.merged == true - runs-on: macos-15 - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Set up Cocoapods - run: gem install cocoapods - - - name: Get new version - id: version - run: echo "VERSION=$(ruby -e 'puts File.read("./OSInAppBrowserLib.podspec").match(/spec.version.*=.*''(\d+\.\d+\.\d+)''/)[1]')" >> $GITHUB_ENV - - - name: Extract release notes - run: sh scripts/extract_release_notes.sh "${{ env.VERSION }}" >> release_notes.md - - - name: Create Tag - id: create_tag - run: | - # Define the tag name and message - TAG_NAME="${{ env.VERSION }}" - TAG_MESSAGE="Tag for version ${{ env.VERSION }}" - - # Create the tag - git tag -a "$TAG_NAME" -m "$TAG_MESSAGE" - git push origin "$TAG_NAME" - - echo "Tag created: $TAG_NAME" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create Release - run: | - # Extract the tag name - TAG_NAME="${{ env.VERSION }}" - RELEASE_NOTES="$(cat release_notes.md)" - - # Create the release using GitHub CLI - gh release create "$TAG_NAME" \ - --title "$TAG_NAME" \ - --notes "$RELEASE_NOTES" \ - "OSInAppBrowserLib.zip" - - echo "Release created for tag: $TAG_NAME" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Deploy to Cocoapods - run: pod trunk push ./OSInAppBrowserLib.podspec --allow-warnings - env: - COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} - - - name: Delete Release Branch - run: git push origin --delete prepare-new-release-${{ env.VERSION }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index f289fcd..8115275 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,7 @@ iOSInjectionProject/ # macOS .DS_Store + +# Node.js / npm +node_modules/ +package-lock.json diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..58e1147 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,54 @@ +{ + "branches": ["main"], + "tagFormat": "${version}", + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/exec", + { + "prepareCmd": "bash ./scripts/update_xcodeproj_version.sh ${nextRelease.version} \"OSInAppBrowserLib.xcodeproj/project.pbxproj\" && bash ./scripts/update_readme_version.sh ${nextRelease.version} \"OSInAppBrowserLib\" \"README.md\" && bash ./scripts/build_framework.sh \"OSInAppBrowserLib\" \"LICENSE\"" + } + ], + "@semantic-release/changelog", + [ + "@semantic-release/npm", + { + "npmPublish": false + } + ], + [ + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md", + "OSInAppBrowserLib.xcodeproj/project.pbxproj", + "OSInAppBrowserLib.podspec", + "package.json", + "README.md" + ], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ], + [ + "@semantic-release/github", + { + "assets": [ + { + "path": "OSInAppBrowserLib.zip", + "label": "OSInAppBrowserLib XCFramework" + } + ], + "successComment": false, + "failComment": false, + "releasedLabels": false + } + ], + [ + "@semantic-release/exec", + { + "publishCmd": "bash ./scripts/publish_cocoapods.sh ${nextRelease.version} \"OSInAppBrowserLib\"" + } + ] + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index e77bb1f..ace45d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,3 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ## 2.3.1 ### Fixes diff --git a/OSInAppBrowserLib.podspec b/OSInAppBrowserLib.podspec index 69eaf3a..aec9998 100644 --- a/OSInAppBrowserLib.podspec +++ b/OSInAppBrowserLib.podspec @@ -1,8 +1,11 @@ +require 'json' +package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) + Pod::Spec.new do |spec| - spec.name = 'OSInAppBrowserLib' - spec.version = '2.3.1' + spec.name = package['name'] + spec.version = package['version'] - spec.summary = 'The `OSInAppBrowserLib` is a library that provides a web browser view to load a web page within a Mobile Application.' + spec.summary = package['description'] spec.description = <<-DESC The InAppBrowserLib library behaves as a standard web browser and is useful to load untrusted content without risking your application's security. @@ -18,8 +21,8 @@ Pod::Spec.new do |spec| DESC spec.homepage = 'https://github.com/OutSystems/OSInAppBrowserLib-iOS' - spec.license = { :type => 'MIT', :file => 'LICENSE' } - spec.author = { 'OutSystems Mobile Ecosystem' => 'rd.mobileecosystem.team@outsystems.com' } + spec.license = { :type => package['license'], :file => 'LICENSE' } + spec.author = { package['author'] => package['email'] } spec.source = { :http => "https://github.com/OutSystems/OSInAppBrowserLib-iOS/releases/download/#{spec.version}/OSInAppBrowserLib.zip", :type => "zip" } spec.vendored_frameworks = "OSInAppBrowserLib.xcframework" diff --git a/OSInAppBrowserLib.zip b/OSInAppBrowserLib.zip deleted file mode 100644 index fb9cb04..0000000 Binary files a/OSInAppBrowserLib.zip and /dev/null differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..ac006ff --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "OSInAppBrowserLib", + "version": "2.3.1", + "description": "The `OSInAppBrowserLib` is a library that provides a web browser view to load a web page within a Mobile Application.", + "author": "OutSystems Mobile Ecosystem", + "email": "rd.mobileecosystem.team@outsystems.com", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/OutSystems/OSInAppBrowserLib-iOS.git" + }, + "private": true, + "scripts": { + "semantic-release": "semantic-release" + }, + "devDependencies": { + "@semantic-release/changelog": "^6.0.0", + "@semantic-release/commit-analyzer": "^13.0.0", + "@semantic-release/exec": "^7.0.0", + "@semantic-release/npm": "^13.0.0", + "@semantic-release/git": "^10.0.0", + "@semantic-release/github": "^12.0.0", + "@semantic-release/release-notes-generator": "^14.0.0", + "semantic-release": "^25.0.0" + } +} diff --git a/scripts/build_framework.sh b/scripts/build_framework.sh index f238a64..4e1b8cc 100755 --- a/scripts/build_framework.sh +++ b/scripts/build_framework.sh @@ -1,37 +1,115 @@ -BUILD_FOLDER="build" -BUILD_SCHEME="OSInAppBrowserLib" -FRAMEWORK_NAME="OSInAppBrowserLib" -SIMULATOR_ARCHIVE_PATH="${BUILD_FOLDER}/iphonesimulator.xcarchive" -IOS_DEVICE_ARCHIVE_PATH="${BUILD_FOLDER}/iphoneos.xcarchive" +#!/bin/bash +set -euo pipefail -rm -rf "${FRAMEWORK_NAME}.zip" -rm -rf ${BUILD_FOLDER} +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" +source "${SCRIPT_DIR}/common.sh" +PROJECT_NAME="${1:-}" +LICENSE_FILE="${2:-}" +BUILD_DIR="./build" + +if [ -z "$PROJECT_NAME" ] || [ -z "$LICENSE_FILE" ]; then + log_error "Usage: build_framework.sh <project_name> <license_file>" + exit 1 +fi + +trap 'log_error "Build failed."' ERR + +# Validate prerequisites +check_command "xcodebuild" +check_file "${PROJECT_NAME}.xcodeproj/project.pbxproj" +check_file "$LICENSE_FILE" + +# Check for optional dependencies +if ! check_command "xcbeautify"; then + log_warning "xcbeautify not found, output will not be formatted" + XCBEAUTIFY_CMD="cat" +else + XCBEAUTIFY_CMD="xcbeautify" +fi + +log_info "đŸ› ī¸ Building XCFramework for ${PROJECT_NAME}..." + +# Clean build directory +rm -rf "$BUILD_DIR" +mkdir -p "$BUILD_DIR" + +# Define xcarchive paths +SIMULATOR_XCARCHIVE="$BUILD_DIR/${PROJECT_NAME}.framework-iphonesimulator.xcarchive" +DEVICE_XCARCHIVE="$BUILD_DIR/${PROJECT_NAME}.framework-iphoneos.xcarchive" + +log_info "đŸ—ī¸ Building iOS Simulator archive..." xcodebuild archive \ - -scheme ${BUILD_SCHEME} \ + -scheme "$PROJECT_NAME" \ -configuration Release \ -destination 'generic/platform=iOS Simulator' \ - -archivePath "./${SIMULATOR_ARCHIVE_PATH}/" \ + -archivePath "$SIMULATOR_XCARCHIVE" \ SKIP_INSTALL=NO \ - BUILD_LIBRARIES_FOR_DISTRIBUTION=YES + BUILD_LIBRARIES_FOR_DISTRIBUTION=YES | ${XCBEAUTIFY_CMD} +log_info "đŸ—ī¸ Building iOS Device archive..." xcodebuild archive \ - -scheme ${BUILD_SCHEME} \ + -scheme "$PROJECT_NAME" \ -configuration Release \ -destination 'generic/platform=iOS' \ - -archivePath "./${IOS_DEVICE_ARCHIVE_PATH}/" \ + -archivePath "$DEVICE_XCARCHIVE" \ SKIP_INSTALL=NO \ - BUILD_LIBRARIES_FOR_DISTRIBUTION=YES + BUILD_LIBRARIES_FOR_DISTRIBUTION=YES | ${XCBEAUTIFY_CMD} + +XCFRAMEWORK_PATH="$BUILD_DIR/${PROJECT_NAME}.xcframework" + +# Define framework and dSYM paths +SIMULATOR_FRAMEWORK="$SIMULATOR_XCARCHIVE/Products/Library/Frameworks/${PROJECT_NAME}.framework" +SIMULATOR_DSYM="$SIMULATOR_XCARCHIVE/dSYMs/${PROJECT_NAME}.framework.dSYM" +DEVICE_FRAMEWORK="$DEVICE_XCARCHIVE/Products/Library/Frameworks/${PROJECT_NAME}.framework" +DEVICE_DSYM="$DEVICE_XCARCHIVE/dSYMs/${PROJECT_NAME}.framework.dSYM" + +# Validate that frameworks were created successfully +if [ ! -d "$SIMULATOR_FRAMEWORK" ]; then + log_error "iOS Simulator framework not found: $SIMULATOR_FRAMEWORK" + exit 1 +fi + +if [ ! -d "$DEVICE_FRAMEWORK" ]; then + log_error "iOS Device framework not found: $DEVICE_FRAMEWORK" + exit 1 +fi + +log_info "đŸ“Ļ Creating XCFramework..." + +# Build xcframework command with conditional dSYM inclusion +XCFRAMEWORK_ARGS="-framework $SIMULATOR_FRAMEWORK" +if [ -d "$SIMULATOR_DSYM" ]; then + log_info "Including iOS Simulator debug symbols" + XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -debug-symbols ${PWD}/$SIMULATOR_DSYM" +else + log_warning "iOS Simulator debug symbols not found, skipping" +fi + +XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -framework $DEVICE_FRAMEWORK" +if [ -d "$DEVICE_DSYM" ]; then + log_info "Including iOS Device debug symbols" + XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -debug-symbols ${PWD}/$DEVICE_DSYM" +else + log_warning "iOS Device debug symbols not found, skipping" +fi + +XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -output $XCFRAMEWORK_PATH" -xcodebuild -create-xcframework \ - -framework "./${SIMULATOR_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework" \ - -debug-symbols "${PWD}/${SIMULATOR_ARCHIVE_PATH}/dSYMs/${FRAMEWORK_NAME}.framework.dSYM" \ - -framework "./${IOS_DEVICE_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework" \ - -debug-symbols "${PWD}/${IOS_DEVICE_ARCHIVE_PATH}/dSYMs/${FRAMEWORK_NAME}.framework.dSYM" \ - -output "./${BUILD_FOLDER}/${FRAMEWORK_NAME}.xcframework" +eval "xcodebuild -create-xcframework $XCFRAMEWORK_ARGS" -cp LICENSE ${BUILD_FOLDER} +# Validate XCFramework was created successfully +if [ ! -d "$XCFRAMEWORK_PATH" ]; then + log_error "XCFramework creation failed" + exit 1 +fi -cd "./${BUILD_FOLDER}" +# Create distribution zip +log_info "đŸ“Ļ Creating distribution package..." +LICENSE_BASENAME="$(basename "$LICENSE_FILE")" +cp "$LICENSE_FILE" "$BUILD_DIR" +cd "$BUILD_DIR" +zip -r "${PROJECT_NAME}.zip" "${PROJECT_NAME}.xcframework" "$LICENSE_BASENAME" +mv "${PROJECT_NAME}.zip" .. -zip -r "${FRAMEWORK_NAME}.zip" "${FRAMEWORK_NAME}.xcframework" LICENSE \ No newline at end of file +log_success "🎉 XCFramework built successfully: ${PROJECT_NAME}.zip" diff --git a/scripts/bump_versions.rb b/scripts/bump_versions.rb deleted file mode 100644 index 0e1c182..0000000 --- a/scripts/bump_versions.rb +++ /dev/null @@ -1,72 +0,0 @@ -# bump_version.rb - -require 'bundler' - -# Read version level from ARGV -level = ARGV[0] - -# Define the path to your .podspec file -podspec_path = "./OSInAppBrowserLib.podspec" - -# Read the .podspec file -podspec_content = File.read(podspec_path) - -# Extract current version -current_version_number = podspec_content.match(/spec.version\s*=\s*["'](\d+\.\d+\.\d+)["']/)[1] - -# Parse the version into major, minor, and patch components -major, minor, patch = current_version_number.split('.').map(&:to_i) - -# Increment the version based on the specified level -case level -when "major" - major += 1 - # Reset minor and patch to 0 when major version is incremented - minor = 0 - patch = 0 -when "minor" - minor += 1 - # Reset patch to 0 when minor version is incremented - patch = 0 -when "patch" - patch += 1 -else - raise ArgumentError, "Invalid version bump level: #{level}. Must be one of: major, minor, patch." -end - -# Combine the new version components -new_version_number = [major, minor, patch].join('.') - -# Replace 'Unreleased' in the CHANGELOG.md with the new version -changelog_path = "./CHANGELOG.md" -changelog_content = File.read(changelog_path) -new_changelog_content = changelog_content.gsub("[Unreleased]", new_version_number) -File.write(changelog_path, new_changelog_content) - -# Replace the old version with the new version in the .podspec content -new_podspec_content = podspec_content.gsub(/(spec.version\s*=\s*["'])\d+\.\d+\.\d+(["'])/, "\\1#{new_version_number}\\2") -File.write(podspec_path, new_podspec_content) - -# Set the application name -LIBRARY_NAME = "OSInAppBrowserLib" - -# Set the Xcode project file path -project_file = "#{LIBRARY_NAME}.xcodeproj/project.pbxproj" - -# Read the project file content -file_content = File.read(project_file) - -# Fetch the current MARKETING_VERSION and CURRENT_PROJECT_VERSION values -current_build_number = Integer(file_content[/CURRENT_PROJECT_VERSION = ([^;]+)/, 1]) - -# Set the new build numbers -new_build_number = current_build_number + 1 - -# Update the MARKETING_VERSION and CURRENT_PROJECT_VERSION values in the project file -updated_content = file_content.gsub(/MARKETING_VERSION = [^;]+;/, "MARKETING_VERSION = #{new_version_number};") - .gsub(/CURRENT_PROJECT_VERSION = [^;]+;/, "CURRENT_PROJECT_VERSION = #{new_build_number};") - -# Write the updated content back to the project file -File.open(project_file, "w") { |file| file.puts updated_content } - -puts "Version updated to #{new_version_number} (Build Number ##{new_build_number})" \ No newline at end of file diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100755 index 0000000..b9a6758 --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Common utilities for project scripts +# This file contains shared functions used across multiple scripts + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[1;36m' +NC='\033[0m' # No Color + +# Logging functions with consistent formatting +log_info() { echo -e "${BLUE}â„šī¸ $1${NC}"; } +log_success() { echo -e "${GREEN}✅ $1${NC}"; } +log_warning() { echo -e "${YELLOW}âš ī¸ $1${NC}"; } +log_error() { echo -e "${RED}❌ $1${NC}"; } + +# Utility functions +check_command() { + if ! command -v "$1" &> /dev/null; then + log_error "$1 is required but not installed" + return 1 + fi + return 0 +} + +check_file() { + if [[ ! -f "$1" ]]; then + log_error "File not found: $1" + return 1 + fi + return 0 +} + +check_directory() { + if [[ ! -d "$1" ]]; then + log_error "Directory not found: $1" + return 1 + fi + return 0 +} diff --git a/scripts/extract_release_notes.sh b/scripts/extract_release_notes.sh deleted file mode 100644 index 35e03d6..0000000 --- a/scripts/extract_release_notes.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Check if a section header is provided -if [ -z "$1" ]; then - echo "No section header provided. Usage: ./extract_release_notes.sh section_header" - exit 1 -fi - -SECTION_HEADER=$1 - -# Escape the section header for use in awk -ESCAPED_HEADER=$(echo "$SECTION_HEADER" | sed 's/[]\/$*.^|[]/\\&/g') - -# Extract the specified section from CHANGELOG.md, remove the empty line after the header, and convert ### to # -awk -v header="$ESCAPED_HEADER" ' - $0 ~ "## " header {flag=1; next} - flag && /^$/ {next} - /^## / && !($0 ~ "## " header) {flag=0} - flag {gsub(/^### /, "# "); print} -' CHANGELOG.md diff --git a/scripts/publish_cocoapods.sh b/scripts/publish_cocoapods.sh new file mode 100755 index 0000000..0214d98 --- /dev/null +++ b/scripts/publish_cocoapods.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" +source "${SCRIPT_DIR}/common.sh" + +VERSION="${1:-}" +PROJECT_NAME="${2:-}" +PODSPEC_PATH="${3:-${PROJECT_NAME}.podspec}" + +if [ -z "$VERSION" ]; then + log_error "No version specified. Usage: publish_cocoapods.sh <version> <project_name> [podspec_path]" + exit 1 +fi + +if [ -z "$PROJECT_NAME" ]; then + log_error "Usage: publish_cocoapods.sh <version> <project_name> [podspec_path]" + exit 1 +fi + +trap 'log_error "Publish failed."' ERR + +log_info "Preparing to publish version $VERSION to CocoaPods" + +if [ -z "${COCOAPODS_TRUNK_TOKEN:-}" ]; then + log_warning "COCOAPODS_TRUNK_TOKEN not set; skipping CocoaPods publish." + exit 0 +fi + +log_info "Checking if version ${VERSION} already exists on CocoaPods for ${PROJECT_NAME}" +INFO="$(pod trunk info "${PROJECT_NAME}" 2>/dev/null || true)" +if echo "$INFO" | grep -E -q "^[[:space:]]*-[[:space:]]+${VERSION}[[:space:]]+\\("; then + log_warning "Version ${VERSION} already exists on CocoaPods for ${PROJECT_NAME}; skipping publish." + exit 0 +fi + +log_info "Running pod trunk push on ${PODSPEC_PATH}" +pod trunk push "${PODSPEC_PATH}" --allow-warnings --skip-tests + +log_success "CocoaPods publish finished" diff --git a/scripts/update_readme_version.sh b/scripts/update_readme_version.sh new file mode 100755 index 0000000..2e0725f --- /dev/null +++ b/scripts/update_readme_version.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +VERSION="${1:-}" +LIB_NAME="${2:-}" +README_FILE="${3:-README.md}" + +if [ -z "$VERSION" ] || [ -z "$LIB_NAME" ]; then + log_error "Usage: update_readme_version.sh <version> <lib_name> [readme_path]" + exit 1 +fi + +if [ ! -f "$README_FILE" ]; then + log_error "README file not found at $README_FILE" + exit 1 +fi + +log_info "Updating CocoaPods version in $README_FILE..." + +# Update the CocoaPods version line in README.md +# This will match lines like: pod 'LibName', '~> 1.0.1' +sed -i '' -E "s/(pod '$LIB_NAME', '~> )[0-9]+\.[0-9]+(\.[0-9]+)?'/\1$VERSION'/g" "$README_FILE" + +log_success "Updated $LIB_NAME version to $VERSION in $README_FILE" diff --git a/scripts/update_xcodeproj_version.sh b/scripts/update_xcodeproj_version.sh new file mode 100755 index 0000000..fa76f71 --- /dev/null +++ b/scripts/update_xcodeproj_version.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +VERSION="${1:-}" +PBXPROJ="${2:-}" + +if [ -z "$VERSION" ] || [ -z "$PBXPROJ" ]; then + log_error "Usage: update_xcodeproj_version.sh <version> <pbxproj_path>" + exit 1 +fi + +if [ ! -f "$PBXPROJ" ]; then + log_error "project.pbxproj not found at $PBXPROJ" + exit 1 +fi + +log_info "Updating MARKETING_VERSION in $PBXPROJ..." +sed -i '' -E "s/MARKETING_VERSION = [0-9]+\.[0-9]+(\.[0-9]+)?;/MARKETING_VERSION = $VERSION;/g" "$PBXPROJ" +log_info "Updating CURRENT_PROJECT_VERSION..." +current_proj_version=$(grep -m1 'CURRENT_PROJECT_VERSION =' "$PBXPROJ" | sed -E 's/.*CURRENT_PROJECT_VERSION = ([0-9]+);/\1/') +new_proj_version=$((current_proj_version+1)) +sed -i '' -E "s/CURRENT_PROJECT_VERSION = [0-9]+;/CURRENT_PROJECT_VERSION = $new_proj_version;/g" "$PBXPROJ" +log_success "Bumped MARKETING_VERSION to $VERSION, CURRENT_PROJECT_VERSION to $new_proj_version"