Skip to content

Commit 0aeac42

Browse files
committed
build: first release
1 parent 6888c52 commit 0aeac42

File tree

3 files changed

+173
-1
lines changed

3 files changed

+173
-1
lines changed

.github/workflows/release.yml

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# iOS Release Workflow
2+
name: Release
3+
4+
on:
5+
workflow_dispatch:
6+
7+
jobs:
8+
release:
9+
runs-on: macos-latest
10+
permissions:
11+
contents: write
12+
defaults:
13+
run:
14+
working-directory: client
15+
steps:
16+
- uses: actions/checkout@v6
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Analyze commits and bump version
21+
id: version
22+
run: |
23+
# Get last tag or use initial version
24+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
25+
echo "Last tag: $LAST_TAG"
26+
27+
# Get commits since last tag
28+
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s" 2>/dev/null || git log --pretty=format:"%s")
29+
30+
# Determine bump type from conventional commits
31+
BUMP="none"
32+
if echo "$COMMITS" | grep -qE "^(feat|fix|refactor|perf|build)(\(.+\))?!:|BREAKING CHANGE:"; then
33+
BUMP="major"
34+
elif echo "$COMMITS" | grep -qE "^feat(\(.+\))?:"; then
35+
BUMP="minor"
36+
elif echo "$COMMITS" | grep -qE "^(fix|perf|refactor|build)(\(.+\))?:"; then
37+
BUMP="patch"
38+
fi
39+
40+
if [ "$BUMP" = "none" ]; then
41+
echo "No conventional commits found. Skipping release."
42+
echo "skip=true" >> $GITHUB_OUTPUT
43+
exit 0
44+
fi
45+
46+
# Extract current version
47+
CURRENT=$(grep '^version:' pubspec.yaml | sed 's/version: //' | cut -d'+' -f1)
48+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
49+
50+
case "$BUMP" in
51+
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
52+
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
53+
patch) PATCH=$((PATCH + 1)) ;;
54+
esac
55+
56+
NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
57+
BUILD_NUMBER=$(date +%Y%m%d%H%M)
58+
59+
# Update pubspec.yaml
60+
sed -i '' "s/^version: .*/version: ${NEW_VERSION}+${BUILD_NUMBER}/" pubspec.yaml
61+
62+
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
63+
echo "build=${BUILD_NUMBER}" >> $GITHUB_OUTPUT
64+
echo "bump=${BUMP}" >> $GITHUB_OUTPUT
65+
echo "skip=false" >> $GITHUB_OUTPUT
66+
echo "Bumping $BUMP: $CURRENT -> $NEW_VERSION"
67+
68+
- name: Skip if no release needed
69+
if: steps.version.outputs.skip == 'true'
70+
run: |
71+
echo "No releasable commits found. Use conventional commits:"
72+
echo " feat: ... (minor bump)"
73+
echo " fix: ... (patch bump)"
74+
echo " feat!: ... or BREAKING CHANGE: (major bump)"
75+
exit 1
76+
77+
- uses: subosito/flutter-action@v2
78+
with:
79+
flutter-version: "3.38.5"
80+
channel: "stable"
81+
cache: true
82+
83+
- name: Install Apple certificate and provisioning profile
84+
env:
85+
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
86+
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
87+
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
88+
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
89+
run: |
90+
# Create variables
91+
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
92+
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
93+
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
94+
95+
# Import certificate and provisioning profile from secrets
96+
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
97+
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
98+
99+
# Create temporary keychain
100+
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
101+
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
102+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
103+
104+
# Import certificate to keychain
105+
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
106+
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
107+
security list-keychain -d user -s $KEYCHAIN_PATH
108+
109+
# Apply provisioning profile
110+
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
111+
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
112+
113+
- name: Install dependencies
114+
run: flutter pub get
115+
116+
- name: Install CocoaPods
117+
run: cd ios && pod install
118+
119+
- name: Build IPA
120+
run: flutter build ipa --release --export-options-plist=ios/ExportOptions.plist
121+
122+
- name: Clean up keychain
123+
if: always()
124+
run: security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
125+
126+
- name: Upload to App Store Connect
127+
uses: apple-actions/upload-testflight-build@v4
128+
with:
129+
app-path: client/build/ios/ipa/*.ipa
130+
issuer-id: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
131+
api-key-id: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
132+
api-private-key: ${{ secrets.APP_STORE_CONNECT_API_PRIVATE_KEY }}
133+
134+
- name: Commit version bump
135+
run: |
136+
git config user.name "github-actions[bot]"
137+
git config user.email "github-actions[bot]@users.noreply.github.com"
138+
git add pubspec.yaml
139+
git commit -m "chore(release): v${{ steps.version.outputs.version }}"
140+
git push
141+
142+
- name: Create GitHub Release
143+
uses: softprops/action-gh-release@v2
144+
with:
145+
tag_name: v${{ steps.version.outputs.version }}
146+
name: v${{ steps.version.outputs.version }}
147+
generate_release_notes: true

client/ios/ExportOptions.plist

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>method</key>
6+
<string>app-store-connect</string>
7+
<key>destination</key>
8+
<string>upload</string>
9+
<key>signingStyle</key>
10+
<string>manual</string>
11+
<key>provisioningProfiles</key>
12+
<dict>
13+
<key>dev.fadigeorge.travelorganizer</key>
14+
<string>Travel Organizer App</string>
15+
</dict>
16+
</dict>
17+
</plist>

client/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@
473473
buildSettings = {
474474
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
475475
CLANG_ENABLE_MODULES = YES;
476+
CODE_SIGN_IDENTITY = "Apple Development";
477+
CODE_SIGN_STYLE = Automatic;
476478
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
477479
DEVELOPMENT_TEAM = Y76TUYCQ8B;
478480
ENABLE_BITCODE = NO;
@@ -483,6 +485,7 @@
483485
);
484486
PRODUCT_BUNDLE_IDENTIFIER = dev.fadigeorge.travelorganizer;
485487
PRODUCT_NAME = "$(TARGET_NAME)";
488+
PROVISIONING_PROFILE_SPECIFIER = "";
486489
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
487490
SWIFT_VERSION = 5.0;
488491
VERSIONING_SYSTEM = "apple-generic";
@@ -679,8 +682,11 @@
679682
buildSettings = {
680683
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
681684
CLANG_ENABLE_MODULES = YES;
685+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
686+
CODE_SIGN_STYLE = Manual;
682687
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
683-
DEVELOPMENT_TEAM = Y76TUYCQ8B;
688+
DEVELOPMENT_TEAM = "";
689+
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = Y76TUYCQ8B;
684690
ENABLE_BITCODE = NO;
685691
INFOPLIST_FILE = Runner/Info.plist;
686692
LD_RUNPATH_SEARCH_PATHS = (
@@ -689,6 +695,8 @@
689695
);
690696
PRODUCT_BUNDLE_IDENTIFIER = dev.fadigeorge.travelorganizer;
691697
PRODUCT_NAME = "$(TARGET_NAME)";
698+
PROVISIONING_PROFILE_SPECIFIER = "";
699+
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Travel Organizer App";
692700
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
693701
SWIFT_VERSION = 5.0;
694702
VERSIONING_SYSTEM = "apple-generic";

0 commit comments

Comments
 (0)