Skip to content

Commit 75280c0

Browse files
authored
Merge pull request #12 from v2er-app/feature/add-github-actions
2 parents 7e30f6d + 36d08e5 commit 75280c0

File tree

6 files changed

+704
-0
lines changed

6 files changed

+704
-0
lines changed

.github/workflows/README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# GitHub Actions Workflows
2+
3+
This directory contains automated workflows for the V2er-iOS project.
4+
5+
## Workflows
6+
7+
### 🔨 iOS Build and Test (`ios-build-test.yml`)
8+
- **Trigger**: Push to main/develop, Pull requests to main
9+
- **Purpose**: Build the app and run tests
10+
- **Features**:
11+
- Builds for iOS Simulator
12+
- Runs unit and UI tests
13+
- Caches Swift Package Manager dependencies
14+
- Uploads test results on failure
15+
16+
### ✅ PR Validation (`pr-validation.yml`)
17+
- **Trigger**: Pull request events
18+
- **Purpose**: Validate pull requests before merge
19+
- **Features**:
20+
- SwiftLint analysis
21+
- PR size labeling (XS, S, M, L, XL, XXL)
22+
- Conventional commit message checking
23+
24+
### 🚀 Release (`release.yml`)
25+
- **Trigger**: Manual workflow dispatch
26+
- **Purpose**: Build and release to App Store
27+
- **Features**:
28+
- Version bumping (major/minor/patch)
29+
- Archive and export IPA
30+
- Upload to TestFlight
31+
- Create GitHub release
32+
- Option for TestFlight-only releases
33+
34+
### 📦 Dependency Updates (`dependency-update.yml`)
35+
- **Trigger**: Weekly (Mondays at 9 AM UTC) or manual
36+
- **Purpose**: Keep dependencies up to date
37+
- **Features**:
38+
- Updates Swift Package dependencies
39+
- Creates automated pull request
40+
- Security vulnerability scanning
41+
42+
### 📊 Code Quality (`code-quality.yml`)
43+
- **Trigger**: Push to main/develop, Pull requests
44+
- **Purpose**: Maintain code quality standards
45+
- **Features**:
46+
- SwiftFormat checking
47+
- Code coverage reporting
48+
- Coverage badge generation
49+
50+
## Required Secrets
51+
52+
To use these workflows, configure the following secrets in your repository:
53+
54+
### For Release Workflow:
55+
- `CERTIFICATES_P12`: Base64 encoded distribution certificate
56+
- `CERTIFICATES_PASSWORD`: Certificate password
57+
- `KEYCHAIN_PASSWORD`: Temporary keychain password
58+
- `PROVISIONING_PROFILE_BASE64`: Base64 encoded provisioning profile
59+
- `TEAM_ID`: Apple Developer Team ID
60+
- `APP_STORE_CONNECT_API_KEY_ID`: App Store Connect API key ID
61+
- `APP_STORE_CONNECT_API_KEY_ISSUER_ID`: API key issuer ID
62+
- `APP_STORE_CONNECT_API_KEY`: API key content
63+
64+
### For Coverage Badge (Optional):
65+
- `GIST_SECRET`: GitHub personal access token with gist scope
66+
67+
## Setup Instructions
68+
69+
1. Generate required certificates and provisioning profiles from Apple Developer portal
70+
2. Encode files to base64:
71+
```bash
72+
base64 -i certificate.p12 -o certificate_base64.txt
73+
base64 -i profile.mobileprovision -o profile_base64.txt
74+
```
75+
3. Add secrets to repository settings
76+
4. Update Xcode version in workflows if needed
77+
5. Customize workflow triggers as needed
78+
79+
## Manual Triggers
80+
81+
Some workflows can be triggered manually from the Actions tab:
82+
- **Release**: Choose release type (major/minor/patch) and TestFlight-only option
83+
- **Dependency Updates**: Manually check for updates
84+
85+
## Maintenance
86+
87+
- Update Xcode version when new versions are released
88+
- Review and update SwiftLint rules as needed
89+
- Adjust test simulator versions for new iOS releases
90+
- Monitor dependency update PRs for breaking changes

