-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
528 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,242 @@ | ||
# This workflow is meant to be called remotely from a Skip app project. | ||
# | ||
# The action will build and test both the Swift and Gradle projects | ||
# transpiled through Skip. | ||
# | ||
# When tagged with a semantic version (e.g., "1.2.3"), the action will | ||
# create and distribute release .apk and .ipa artifacts from the project. | ||
# | ||
# An example invocation script is as follows, which runs for | ||
# every push, every PR, every semver tag, and every day at noon GMT: | ||
# | ||
# name: skipapp | ||
# on: | ||
# push: | ||
# branches: '*' | ||
# tags: "[0-9]+.[0-9]+.[0-9]+" | ||
# schedule: | ||
# - cron: '0 12 * * *' | ||
# workflow_dispatch: | ||
# pull_request: | ||
# | ||
# permissions: | ||
# contents: write | ||
# | ||
# jobs: | ||
# call-workflow: | ||
# uses: skiptools/actions/.github/workflows/skip-app.yml@main | ||
# | ||
name: "Skip App CI" | ||
on: | ||
workflow_call: | ||
jobs: | ||
skip-app: | ||
runs-on: macos-14 | ||
timeout-minutes: 120 | ||
env: | ||
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer | ||
steps: | ||
- uses: gradle/actions/setup-gradle@v3 | ||
with: | ||
gradle-version: current | ||
generate-job-summary: false | ||
|
||
- run: brew install skiptools/skip/skip | ||
|
||
- uses: actions/checkout@v4 | ||
with: | ||
submodules: 'recursive' | ||
|
||
- name: Setup | ||
run: | | ||
# convert "refs/tags/1.0.0" to "1.0.0" | ||
# and "refs/heads/main" to "main" | ||
TAG=${GITHUB_REF#refs/*/} | ||
# the version if it matches the semantic tag pattern, otherwise "dev" | ||
echo "RELTAG=${TAG:-'dev'}" >> $GITHUB_ENV | ||
# the path to generate the artifacts (.ipa, .apk, etc.) | ||
echo "RELDIR=Skip/build/artifacts" >> $GITHUB_ENV | ||
echo "COMMIT_DATE=$(git log -1 --format=%ad --date=iso-strict ${TAG})" >> $GITHUB_ENV | ||
# the primary skip module is the first product name | ||
#SKIP_MODULE=$(swift package dump-package | jq -r '.products[0].name') | ||
SKIP_MODULE=$(basename Darwin/*.xcodeproj .xcodeproj) | ||
echo "SKIP_MODULE=${SKIP_MODULE}" >> $GITHUB_ENV | ||
XCODE_SETTINGS=$(xcodebuild -showBuildSettings -json -project Darwin/${SKIP_MODULE}.xcodeproj -scheme "${SKIP_MODULE}") | ||
# log the build settings | ||
echo "${XCODE_SETTINGS}" | jq . | ||
# update Skip.env to set version string to the latest semver tag | ||
sed -i '' "s;MARKETING_VERSION = .*;MARKETING_VERSION = $(git describe --tags --abbrev=0 --match '[0-9]*\.[0-9]*\.[0-9]*' --first-parent);g" Skip.env | ||
# update Skip.env to set build number to the git commit count | ||
sed -i '' "s;PRODUCT_VERSION = .*;PRODUCT_VERSION = $(git rev-list --count HEAD);g" Skip.env | ||
- name: Verify Skip App | ||
run: skip verify | ||
|
||
- name: Run Tests | ||
run: test ! -d Tests || skip test || skip test -v | ||
|
||
- name: Export project | ||
run: | | ||
skip export || skip export -v | ||
# output exported AAR sizes table to the job summary | ||
echo "Artifact | Size" >> $GITHUB_STEP_SUMMARY | ||
echo "--- | ---" >> $GITHUB_STEP_SUMMARY | ||
for file in .build/skip-export/[dr]e*/*/*.*; do | ||
fileSize=$(du -sh "$file" | cut -f1) | ||
fileName=$(basename $file) | ||
echo "\`$fileName\` | \`$fileSize\`" >> $GITHUB_STEP_SUMMARY | ||
done | ||
echo "" >> $GITHUB_STEP_SUMMARY | ||
- name: Build iOS ipa | ||
run: | | ||
if [ -f "Darwin/fastlane/Fastfile" ]; then | ||
cd Darwin/ | ||
#fastlane ios assemble | ||
cd - | ||
fi | ||
mkdir -p ${RELDIR} | ||
APPARTIFACT="${SKIP_MODULE}" | ||
#export NOSKIP=1 | ||
for CONFIGURATION in "Debug" "Release"; do | ||
ARCHIVE_PATH=".build/Darwin/Archives/${CONFIGURATION}/${APPARTIFACT}.xcarchive" | ||
SKIP_ZERO=1 xcodebuild -project Darwin/${SKIP_MODULE}.xcodeproj -derivedDataPath .build/Darwin/DerivedData -skipPackagePluginValidation -archivePath "${ARCHIVE_PATH}" -configuration "${CONFIGURATION}" -scheme "${SKIP_MODULE}" -sdk "iphoneos" -destination "generic/platform=iOS" -jobs 1 archive CODE_SIGNING_ALLOWED=NO SKIP_ACTION=build ZERO_AR_DATE=1 | ||
brew install tree | ||
tree "${ARCHIVE_PATH}" | ||
cd "${ARCHIVE_PATH}"/Products/ | ||
find . -type f | ||
mv "Applications" "Payload" | ||
# create zip file with reproducible timestamps | ||
find "Payload" -exec touch -t 197001010000 {} \; | ||
zip -9 -r "${APPARTIFACT}-${CONFIGURATION}.ipa" "Payload" | ||
cd - | ||
cp -av "${ARCHIVE_PATH}/Products/${APPARTIFACT}-${CONFIGURATION}.ipa" ${RELDIR}/ | ||
done | ||
- name: Build Android apk | ||
run: | | ||
if [ -f "Android/fastlane/Fastfile" ]; then | ||
cd Android/ | ||
#fastlane android assemble | ||
cd - | ||
fi | ||
skip gradle -p Android assemble | ||
cp -av .build/Android/app/outputs/apk/*/*.apk ${RELDIR}/ | ||
ls -la ${RELDIR}/ | ||
shasum -a 256 ${RELDIR}/*.apk | ||
- name: Archive Swift Source | ||
run: | | ||
# create the source zip file with predictable timestamps for reproducibility | ||
find . -exec touch -d "${COMMIT_DATE:0:19}" {} \; | ||
mkdir -p ${RELDIR}/ | ||
# create 2 zips: one with the Package.resolved for reproducibility, | ||
zip -9 -r "${RELDIR}/App-Source.zip" . -x "Skip/*" -x ".*/*" | ||
|
||
# and the other without the Package.resolved for templating. | ||
TEMPLATE_FILE="${RELDIR}/skip-template-source.zip" | ||
zip -9 -r "${TEMPLATE_FILE}" . -x "Package.resolved" -x "Skip/*" -x ".git/*" -x ".build/*" -x ".swiftpm/*" | ||
|
||
# verify that the template can be used to derive a new app | ||
#skip app create --template-file "${TEMPLATE_FILE}" --build --test $(mktemp -d) | ||
|
||
- name: Prepare Artifacts | ||
run: | | ||
APPNAME="${SKIP_MODULE}" | ||
mkdir -p ${RELDIR}/ | ||
cp -a .build/skip-export ${RELDIR}/ | ||
# merge the ipa and apk zips into a single archive | ||
cd ${RELDIR}/ | ||
ls -la | ||
APPZ="${SKIP_MODULE}.appz" | ||
IPA="${APPNAME}-Release.ipa" | ||
# the .apk name will default to the name of the enclosing module | ||
# (e.g., "SkipWeather-release.apk" rather than "SkipWeather-") | ||
APPMODULE="${APPNAME}" | ||
#APK="${APPMODULE}-release.apk" | ||
APK="app-release.apk" | ||
APK_DEBUG="app-debug.apk" | ||
APK_UNSIGNED="app-release-unsigned.apk" | ||
# in case the APK has the -unsigned suffix, move it to the APK | ||
mv -v ${APK_UNSIGNED} ${APK} || true | ||
TMPDIR=$(mktemp -d) | ||
unzip -q "$IPA" -d "$TMPDIR" | ||
cp "${APK}" "${TMPDIR}/.source.apk" | ||
cd "${TMPDIR}" | ||
zip -qr9 ".source.apk" ./* | ||
cd - | ||
mv "${TMPDIR}/.source.apk" "${APPZ}" | ||
shasum -a 256 ${APK} ${IPA} ${APPZ} | ||
ls -lah ${APK} ${IPA} ${APPZ} | ||
mv -v ${APK} ${APPNAME}-android-${RELTAG}.apk | ||
mv -v ${APK_DEBUG} ${APPNAME}-android-${RELTAG}-debug.apk | ||
mv -v ${APPNAME}-Release.ipa ${APPNAME}-ios-${RELTAG}.ipa | ||
mv -v ${APPNAME}-Debug.ipa ${APPNAME}-ios-${RELTAG}-debug.ipa | ||
# fix artifact names for release (retain App-Source.zip for template) | ||
#mv -v App-Source.zip ${APPNAME}-ios-${RELTAG}-source.zip | ||
#mv -v App-android-source.zip ${APPNAME}-android-${RELTAG}-source.zip | ||
mv -v ${APPZ} ${APPNAME}-${RELTAG}.appz | ||
# output file sizes table to the job summary | ||
echo "Artifact | Size" >> $GITHUB_STEP_SUMMARY | ||
echo "--- | ---" >> $GITHUB_STEP_SUMMARY | ||
for file in *.apk *.ipa; do | ||
fileSize=$(du -sh "$file" | cut -f1) | ||
fileName=$(basename $file) | ||
#echo "::set-output name=$fileName::$fileSize" | ||
echo "\`$fileName\` | \`$fileSize\`" >> $GITHUB_STEP_SUMMARY | ||
done | ||
echo "" >> $GITHUB_STEP_SUMMARY | ||
# move debug build out of release candidates | ||
mkdir debug | ||
mv *-debug.* debug/ | ||
mv *.appz debug/ | ||
# finally create the checksums file for everything remaining | ||
shasum -a 256 *.* > checksums.txt | ||
# sign the checksums file | ||
#echo "$SKIP_SIGNING_KEY" | gpg --import | ||
#gpg --clearsign --yes --output checksums.txt.asc checksums.txt | ||
env: | ||
SKIP_SIGNING_KEY: ${{ secrets.SKIP_SIGNING_KEY }} | ||
|
||
|
||
- name: "Release" | ||
if: startsWith(github.ref, 'refs/tags/') | ||
env: | ||
GH_TOKEN: ${{ github.token }} | ||
run: | | ||
echo "Creating release: ${RELTAG}" | ||
cd ${RELDIR}/ | ||
gh release create "${RELTAG}" -t "Release ${RELTAG}" --generate-notes *.* | ||
- name: "Upload Build Artifacts" | ||
# upload the artifacts generated from each build | ||
uses: actions/upload-artifact@v4 | ||
if: always() | ||
with: | ||
path: Skip/build/artifacts/ | ||
|
Oops, something went wrong.