Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MacOS Docker containers #3915

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
270 changes: 136 additions & 134 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,144 +21,146 @@ env:
RELEASE_TAG: latest

jobs:
build:
name: "Build Firedrake"
# Run on our self-hosted machines
runs-on: [self-hosted, Linux]
container:
image: firedrakeproject/firedrake-env:latest
strategy:
# Don't immediately kill real if complex fails and vice versa.
fail-fast: false
matrix:
include:
- scalar-type: real
complex: ""
petsc_arch: default
- scalar-type: complex
complex: --complex
petsc_arch: complex
env:
# PETSC_DIR and MPICH_DIR are set inside the docker image
FIREDRAKE_CI_TESTS: 1
PYOP2_CI_TESTS: 1
PETSC_ARCH: ${{ matrix.petsc_arch }}
OMP_NUM_THREADS: 1
OPENBLAS_NUM_THREADS: 1
COMPLEX: ${{ matrix.complex }}
RDMAV_FORK_SAFE: 1
steps:
- uses: actions/checkout@v4
- name: Cleanup
if: ${{ always() }}
run: |
cd ..
rm -rf firedrake_venv
- name: Build Firedrake
run: |
cd ..
# Linting should ignore unquoted shell variable $COMPLEX
# shellcheck disable=SC2086
./firedrake/scripts/firedrake-install \
$COMPLEX \
--honour-petsc-dir \
--mpicc="$MPICH_DIR"/mpicc \
--mpicxx="$MPICH_DIR"/mpicxx \
--mpif90="$MPICH_DIR"/mpif90 \
--mpiexec="$MPICH_DIR"/mpiexec \
--mpihome="$MPICH_DIR"/.. \
--venv-name firedrake_venv \
--no-package-manager \
--disable-ssh \
--documentation-dependencies \
--torch \
--jax \
--netgen \
--slepc \
--install thetis \
--install gusto \
--install icepack \
--install irksome \
--install femlium \
--install fascd \
--install defcon \
--install gadopt \
--install asQ \
|| (cat firedrake-install.log && /bin/false)
- name: Install test dependencies
run: |
. ../firedrake_venv/bin/activate
python "$(which firedrake-clean)"
python -m pip install \
pytest-xdist pytest-timeout ipympl
python -m pip list
- name: Test Firedrake
run: |
. ../firedrake_venv/bin/activate
echo OMP_NUM_THREADS is "$OMP_NUM_THREADS"
echo OPENBLAS_NUM_THREADS is "$OPENBLAS_NUM_THREADS"
python -m pytest -v tests/firedrake/test_0init.py
python -m pytest \
--durations=200 \
--timeout=1800 \
--timeout-method=thread \
-o faulthandler_timeout=1860 \
-n 12 --dist worksteal \
--junit-xml=firedrake.xml \
-sv tests/firedrake
timeout-minutes: 120
- name: Publish Test Report
uses: mikepenz/[email protected]
if: ${{ always() && ( github.ref != 'refs/heads/master') }}
with:
report_paths: '/__w/firedrake/firedrake/firedrake.xml'
comment: true
check_name: "Firedrake ${{ matrix.scalar-type }}"
updateComment: true
flaky_summary: true
- name: Test pyadjoint
if: ${{ matrix.scalar-type == 'real' }}
run: |
. ../firedrake_venv/bin/activate
cd ../firedrake_venv/src/pyadjoint
python -m pytest \
--durations=200 \
--timeout=600 \
--timeout-method=thread \
-o faulthandler_timeout=660 \
-n 12 --dist worksteal \
-sv tests/firedrake_adjoint
timeout-minutes: 30
- name: Cleanup
# Belt and braces: clean up before and after the run.
if: ${{ always() }}
run: |
cd ..
rm -rf firedrake_venv
docker_tag:
name: "Set the Docker release tag"
runs-on: [self-hosted, Linux]
if: ${{ github.ref == 'refs/heads/master' }}
steps:
- name: Set release tag
# Set a release tag if triggered by monthly CRON job
if: github.event.schedule == '0 0 1 * *'
run: |
DATE_TAG="$(date +%Y-%m)"
echo "RELEASE_TAG=$DATE_TAG" >> "$GITHUB_ENV"
- name: Print release tag being used
run: |
echo The release tag is "$RELEASE_TAG"
outputs:
tag: ${{ env.RELEASE_TAG }}
# build:
# name: "Build Firedrake"
# # Run on our self-hosted machines
# runs-on: [self-hosted, Linux]
# container:
# image: firedrakeproject/firedrake-env:latest
# strategy:
# # Don't immediately kill real if complex fails and vice versa.
# fail-fast: false
# matrix:
# include:
# - scalar-type: real
# complex: ""
# petsc_arch: default
# - scalar-type: complex
# complex: --complex
# petsc_arch: complex
# env:
# # PETSC_DIR and MPICH_DIR are set inside the docker image
# FIREDRAKE_CI_TESTS: 1
# PYOP2_CI_TESTS: 1
# PETSC_ARCH: ${{ matrix.petsc_arch }}
# OMP_NUM_THREADS: 1
# OPENBLAS_NUM_THREADS: 1
# COMPLEX: ${{ matrix.complex }}
# RDMAV_FORK_SAFE: 1
# steps:
# - uses: actions/checkout@v4
# - name: Cleanup
# if: ${{ always() }}
# run: |
# cd ..
# rm -rf firedrake_venv
# - name: Build Firedrake
# run: |
# cd ..
# # Linting should ignore unquoted shell variable $COMPLEX
# # shellcheck disable=SC2086
# ./firedrake/scripts/firedrake-install \
# $COMPLEX \
# --honour-petsc-dir \
# --mpicc="$MPICH_DIR"/mpicc \
# --mpicxx="$MPICH_DIR"/mpicxx \
# --mpif90="$MPICH_DIR"/mpif90 \
# --mpiexec="$MPICH_DIR"/mpiexec \
# --mpihome="$MPICH_DIR"/.. \
# --venv-name firedrake_venv \
# --no-package-manager \
# --disable-ssh \
# --documentation-dependencies \
# --torch \
# --jax \
# --netgen \
# --slepc \
# --install thetis \
# --install gusto \
# --install icepack \
# --install irksome \
# --install femlium \
# --install fascd \
# --install defcon \
# --install gadopt \
# --install asQ \
# || (cat firedrake-install.log && /bin/false)
# - name: Install test dependencies
# run: |
# . ../firedrake_venv/bin/activate
# python "$(which firedrake-clean)"
# python -m pip install \
# pytest-xdist pytest-timeout ipympl
# python -m pip list
# - name: Test Firedrake
# run: |
# . ../firedrake_venv/bin/activate
# echo OMP_NUM_THREADS is "$OMP_NUM_THREADS"
# echo OPENBLAS_NUM_THREADS is "$OPENBLAS_NUM_THREADS"
# python -m pytest -v tests/firedrake/test_0init.py
# python -m pytest \
# --durations=200 \
# --timeout=1800 \
# --timeout-method=thread \
# -o faulthandler_timeout=1860 \
# -n 12 --dist worksteal \
# --junit-xml=firedrake.xml \
# -sv tests/firedrake
# timeout-minutes: 120
# - name: Publish Test Report
# uses: mikepenz/[email protected]
# if: ${{ always() && ( github.ref != 'refs/heads/master') }}
# with:
# report_paths: '/__w/firedrake/firedrake/firedrake.xml'
# comment: true
# check_name: "Firedrake ${{ matrix.scalar-type }}"
# updateComment: true
# flaky_summary: true
# - name: Test pyadjoint
# if: ${{ matrix.scalar-type == 'real' }}
# run: |
# . ../firedrake_venv/bin/activate
# cd ../firedrake_venv/src/pyadjoint
# python -m pytest \
# --durations=200 \
# --timeout=600 \
# --timeout-method=thread \
# -o faulthandler_timeout=660 \
# -n 12 --dist worksteal \
# -sv tests/firedrake_adjoint
# timeout-minutes: 30
# - name: Cleanup
# # Belt and braces: clean up before and after the run.
# if: ${{ always() }}
# run: |
# cd ..
# rm -rf firedrake_venv
#
# docker_tag:
# name: "Set the Docker release tag"
# runs-on: [self-hosted, Linux]
# if: ${{ github.ref == 'refs/heads/master' }}
# steps:
# - name: Set release tag
# # Set a release tag if triggered by monthly CRON job
# if: github.event.schedule == '0 0 1 * *'
# run: |
# DATE_TAG="$(date +%Y-%m)"
# echo "RELEASE_TAG=$DATE_TAG" >> "$GITHUB_ENV"
# - name: Print release tag being used
# run: |
# echo The release tag is "$RELEASE_TAG"
# outputs:
# tag: ${{ env.RELEASE_TAG }}