.github/workflows/code-quality.yml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Code Quality
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
swiftformat:
11+
name: SwiftFormat Check
12+
runs-on: macos-latest
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Install SwiftFormat
19+
run: brew install swiftformat
20+
21+
- name: Check code formatting
22+
run: |
23+
swiftformat --version
24+
swiftformat . --lint --verbose
25+
continue-on-error: true
26+
27+
- name: Generate format diff
28+
if: failure()
29+
run: |
30+
swiftformat . --dryrun > format-diff.txt
31+
cat format-diff.txt
32+
33+
- name: Upload format diff
34+
if: failure()
35+
uses: actions/upload-artifact@v4
36+
with:
37+
name: format-diff
38+
path: format-diff.txt
39+
40+
code-coverage:
41+
name: Code Coverage
42+
runs-on: macos-latest
43+
44+
steps:
45+
- name: Checkout repository
46+
uses: actions/checkout@v4
47+
with:
48+
submodules: recursive
49+
50+
- name: Select Xcode version
51+
run: sudo xcode-select -s /Applications/Xcode_15.4.app/Contents/Developer
52+
53+
- name: Install xcpretty
54+
run: gem install xcpretty
55+
56+
- name: Build and test with coverage
57+
run: |
58+
xcodebuild test \
59+
-project V2er.xcodeproj \
60+
-scheme V2er \
61+
-sdk iphonesimulator \
62+
-destination 'platform=iOS Simulator,name=iPhone 15' \
63+
-enableCodeCoverage YES \
64+
-derivedDataPath build/DerivedData \
65+
CODE_SIGN_IDENTITY="" \
66+
CODE_SIGNING_REQUIRED=NO | xcpretty
67+
68+
- name: Generate coverage report
69+
run: |
70+
cd build/DerivedData
71+
# Find the xcresult bundle
72+
RESULT_BUNDLE=$(find . -name '*.xcresult' -type d | head -n 1)
73+
74+
if [ -z "$RESULT_BUNDLE" ]; then
75+
echo "No test results found, setting coverage to 0%"
76+
echo "coverage=0.00" >> $GITHUB_ENV
77+
else
78+
xcrun xccov view --report --json "$RESULT_BUNDLE" > coverage.json || echo '{}' > coverage.json
79+
80+
# Extract coverage percentage with fallback
81+
COVERAGE=$(cat coverage.json | jq -r '.lineCoverage // 0' | awk '{printf "%.2f", $1 * 100}')
82+
echo "Code coverage: ${COVERAGE}%"
83+
echo "coverage=${COVERAGE}" >> $GITHUB_ENV
84+
fi
85+
86+
- name: Create coverage badge
87+
if: env.GIST_SECRET != ''
88+
uses: schneegans/dynamic-badges-action@v1.6.0
89+
with:
90+
auth: ${{ secrets.GIST_SECRET }}
91+
gistID: ${{ secrets.GIST_ID }}
92+
filename: v2er-ios-coverage.json
93+
label: Coverage
94+
message: ${{ env.coverage }}%
95+
color: ${{ env.coverage > 80 && 'success' || env.coverage > 60 && 'yellow' || 'critical' }}
96+
env:
97+
GIST_SECRET: ${{ secrets.GIST_SECRET }}
98+
99+
- name: Comment PR with coverage
100+
if: github.event_name == 'pull_request'
101+
uses: actions/github-script@v7
102+
with:
103+
script: |
104+
const coverage = parseFloat('${{ env.coverage }}');
105+
const emoji = coverage > 80 ? '✅' : coverage > 60 ? '⚠️' : '❌';
106+
107+
github.rest.issues.createComment({
108+
issue_number: context.issue.number,
109+
owner: context.repo.owner,
110+
repo: context.repo.repo,
111+
body: `## Code Coverage Report ${emoji}\n\nCurrent coverage: **${coverage}%**`
112+
});
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Dependency Updates
2+
3+
on:
4+
schedule:
5+
# Run every Monday at 9 AM UTC
6+
- cron: '0 9 * * 1'
7+
workflow_dispatch:
8+
9+
jobs:
10+
update-dependencies:
11+
name: Update Swift Package Dependencies
12+
runs-on: macos-latest
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
with:
18+
token: ${{ secrets.GITHUB_TOKEN }}
19+
20+
- name: Select Xcode version
21+
run: sudo xcode-select -s /Applications/Xcode_15.4.app/Contents/Developer
22+
23+
- name: Update Swift packages
24+
run: |
25+
# Update all Swift package dependencies to latest versions
26+
xcodebuild -project V2er.xcodeproj \
27+
-scheme V2er \
28+
-resolvePackageDependencies \
29+
-scmProvider system
30+
31+
- name: Check for changes
32+
id: git-check
33+
run: |
34+
git diff --exit-code || echo "changes=true" >> $GITHUB_OUTPUT
35+
36+
- name: Create Pull Request
37+
if: steps.git-check.outputs.changes == 'true'
38+
uses: peter-evans/create-pull-request@v5
39+
with:
40+
token: ${{ secrets.GITHUB_TOKEN }}
41+
commit-message: 'chore: update Swift package dependencies'
42+
title: 'chore: update Swift package dependencies'
43+
body: |
44+
## Automated Dependency Update
45+
46+
This PR updates the Swift Package Manager dependencies to their latest compatible versions.
47+
48+
### Changes
49+
- Updated Package.resolved with latest dependency versions
50+
51+
### Checklist
52+
- [ ] Build passes with updated dependencies
53+
- [ ] Tests pass with updated dependencies
54+
- [ ] No breaking changes identified
55+
56+
Please review the dependency changes and ensure they don't introduce any breaking changes.
57+
58+
---
59+
*This PR was automatically created by the dependency update workflow.*
60+
branch: automated/dependency-updates
61+
delete-branch: true
62+
labels: |
63+
dependencies
64+
automated
65+
66+
check-vulnerabilities:
67+
name: Security Vulnerability Check
68+
runs-on: ubuntu-latest
69+
70+
steps:
71+
- name: Checkout repository
72+
uses: actions/checkout@v4
73+
74+
- name: Run security audit
75+
uses: actions/dependency-review-action@v3
76+
with:
77+
fail-on-severity: moderate
78+
79+
- name: Upload security report
80+
uses: actions/upload-artifact@v4
81+
if: failure()
82+
with:
83+
name: security-report
84+
path: dependency-review-report.json

