Skip to content

CD

CD #504

Workflow file for this run

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}