docker:
name: "Build Docker containers"
# Only run on master, but always generate firedrake-env image,
# even if build fails (see docker.yml)
if: ${{ (github.ref == 'refs/heads/master') && always() }}
needs: [build, docker_tag]
# if: ${{ (github.ref == 'refs/heads/master') && always() }}
if: ${{ always() }}
uses: ./.github/workflows/docker.yml
with:
tag: ${{ needs.docker_tag.outputs.tag }}
status: ${{ needs.build.result }}
tag: testing
status: success
secrets: inherit
4 changes: 2 additions & 2 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
docker_vanilla:
needs: docker_env
# Only run if "Build Firedrake" succeeds
if: ${{ inputs.status == 'success' }}
# if: ${{ inputs.status == 'success' }}
uses: ./.github/workflows/docker_reuse.yml
with:
target: firedrake-vanilla
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
docker_complex:
needs: docker_env
# Only run if "Build Firedrake" succeeds
if: ${{ inputs.status == 'success' }}
# if: ${{ inputs.status == 'success' }}
uses: ./.github/workflows/docker_reuse.yml
with:
target: firedrake-complex
Expand Down
81 changes: 75 additions & 6 deletions .github/workflows/docker_reuse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,93 @@ on:
required: true

jobs:
docker_workflow:
docker_build:
name: "Build the ${{ inputs.target }} container"
runs-on: [self-hosted, Linux]
strategy:
fail-fast: false
# see https://docs.docker.com/build/ci/github-actions/multi-platform/
matrix:
os: [Linux, macOS]
include:
- os: Linux
platform: linux/amd64
- os: macOS
platform: linux/arm64
runs-on: [self-hosted, "${{ matrix.os }}"]
steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Add homebrew to PATH
if: ${{ matrix.os == 'macOS' }}
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-system-path
run: echo "/opt/homebrew/bin" >> "$GITHUB_PATH"

- name: Prepare environment
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3

- name: Build and push ${{ inputs.target }}
id: build
uses: docker/build-push-action@v6
with:
push: true
no-cache: true
platforms: ${{ matrix.platform }}
file: ${{ inputs.dockerfile }}
tags: firedrakeproject/${{ inputs.target }}:${{ inputs.tag }}
outputs: type=image,name=firedrakeproject/${{ inputs.target }},push-by-digest=true,name-canonical=true,push=true

- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.imageid }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"

- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1

docker_merge:
runs-on: [self-hosted, Linux]
container:
image: ubuntu:latest
needs:
- docker_build
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf 'firedrakeproject/${{ inputs.target }}@sha256:%s ' *)

- name: Inspect image
run: |
docker buildx imagetools inspect firedrakeproject/${{ inputs.target }}:${{ inputs.tag }}
Loading
Loading