CD #413
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CD | |
# | Platform | Nightly | Weekly (if diff HEAD) | TestFlight Tag | Post App Release | | |
# |-----------------|---------|------------------------|----------------|------------------| | |
# | macOS | ftp | app-store | app-store | ftp | | |
# | iOS | ftp | app-store | app-store | - | | |
# |-----------------|---------|------------------------|----------------|------------------| | |
# | VERSION | Date | get from project.yml | project.yml | project.yml | | |
# |-----------------|---------|------------------------|----------------|------------------| | |
# | UPLOAD_FOLDER | nightly | - | - | release | | |
# |-----------------|---------|------------------------|----------------|------------------| | |
on: | |
schedule: | |
- cron: '32 1 * * *' # NIGHTLY @ 01:32 | |
- cron: '00 2 * * 1' # WEEKLY @ 02:00 on Monday | |
push: | |
tags: | |
- testflight** # TestFlight Tag | |
release: | |
types: [published] # Post App Release | |
env: | |
KEYCHAIN: /Users/runner/build.keychain-db | |
KEYCHAIN_PASSWORD: mysecretpassword | |
KEYCHAIN_PROFILE: build-profile | |
SSH_KEY: /tmp/id_rsa | |
APPLE_STORE_AUTH_KEY_PATH: /tmp/authkey.p8 | |
APPLE_AUTH_PARAMS: "-authenticationKeyPath /tmp/authkey.p8 -authenticationKeyID ${{ secrets.APPLE_STORE_AUTH_KEY_ID }} -authenticationKeyIssuerID ${{ secrets.APPLE_STORE_AUTH_KEY_ISSUER_ID }}" | |
# conditionally updated later: | |
EXPORT_METHOD: "app-store" | |
EXTRA_XCODEBUILD: "" | |
UPLOAD_TO: "" # !important | |
VERSION: "" | |
SIGNING_CERTIFICATE: "" | |
SIGNING_CERTIFICATE_P12_PASSWORD: "" | |
jobs: | |
build_and_deploy: | |
strategy: | |
fail-fast: false | |
matrix: | |
platform: [iOS, macOS] | |
runs-on: macos-13 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Install python dependencies | |
run: pip install pyyaml==6.0.1 | |
- name: Set VERSION from code | |
shell: python | |
run: | | |
import yaml | |
import os | |
with open("project.yml") as yml_file: | |
project = yaml.safe_load(yml_file) | |
version = project['targets']['Kiwix']['settings']['base']['MARKETING_VERSION'] | |
with open(os.getenv("GITHUB_ENV"), "a") as fh: | |
fh.write(f"VERSION={version}\n") | |
- name: Get the date of last change | |
run: echo "DATE_OF_LAST_CHANGE=`git log -1 --format=%ct`" >> $GITHUB_ENV | |
- name: Check for code changes in the last week | |
shell: python | |
run: | | |
import datetime | |
import os | |
now = datetime.datetime.now() | |
last_change = datetime.datetime.fromtimestamp(int(os.getenv("DATE_OF_LAST_CHANGE"))) | |
value = "yes" if (now - last_change).days < 7 else "no" | |
with open(os.getenv("GITHUB_ENV"), "a") as fh: | |
fh.write(f"HAS_CHANGED_LAST_WEEK={value}\n") | |
- name: Nightly setup # use ftp and overrwrite VERSION with current date | |
if: github.event_name == 'schedule' && github.event.schedule == '32 1 * * *' | |
shell: python | |
run: | | |
import datetime | |
import os | |
version = str(datetime.date.today()) | |
with open(os.getenv("GITHUB_ENV"), "a") as fh: | |
fh.write(f"VERSION={version}\n") | |
fh.write(f"UPLOAD_TO=ftp\n") | |
fh.write(f"UPLOAD_FOLDER=nightly/{version}\n") | |
- name: Weekly setup | |
if: github.event_name == 'schedule' && github.event.schedule == '00 2 * * 1' && env.HAS_CHANGED_LAST_WEEK == 'yes' | |
run: echo "UPLOAD_TO=app-store" >> $GITHUB_ENV | |
- name: Testflight tag setup | |
if: github.event_name == 'push' | |
run: echo "UPLOAD_TO=app-store" >> $GITHUB_ENV | |
- name: Post App Release macOS setup | |
if: github.event_name == 'release' && matrix.platform == 'macOS' | |
run: | | |
echo "UPLOAD_TO=ftp" >> $GITHUB_ENV | |
echo "UPLOAD_FOLDER=release/kiwix-macos" >> $GITHUB_ENV | |
# Post App Release: skip steps for iOS, by leaving the UPLOAD_TO empty ("") | |
- name: Set iOS extra xcode params | |
if: matrix.platform == 'iOS' | |
run: echo "EXTRA_XCODEBUILD=-sdk iphoneos ${{ env.APPLE_AUTH_PARAMS }}" >> $GITHUB_ENV | |
- name: Set macOS FTP export method | |
if: matrix.platform == 'macOS' && env.UPLOAD_TO == 'ftp' | |
run: echo "EXPORT_METHOD=developer-id" >> $GITHUB_ENV | |
- name: Use Developer ID Certificate | |
if: env.UPLOAD_TO == 'ftp' && matrix.platform == 'macOS' | |
run: | | |
echo "SIGNING_CERTIFICATE=${{ secrets.APPLE_DEVELOPER_ID_SIGNING_CERTIFICATE }}" >> $GITHUB_ENV | |
echo "SIGNING_CERTIFICATE_P12_PASSWORD=${{ secrets.APPLE_DEVELOPER_ID_SIGNING_P12_PASSWORD }}" >> $GITHUB_ENV | |
echo "SIGNING_IDENTITY=${{ secrets.APPLE_DEVELOPER_ID_SIGNING_IDENTITY }}" >> $GITHUB_ENV | |
- name: Use Apple Development Certificate | |
if: env.UPLOAD_TO == 'ftp' && matrix.platform == 'iOS' | |
run: | | |
echo "SIGNING_CERTIFICATE=${{ secrets.APPLE_DEVELOPMENT_SIGNING_CERTIFICATE }}" >> $GITHUB_ENV | |
echo "SIGNING_CERTIFICATE_P12_PASSWORD=${{ secrets.APPLE_DEVELOPMENT_SIGNING_P12_PASSWORD }}" >> $GITHUB_ENV | |
echo "SIGNING_IDENTITY=${{ secrets.APPLE_DEVELOPMENT_SIGNING_IDENTITY }}" >> $GITHUB_ENV | |
- name: Use Apple Distribution Certificate | |
if: env.UPLOAD_TO == 'app-store' | |
run: | | |
echo "SIGNING_CERTIFICATE=${{ secrets.APPLE_DISTRIBUTION_SIGNING_CERTIFICATE }}" >> $GITHUB_ENV | |
echo "SIGNING_CERTIFICATE_P12_PASSWORD=${{ secrets.APPLE_DISTRIBUTION_SIGNING_P12_PASSWORD }}" >> $GITHUB_ENV | |
echo "SIGNING_IDENTITY=${{ secrets.APPLE_DEVELOPMENT_SIGNING_IDENTITY }}" >> $GITHUB_ENV | |
- name: Decode Apple Store Key | |
if: env.UPLOAD_TO != '' | |
run: echo "${{ secrets.APPLE_STORE_AUTH_KEY }}" | base64 --decode -o ${{ env.APPLE_STORE_AUTH_KEY_PATH }} | |
- name: Build xcarchive | |
uses: ./.github/actions/xcbuild | |
if: env.UPLOAD_TO != '' | |
with: | |
action: archive | |
xc-destination: generic/platform=${{ matrix.platform }} | |
version: ${{ env.VERSION }} | |
APPLE_DEVELOPMENT_SIGNING_CERTIFICATE: ${{ secrets.APPLE_DEVELOPMENT_SIGNING_CERTIFICATE }} | |
APPLE_DEVELOPMENT_SIGNING_P12_PASSWORD: ${{ secrets.APPLE_DEVELOPMENT_SIGNING_P12_PASSWORD }} | |
DEPLOYMENT_SIGNING_CERTIFICATE: ${{ env.SIGNING_CERTIFICATE }} | |
DEPLOYMENT_SIGNING_CERTIFICATE_P12_PASSWORD: ${{ env.SIGNING_CERTIFICATE_P12_PASSWORD }} | |
KEYCHAIN: ${{ env.KEYCHAIN }} | |
KEYCHAIN_PASSWORD: ${{ env.KEYCHAIN_PASSWORD }} | |
KEYCHAIN_PROFILE: ${{ env.KEYCHAIN_PROFILE }} | |
EXTRA_XCODEBUILD: ${{ env.EXTRA_XCODEBUILD }} | |
- name: Add altool credentials to Keychain | |
if: env.UPLOAD_TO == 'ftp' | |
env: | |
APPLE_SIGNING_ALTOOL_USERNAME: ${{ secrets.APPLE_SIGNING_ALTOOL_USERNAME }} | |
APPLE_SIGNING_ALTOOL_PASSWORD: ${{ secrets.APPLE_SIGNING_ALTOOL_PASSWORD }} | |
APPLE_SIGNING_TEAM: ${{ secrets.APPLE_SIGNING_TEAM }} | |
run: | | |
security find-identity -v $KEYCHAIN | |
security unlock-keychain -p $KEYCHAIN_PASSWORD $KEYCHAIN | |
xcrun notarytool store-credentials \ | |
--apple-id "${APPLE_SIGNING_ALTOOL_USERNAME}" \ | |
--password "${APPLE_SIGNING_ALTOOL_PASSWORD}" \ | |
--team-id "${APPLE_SIGNING_TEAM}" \ | |
--validate \ | |
--keychain $KEYCHAIN \ | |
$KEYCHAIN_PROFILE | |
- name: Prepare export for IPA | |
if: matrix.platform == 'iOS' && env.UPLOAD_TO == 'ftp' | |
run: | | |
plutil -create xml1 ./export.plist | |
plutil -insert method -string ad-hoc ./export.plist | |
plutil -insert provisioningProfiles -dictionary ./export.plist | |
plutil -replace provisioningProfiles -json '{ "self.Kiwix" : "iOS Team Provisioning Profile" }' ./export.plist | |
- name: Prepare export for not IPA | |
# else statement for Prepare export for IPA | |
# excluding UPLOAD_TO == '', which means skip upload | |
# [(macOS, ftp), (macOS, app-store), (iOS, app-store)] | |
if: matrix.platform != 'iOS' || env.UPLOAD_TO == 'app-store' | |
run: | | |
plutil -create xml1 ./export.plist | |
plutil -insert destination -string upload ./export.plist | |
plutil -insert method -string $EXPORT_METHOD ./export.plist | |
- name: Upload Archive to Apple (App Store or Notarization) | |
if: env.UPLOAD_TO != '' | |
env: | |
VERSION: ${{ env.VERSION }} | |
run: python .github/retry-if-retcode.py --sleep 60 --attempts 5 --retcode 70 xcrun xcodebuild -exportArchive -archivePath $PWD/Kiwix-$VERSION.xcarchive -exportPath $PWD/export/ -exportOptionsPlist export.plist -allowProvisioningUpdates ${{ env.APPLE_AUTH_PARAMS }} | |
- name: Export notarized App from archive | |
if: matrix.platform == 'macOS' && env.UPLOAD_TO == 'ftp' | |
run: python .github/retry-if-retcode.py --sleep 60 --attempts 20 --retcode 65 xcrun xcodebuild -exportNotarizedApp -archivePath $PWD/Kiwix-$VERSION.xcarchive -exportPath $PWD/export/ -allowProvisioningUpdates ${{ env.APPLE_AUTH_PARAMS }} | |
- name: Create and Notarize DMG | |
if: matrix.platform == 'macOS' && env.UPLOAD_TO == 'ftp' | |
run: | | |
pip install dmgbuild | |
dmgbuild -s .github/dmg-settings.py -Dapp=$PWD/export/Kiwix.app -Dbg=.github/dmg-bg.png "Kiwix-$VERSION" $PWD/kiwix-$VERSION.dmg | |
xcrun notarytool submit --keychain $KEYCHAIN --keychain-profile $KEYCHAIN_PROFILE --wait $PWD/kiwix-$VERSION.dmg | |
xcrun stapler staple $PWD/kiwix-$VERSION.dmg | |
- name: Add SSH_KEY to filesystem | |
if: env.UPLOAD_TO == 'ftp' | |
run: | | |
echo "${{ secrets.SSH_KEY }}" > $SSH_KEY | |
chmod 600 $SSH_KEY | |
- name: Upload DMG | |
if: env.UPLOAD_TO == 'ftp' && matrix.platform == 'macOS' | |
run: | | |
mv ${PWD}/kiwix-${VERSION}.dmg ${PWD}/kiwix-macos_${VERSION}.dmg | |
python .github/upload_file.py --src ${PWD}/kiwix-macos_${VERSION}.dmg --dest [email protected]:30022/data/download/${UPLOAD_FOLDER} --ssh-key ${SSH_KEY} | |
mv ${PWD}/kiwix-macos_${VERSION}.dmg ${PWD}/kiwix-${VERSION}.dmg | |
- name: Upload IPA | |
if: env.UPLOAD_TO == 'ftp' && matrix.platform == 'iOS' | |
run: | | |
mv ${PWD}/export/Kiwix.ipa ${PWD}/export/kiwix-${VERSION}.ipa | |
python .github/upload_file.py --src ${PWD}/export/kiwix-${VERSION}.ipa --dest [email protected]:30022/data/download/${UPLOAD_FOLDER} --ssh-key ${SSH_KEY} |