Skip to content

Build via Dockerfile #178

Build via Dockerfile

Build via Dockerfile #178

name: Build via Dockerfile
on:
workflow_dispatch:
inputs:
package:
required: true
type: string
version:
required: true
type: string
python_version:
required: true
type: string
workflow_call:
inputs:
package:
required: true
type: string
version:
required: true
type: string
python_version:
required: true
type: string
jobs:
calculate_matrix:
name: Calculate build matrix
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install required packages
run: |
pip install pyyaml
- name: Get build strategy
working-directory: packages/${{ inputs.package }}
run: |
echo STRATEGY=$(cat build.yaml | yq .strategy) >> $GITHUB_ENV
- uses: nick-fields/assert-action@v2
with:
expected: "dockerfile"
actual: ${{ env.STRATEGY }}
comparison: exact
- name: Calculate build matrix
id: gen_matrix
working-directory: packages/${{ inputs.package }}
run: |
set -x
echo "::set-output name=matrix::$(cat build.yaml | ../../scripts/extract_dockerfile_matrix.py)"
echo "::set-output name=matrix_last::$(cat build.yaml | ../../scripts/extract_dockerfile_matrix.py | jq 'length')"
outputs:
build_matrix: ${{ steps.gen_matrix.outputs.matrix }}
build_matrix_last: ${{ steps.gen_matrix.outputs.matrix_last }}
build:
name: Python ${{ inputs.python_version }} ${{ inputs.package }} ${{ inputs.version }} ${{ fromJSON(needs.calculate_matrix.outputs.build_matrix_last) == 1 && ' ' || matrix.build_params['key'] }}
runs-on: ${{ matrix.build_params['extended'] && 'self-hosted' || 'ubuntu-latest' }}
timeout-minutes: ${{ matrix.build_params['extended'] && 7200 || 360 }}
needs: calculate_matrix
strategy:
matrix:
build_params: ${{ fromJSON(needs.calculate_matrix.outputs.build_matrix) }}
fail-fast: true
max-parallel: 1
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Create scoped tmpdir
run: |
mkdir -p /tmp/gha-run-${{ github.run_id }}-${{ github.run_attempt }}
echo "GHA_TMPDIR=/tmp/gha-run-${{ github.run_id }}-${{ github.run_attempt }}" >> $GITHUB_ENV
- name: Calculate previous build number
if: ${{ matrix.build_params['key'] != 1 }}
run: |
echo "PREVIOUS=$((${{ matrix.build_params['key'] }} - 1))" >> $GITHUB_ENV
- name: Download artifact
uses: actions/download-artifact@v4
if: ${{ matrix.build_params['key'] != 1 }}
with:
name: ${{ inputs.package }}-${{ inputs.version }}-cpython${{ inputs.python_version }}-dockerstage${{ env.PREVIOUS }}
path: ${{ env.GHA_TMPDIR }}
- name: Load image
if: ${{ matrix.build_params['key'] != 1 }}
run: |
docker load --input ${{ env.GHA_TMPDIR }}/stage.tar
docker image ls -a
rm ${{ env.GHA_TMPDIR }}/stage.tar
- name: Push image to local registry
if: ${{ matrix.build_params['key'] != 1 }}
run: |
docker image tag armv7l:latest localhost:5000/base:latest
docker image push localhost:5000/base:latest
docker system prune -a -f
- name: Calculate cache tag
if: ${{ !matrix.build_params['common'] }}
run: |
echo "CACHE_TAG=${{ github.ref }}-${{ inputs.package }}-${{ inputs.version }}-${{ inputs.python_version }}-${{ matrix.build_params['key'] }}" >> $GITHUB_ENV
- name: Calculate cache tag (common)
if: ${{ matrix.build_params['common'] }}
run: |
echo "CACHE_TAG=${{ github.ref }}-${{ inputs.package }}-${{ inputs.version }}-common-${{ matrix.build_params['key'] }}" >> $GITHUB_ENV
- name: Build wheels via Docker
uses: docker/build-push-action@v6
with:
context: packages/${{ inputs.package }}
file: packages/${{ inputs.package }}/${{ matrix.build_params['file'] }}
build-contexts: base=docker-image://${{ matrix.build_params['key'] == 1 && 'ghcr.io/bjia56/armv7l-wheel-builder:main' || 'localhost:5000/base:latest' }}
build-args: |
PYTHON_VERSION=${{ inputs.python_version }}
PACKAGE=${{ inputs.package }}
VERSION=${{ inputs.version }}
OUTPUT_DIR=/export
push: false
platforms: linux/armhf
tags: armv7l:latest
cache-from: type=gha,scope=${{ env.CACHE_TAG }}
cache-to: type=gha,mode=max,scope=${{ env.CACHE_TAG }}
outputs: type=docker,dest=${{ env.GHA_TMPDIR }}/stage.tar
- name: Upload artifact
uses: actions/upload-artifact@v4
if: ${{ matrix.build_params['key'] != fromJSON(needs.calculate_matrix.outputs.build_matrix_last) }}
with:
name: ${{ inputs.package }}-${{ inputs.version }}-cpython${{ inputs.python_version }}-dockerstage${{ matrix.build_params['key'] }}
path: ${{ env.GHA_TMPDIR }}/stage.tar
- name: Load image
if: ${{ matrix.build_params['key'] == fromJSON(needs.calculate_matrix.outputs.build_matrix_last) }}
run: |
docker load --input ${{ env.GHA_TMPDIR }}/stage.tar
docker image ls -a
rm ${{ env.GHA_TMPDIR }}/stage.tar
- name: Extract output
if: ${{ matrix.build_params['key'] == fromJSON(needs.calculate_matrix.outputs.build_matrix_last) }}
run: |
docker run -v ${{ env.GHA_TMPDIR }}/output:/host armv7l:latest bash -c "cp /export/* /host/"
- name: Upload Artifacts
uses: actions/upload-artifact@v4
if: ${{ matrix.build_params['key'] == fromJSON(needs.calculate_matrix.outputs.build_matrix_last) }}
with:
name: ${{ inputs.package }}-${{ inputs.version }}-cpython${{ inputs.python_version }}
path: ${{ env.GHA_TMPDIR }}/output/*.whl
- name: Remove scoped tmpdir
if: ${{ always() }}
run: |
sudo rm -rf ${{ env.GHA_TMPDIR }}