Skip to content

Commit b15dec2

Browse files
committed
ci: Add GitHub Actions, Dependabot, CODEOWNERS, and PR template
- Add CI workflow (Swift build on macOS runner) - Add release workflow (DMG build + GitHub release + Homebrew update) - Add Dependabot for GitHub Actions and Swift dependencies - Add CODEOWNERS (assigns @GeiserX to all PRs) - Add PR template with testing checklist - Fix Homebrew cask URLs (vpn-macos-bypass → VPNBypass)
1 parent 86c5277 commit b15dec2

6 files changed

Lines changed: 310 additions & 2 deletions

File tree

.github/CODEOWNERS

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Default owner for all files
2+
* @GeiserX
3+
4+
# Source code
5+
/Sources/ @GeiserX
6+
/Helper/ @GeiserX
7+
8+
# Infrastructure and CI
9+
/.github/ @GeiserX
10+
/Makefile @GeiserX
11+
12+
# Documentation
13+
/docs/ @GeiserX
14+
/*.md @GeiserX

.github/dependabot.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
version: 2
2+
3+
updates:
4+
# GitHub Actions - keep workflows up to date
5+
- package-ecosystem: "github-actions"
6+
directory: "/"
7+
schedule:
8+
interval: "monthly"
9+
commit-message:
10+
prefix: "ci"
11+
labels:
12+
- "ci"
13+
- "automated"
14+
groups:
15+
github-actions:
16+
patterns:
17+
- "*"
18+
ignore:
19+
# Ignore major version updates - review manually
20+
- dependency-name: "*"
21+
update-types: ["version-update:semver-major"]
22+
23+
# Swift Package Manager dependencies
24+
- package-ecosystem: "swift"
25+
directory: "/"
26+
schedule:
27+
interval: "weekly"
28+
day: "monday"
29+
commit-message:
30+
prefix: "deps"
31+
labels:
32+
- "dependencies"
33+
- "automated"
34+
open-pull-requests-limit: 5

.github/pull_request_template.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## Summary
2+
3+
<!-- Describe the change in 1-2 bullets -->
4+
5+
-
6+
7+
## Type of Change
8+
9+
- [ ] Bug fix (non-breaking change that fixes an issue)
10+
- [ ] New feature (non-breaking change that adds functionality)
11+
- [ ] Breaking change (fix or feature that causes existing functionality to change)
12+
- [ ] Documentation update
13+
14+
## Testing
15+
16+
- [ ] Tested on macOS Ventura (13+)
17+
- [ ] Tested on macOS Sonoma (14+)
18+
- [ ] Tested with VPN connected
19+
- [ ] Tested with VPN disconnected
20+
21+
## Checklist
22+
23+
- [ ] Code builds without warnings (`make build`)
24+
- [ ] App bundle creates successfully (`make bundle`)
25+
- [ ] No hardcoded credentials or secrets
26+
- [ ] Updated CHANGELOG.md (if applicable)
27+
28+
## Screenshots (if applicable)
29+
30+
<!-- Add screenshots for UI changes -->
31+

.github/workflows/ci.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
# Cancel in-progress runs when a new commit is pushed
10+
concurrency:
11+
group: ci-${{ github.event.pull_request.number || github.ref }}
12+
cancel-in-progress: true
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
build:
19+
name: Build
20+
runs-on: macos-14 # macOS Sonoma with Apple Silicon
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v4
25+
26+
- name: Setup Xcode
27+
uses: maxim-lobanov/setup-xcode@v1
28+
with:
29+
xcode-version: latest-stable
30+
31+
- name: Build main app
32+
run: swift build -c release
33+
34+
- name: Build helper
35+
run: make build-helper
36+
37+
- name: Create app bundle
38+
run: make bundle
39+
40+
- name: Verify bundle structure
41+
run: |
42+
echo "📦 Checking app bundle..."
43+
test -d "VPN Bypass.app" || { echo "❌ App bundle not created"; exit 1; }
44+
test -f "VPN Bypass.app/Contents/MacOS/VPNBypass" || { echo "❌ Main executable missing"; exit 1; }
45+
test -f "VPN Bypass.app/Contents/MacOS/com.geiserx.vpnbypass.helper" || { echo "❌ Helper missing"; exit 1; }
46+
test -f "VPN Bypass.app/Contents/Info.plist" || { echo "❌ Info.plist missing"; exit 1; }
47+
echo "✅ App bundle structure verified"
48+
49+
- name: Upload build artifact
50+
uses: actions/upload-artifact@v4
51+
with:
52+
name: VPNBypass-app
53+
path: "VPN Bypass.app"
54+
retention-days: 7
55+
56+
summary:
57+
name: CI Summary
58+
runs-on: ubuntu-latest
59+
needs: [build]
60+
if: always()
61+
62+
steps:
63+
- name: Check results
64+
run: |
65+
if [ "${{ needs.build.result }}" != "success" ]; then
66+
echo "❌ CI failed"
67+
exit 1
68+
fi
69+
echo "✅ All checks passed"

.github/workflows/release.yml

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
version:
10+
description: 'Version to release (e.g., 1.2.0)'
11+
required: true
12+
type: string
13+
14+
permissions:
15+
contents: write
16+
17+
jobs:
18+
release:
19+
name: Build and Release
20+
runs-on: macos-14
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 0
27+
28+
- name: Setup Xcode
29+
uses: maxim-lobanov/setup-xcode@v1
30+
with:
31+
xcode-version: latest-stable
32+
33+
- name: Determine version
34+
id: version
35+
run: |
36+
if [ -n "${{ github.event.inputs.version }}" ]; then
37+
VERSION="${{ github.event.inputs.version }}"
38+
else
39+
VERSION="${GITHUB_REF#refs/tags/v}"
40+
fi
41+
echo "version=$VERSION" >> $GITHUB_OUTPUT
42+
echo "📦 Building version: $VERSION"
43+
44+
- name: Update Info.plist version
45+
run: |
46+
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${{ steps.version.outputs.version }}" Info.plist
47+
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${{ steps.version.outputs.version }}" Info.plist
48+
49+
- name: Build release
50+
run: make release
51+
52+
- name: Calculate SHA256
53+
id: sha
54+
run: |
55+
SHA256=$(shasum -a 256 dist/VPNBypass-${{ steps.version.outputs.version }}.dmg | awk '{print $1}')
56+
echo "sha256=$SHA256" >> $GITHUB_OUTPUT
57+
echo "📝 SHA256: $SHA256"
58+
59+
- name: Generate changelog
60+
id: changelog
61+
run: |
62+
VERSION="v${{ steps.version.outputs.version }}"
63+
PREV_TAG=$(git tag -l "v*" --sort=-version:refname | sed -n '2p')
64+
65+
if [ -z "$PREV_TAG" ]; then
66+
PREV_TAG=$(git rev-list --max-parents=0 HEAD)
67+
fi
68+
69+
echo "📝 Generating changelog from $PREV_TAG to $VERSION"
70+
71+
{
72+
echo "## What's Changed"
73+
echo ""
74+
75+
# Features
76+
FEATURES=$(git log $PREV_TAG..HEAD --pretty=format:"- %s" --grep="^feat" 2>/dev/null || true)
77+
if [ -n "$FEATURES" ]; then
78+
echo "### ✨ Features"
79+
echo "$FEATURES" | head -20
80+
echo ""
81+
fi
82+
83+
# Fixes
84+
FIXES=$(git log $PREV_TAG..HEAD --pretty=format:"- %s" --grep="^fix" 2>/dev/null || true)
85+
if [ -n "$FIXES" ]; then
86+
echo "### 🐛 Bug Fixes"
87+
echo "$FIXES" | head -20
88+
echo ""
89+
fi
90+
91+
# Other changes
92+
OTHERS=$(git log $PREV_TAG..HEAD --pretty=format:"- %s" --invert-grep --grep="^feat" --invert-grep --grep="^fix" 2>/dev/null | head -10 || true)
93+
if [ -n "$OTHERS" ]; then
94+
echo "### 🔧 Other Changes"
95+
echo "$OTHERS"
96+
echo ""
97+
fi
98+
99+
echo "---"
100+
echo ""
101+
echo "## Installation"
102+
echo ""
103+
echo "### Homebrew (recommended)"
104+
echo '```bash'
105+
echo "brew tap GeiserX/vpn-bypass"
106+
echo "brew install --cask vpn-bypass"
107+
echo '```'
108+
echo ""
109+
echo "### Manual Download"
110+
echo "Download \`VPNBypass-${{ steps.version.outputs.version }}.dmg\` from the assets below."
111+
echo ""
112+
echo "---"
113+
echo ""
114+
echo "**SHA256:** \`${{ steps.sha.outputs.sha256 }}\`"
115+
echo ""
116+
echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...$VERSION"
117+
} > changelog.md
118+
119+
cat changelog.md
120+
121+
- name: Create GitHub Release
122+
uses: softprops/action-gh-release@v2
123+
with:
124+
tag_name: v${{ steps.version.outputs.version }}
125+
name: "VPNBypass v${{ steps.version.outputs.version }}"
126+
body_path: changelog.md
127+
draft: false
128+
prerelease: false
129+
files: |
130+
dist/VPNBypass-${{ steps.version.outputs.version }}.dmg
131+
132+
- name: Update Homebrew Cask
133+
env:
134+
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
135+
run: |
136+
if [ -z "$HOMEBREW_TAP_TOKEN" ]; then
137+
echo "⚠️ HOMEBREW_TAP_TOKEN not set, skipping Homebrew update"
138+
echo "To enable automatic Homebrew updates, add a PAT with repo scope as HOMEBREW_TAP_TOKEN secret"
139+
exit 0
140+
fi
141+
142+
VERSION="${{ steps.version.outputs.version }}"
143+
SHA256="${{ steps.sha.outputs.sha256 }}"
144+
145+
# Clone homebrew tap
146+
git clone "https://x-access-token:${HOMEBREW_TAP_TOKEN}@github.com/GeiserX/homebrew-vpn-bypass.git" homebrew-tap
147+
cd homebrew-tap
148+
149+
# Update cask file
150+
sed -i '' "s/version \".*\"/version \"$VERSION\"/" Casks/vpn-bypass.rb
151+
sed -i '' "s/sha256 \".*\"/sha256 \"$SHA256\"/" Casks/vpn-bypass.rb
152+
153+
# Commit and push
154+
git config user.name "github-actions[bot]"
155+
git config user.email "github-actions[bot]@users.noreply.github.com"
156+
git add Casks/vpn-bypass.rb
157+
git commit -m "Update vpn-bypass to v$VERSION"
158+
git push
159+
160+
echo "✅ Homebrew cask updated to v$VERSION"

Casks/vpn-bypass.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
version "1.1.0"
77
sha256 "37b127a55aec0bdb80e824e59e840ce5b529c09086aac7fc24dc4616abb817bd"
88

9-
url "https://github.com/GeiserX/vpn-macos-bypass/releases/download/v#{version}/VPNBypass-#{version}.dmg"
9+
url "https://github.com/GeiserX/VPNBypass/releases/download/v#{version}/VPNBypass-#{version}.dmg"
1010
name "VPN Bypass"
1111
desc "macOS menu bar app to route specific traffic around VPN"
12-
homepage "https://github.com/GeiserX/vpn-macos-bypass"
12+
homepage "https://github.com/GeiserX/VPNBypass"
1313

1414
depends_on macos: ">= :ventura"
1515

0 commit comments

Comments
 (0)