WindowsMacOS #242
Workflow file for this run
This file contains hidden or 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
name: WindowsMacOS | |
on: | |
push: | |
branches: | |
- main | |
- release/[0-9]+.[0-9]+ | |
tags: | |
- v[0-9]+.[0-9]+.[0-9]+ | |
pull_request: | |
types: [opened, synchronize, reopened, ready_for_review] | |
merge_group: | |
types: [checks_requested] | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.number && format('pr{0}', github.event.number) || github.run_id }} | |
cancel-in-progress: true | |
env: | |
HOMEBREW_NO_AUTO_UPDATE: 1 | |
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
S3_BUCKET: multipass-ci | |
jobs: | |
CheckLint: | |
runs-on: ubuntu-latest | |
if: ${{ !cancelled() }} | |
outputs: | |
conclusion: ${{ steps.check-lint.outputs.conclusion }} | |
steps: | |
- name: Check out code | |
uses: actions/checkout@v4 | |
- name: Check Lint Status | |
id: check-lint | |
uses: ./.github/actions/check-lint | |
GetMatrix: | |
runs-on: ubuntu-latest | |
if: ${{ !cancelled() }} | |
outputs: | |
matrix: ${{ steps.set-matrix.outputs.matrix }} | |
steps: | |
- name: Determine build matrix | |
id: set-matrix | |
run: | | |
set -euo pipefail | |
MATRIX='{"include": [' | |
MATRIX+='{"runs-on": "windows-latest"},' | |
MATRIX+='{"runs-on": "multipass-macos-12-x64", "arch": "x86_64", "target": "12"},' | |
MATRIX+='{"runs-on": "multipass-macos-12-arm", "arch": "arm64", "target": "12"},' | |
MATRIX+='{"runs-on": "macos-13", "arch": "x86_64", "target": "13"},' | |
MATRIX+='{"runs-on": "macos-14", "arch": "arm64", "target": "14"},' | |
MATRIX+='{"runs-on": "macos-15", "arch": "arm64", "target": "15"}' | |
MATRIX+=']}' | |
echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT | |
BuildAndTest: | |
needs: [CheckLint, GetMatrix] | |
# Proceed if Lint failed on a PR | |
if: ${{ !cancelled() && success() && | |
(needs.CheckLint.outputs.conclusion == 'success' || | |
(needs.CheckLint.outputs.conclusion == 'failure' && github.event_name == 'pull_request')) | |
}} | |
strategy: | |
matrix: ${{ fromJSON(needs.GetMatrix.outputs.matrix) }} | |
fail-fast: ${{ github.event_name == 'merge_group' }} | |
outputs: | |
build-label: ${{ steps.build-params.outputs.label }} | |
# Use artifacts from macos-12 in official package | |
mac-x86-package-artifact-name: ${{ steps.publish-data.outputs.multipass-macos-12-x64-x86_64-package-artifact-name }} | |
mac-arm-package-artifact-name: ${{ steps.publish-data.outputs.multipass-macos-12-arm-arm64-package-artifact-name }} | |
mac-x86-package-file-name: ${{ steps.publish-data.outputs.multipass-macos-12-x64-x86_64-package-file-name }} | |
mac-arm-package-file-name: ${{ steps.publish-data.outputs.multipass-macos-12-arm-arm64-package-file-name }} | |
runs-on: ${{ matrix.runs-on }} | |
continue-on-error: ${{ contains(matrix.runs-on, 'macos-13') || contains(matrix.runs-on, 'macos-14') || contains(matrix.runs-on, 'macos-15') }} | |
env: | |
BUILD_DIR: ${{ github.workspace }}/build | |
CCACHE_DIR: ${{ github.workspace }}/build/ccache | |
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.target }} | |
steps: | |
- name: Check out code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # Need full history to derive version | |
submodules: 'recursive' | |
- name: Enable symlinks | |
if: ${{ runner.os == 'Windows' }} | |
run: git config --local core.symlinks true | |
- name: Disable auto CRLF on Windows | |
if: ${{ runner.os == 'Windows' }} | |
run: git config --local core.autocrlf false | |
- name: Determine build parameters | |
id: build-params | |
uses: ./.github/actions/build-params | |
- name: Set preferred tar | |
if: ${{ runner.os == 'macOS' }} | |
id: preferred-tar | |
run: | | |
# Prepend gnu-tar's (future) location to the path, to prioritize it over system tar | |
# Needed for cache: https://github.com/actions/cache?tab=readme-ov-file#pre-requisites | |
echo "$( brew --prefix gnu-tar )/libexec/gnubin" >> ${GITHUB_PATH} | |
- name: Set the arch wrapper | |
if: ${{ matrix.arch }} | |
run: echo "ARCH_WRAPPER=arch -arch ${{ matrix.arch }}" >> ${GITHUB_ENV} | |
- name: Force pip to allow break-system-packages via pip.conf | |
if: ${{ runner.os == 'macOS' }} | |
run: | | |
mkdir -p ~/.pip | |
echo -e "[install]\nbreak-system-packages = true" > ~/.pip/pip.conf | |
- name: Install dependencies from brew | |
if: ${{ runner.os == 'macOS' }} | |
run: | | |
${{ env.ARCH_WRAPPER }} \ | |
brew install \ | |
cmake \ | |
coreutils \ | |
dylibbundler \ | |
git \ | |
glib \ | |
gnu-tar \ | |
libev \ | |
libffi \ | |
ninja \ | |
openssl@3 \ | |
pixman \ | |
pkg-config \ | |
python \ | |
wget | |
- name: Install specific QEMU from Choco | |
if: ${{ runner.os == 'Windows' }} | |
uses: crazy-max/ghaction-chocolatey@v3 | |
with: | |
args: install --yes qemu --version=2023.4.24 | |
- name: Install other packages from Choco | |
if: ${{ runner.os == 'Windows' }} | |
uses: crazy-max/ghaction-chocolatey@v3 | |
with: | |
args: install --yes wget unzip | |
- name: Set up vcpkg | |
id: setup-vcpkg | |
uses: lukka/run-vcpkg@v11 | |
with: | |
vcpkgDirectory: '${{ github.workspace }}/3rd-party/vcpkg' | |
- name: Set up CCache | |
if: ${{ runner.os == 'macOS' }} | |
id: setup-ccache | |
run: | # TODO increase the cache size for standard runners | |
${{ env.ARCH_WRAPPER }} brew install ccache | |
ccache --max-size=700M | |
# Find common base between main and HEAD to use as cache key. | |
# This avoids PRs from publishing caches. | |
git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules origin main | |
echo "cache-key=$( git merge-base origin/main ${{ github.sha }} )" >> $GITHUB_OUTPUT | |
echo "$( brew --prefix ccache )/libexec" >> ${GITHUB_PATH} | |
- name: CCache | |
if: ${{ runner.os == 'macOS' }} | |
uses: actions/cache@v4 | |
with: | |
key: "ccache-${{ runner.os }}-${{ env.MACOSX_DEPLOYMENT_TARGET }}-${{ matrix.arch }}-\ | |
${{ steps.setup-ccache.outputs.cache-key }}" | |
restore-keys: | | |
ccache-${{ runner.os }}-${{ env.MACOSX_DEPLOYMENT_TARGET }}-${{ matrix.arch }} | |
path: ${{ env.CCACHE_DIR }} | |
- name: Install OpenSSL from Choco | |
if: ${{ runner.os == 'Windows' }} | |
uses: crazy-max/ghaction-chocolatey@v3 | |
with: | |
args: install --yes openssl --version=3.1.1 | |
- name: Install Windows ADK | |
if: ${{ runner.os == 'Windows' }} | |
uses: crazy-max/ghaction-chocolatey@v3 | |
with: | |
args: install --yes windows-adk-deploy | |
- name: Install cmake | |
if: ${{ runner.os == 'Windows' }} | |
uses: lukka/[email protected] | |
- name: Install Qt | |
uses: jurplel/install-qt-action@v4 | |
with: | |
version: 6.2.4 | |
setup-python: false | |
aqtversion: '==3.1.*' | |
py7zrversion: '==0.20.*' | |
timeout-minutes: 20 | |
- name: Set up MSVC | |
if: ${{ runner.os == 'Windows' }} | |
uses: ilammy/msvc-dev-cmd@v1 | |
- name: Configure | |
run: > | |
${{ env.ARCH_WRAPPER }} | |
cmake | |
-B${{ env.BUILD_DIR }} | |
-DCMAKE_BUILD_TYPE=RelWithDebInfo | |
-GNinja | |
-DCMAKE_PREFIX_PATH=${{ env.Qt6_Dir }} | |
-DMULTIPASS_UPSTREAM=origin | |
-DMULTIPASS_BUILD_LABEL=${{ steps.build-params.outputs.label }} | |
${{ runner.os == 'Windows' && '-DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe' || '' }} | |
${{ github.workspace }} | |
- name: Throttle parallel build processes on arm64 | |
if: ${{ runner.os == 'macOS' && matrix.arch == 'arm64' }} | |
run: echo CMAKE_BUILD_PARALLEL_LEVEL=2 >> ${GITHUB_ENV} | |
- name: Build | |
run: ${{ env.ARCH_WRAPPER }} cmake --build ${{ env.BUILD_DIR }} | |
- name: Clear CCache stats | |
if: ${{ runner.os == 'macOS' }} | |
run: ccache --show-stats --zero-stats | |
- name: Test | |
working-directory: ${{ env.BUILD_DIR }} | |
run: | | |
${{ env.ARCH_WRAPPER }} bin/multipass_tests | |
- name: Package | |
id: cmake-package | |
working-directory: ${{ env.BUILD_DIR }} | |
run: > | |
${{ env.ARCH_WRAPPER }} cmake --build . --target package | |
echo "name=$( ${{ runner.os != 'Windows' && 'basename *.pkg' || | |
'( Get-ChildItem .\packages\en-US\multipass-*.msi ).Name' }} ) " >> | |
${{ runner.os != 'Windows' && '$GITHUB_OUTPUT' || '$env:GITHUB_OUTPUT' }} | |
echo "path=$( ${{ runner.os != 'Windows' && 'greadlink -f *.pkg' || | |
'( Get-ChildItem .\packages\en-US\multipass-*.msi ).FullName' }} )" >> | |
${{ runner.os != 'Windows' && '$GITHUB_OUTPUT' || '$env:GITHUB_OUTPUT' }} | |
- name: Get package logs | |
if: ${{ failure() && steps.cmake-package.outcome == 'failure' }} | |
run: > | |
${{ format('cat {0}/_CPack_Packages/{1}', env.BUILD_DIR, | |
runner.os == 'Windows' && 'win64/External/WiXOutput.log' || 'Darwin/productbuild/InstallOutput.log') }} | |
- name: Upload package | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ matrix.runs-on }}-${{ steps.cmake-package.outputs.name }} | |
path: ${{ steps.cmake-package.outputs.path }} | |
if-no-files-found: error | |
retention-days: 7 | |
# Put the package on S3 for public consumption | |
- name: Publish package on S3 | |
id: s3-upload | |
uses: canonical/actions/s3-upload@release | |
with: | |
path: ${{ steps.cmake-package.outputs.path }} | |
bucket: ${{ env.S3_BUCKET }} | |
prefix: ${{ steps.build-params.outputs.label }} | |
public: true | |
storage-class: ONEZONE_IA | |
timeout-minutes: 5 | |
# This shows up on this run's page | |
- name: Report public URL | |
run: | | |
echo "##[warning] Public URL: ${{ steps.s3-upload.outputs.url }}" | |
- name: Store publishing outputs | |
if: always() | |
id: publish-data | |
shell: bash | |
run: | | |
NAME="${{ steps.cmake-package.outputs.name }}" | |
ARTIFACT_NAME="${{ matrix.runs-on }}-${{ matrix.arch }}-package-artifact-name=${{ matrix.runs-on }}-${NAME}" | |
FILE_NAME="${{ matrix.runs-on }}-${{ matrix.arch }}-package-file-name=${NAME}" | |
echo "$ARTIFACT_NAME" >> "$GITHUB_OUTPUT" | |
echo "$FILE_NAME" >> "$GITHUB_OUTPUT" | |
CombineAndPublishMacOSPackage: | |
# Want to run even if one of the builds above failed | |
if: ${{ !cancelled() && always() }} | |
needs: [BuildAndTest] | |
runs-on: macos-13 | |
steps: | |
- name: Check out code | |
uses: actions/checkout@v4 | |
- name: Retrieve the macOS x86 package | |
id: retrieve-x86 | |
if: ${{ needs.BuildAndTest.outputs.mac-x86-package-artifact-name }} | |
uses: actions/download-artifact@v4 | |
with: | |
name: ${{ needs.BuildAndTest.outputs.mac-x86-package-artifact-name }} | |
- name: Retrieve the macOS ARM package | |
id: retrieve-arm | |
if: ${{ needs.BuildAndTest.outputs.mac-arm-package-artifact-name }} | |
uses: actions/download-artifact@v4 | |
with: | |
name: ${{ needs.BuildAndTest.outputs.mac-arm-package-artifact-name }} | |
- name: Set the arch wrapper | |
run: > | |
echo "ARCH_WRAPPER=arch -arch $( sysctl machdep.cpu.brand_string | grep -q Apple && | |
echo arm64 || echo x86_64 )" >> ${GITHUB_ENV} | |
- name: Combine the macOS package | |
id: combine-package | |
if: ${{ steps.retrieve-x86.outputs.download-path && steps.retrieve-arm.outputs.download-path }} | |
run: | | |
${ARCH_WRAPPER} brew install python | |
${ARCH_WRAPPER} brew install coreutils | |
${ARCH_WRAPPER} python3 -m pip install --user --upgrade lxml | |
PKG=${{ needs.BuildAndTest.outputs.mac-x86-package-file-name }} | |
PKG=${PKG/.x86_64/} | |
${ARCH_WRAPPER} packaging/macos/merge_pkgs.py \ | |
${{ needs.BuildAndTest.outputs.mac-x86-package-file-name }} \ | |
${{ needs.BuildAndTest.outputs.mac-arm-package-file-name }} \ | |
${PKG} | |
${ARCH_WRAPPER} packaging/macos/sign-and-notarize.sh \ | |
--app-signer - \ | |
${PKG} | |
echo "name=${PKG}" >> $GITHUB_OUTPUT | |
echo "path=$( greadlink -f ${PKG} )" >> $GITHUB_OUTPUT | |
- name: Upload combined macOS package | |
if: ${{ steps.combine-package.outputs.path }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.combine-package.outputs.name }} | |
path: ${{ steps.combine-package.outputs.path }} | |
if-no-files-found: error | |
retention-days: 7 | |
- name: Publish combined macOS package on S3 | |
if: ${{ steps.combine-package.outputs.path }} | |
id: s3-upload | |
uses: canonical/actions/s3-upload@release | |
with: | |
path: ${{ steps.combine-package.outputs.path }} | |
bucket: ${{ env.S3_BUCKET }} | |
prefix: ${{ needs.BuildAndTest.outputs.build-label }} | |
public: true | |
storage-class: ONEZONE_IA | |
timeout-minutes: 5 | |
- name: Report public URL | |
run: | | |
echo "##[warning] Public URL: ${{ steps.s3-upload.outputs.url }}" | |
DeleteSeparateMacPackages: | |
if: ${{ !cancelled() && success() && needs.CombineAndPublishMacOSPackage.result == 'success' }} | |
needs: [BuildAndTest, CombineAndPublishMacOSPackage] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Delete unused artifacts from github | |
uses: geekyeggo/delete-artifact@v5 | |
with: | |
name: | | |
${{ needs.BuildAndTest.outputs.mac-x86-package-artifact-name }} | |
${{ needs.BuildAndTest.outputs.mac-arm-package-artifact-name }} | |
failOnError: false |