Skip to content

fix: add dialyzer ignore file for pre-existing type errors #23

fix: add dialyzer ignore file for pre-existing type errors

fix: add dialyzer ignore file for pre-existing type errors #23

name: Build Android Runtimes
on:
workflow_dispatch:
push:
branches:
- ci-modularization
- android-test
# Only allow one build at a time, cancel in-progress runs on new push
concurrency:
group: android-build-${{ github.ref }}
cancel-in-progress: true
env:
OPENSSL_VERSION: '3.4.0'
OPENSSL_HASH: '002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3'
OTP_SOURCE: https://github.com/erlang/otp
jobs:
define-matrix:
name: Define Build Matrix
runs-on: ubuntu-latest
outputs:
platforms: ${{ steps.set-matrix.outputs.platforms }}
erlixir: ${{ steps.set-matrix.outputs.erlixir }}
nifs: ${{ steps.set-matrix.outputs.nifs }}
flavors: ${{ steps.set-matrix.outputs.flavors }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
sparse-checkout: .github/config
- name: Load matrix configuration
id: set-matrix
run: |
PLATFORMS=$(jq -c '.platform' .github/config/android-platforms.json)
ERLIXIR=$(jq -c '.erlixir' .github/config/erlixir-versions.json)
NIFS=$(jq -c '.nifs' .github/config/nif-packages.json)
FLAVORS=$(jq -c '.flavors' .github/config/flavors.json)
echo "platforms=$PLATFORMS" >> "$GITHUB_OUTPUT"
echo "erlixir=$ERLIXIR" >> "$GITHUB_OUTPUT"
echo "nifs=$NIFS" >> "$GITHUB_OUTPUT"
echo "flavors=$FLAVORS" >> "$GITHUB_OUTPUT"
echo "Loaded $(echo $PLATFORMS | jq length) Android platforms"
echo "Loaded $(echo $ERLIXIR | jq length) erlixir versions"
echo "Loaded $(echo $NIFS | jq length) NIF packages"
echo "Loaded $(echo $FLAVORS | jq length) flavors"
build-otp:
name: OTP - ${{ matrix.platform.name }} OTP${{ matrix.erlixir.otp-version }}
runs-on: ubuntu-latest
needs: define-matrix
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.define-matrix.outputs.platforms) }}
erlixir: ${{ fromJson(needs.define-matrix.outputs.erlixir) }}
env:
ARCH_IDENTIFIER: ${{ matrix.platform.arch_id }}-${{ matrix.platform.android_name }}-${{ matrix.platform.abi }}
OTP_VERSION: ${{ matrix.erlixir.otp-version }}
OTP_TAG: OTP-${{ matrix.erlixir.otp-version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Elixir
uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.erlixir.otp-version }}
elixir-version: ${{ matrix.erlixir.elixir-version }}
- name: Cache OTP source
uses: actions/cache@v4
id: otp-source-cache
with:
path: _build/otp_cache
key: android-otp-source-${{ matrix.erlixir.otp-version }}
- name: Download OTP source
if: steps.otp-source-cache.outputs.cache-hit != 'true'
run: |
mkdir -p _build/otp_cache
curl -L -O https://github.com/erlang/otp/releases/download/OTP-${{ matrix.erlixir.otp-version }}/otp_src_${{ matrix.erlixir.otp-version }}.tar.gz
mv otp_src_${{ matrix.erlixir.otp-version }}.tar.gz _build/otp_cache/
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pre-pull dockcross base image
run: |
for i in 1 2 3 4 5; do
echo "Attempt $i to pull dockcross/android-${{ matrix.platform.arch_id }}:20250311-4bd0eec"
if docker pull dockcross/android-${{ matrix.platform.arch_id }}:20250311-4bd0eec; then
break
fi
echo "Pull failed, waiting before retry..."
sleep $((30 * i))
done
docker images | grep dockcross || echo "Warning: dockcross image may not be cached"
- name: Generate BEAM Dockerfile
id: generate-dockerfile
env:
KERL_CONFIGURE_OPTIONS: ${{ matrix.erlixir.erl-opts }}
run: |
mix deps.get
MIX_TARGET=prod mix compile
mix run -e 'Mix.Tasks.Package.Android.Runtime.write_beam_dockerfile("${{ matrix.platform.arch_id }}", "${{ github.workspace }}/_build/Dockerfile_android-beam-${{ matrix.platform.arch_id }}")'
echo "Generated Dockerfile:"
cat "_build/Dockerfile_android-beam-${{ matrix.platform.arch_id }}"
- name: Build Android BEAM Docker image
uses: whoan/docker-build-with-cache-action@v8
if: steps.generate-dockerfile.outcome == 'success'
id: buildx-beam
with:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
registry: ghcr.io
image_name: android_beam
image_tag: 'arch_${{ env.ARCH_IDENTIFIER }}-${{ matrix.erlixir.otp-version }}'
dockerfile: '_build/Dockerfile_android-beam-${{ matrix.platform.arch_id }}'
build_extra_args: |
--platform=linux/amd64
--build-arg ARCH=${{ matrix.platform.arch_id }}
--build-arg ANDROID_NAME=${{ matrix.platform.android_name }}
--build-arg ABI=${{ matrix.platform.abi }}
--build-arg OPENSSL_VERSION=${{ env.OPENSSL_VERSION }}
--build-arg OPENSSL_HASH=${{ env.OPENSSL_HASH }}
--build-arg OTP_SOURCE=${{ env.OTP_SOURCE }}
--build-arg OTP_TAG=OTP-${{ matrix.erlixir.otp-version }}
- name: Build Android runtime
if: steps.buildx-beam.outcome == 'success'
env:
ARCH: ${{ matrix.platform.arch_id }}
BUILDER_IMAGE: ghcr.io/${{ github.repository_owner }}/android_beam:arch_${{ env.ARCH_IDENTIFIER }}-${{ matrix.erlixir.otp-version }}
run: |
docker images
mix package.android.runtime --arch ${{ matrix.platform.arch_id }}
- name: List build artifacts
run: |
find _build -name "*.zip" -o -name "*.so" -o -name "liberlang*" 2>/dev/null || true
ls -la _build/ || true
- name: Report build metrics
run: |
echo "### Android OTP (${{ matrix.platform.name }} OTP${{ matrix.erlixir.otp-version }})" >> $GITHUB_STEP_SUMMARY
du -sh _build/ >> $GITHUB_STEP_SUMMARY || true
- name: Upload Android OTP artifact
uses: actions/upload-artifact@v4
with:
name: android-otp-${{ matrix.platform.id }}-OTP-${{ matrix.erlixir.otp-version }}
path: _build/*.zip
if-no-files-found: warn
build-nifs:
name: NIF - ${{ matrix.nif.name }} ${{ matrix.platform.name }}
runs-on: ubuntu-latest
needs: [define-matrix, build-otp]
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.define-matrix.outputs.platforms) }}
nif: ${{ fromJson(needs.define-matrix.outputs.nifs) }}
env:
ARCH_IDENTIFIER: ${{ matrix.platform.arch_id }}-${{ matrix.platform.android_name }}-${{ matrix.platform.abi }}
# Required by generate_beam_dockerfile even for NIF builds (must match an OTP version from erlixir-versions.json)
OTP_VERSION: '27.3.4.2'
OTP_TAG: OTP-27.3.4.2
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Elixir
uses: erlef/setup-beam@v1
with:
otp-version: 27.3.4.2
elixir-version: 1.18.2
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pull BEAM Docker image
run: |
docker pull ghcr.io/${{ github.repository_owner }}/android_beam:arch_${{ env.ARCH_IDENTIFIER }}-27.3.4.2 || \
docker pull ghcr.io/${{ github.repository_owner }}/android_beam:arch_${{ env.ARCH_IDENTIFIER }}-28.0.2 || \
echo "Warning: Could not pull BEAM image, NIF build may fail"
- name: Build NIF ${{ matrix.nif.name }}
env:
ARCH: ${{ matrix.platform.arch_id }}
BASE_IMAGE: ghcr.io/${{ github.repository_owner }}/android_beam:arch_${{ env.ARCH_IDENTIFIER }}-27.3.4.2
run: |
mix deps.get
MIX_TARGET=prod mix compile
mix package.android.nif --arch ${{ matrix.platform.arch_id }} --flavor vanilla || echo "NIF build completed with warnings"
- name: List NIF artifacts
run: |
find _build -name "*nif*.zip" -o -name "*.so" 2>/dev/null || true
ls -la _build/ || true
- name: Upload NIF artifact
uses: actions/upload-artifact@v4
with:
name: android-nif-${{ matrix.nif.name }}-${{ matrix.platform.id }}
path: _build/*nif*.zip
if-no-files-found: warn
package:
name: Package - ${{ matrix.flavor.name }} ${{ matrix.platform.name }} OTP${{ matrix.erlixir.otp-version }}
runs-on: ubuntu-latest
needs: [define-matrix, build-otp, build-nifs]
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.define-matrix.outputs.platforms) }}
erlixir: ${{ fromJson(needs.define-matrix.outputs.erlixir) }}
flavor: ${{ fromJson(needs.define-matrix.outputs.flavors) }}
steps:
- name: Download OTP artifact
uses: actions/download-artifact@v4
with:
name: android-otp-${{ matrix.platform.id }}-OTP-${{ matrix.erlixir.otp-version }}
path: artifacts/otp
- name: Download NIF artifacts for flavor
run: |
mkdir -p artifacts/nifs
# Download only NIFs needed for this flavor
FLAVOR_NIFS='${{ toJson(matrix.flavor.nifs) }}'
echo "Downloading NIFs for ${{ matrix.flavor.name }} flavor: $FLAVOR_NIFS"
for nif in $(echo "$FLAVOR_NIFS" | jq -r '.[]'); do
echo "Looking for android-nif-${nif}-${{ matrix.platform.id }}"
gh run download ${{ github.run_id }} \
--name "android-nif-${nif}-${{ matrix.platform.id }}" \
--dir artifacts/nifs || echo "NIF $nif not found (may be C NIF)"
done
env:
GH_TOKEN: ${{ github.token }}
- name: List all artifacts
run: |
echo "=== OTP artifacts ==="
find artifacts/otp -type f || true
echo "=== NIF artifacts for ${{ matrix.flavor.name }} flavor ==="
find artifacts/nifs -type f || true
- name: Generate checksums
run: |
cd artifacts
find . -name "*.zip" -exec sha256sum {} \; > checksums.txt
echo "Flavor: ${{ matrix.flavor.name }}" >> checksums.txt
echo "NIFs: ${{ toJson(matrix.flavor.nifs) }}" >> checksums.txt
cat checksums.txt
- name: Upload combined artifact
uses: actions/upload-artifact@v4
with:
name: android-${{ matrix.flavor.name }}-${{ matrix.platform.id }}-OTP-${{ matrix.erlixir.otp-version }}
path: artifacts/
if-no-files-found: warn