Skip to content

Add File History Browser for versioned file snapshots #191

Add File History Browser for versioned file snapshots

Add File History Browser for versioned file snapshots #191

Workflow file for this run

# ==========================================
# UNIT TESTS WORKFLOW
# ==========================================
# This workflow runs the macOS app's unit test suite and lints the codebase.
# It can be triggered in three ways:
# 1. Automatically on pushes to main
# 2. Automatically on pull requests to main
# 3. Manually via workflow_dispatch with custom Xcode version
#
# The workflow uses xcodebuild for building and testing, with SwiftLint
# for code quality enforcement.
name: Unit Tests
on:
# ==========================================
# AUTOMATIC TRIGGERS
# ==========================================
push:
branches: [main]
pull_request:
branches: [main]
# ==========================================
# REUSABLE WORKFLOW TRIGGER
# ==========================================
# Allows this workflow to be called by other workflows
workflow_call:
inputs:
xcode_version:
description: 'Xcode Version'
required: false
default: 'Xcode_26.0.app'
type: string
# ==========================================
# MANUAL TRIGGER
# ==========================================
# Allows manual execution with custom parameters
workflow_dispatch:
inputs:
xcode_version:
description: 'Xcode Version'
required: false
default: 'Xcode_26.0.app'
type: choice
options:
- Xcode_26.0.app
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: macOS Tests
runs-on: macos-latest
timeout-minutes: 30
env:
# Prevent macOS system gitconfig from loading osxkeychain
# credential helper, which triggers a blocking Keychain dialog
# on self-hosted runners.
GIT_CONFIG_NOSYSTEM: true
steps:
# ==========================================
# STEP 1: CHECKOUT CODE
# ==========================================
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
# ==========================================
# STEP 2: SETUP XCODE
# ==========================================
- name: Setup Xcode
run: |
XCODE_PATH="/Applications/${{ inputs.xcode_version || 'Xcode_26.0.app' }}"
if [ -d "$XCODE_PATH" ]; then
echo "DEVELOPER_DIR=$XCODE_PATH/Contents/Developer" >> $GITHUB_ENV
echo "Using Xcode: $XCODE_PATH"
else
echo "::error::Xcode not found at $XCODE_PATH"
ls /Applications/ | grep -i xcode || echo "No Xcode installations found"
exit 1
fi
# ==========================================
# STEP 3: SETUP HOMEBREW
# ==========================================
- name: Setup Homebrew
run: |
if [ -f /opt/homebrew/bin/brew ]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [ -f /usr/local/bin/brew ]; then
eval "$(/usr/local/bin/brew shellenv)"
else
echo "::error::Homebrew not found"
exit 1
fi
echo "$(brew --prefix)/bin" >> $GITHUB_PATH
# ==========================================
# STEP 4: INSTALL LINT & FORMAT TOOLS
# ==========================================
- name: Install SwiftLint & SwiftFormat
run: brew install swiftlint swiftformat
# ==========================================
# STEP 5: COMPUTE METADATA
# ==========================================
- name: Compute short SHA and start time
run: |
echo "SHORT_SHA=${GITHUB_SHA::7}" >> "$GITHUB_ENV"
echo "START_TIME=$(date +%s)" >> "$GITHUB_ENV"
# ==========================================
# STEP 6: BUILD FOR TESTING
# ==========================================
- name: Build
run: |
xcodebuild -scheme Poirot \
-destination 'platform=macOS' \
-skipMacroValidation \
CODE_SIGNING_ALLOWED=NO \
build-for-testing
# ==========================================
# STEP 7: RUN TESTS (uses build from step 6)
# ==========================================
- name: Test
id: test
run: |
xcodebuild -scheme Poirot \
-destination 'platform=macOS' \
-skipMacroValidation \
CODE_SIGNING_ALLOWED=NO \
-resultBundlePath TestResults/Poirot.xcresult \
-skip-testing PoirotTests/ScreenshotTests_Analytics \
-skip-testing PoirotTests/ScreenshotTests_ConfigScreens \
-skip-testing PoirotTests/ScreenshotTests_DebugLog \
-skip-testing PoirotTests/ScreenshotTests_EditDiff \
-skip-testing PoirotTests/ScreenshotTests_Facets \
-skip-testing PoirotTests/ScreenshotTests_FullViews \
-skip-testing PoirotTests/ScreenshotTests_History \
-skip-testing PoirotTests/ScreenshotTests_Memory \
-skip-testing PoirotTests/ScreenshotTests_Plans \
-skip-testing PoirotTests/ScreenshotTests_SessionDetail \
-skip-testing PoirotTests/ScreenshotTests_Sidebar \
-skip-testing PoirotTests/ScreenshotTests_Standalone \
-skip-testing PoirotTests/ScreenshotTests_ThinkingBlocks \
-skip-testing PoirotTests/ScreenshotTests_Todos \
-skip-testing PoirotTests/ScreenshotTests_ToolBlocks \
-skip-testing PoirotTests/ScreenshotTests_Windows \
test-without-building
# ==========================================
# STEP 8: LINT
# ==========================================
- name: Lint
if: always() && steps.test.outcome != 'cancelled'
run: |
swiftlint lint \
--config .swiftlint.yml \
Poirot/Sources \
--reporter github-actions-logging
# ==========================================
# STEP 9: UPLOAD TEST ARTIFACTS
# ==========================================
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ github.run_number }}
path: |
TestResults/*.xcresult
retention-days: 21
# ==========================================
# STEP 10: POST WORKFLOW SUMMARY
# ==========================================
- name: Post test summary
if: always()
run: |
echo "## 🧪 Test Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ steps.test.outcome }}" = "success" ]; then
echo "✅ **All tests passed successfully!**" >> $GITHUB_STEP_SUMMARY
elif [ "${{ steps.test.outcome }}" = "failure" ]; then
echo "❌ **Tests failed**" >> $GITHUB_STEP_SUMMARY
if [ -d "TestResults" ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Failure Details:" >> $GITHUB_STEP_SUMMARY
XCRESULT=$(find TestResults -name "*.xcresult" -type d | head -n 1)
if [ -n "$XCRESULT" ]; then
xcrun xcresulttool get test-results summary --path "$XCRESULT" >> $GITHUB_STEP_SUMMARY 2>/dev/null || echo "Could not extract detailed test results" >> $GITHUB_STEP_SUMMARY
fi
fi
else
echo "⚠️ **Tests did not complete**" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Configuration:" >> $GITHUB_STEP_SUMMARY
echo "- **Scheme:** Poirot" >> $GITHUB_STEP_SUMMARY
echo "- **Platform:** macOS" >> $GITHUB_STEP_SUMMARY
echo "- **Xcode:** ${{ inputs.xcode_version || 'Xcode_26.0.app' }}" >> $GITHUB_STEP_SUMMARY
# ==========================================
# STEP 11: CALCULATE DURATION
# ==========================================
- name: Calculate duration
if: always()
run: |
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
MINUTES=$((DURATION / 60))
SECONDS=$((DURATION % 60))
if [ $MINUTES -gt 0 ]; then
echo "⏱️ Duration: ${MINUTES}m ${SECONDS}s" >> $GITHUB_STEP_SUMMARY
else
echo "⏱️ Duration: ${SECONDS}s" >> $GITHUB_STEP_SUMMARY
fi
# ==========================================
# STEP 12: FAIL JOB IF TESTS FAILED
# ==========================================
- name: Fail job if tests failed
if: always() && steps.test.outcome == 'failure'
run: |
echo "❌ Tests failed - failing the job"
exit 1