.github/workflows/ios-build-test.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: iOS Build and Test
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
env:
11+
DEVELOPER_DIR: /Applications/Xcode.app/Contents/Developer
12+
13+
jobs:
14+
build-and-test:
15+
name: Build and Test
16+
runs-on: macos-latest
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
with:
22+
submodules: recursive
23+
24+
- name: Select Xcode version
25+
run: sudo xcode-select -s /Applications/Xcode_15.4.app/Contents/Developer
26+
27+
- name: Show Xcode version
28+
run: xcodebuild -version
29+
30+
- name: Install xcpretty
31+
run: gem install xcpretty
32+
33+
- name: Cache SPM packages
34+
uses: actions/cache@v4
35+
with:
36+
path: ~/Library/Developer/Xcode/DerivedData/**/SourcePackages
37+
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
38+
restore-keys: |
39+
${{ runner.os }}-spm-
40+
41+
- name: Resolve Swift packages
42+
run: |
43+
xcodebuild -resolvePackageDependencies \
44+
-project V2er.xcodeproj \
45+
-scheme V2er
46+
47+
- name: Build for testing
48+
run: |
49+
set -o pipefail && xcodebuild build-for-testing \
50+
-project V2er.xcodeproj \
51+
-scheme V2er \
52+
-sdk iphonesimulator \
53+
-destination 'platform=iOS Simulator,name=iPhone 15' \
54+
ONLY_ACTIVE_ARCH=YES \
55+
CODE_SIGN_IDENTITY="" \
56+
CODE_SIGNING_REQUIRED=NO | xcpretty --color
57+
58+
- name: Run tests
59+
run: |
60+
set -o pipefail && xcodebuild test-without-building \
61+
-project V2er.xcodeproj \
62+
-scheme V2er \
63+
-sdk iphonesimulator \
64+
-destination 'platform=iOS Simulator,name=iPhone 15' \
65+
ONLY_ACTIVE_ARCH=YES \
66+
CODE_SIGN_IDENTITY="" \
67+
CODE_SIGNING_REQUIRED=NO | xcpretty --color --test
68+
69+
- name: Upload test results
70+
uses: actions/upload-artifact@v4
71+
if: failure()
72+
with:
73+
name: test-results
74+
path: |
75+
~/Library/Logs/DiagnosticReports/
76+
~/Library/Developer/Xcode/DerivedData/**/Logs/Test/

0 commit comments

Comments
 (0)