[tests] Assert petname words are not empty #741
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: | ||
| workflow_call: | ||
| permissions: | ||
| contents: read | ||
| concurrency: | ||
| group: windows-macos-${{ 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 }} | ||
| FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json | ||
| S3_BUCKET: multipass-ci | ||
| USERNAME: ${{ github.repository_owner }} | ||
| VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" | ||
| jobs: | ||
| 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": "macos-13", "arch": "x86_64", "mono": "mono"},' | ||
| MATRIX+='{"runs-on": "macos-14", "arch": "arm64"},' | ||
| MATRIX+='{"runs-on": "macos-latest", "arch": "arm64"}' | ||
| MATRIX+=']}' | ||
| echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT | ||
| BuildAndTest: | ||
| needs: GetMatrix | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| if: ${{ !cancelled() }} | ||
| 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-13 and macos-14 in official package | ||
| mac-x86-package-artifact-name: ${{ steps.publish-data.outputs.macos-13-x86_64-package-artifact-name }} | ||
| mac-arm-package-artifact-name: ${{ steps.publish-data.outputs.macos-14-arm64-package-artifact-name }} | ||
| mac-x86-package-file-name: ${{ steps.publish-data.outputs.macos-13-x86_64-package-file-name }} | ||
| mac-arm-package-file-name: ${{ steps.publish-data.outputs.macos-14-arm64-package-file-name }} | ||
| runs-on: ${{ matrix.runs-on }} | ||
| env: | ||
| BUILD_DIR: ${{ github.workspace }}/build | ||
| CCACHE_DIR: ${{ github.workspace }}/build/ccache | ||
| steps: | ||
| - name: Check out code | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| fetch-depth: 0 # Need full history to derive version | ||
| submodules: 'recursive' | ||
| # Use specific xcode version in macos-15. The reason is that protobuf 29 is not | ||
| # happy with the AppleClang-17, which is shipped with Xcode >= 16.3. | ||
| # | ||
| # https://github.com/protocolbuffers/protobuf/issues/21447 | ||
| - uses: maxim-lobanov/setup-xcode@v1 | ||
| if: ${{ contains(matrix.runs-on, 'macos-latest') }} | ||
| with: | ||
| xcode-version: '16.2' | ||
| - 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} | ||
| # TODO: find a friendlier approach for installing pip packages on GitHub runners | ||
| - 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: | | ||
| # Avoid reinstalling cmake | ||
| ${{ env.ARCH_WRAPPER }} brew list cmake > /dev/null || \ | ||
| ${{ env.ARCH_WRAPPER }} brew install cmake | ||
| ${{ env.ARCH_WRAPPER }} \ | ||
| brew install \ | ||
| coreutils \ | ||
| dylibbundler \ | ||
| git \ | ||
| glib \ | ||
| gnu-tar \ | ||
| libev \ | ||
| libffi \ | ||
| ninja \ | ||
| openssl@3 \ | ||
| pixman \ | ||
| pkg-config \ | ||
| python \ | ||
| wget \ | ||
| rustup-init | ||
| - name: Install dependencies from pip | ||
| if: ${{ runner.os == 'macOS' }} | ||
| run: | | ||
| ${ARCH_WRAPPER} python3 -m pip install --user --upgrade distlib | ||
| - 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 rustup.install | ||
| - name: Set up vcpkg | ||
| id: setup-vcpkg | ||
| uses: lukka/run-vcpkg@v11 | ||
| with: | ||
| vcpkgDirectory: '${{ github.workspace }}/3rd-party/vcpkg' | ||
| # TODO: remove this when self-hosted runners are dropped | ||
| - name: Disable vcpkg binary cache on self-hosted runners | ||
| id: disable-cache | ||
| shell: bash | ||
| run: | | ||
| if [[ "${{ matrix['runs-on'] }}" == *multipass* ]]; then | ||
| echo "VCPKG_BINARY_SOURCES=" >> $GITHUB_ENV | ||
| fi | ||
| - name: Install nuget | ||
| if: ${{ matrix.arch == 'arm64' }} | ||
| run: | | ||
| brew install nuget mono | ||
| - name: Configure NuGet Source | ||
| if: ${{ env.VCPKG_BINARY_SOURCES }} # TODO: remove this when self-hosted runners are dropped | ||
| id: setup_nuget | ||
| continue-on-error: true | ||
| shell: 'bash' | ||
| run: | | ||
| # https://learn.microsoft.com/en-us/vcpkg/consume/binary-caching-github-packages | ||
| ${{ matrix.mono }} "$($VCPKG_ROOT/vcpkg fetch nuget | tail -n 1)" \ | ||
| sources add \ | ||
| -source "${{ env.FEED_URL }}" \ | ||
| -storepasswordincleartext \ | ||
| -name "GitHubPackages" \ | ||
| -username "${{ env.USERNAME }}" \ | ||
| -password "${{ secrets.GITHUB_TOKEN }}" | ||
| ${{ matrix.mono }} "$($VCPKG_ROOT/vcpkg fetch nuget | tail -n 1)" \ | ||
| setapikey "${{ secrets.GITHUB_TOKEN }}" \ | ||
| -source "${{ env.FEED_URL }}" | ||
| - name: Overwrite Homebrew nuget shim with nuget DLL | ||
| continue-on-error: true | ||
| if: ${{ steps.setup_nuget.outcome == 'success' && runner.os == 'macOS' && matrix.arch == 'arm64' }} | ||
| run: | | ||
| # Locate the real NuGet.exe in Homebrew’s Cellar | ||
| NUGET_EXE="$(brew --prefix nuget)/libexec/NuGet.exe" | ||
| # Remove the old shim and replace it with a symlink | ||
| sudo rm -f /opt/homebrew/bin/nuget | ||
| sudo ln -s "$NUGET_EXE" /opt/homebrew/bin/nuget | ||
| sudo chmod +x /opt/homebrew/bin/nuget | ||
| - name: Set up CCache | ||
| if: ${{ runner.os == 'macOS' }} | ||
| id: setup-ccache | ||
| run: | | ||
| ${{ env.ARCH_WRAPPER }} brew install ccache | ||
| # 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-${{ matrix.runs-on }}-${{ steps.setup-ccache.outputs.cache-key }}" | ||
| restore-keys: | | ||
| ccache-${{ matrix.runs-on }} | ||
| 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/get-cmake@v4.1.2 | ||
| - 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: Initialize Rust toolchain | ||
| shell: bash | ||
| run: | | ||
| if [[ "${{ runner.os }}" == "Windows" ]]; then | ||
| # On Windows, rustup.install from chocolatey should be available | ||
| if command -v rustup >/dev/null 2>&1; then | ||
| rustup default stable | ||
| rustup update | ||
| else | ||
| echo "Error: rustup not found. Please ensure it is installed and in the PATH." | ||
| exit 1 | ||
| fi | ||
| elif [[ "${{ runner.os }}" == "macOS" ]]; then | ||
| # On macOS, initialize rustup-init | ||
| if command -v rustup-init >/dev/null 2>&1; then | ||
| rustup-init -y --default-toolchain stable | ||
| source ~/.cargo/env | ||
| else | ||
| echo "Error: rustup-init not found. Please ensure it is installed and in the PATH." | ||
| exit 1 | ||
| fi | ||
| fi | ||
| # Add cargo bin to PATH for subsequent steps | ||
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | ||
| - 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: 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 | ||
| run: |\ | ||
| ${{ env.ARCH_WRAPPER }} ctest --test-dir ${{ env.BUILD_DIR }} --output-on-failure | ||
| - 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 | ||
| if: ${{ env.AWS_ACCESS_KEY_ID }} | ||
| 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@v5 | ||
| # TODO: find a friendlier approach for installing pip packages on GitHub runners | ||
| - 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: Retrieve the macOS x86 package | ||
| id: retrieve-x86 | ||
| if: ${{ needs.BuildAndTest.outputs.mac-x86-package-artifact-name }} | ||
| uses: actions/download-artifact@v5 | ||
| 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@v5 | ||
| 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 && env.AWS_ACCESS_KEY_ID }} | ||
| 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 | ||