Skip to content

Commit f11fa9a

Browse files
committed
First attempt at semaphore build.
1 parent af90379 commit f11fa9a

16 files changed

Lines changed: 386 additions & 1 deletion

File tree

.gitignore

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,14 @@ ios/Runner/GoogleService-Info.plist
6666

6767
**/dgph
6868

69-
.crowdin-token
69+
.crowdin-token
70+
71+
# Fastlane
72+
**/fastlane/.next_version_code
73+
**/fastlane/google-play-service-account.json
74+
**/fastlane/report.xml
75+
**/fastlane/README.md
76+
77+
# Android signing (CI-injected)
78+
**/android/key.properties
79+
**/android/app/upload-keystore.jks

.semaphore/semaphore.yml

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
version: v1.0
2+
name: Build and deploy
3+
4+
agent:
5+
machine:
6+
type: f1-standard-4
7+
os_image: ubuntu2404
8+
9+
global_job_config:
10+
env_vars:
11+
- name: FLUTTER_VERSION
12+
value: 3.32.0
13+
14+
# Step 1: BCCM Android only. Kids Android, BCCM iOS, Kids iOS will be added
15+
# in subsequent steps once this path is green.
16+
17+
blocks:
18+
- name: Prep bccm version
19+
dependencies: []
20+
task:
21+
secrets:
22+
- name: android-play-store-api
23+
jobs:
24+
- name: Compute bccm versionCode
25+
commands:
26+
- checkout
27+
- sem-version ruby 3.2
28+
- cp /home/semaphore/google-play-service-account.json android/fastlane/google-play-service-account.json
29+
- cd android
30+
- bundle install
31+
- bundle exec fastlane next_version_code
32+
- export BUILD_NUMBER=$(cat fastlane/.next_version_code)
33+
- test -n "$BUILD_NUMBER" && test "$BUILD_NUMBER" -gt 0
34+
- echo "$BUILD_NUMBER" > /tmp/bccm_build_number
35+
- artifact push workflow /tmp/bccm_build_number -d bccm_build_number
36+
37+
- name: Build bccm Android
38+
dependencies: [Prep bccm version]
39+
task:
40+
secrets:
41+
- name: brunstadtv-env
42+
- name: android-keystore-bccm
43+
prologue:
44+
commands:
45+
- checkout
46+
- git submodule update --init --recursive
47+
- cp /home/semaphore/env.dart lib/env/.env.dart
48+
- sem-version java 17
49+
- cache restore flutter-sdk-linux-$FLUTTER_VERSION
50+
- |
51+
if [ ! -d "$HOME/flutter" ]; then
52+
wget -q https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz -O /tmp/flutter.tar.xz
53+
tar xf /tmp/flutter.tar.xz -C $HOME
54+
fi
55+
- cache store flutter-sdk-linux-$FLUTTER_VERSION $HOME/flutter
56+
- export PATH="$HOME/flutter/bin:$PATH"
57+
- flutter --version
58+
- export ANDROID_HOME="$HOME/android-sdk"
59+
- cache restore android-sdk
60+
- |
61+
if [ ! -d "$ANDROID_HOME/platforms/android-36" ]; then
62+
mkdir -p "$ANDROID_HOME/cmdline-tools"
63+
curl -sSL -o /tmp/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
64+
unzip -q /tmp/cmdline-tools.zip -d "$ANDROID_HOME/cmdline-tools"
65+
mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest"
66+
yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null
67+
"$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "platform-tools" "platforms;android-36" "build-tools;36.0.0"
68+
fi
69+
- cache store android-sdk $ANDROID_HOME
70+
- export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"
71+
jobs:
72+
- name: Build AAB
73+
commands:
74+
- artifact pull workflow bccm_build_number
75+
- export BUILD_NUMBER=$(cat bccm_build_number)
76+
- echo "Building with versionCode=$BUILD_NUMBER"
77+
- keystore_path="$(pwd)/android/app/upload-keystore.jks"
78+
- echo "$KEYSTORE_FILE" | base64 -d > "$keystore_path"
79+
- |
80+
cat > android/key.properties << EOF
81+
storePassword=$KEYSTORE_PASSWORD
82+
keyPassword=$KEY_PASSWORD
83+
keyAlias=$KEY_ALIAS
84+
storeFile=$keystore_path
85+
EOF
86+
- cache restore pub-linux-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml),pub-linux-$(checksum pubspec.yaml),pub-linux
87+
- make pubgetall
88+
- cache store pub-linux-$SEMAPHORE_GIT_BRANCH-$(checksum pubspec.yaml) $HOME/.pub-cache
89+
- flutter build appbundle --release --flavor prod -t lib/main_prod.dart --build-number=$BUILD_NUMBER
90+
- artifact push workflow build/app/outputs/bundle/prodRelease/app-prod-release.aab -d bccm.aab
91+
92+
- name: Deploy bccm Android
93+
dependencies: [Build bccm Android]
94+
run:
95+
when: "branch = 'master'"
96+
task:
97+
secrets:
98+
- name: android-play-store-api
99+
jobs:
100+
- name: Upload to Play (internal + beta)
101+
commands:
102+
- checkout
103+
- sem-version ruby 3.2
104+
- cp /home/semaphore/google-play-service-account.json android/fastlane/google-play-service-account.json
105+
- mkdir -p build/app/outputs/bundle/prodRelease
106+
- artifact pull workflow bccm.aab
107+
- mv bccm.aab build/app/outputs/bundle/prodRelease/app-prod-release.aab
108+
- cd android
109+
- bundle install
110+
- bundle exec fastlane upload

