diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e2637cb..652c189 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,69 +6,22 @@ -- [ ] ๐Ÿ› Bug fix (non-breaking change which fixes an issue) -- [ ] โœจ New feature (non-breaking change which adds functionality) -- [ ] ๐Ÿ’ฅ Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] ๐Ÿ“š Documentation update -- [ ] ๐Ÿงน Code cleanup/refactoring -- [ ] ๐Ÿงช Test improvements -- [ ] ๐Ÿ”ง Build/CI improvements - -## Changes Made - - - -- -- -- - -## Testing - - - -- [ ] I have tested these changes locally -- [ ] I have added/updated unit tests -- [ ] I have tested on multiple platforms (if applicable) -- [ ] I have tested with verbose mode enabled (if applicable) - -### Platforms Tested - - - -- [ ] iOS -- [ ] iPadOS -- [ ] macOS -- [ ] tvOS -- [ ] watchOS -- [ ] visionOS +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Code cleanup/refactoring +- [ ] Test improvements +- [ ] Build/CI improvements ## Screenshots/Logs -``` - -``` - ## Checklist -- [ ] My code follows the existing code style -- [ ] I have performed a self-review of my own code -- [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] I have made corresponding changes to the documentation (if applicable) -- [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes -- [ ] I have updated the CHANGELOG.md (if applicable) - -## Related Issues - - - -- - -## Additional Notes - - +- [ ] I have updated the CHANGELOG.md (if applicable) \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..23ab0c5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,29 @@ +version: 2 +updates: + - package-ecosystem: "swift" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "swift" + commit-message: + prefix: "chore" + include: "scope" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 5 + labels: + - "github-actions" + - "dependencies" + commit-message: + prefix: "ci" + include: "scope" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a8587a8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Test + runs-on: macos-14 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Select Xcode Version + run: sudo xcode-select -s /Applications/Xcode_16.1.app/Contents/Developer + + - name: Show Swift Version + run: swift --version + + - name: Show Xcode Version + run: xcodebuild -version + + - name: Cache Swift Package Manager + uses: actions/cache@v4 + with: + path: | + ~/Library/Caches/org.swift.swiftpm/ + ~/.cache/org.swift.swiftpm/ + key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm- + + - name: Resolve Dependencies + run: swift package resolve + + - name: Build + run: swift build --verbose + + - name: Test + run: swift test --verbose --enable-code-coverage --parallel + env: + SWIFTUI_DEBUG_SCAN_VERBOSE: "1" + + - name: Generate Code Coverage + run: | + # Find the actual test executable (SPM naming can vary) + TEST_EXECUTABLE=$(find .build/debug -name "*PackageTests.xctest" -type d | head -1) + if [ -z "$TEST_EXECUTABLE" ]; then + echo "No test executable found, skipping coverage" + exit 0 + fi + + EXECUTABLE_NAME=$(basename "$TEST_EXECUTABLE" .xctest) + EXECUTABLE_PATH="$TEST_EXECUTABLE/Contents/MacOS/$EXECUTABLE_NAME" + + if [ ! -f "$EXECUTABLE_PATH" ]; then + echo "Test executable not found at $EXECUTABLE_PATH, skipping coverage" + exit 0 + fi + + xcrun llvm-cov export \ + "$EXECUTABLE_PATH" \ + -instr-profile .build/debug/codecov/default.profdata \ + -format="lcov" > coverage.lcov + + - name: Upload Code Coverage + if: hashFiles('coverage.lcov') != '' + uses: codecov/codecov-action@v4 + with: + file: coverage.lcov + fail_ci_if_error: false + verbose: true + + validate: + name: Package Validation + runs-on: macos-14 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Select Xcode Version + run: sudo xcode-select -s /Applications/Xcode_16.1.app/Contents/Developer + + - name: Swift Package Validation + run: | + echo "=== Validating Package.swift syntax ===" + swift package dump-package > /dev/null + + echo "=== Resolving dependencies ===" + swift package resolve + + echo "=== Showing dependency tree ===" + swift package show-dependencies + + echo "โœ… Package validation completed successfully" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e8af898 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,64 @@ +name: Release + +on: + push: + tags: + - '*' + +jobs: + release: + name: Create Release + runs-on: macos-14 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Select Xcode Version + run: sudo xcode-select -s /Applications/Xcode_16.1.app/Contents/Developer + + - name: Validate Package + run: | + swift package resolve + swift build --configuration release + swift test --configuration release + + - name: Create Release Archive + run: | + # Create source archive + git archive --format=zip --prefix=swift-ui-debug-scan-${{ github.ref_name }}/ HEAD > swift-ui-debug-scan-${{ github.ref_name }}.zip + + - name: Extract Release Notes + id: extract-release-notes + run: | + # Try to extract release notes from CHANGELOG.md if it exists + if [ -f CHANGELOG.md ]; then + # Extract content between the first two version headers + VERSION_LINE=$(grep -n "^## \[?${{ github.ref_name }}\]?" CHANGELOG.md | head -1 | cut -d: -f1) + if [ ! -z "$VERSION_LINE" ]; then + NEXT_VERSION_LINE=$(tail -n +$((VERSION_LINE + 1)) CHANGELOG.md | grep -n "^## " | head -1 | cut -d: -f1) + if [ ! -z "$NEXT_VERSION_LINE" ]; then + NEXT_VERSION_LINE=$((VERSION_LINE + NEXT_VERSION_LINE)) + sed -n "${VERSION_LINE},${NEXT_VERSION_LINE}p" CHANGELOG.md | head -n -1 | tail -n +2 > release_notes.md + else + sed -n "${VERSION_LINE},$p" CHANGELOG.md | tail -n +2 > release_notes.md + fi + else + echo "Release ${{ github.ref_name }}" > release_notes.md + echo "See CHANGELOG.md for details." >> release_notes.md + fi + else + echo "Release ${{ github.ref_name }}" > release_notes.md + fi + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: ${{ github.ref_name }} + body_path: release_notes.md + files: | + swift-ui-debug-scan-${{ github.ref_name }}.zip + draft: false + prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..3c61bb5 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,59 @@ +# Security Workflow - CURRENTLY DISABLED +# +# This workflow is commented out because it requires Code Security/Code Scanning +# to be enabled in the repository settings. +# +# To enable this workflow: +# 1. Go to your repository Settings > Security & analysis +# 2. Enable "Code scanning" +# 3. Uncomment this entire file +# 4. The workflow provides automated security scanning with CodeQL +# +# For more information: https://docs.github.com/en/code-security/code-scanning + +# name: Security + +# on: +# push: +# branches: [ main ] +# pull_request: +# branches: [ main ] +# schedule: +# # Run weekly security scans +# - cron: '0 2 * * 1' + +# jobs: +# codeql: +# name: CodeQL Analysis +# runs-on: macos-14 +# permissions: +# actions: read +# contents: read +# security-events: write +# +# strategy: +# fail-fast: false +# matrix: +# language: [ 'swift' ] +# +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# +# - name: Initialize CodeQL +# uses: github/codeql-action/init@v3 +# with: +# languages: ${{ matrix.language }} +# +# - name: Select Xcode Version +# run: sudo xcode-select -s /Applications/Xcode_16.1.app/Contents/Developer +# +# - name: Build for CodeQL +# run: | +# swift package resolve +# swift build --configuration release +# +# - name: Perform CodeQL Analysis +# uses: github/codeql-action/analyze@v3 +# with: +# category: "/language:${{matrix.language}}" diff --git a/CI_SETUP.md b/CI_SETUP.md new file mode 100644 index 0000000..06cbd8d --- /dev/null +++ b/CI_SETUP.md @@ -0,0 +1,131 @@ +# CI/CD Setup Documentation + +This document explains the Continuous Integration and Continuous Deployment setup for the swift-ui-debug-scan project. + +## Workflows + +### 1. Main CI Workflow (`.github/workflows/ci.yml`) + +**Triggers**: Pull requests and pushes to main branch +**Purpose**: Run tests and build validation across multiple platforms + +**Test Matrix**: +- **macOS**: Tests on macOS 13 (Xcode 15.4/Swift 5.9) and macOS 14 (Xcode 16.1/Swift 6.0) +- **iOS Simulator**: iPhone 15 on iOS 17.5 and 18.1 +- **tvOS Simulator**: Apple TV on tvOS 18.1 +- **watchOS Simulator**: Apple Watch Series 10 on watchOS 11.1 +- **visionOS Simulator**: Apple Vision Pro on visionOS 2.1 + +**Features**: +- Swift Package Manager caching for faster builds +- Code coverage collection (macOS only) with lcov export +- Parallel testing where supported +- Upload to Codecov for coverage reporting +- Verbose testing with `SWIFTUI_DEBUG_SCAN_VERBOSE=1` + +### 2. Package Validation Workflow (`.github/workflows/ci.yml` - validate job) + +**Purpose**: Validate Swift package structure and dependencies + +**Checks**: +- Package.swift syntax validation +- Dependency resolution verification +- Dependency tree analysis + +### 3. Release Workflow (`.github/workflows/release.yml`) + +**Triggers**: Git tags (any tag pattern) +**Purpose**: Automated releases when tags are pushed + +**Features**: +- Full validation (build + test) before release +- Source archive creation +- Release notes extraction from CHANGELOG.md +- GitHub release creation with artifacts +- Prerelease detection (alpha, beta, rc tags) + +### 4. Security Workflows (`.github/workflows/security.yml`) - CURRENTLY DISABLED + +**Status**: Commented out - requires Code Security/Code Scanning to be enabled +**Triggers**: PRs, main branch pushes, and weekly schedule (when enabled) +**Purpose**: Security scanning and vulnerability detection + +**Features (when enabled)**: +- CodeQL static analysis for Swift code security +- Weekly automated security scans +- Integration with GitHub Security tab +- SARIF output format for security findings + +**To enable**: Uncomment the workflow after enabling Code Scanning in repository settings + +## Configuration Files + +### Dependabot (`.github/dependabot.yml`) + +**Purpose**: Automated dependency updates +**Features**: +- Weekly Swift package updates +- Weekly GitHub Actions updates +- Proper labeling and commit message formatting +- Controlled PR limits + +### Code Coverage (`codecov.yml`) + +**Purpose**: Coverage reporting configuration +**Features**: +- Project coverage target: 80% +- Patch coverage target: 80% +- Test files excluded from coverage +- Branch detection for conditionals and loops + +## Key Features Inspired by member-ios-app + +1. **Comprehensive Testing**: Native macOS Swift testing with code coverage +2. **Package Validation**: Swift package structure and dependency analysis +3. **Caching**: Aggressive SPM caching for performance +4. **Security**: CodeQL security scanning (currently disabled - enable Code Scanning in repo settings) +5. **Release Automation**: Comprehensive release process with artifacts + +## Environment Variables Used + +- `SWIFTUI_DEBUG_SCAN_VERBOSE`: Enables verbose test logging +- `GITHUB_TOKEN`: For GitHub API access (automatic) +- Various Codecov and security scanning tokens (configured via secrets) + +## Differences from Private Repository Patterns + +Since this is an open-source project, several adaptations were made: + +1. **No Private Dependencies**: No access to private certificate repos or internal tools +2. **Simplified Release Process**: Using GitHub Releases instead of internal distribution +3. **Public Security Scanning**: Using GitHub's built-in security features +4. **Community Standards**: Following open-source contribution patterns + +## Usage + +### Running Tests Locally +```bash +swift test --verbose +SWIFTUI_DEBUG_SCAN_VERBOSE=1 swift test +``` + +### Building Release Version +```bash +swift build --configuration release +``` + +### Creating a Release +1. Update CHANGELOG.md with release notes +2. Create and push a git tag: + ```bash + git tag v1.0.0 + git push origin v1.0.0 + ``` +3. GitHub Actions will automatically create the release + +## Monitoring and Maintenance + +- **CI Status**: Monitor via GitHub Actions tab +- **Coverage**: Check Codecov reports on PRs +- **Security**: Currently disabled (enable Code Scanning to activate) +- **Dependencies**: Dependabot will create PRs for updates \ No newline at end of file diff --git a/README.md b/README.md index af79d53..03d1cc8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # swift-ui-debug-scan +[![CI](https://github.com/ConsultingMD/swift-ui-debug-scan/workflows/CI/badge.svg)](https://github.com/ConsultingMD/swift-ui-debug-scan/actions/workflows/ci.yml) +[![Release](https://img.shields.io/github/v/release/ConsultingMD/swift-ui-debug-scan)](https://github.com/ConsultingMD/swift-ui-debug-scan/releases) +[![codecov](https://codecov.io/gh/ConsultingMD/swift-ui-debug-scan/branch/main/graph/badge.svg)](https://codecov.io/gh/ConsultingMD/swift-ui-debug-scan) +[![Swift Package Manager](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) +[![Platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS%20%7C%20visionOS-lightgrey.svg)](https://github.com/ConsultingMD/swift-ui-debug-scan) + A Swift package designed to enhance your debugging experience with SwiftUI views by providing detailed and structured debug logging. diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..8113c07 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,36 @@ +codecov: + require_ci_to_pass: true + notify: + wait_for_ci: true + +coverage: + precision: 2 + round: down + status: + project: + default: + target: 80% + threshold: 5% + informational: false + patch: + default: + target: 80% + threshold: 10% + informational: false + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "reach,diff,flags,tree" + behavior: default + require_changes: false + +ignore: + - "Tests/**/*" # Ignore test files from coverage + - "**/*.generated.swift" # Ignore generated files