Skip to content

Commit 81216a0

Browse files
committed
Consolidate CI workflows
1 parent 295466e commit 81216a0

4 files changed

Lines changed: 188 additions & 392 deletions

File tree

.github/workflows/build.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
name: Build and Push
1+
name: Service Images
22

33
on:
44
push:
55
branches:
66
- main
7-
- dev
8-
pull_request:
9-
branches:
10-
- main
11-
- dev
127

138
env:
149
NODE_VERSION: "20"
@@ -58,7 +53,6 @@ jobs:
5853
docker:
5954
needs: build
6055
runs-on: ubuntu-latest
61-
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')
6256
steps:
6357
- uses: actions/checkout@v4
6458

@@ -100,3 +94,14 @@ jobs:
10094
ghcr.io/${{ github.repository_owner }}/monkeycode-frontend:${{ github.sha }}
10195
ghcr.io/${{ github.repository_owner }}/monkeycode-frontend:latest
10296
platforms: linux/amd64
97+
98+
- name: Build and push backend image
99+
uses: docker/build-push-action@v6
100+
with:
101+
context: backend
102+
file: backend/build/Dockerfile
103+
push: true
104+
tags: |
105+
ghcr.io/${{ github.repository_owner }}/monkeycode-backend:${{ github.sha }}
106+
ghcr.io/${{ github.repository_owner }}/monkeycode-backend:latest
107+
platforms: linux/amd64

.github/workflows/electron-release.yml

Lines changed: 176 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Android 产物为 release APK,需在仓库 Secrets 配置签名密钥:
44
# ANDROID_KEYSTORE_BASE64 / ANDROID_KEY_ALIAS / ANDROID_KEY_PASSWORD / ANDROID_STORE_PASSWORD
55

6-
name: Desktop & Android Release
6+
name: Client Release
77

88
on:
99
push:
@@ -22,7 +22,9 @@ concurrency:
2222

2323
env:
2424
NODE_VERSION: "20"
25+
RUBY_VERSION: "3.3"
2526
CSC_IDENTITY_AUTO_DISCOVERY: false
27+
IOS_BUNDLE_ID: "com.monkeycode.mobile"
2628