android/Gemfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "fastlane"
4+
gem "abbrev"
5+
gem "csv"

android/fastlane/Appfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
json_key_file("fastlane/google-play-service-account.json")
2+
package_name("tv.brunstad.app")

android/fastlane/Fastfile

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
default_platform(:android)
2+
3+
PACKAGE_NAME = 'tv.brunstad.app'
4+
AAB_PATH = '../build/app/outputs/bundle/prodRelease/app-prod-release.aab'
5+
JSON_KEY = 'fastlane/google-play-service-account.json'
6+
7+
platform :android do
8+
desc "Write next versionCode (max of all uploaded AABs/APKs + 1) to fastlane/.next_version_code"
9+
lane :next_version_code do
10+
# Play Console is the source of truth for versionCode. Query every version
11+
# ever uploaded — once a release is superseded, its code disappears from
12+
# track listings but Google still considers it used and will reject reuse.
13+
require 'supply'
14+
require 'supply/options'
15+
require 'supply/client'
16+
17+
Supply.config = FastlaneCore::Configuration.create(
18+
Supply::Options.available_options,
19+
{
20+
package_name: PACKAGE_NAME,
21+
json_key: File.join(__dir__, 'google-play-service-account.json'),
22+
track: 'internal'
23+
}
24+
)
25+
26+
client = Supply::Client.make_from_config
27+
client.begin_edit(package_name: PACKAGE_NAME)
28+
codes = []
29+
begin
30+
codes.concat(Array(client.aab_version_codes))
31+
codes.concat(Array(client.apks_version_codes))
32+
ensure
33+
client.abort_current_edit
34+
end
35+
36+
codes = codes.compact.map(&:to_i)
37+
next_code = (codes.max || 0) + 1
38+
UI.message "Found #{codes.size} previously uploaded version codes (max=#{codes.max || 'none'})"
39+
UI.message "Next versionCode for #{PACKAGE_NAME}: #{next_code}"
40+
File.write(File.join(__dir__, '.next_version_code'), next_code.to_s)
41+
end
42+
43+
desc "Upload AAB to internal and promote to beta"
44+
lane :upload do
45+
upload_to_play_store(
46+
package_name: PACKAGE_NAME,
47+
track: 'internal',
48+
aab: AAB_PATH,
49+
json_key: JSON_KEY,
50+
skip_upload_changelogs: true,
51+
skip_upload_images: true,
52+
skip_upload_screenshots: true,
53+
skip_upload_metadata: true,
54+
skip_upload_apk: true
55+
)
56+
57+
# Promote the just-uploaded release from internal to beta in the same run.
58+
upload_to_play_store(
59+
package_name: PACKAGE_NAME,
60+
track: 'internal',
61+
track_promote_to: 'beta',
62+
json_key: JSON_KEY,
63+
skip_upload_aab: true,
64+
skip_upload_apk: true,
65+
skip_upload_changelogs: true,
66+
skip_upload_images: true,
67+
skip_upload_screenshots: true,
68+
skip_upload_metadata: true
69+
)
70+
end
71+
end

ios/ExportOptions.plist

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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</string>
7+
<key>teamID</key>
8+
<string>6734NUF6AV</string>
9+
<key>signingStyle</key>
10+
<string>manual</string>
11+
<key>provisioningProfiles</key>
12+
<dict>
13+
<key>tv.brunstad.app</key>
14+
<string>BCC Media AppStore</string>
15+
</dict>
16+
<key>stripSwiftSymbols</key>
17+
<true/>
18+
<key>uploadSymbols</key>
19+
<true/>
20+
</dict>
21+
</plist>

ios/Gemfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "fastlane"
4+
gem "abbrev"
5+
gem "csv"

ios/fastlane/Appfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
app_identifier("tv.brunstad.app")
2+
team_id("6734NUF6AV")

ios/fastlane/Fastfile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
default_platform(:ios)
2+
3+
APPLE_TEAM_ID = '6734NUF6AV'
4+
APP_IDENTIFIER = 'tv.brunstad.app'
5+
6+
platform :ios do
7+
desc "Upload to TestFlight — internal + external Beta group"
8+
lane :testflight do
9+
api_key = app_store_connect_api_key(
10+
key_id: ENV['APP_STORE_CONNECT_KEY_ID'],
11+
issuer_id: ENV['APP_STORE_CONNECT_ISSUER_ID'],
12+
key_filepath: "#{Dir.home}/.private_keys/AuthKey_#{ENV['APP_STORE_CONNECT_KEY_ID']}.p8",
13+
in_house: false
14+
)
15+
16+
upload_to_testflight(
17+
api_key: api_key,
18+
app_identifier: APP_IDENTIFIER,
19+
team_id: APPLE_TEAM_ID,
20+
ipa: '../build/ios/ipa/bccm.ipa',
21+
distribute_external: true,
22+
groups: ['Beta'],
23+
skip_waiting_for_build_processing: false,
24+
changelog: 'Automated build from master'
25+
)
26+
end
27+
end

kids/android/Gemfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "fastlane"
4+
gem "abbrev"
5+
gem "csv"

0 commit comments

Comments
 (0)