Skip to content

Build CartoMobileSDK #208

Build CartoMobileSDK

Build CartoMobileSDK #208

Workflow file for this run

name: Build CartoMobileSDK
permissions:
contents: write
on:
workflow_dispatch:
inputs:
version:
required: false
description: 'version number'
publish:
description: "Should we publish on Github?"
default: true
required: true
type: boolean
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
variants: ${{ steps.set.outputs.variants }}
profiles: ${{ steps.set.outputs.profiles }}
steps:
- id: set
run: |
echo 'variants=["android","ios"]' >> $GITHUB_OUTPUT
echo 'profiles=["standard+valhalla","standard", "lite"]' >> $GITHUB_OUTPUT
create-release:
runs-on: ubuntu-latest
if: github.event.inputs.publish == 'true'
outputs:
RELEASE_UPLOAD_ID: ${{ steps.create_release.outputs.id }}
VERSION: ${{ steps.get_version_or_prompt.outputs.result }}
VERSION_TAG: v${{ steps.get_version_or_prompt.outputs.result }}
steps:
- name: setup node
uses: actions/setup-node@v4
with:
node-version: lts/*
- uses: actions/github-script@v6
id: get_version_or_prompt
with:
result-encoding: string
script: |
if ("${{ github.event.inputs.version }}".length) {
return "${{ github.event.inputs.version }}";
}
- name: create release
id: create_release
uses: ncipollo/release-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# This pulls from the "Get Changelog Entry" step above, referencing it's ID to get its outputs object.
# See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
tag: v${{ steps.get_version_or_prompt.outputs.result }}
name: v${{ steps.get_version_or_prompt.outputs.result }}
draft: true
token: ${{ secrets.GITHUB_TOKEN }}
build:
permissions:
contents: write
strategy:
matrix:
variant: ${{ fromJson(needs.prepare.outputs.variants) }}
profile: ${{ fromJson(needs.prepare.outputs.profiles) }}
runs-on: ${{ matrix.variant == 'android' && 'ubuntu-latest' || 'macos-latest' }}
needs: [create-release, prepare]
if: always()
name: "CartoMobileSDK ${{ matrix.variant }} - Profile: ${{ matrix.profile }}"
steps:
- name: Runner platform name
run: |
export PLATFORM_UP=${{ runner.os }}
echo "PLATFORM_UP=$PLATFORM_UP"
echo "PLATFORM=$(echo "$PLATFORM_UP" | tr "[:upper:]" "[:lower:]")" >>${GITHUB_ENV}
echo "PLATFORM=${{ env.PLATFORM }}"
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: maxim-lobanov/setup-xcode@7f352e61cbe8130c957c3bc898c4fb025784ea1e
if: matrix.variant == 'ios'
with:
xcode-version: 16.4
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
- name: Setup JDK
uses: actions/setup-java@v4
if: matrix.variant == 'android'
with:
java-version: 17
distribution: 'temurin'
- name: Setup Android SDK
if: matrix.variant == 'android'
uses: android-actions/setup-android@v3
# - if: matrix.variant == 'android'
# name: run SDKManager
# run: sdkmanager "build-tools;30.0.3"
- uses: nttld/[email protected]
if: matrix.variant == 'android'
id: setup-ndk
with:
ndk-version: r27
add-to-path: true
link-to-sdk: true
local-cache: true
# TODO revisit after some updates of nttld/setup-ndk
- name: Restore Android Symlinks
run: |
directory="${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin"
find "$directory" -type l | while read link; do
current_target=$(readlink "$link")
new_target="$directory/$(basename "$current_target")"
ln -sf "$new_target" "$link"
echo "Changed $(basename "$link") from $current_target to $new_target"
done
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: "8.14.3"
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: ensure dist
run: |
mkdir dist
- name: fetch externals
run: |
git submodule update --init --remote --recursive
- name: Install build tools
if: matrix.variant == 'android'
run: |
sudo apt-get install autoconf automake libtool build-essential
- name: Install build tools
if: matrix.variant == 'ios'
run: |
brew install autoconf automake libtool
- name: prepare boost
run: |
wget -q -O boost_1_89_0.zip https://sourceforge.net/projects/boost/files/boost/1.89.0/boost_1_89_0.zip
unzip -q boost_1_89_0.zip
ln -s ../boost_1_89_0 libs-external/boost
cd boost_1_89_0
./bootstrap.sh
./b2 headers
- name: Build CSS2XML
if: matrix.profile == 'lite'
run: |
cd libs-carto/cartocss/util
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
cd build
make css2xml
mv css2xml css2xml_${{ env.PLATFORM }}
zip ../../../../dist/css2xml_${{ env.PLATFORM }}.zip css2xml_${{ env.PLATFORM }}
- name: Build swig
if: matrix.variant == 'android'
run: |
git clone https://github.com/farfromrefug/mobile-swig.git
cd mobile-swig
wget https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.44/pcre2-10.44.tar.gz
./Tools/pcre-build.sh
./autogen.sh
./configure
make
- name: Build swig
if: matrix.variant == 'ios'
run: |
git clone https://github.com/farfromrefug/mobile-swig.git
cd mobile-swig
wget https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.44/pcre2-10.44.tar.gz
./Tools/pcre-build.sh
./autogen.sh
./configure
make
- name: Build swig-objc
if: matrix.variant == 'ios'
run: |
cd scripts
python swigpp-objc.py --profile ${{ matrix.profile }} --swig ../mobile-swig/swig
- name: Build swig-java
if: matrix.variant == 'android'
run: |
cd scripts
python swigpp-java.py --profile ${{ matrix.profile }} --swig ../mobile-swig/swig
- name: Build CartoSDK for Android
if: matrix.variant == 'android'
run: |
cd scripts
python build-android.py --profile ${{ matrix.profile }} --build-aar --build-version ${{ github.event.inputs.version }} --configuration=Release
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- name: Build CartoSDK for IOS
if: matrix.variant == 'ios'
run: |
cd scripts
python build-ios.py --profile ${{ matrix.profile }} --build-version ${{ github.event.inputs.version }} --configuration=Release --build-xcframework --use-metalangle
- name: Upload Release Asset
if: github.event.inputs.publish == 'true' && matrix.profile == 'lite'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload ${{ needs.create-release.outputs.VERSION_TAG }} dist/css2xml_*.zip
- name: Upload Release Asset
if: github.event.inputs.publish == 'true' && matrix.variant == 'android'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
ls -la dist/android
gh release upload ${{ needs.create-release.outputs.VERSION_TAG }} dist/android/*.aar
- name: Upload Release Asset
if: github.event.inputs.publish == 'true' && matrix.variant == 'ios'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload ${{ needs.create-release.outputs.VERSION_TAG }} dist/ios_metal/*.zip
- uses: actions/upload-artifact@v4
if: github.event.inputs.publish != 'true' && matrix.variant == 'ios'
with:
name: CartoSDK-{{matrix.variant}}-{{ matrix.profile }}
path: |
dist/ios_metal/*.zip
retention-days: 7
if-no-files-found: error
- name: Write checksum JSON
if: github.event.inputs.publish == 'true' && matrix.variant == 'ios'
run: |
SHA=$(sha256sum dist/ios_metal/*.zip | awk '{print $1}')
printf '{"%s":"%s"}\n' "${{ matrix.profile }}" "$SHA" > dist/checksum-${{ matrix.profile }}.json
- uses: actions/upload-artifact@v4
if: github.event.inputs.publish == 'true' && matrix.variant == 'ios'
with:
name: ios-checksum-${{ matrix.profile }}
path: dist/checksum-${{ matrix.profile }}.json
- uses: actions/upload-artifact@v4
if: github.event.inputs.publish != 'true' && matrix.variant == 'android'
with:
name: CartoSDK-{{matrix.variant}}-{{ matrix.profile }}
path: |
dist/android/*android*.aar
retention-days: 7
if-no-files-found: error
- uses: actions/upload-artifact@v4
if: github.event.inputs.publish != 'true' && matrix.profile == 'lite'
with:
name: CartoSDK-{{matrix.variant}}-{{ matrix.profile }}-css2xml
path: |
dist/css2xml_*.zip
retention-days: 7
if-no-files-found: error
- name: Rollback Release
if: failure()
uses: author/action-rollback@stable
with:
release_id: ${{ needs.create-release.outputs.RELEASE_UPLOAD_ID }}
tag: v${{ github.event.inputs.version }}
# If the release does not exist but the tag does, setting this to true will remove the tag.
delete_orphan_tag: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
create-jitpack-swiftpackage-release:
runs-on: ubuntu-latest
needs: [prepare, build]
if: github.event.inputs.publish == 'true'
permissions:
contents: write # release changes require contents write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oleksiyrudenko/[email protected]
with:
token: '${{ secrets.GITHUB_TOKEN }}'
global: true
actor: farfromrefug
name: Martin Guillon
email: [email protected]
- name: Checkout mobile-sdk-android-aar
uses: actions/checkout@v4
with:
repository: Akylas/mobile-sdk-android-aar
token: '${{ secrets.AAR_SWIFT_TOKEN }}'
path: mobile-sdk-android-aar
- name: Generate jitpack.yml then publish/tag
run: |
PROFILES_CSV=$(echo '${{ needs.prepare.outputs.profiles }}' | python3 -c 'import json,sys; print(",".join(json.load(sys.stdin)))')
cd mobile-sdk-android-aar
python ../scripts/generate-jitpack.py --version ${{ github.event.inputs.version }} --profiles $PROFILES_CSV
mv -f ../dist/android/jitpack.yml ./
git add jitpack.yml
git commit -m "Automated update jitpack.yml for version ${{ github.event.inputs.version }} and profile $PROFILES_CSV"
git push origin main
git tag ${{ github.event.inputs.version }}
git push origin ${{ github.event.inputs.version }}
- name: Download ios checksum artifacts
uses: actions/download-artifact@v4
with:
path: ios-checksums
- name: Download only ios-checksum artifacts (no zips/aar)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
RUN_ID: ${{ github.run_id }}
run: |
set -euo pipefail
mkdir -p ios-checksums
echo "Listing artifacts for run $RUN_ID in $REPO"
artifacts_json=$(curl -s -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
"https://api.github.com/repos/$REPO/actions/artifacts?per_page=100")
# Filter artifact list to ios-checksum-* entries and write JSON list to a temp file
echo "$artifacts_json" | python3 - <<'PY' > /tmp/ios_checks_list.json
import json,sys
data = json.load(sys.stdin)
artifacts = data.get("artifacts", [])
out = []
for a in artifacts:
name = a.get("name","")
if name.startswith("ios-checksum-"):
out.append({"name": name, "id": a.get("id"), "url": a.get("archive_download_url")})
print(json.dumps(out))
PY
count=$(jq 'length' /tmp/ios_checks_list.json)
if [ "$count" -eq 0 ]; then
echo "No ios-checksum-* artifacts found"
exit 0
fi
for i in $(seq 0 $((count-1))); do
url=$(jq -r ".[$i].url" /tmp/ios_checks_list.json)
name=$(jq -r ".[$i].name" /tmp/ios_checks_list.json)
echo "Downloading artifact $name"
curl -sL -H "Authorization: Bearer $GITHUB_TOKEN" -o /tmp/artifact.zip "$url"
unzip -o /tmp/artifact.zip -d ios-checksums >/dev/null
rm -f /tmp/artifact.zip
done
- name: Merge ios checksums
run: |
python3 - <<'PY'
import json,glob,sys
out={}
for fn in glob.glob('ios-checksums/*.json'):
try:
with open(fn,'r') as f:
out.update(json.load(f))
except Exception as e:
print("warning reading", fn, e, file=sys.stderr)
with open('combined_ios_checksums.json','w') as f:
json.dump(out,f)
print('Wrote combined_ios_checksums.json with keys:', list(out.keys()))
PY
- name: Generate Package.swift using precomputed checksums and publish/tag
run: |
PROFILES_CSV=$(echo '${{ needs.prepare.outputs.profiles }}' | python3 -c 'import json,sys; print(",".join(json.load(sys.stdin)))')
cd mobile-sdk-ios-swift
# pass checksums file path relative to repo path
python ../scripts/generate-swiftpackage.py --version ${{ github.event.inputs.version }} --profiles "$PROFILES_CSV" --checksums-file ../combined_ios_checksums.json
mv -f ../dist/ios_metal/Package.swift ./
git add Package.swift
git commit -m "Automated update Package.swift from workflow for new release" || true
git push origin main
git tag ${{ github.event.inputs.version }}
git push origin ${{ github.event.inputs.version }}
update-release:
runs-on: ubuntu-latest
needs: [create-release, build, create-jitpack-swiftpackage-release]
if: github.event.inputs.publish == 'true'
permissions:
contents: write # release changes require contents write
steps:
# we need to do this so that the tag is created now that the build worked
- name: Update release
uses: irongut/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
id: ${{ needs.create-release.outputs.RELEASE_UPLOAD_ID }}
prerelease: true
draft: false
- name: Update CHANGELOG
id: changelog
uses: requarks/changelog-action@v1
with:
useGitmojis: false
excludeTypes: build,docs,other,style,chore,perf,doc
token: ${{ secrets.GITHUB_TOKEN }}
tag: v${{ github.event.inputs.version }}
- name: Commit CHANGELOG.md
uses: stefanzweifel/git-auto-commit-action@v4
with:
branch: master
commit_message: 'docs: update CHANGELOG.md for ${{ github.ref_name }} [skip ci]'
file_pattern: CHANGELOG.md
- name: Update release
uses: irongut/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
id: ${{ needs.create-release.outputs.RELEASE_UPLOAD_ID }}
body: ${{ steps.changelog.outputs.changes }}
prerelease: true
draft: false