2729
jobs:
2830
electron-windows:
@@ -248,8 +250,128 @@ jobs:
248250
path: mobile/release-apk/*.apk
249251
if-no-files-found: error
250252

253+
capacitor-ios:
254+
runs-on: macos-latest
255+
steps:
256+
- uses: actions/checkout@v4
257+
258+
- uses: pnpm/action-setup@v4
259+
with:
260+
version: 9
261+
262+
- uses: actions/setup-node@v4
263+
with:
264+
node-version: ${{ env.NODE_VERSION }}
265+
cache: pnpm
266+
cache-dependency-path: |
267+
frontend/pnpm-lock.yaml
268+
mobile/pnpm-lock.yaml
269+
270+
- uses: ruby/setup-ruby@v1
271+
with:
272+
ruby-version: ${{ env.RUBY_VERSION }}
273+
274+
- name: Install fastlane gems
275+
working-directory: mobile/ios
276+
run: bundle install --jobs 4 --retry 3
277+
278+
- name: Set versions (tag / CI)
279+
shell: bash
280+
run: |
281+
set -euo pipefail
282+
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
283+
V="${GITHUB_REF_NAME#v}"
284+
else
285+
V="0.0.0-ci.${{ github.run_number }}"
286+
fi
287+
if [[ "$V" =~ ^[0-9]+\.[0-9]+$ ]]; then
288+
V="${V}.0"
289+
fi
290+
BUILD_NUMBER="${{ github.run_number }}"
291+
echo "APP_VERSION=$V" >> "$GITHUB_ENV"
292+
echo "BUILD_NUMBER=$BUILD_NUMBER" >> "$GITHUB_ENV"
293+
echo "IPA_NAME=MonkeyCode-${V}-ios-release.ipa" >> "$GITHUB_ENV"
294+
node -e "const fs=require('fs');const p='mobile/package.json';const j=JSON.parse(fs.readFileSync(p,'utf8'));j.version=process.argv[1];fs.writeFileSync(p,JSON.stringify(j,null,2)+'\n');" "$V"
295+
perl -0pi -e "s/MARKETING_VERSION = [^;]+;/MARKETING_VERSION = ${V};/g; s/CURRENT_PROJECT_VERSION = [^;]+;/CURRENT_PROJECT_VERSION = ${BUILD_NUMBER};/g" mobile/ios/App/App.xcodeproj/project.pbxproj
296+
297+
- name: Install frontend deps
298+
working-directory: frontend
299+
run: pnpm install --frozen-lockfile
300+
301+
- name: Install mobile deps
302+
working-directory: mobile
303+
run: pnpm install --frozen-lockfile
304+
305+
- name: Build frontend
306+
working-directory: frontend
307+
run: pnpm run build
308+
309+
- name: Capacitor sync iOS
310+
working-directory: mobile
311+
run: pnpm exec cap sync ios
312+
313+
- name: Install signing assets
314+
shell: bash
315+
env:
316+
IOS_CERTIFICATE_BASE64: ${{ secrets.IOS_CERTIFICATE_BASE64 }}
317+
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
318+
IOS_PROVISIONING_PROFILE_BASE64: ${{ secrets.IOS_PROVISIONING_PROFILE_BASE64 }}
319+
run: |
320+
set -euo pipefail
321+
: "${IOS_CERTIFICATE_BASE64:?Missing IOS_CERTIFICATE_BASE64}"
322+
: "${IOS_CERTIFICATE_PASSWORD:?Missing IOS_CERTIFICATE_PASSWORD}"
323+
: "${IOS_PROVISIONING_PROFILE_BASE64:?Missing IOS_PROVISIONING_PROFILE_BASE64}"
324+
CERT_PATH="$RUNNER_TEMP/build_certificate.p12"
325+
PROFILE_PATH="$RUNNER_TEMP/build_profile.mobileprovision"
326+
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
327+
KEYCHAIN_PASSWORD="$(openssl rand -base64 24)"
328+
echo "$IOS_CERTIFICATE_BASE64" | base64 -D > "$CERT_PATH"
329+
echo "$IOS_PROVISIONING_PROFILE_BASE64" | base64 -D > "$PROFILE_PATH"
330+
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
331+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
332+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
333+
security import "$CERT_PATH" -P "$IOS_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
334+
security list-keychains -d user -s "$KEYCHAIN_PATH"
335+
security default-keychain -s "$KEYCHAIN_PATH"
336+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
337+
mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles"
338+
security cms -D -i "$PROFILE_PATH" > "$RUNNER_TEMP/profile.plist"
339+
PROFILE_UUID=$(/usr/libexec/PlistBuddy -c "Print UUID" "$RUNNER_TEMP/profile.plist")
340+
PROFILE_NAME=$(/usr/libexec/PlistBuddy -c "Print Name" "$RUNNER_TEMP/profile.plist")
341+
cp "$PROFILE_PATH" "$HOME/Library/MobileDevice/Provisioning Profiles/$PROFILE_UUID.mobileprovision"
342+
echo "IOS_KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"
343+
echo "IOS_PROFILE_NAME=$PROFILE_NAME" >> "$GITHUB_ENV"
344+
345+
- name: Build iOS IPA
346+
working-directory: mobile/ios
347+
env:
348+
IOS_TEAM_ID: ${{ secrets.IOS_TEAM_ID }}
349+
IOS_BUNDLE_ID: ${{ env.IOS_BUNDLE_ID }}
350+
IOS_PROFILE_NAME: ${{ env.IOS_PROFILE_NAME }}
351+
IOS_OUTPUT_NAME: ${{ env.IPA_NAME }}
352+
run: bundle exec fastlane ios build_release
353+
354+
- name: Stage IPA for artifact / release
355+
shell: bash
356+
run: |
357+
test -f "mobile/ios/App/output/${IPA_NAME}"
358+
mkdir -p mobile/release-ios
359+
cp "mobile/ios/App/output/${IPA_NAME}" "mobile/release-ios/${IPA_NAME}"
360+
361+
- uses: actions/upload-artifact@v4
362+
with:
363+
name: capacitor-ios-ipa
364+
path: mobile/release-ios/*.ipa
365+
if-no-files-found: error
366+
367+
- name: Cleanup signing keychain
368+
if: always() && env.IOS_KEYCHAIN_PATH != ''
369+
shell: bash
370+
run: |
371+
security delete-keychain "$IOS_KEYCHAIN_PATH" || true
372+
251373
publish-release:
252-
needs: [electron-windows, electron-macos, capacitor-android]
374+
needs: [electron-windows, electron-macos, capacitor-android, capacitor-ios]
253375
if: startsWith(github.ref, 'refs/tags/v')
254376
runs-on: ubuntu-latest
255377
steps:
@@ -268,6 +390,11 @@ jobs:
268390
name: capacitor-android-apk
269391
path: release-assets/android
270392

393+
- uses: actions/download-artifact@v4
394+
with:
395+
name: capacitor-ios-ipa
396+
path: release-assets/ios
397+
271398
- name: List release files
272399
run: find release-assets -type f -exec ls -lh {} \;
273400

@@ -281,5 +408,52 @@ jobs:
281408
release-assets/windows/*
282409
release-assets/macos/*
283410
release-assets/android/*
411+
release-assets/ios/*
284412
env:
285413
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
414+
415+
ios-distribute:
416+
needs: [capacitor-ios, publish-release]
417+
if: startsWith(github.ref, 'refs/tags/v')
418+
runs-on: macos-latest
419+
steps:
420+
- uses: actions/checkout@v4
421+
422+
- uses: ruby/setup-ruby@v1
423+
with:
424+
ruby-version: ${{ env.RUBY_VERSION }}
425+
426+
- name: Install fastlane gems
427+
working-directory: mobile/ios
428+
run: bundle install --jobs 4 --retry 3
429+
430+
- uses: actions/download-artifact@v4
431+
with:
432+
name: capacitor-ios-ipa
433+
path: mobile/release-ios
434+
435+
- name: Resolve IPA path
436+
shell: bash
437+
run: |
438+
set -euo pipefail
439+
IPA_PATH="$(find mobile/release-ios -name '*.ipa' | head -1)"
440+
test -n "$IPA_PATH"
441+
echo "IOS_IPA_PATH=$IPA_PATH" >> "$GITHUB_ENV"
442+
443+
- name: Upload to TestFlight
444+
working-directory: mobile/ios
445+
env:
446+
IOS_IPA_PATH: ${{ env.IOS_IPA_PATH }}
447+
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
448+
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
449+
APP_STORE_CONNECT_PRIVATE_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY_BASE64 }}
450+
run: bundle exec fastlane ios upload_testflight ipa:"$IOS_IPA_PATH"
451+
452+
- name: Submit to App Store
453+
working-directory: mobile/ios
454+
env:
455+
IOS_IPA_PATH: ${{ env.IOS_IPA_PATH }}
456+
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
457+
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
458+
APP_STORE_CONNECT_PRIVATE_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY_BASE64 }}
459+
run: bundle exec fastlane ios submit_app_store ipa:"$IOS_IPA_PATH"

0 commit comments

Comments
 (0)