diff --git a/.github/install_march_build_deps.sh b/.github/install_march_build_deps.sh new file mode 100755 index 000000000..bf55bf725 --- /dev/null +++ b/.github/install_march_build_deps.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +if [[ -z "${NO_APT_UPDATE}" ]]; then + sudo apt-get update +fi + +march="$1" +shift + +do_aarch64() { + wget -O aarch64-toolchain.tar.gz https://sel4-toolchains.s3.us-east-2.amazonaws.com/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-elf.tar.xz%3Frev%3D28d5199f6db34e5980aae1062e5a6703%26hash%3DF6F5604BC1A2BBAAEAC4F6E98D8DC35B + tar xf aarch64-toolchain.tar.gz + echo "$(pwd)/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-elf/bin" >> $GITHUB_PATH +} + +do_riscv64() { + sudo apt-get install -qq gcc-riscv64-unknown-elf +} + +do_x86_64() { + sudo apt-get install -qq gcc-x86-64-linux-gnu +} + +case "${march}" in + aarch64) + do_aarch64 + ;; + + riscv64) + do_riscv64 + ;; + + x86_64) + do_x86_64 + ;; + + *) + echo "Unknown or empty march value '${march}'" >&2 + exit 1 + ;; +esac diff --git a/.github/install_ubuntu_deps.sh b/.github/install_ubuntu_deps.sh new file mode 100755 index 000000000..4e30cb0a6 --- /dev/null +++ b/.github/install_ubuntu_deps.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +rustup install 1.94.0 +rustup default 1.94.0 +rustup target add x86_64-unknown-linux-musl +rustup component add rust-src --toolchain 1.94.0-x86_64-unknown-linux-gnu +rustup target add aarch64-unknown-none +rustup target add riscv64gc-unknown-none-elf +rustup target add x86_64-unknown-none + +sudo apt-get update + +NO_APT_UPDATE=1 $SCRIPT_DIR/install_march_build_deps.sh aarch64 +NO_APT_UPDATE=1 $SCRIPT_DIR/install_march_build_deps.sh riscv64 +NO_APT_UPDATE=1 $SCRIPT_DIR/install_march_build_deps.sh x86_64 + +# sel4-only dependencies +sudo apt-get install -qq software-properties-common +sudo add-apt-repository ppa:deadsnakes/ppa +sudo apt-get install -qq \ + cmake pandoc device-tree-compiler ninja-build \ + texlive-latex-base texlive-latex-recommended \ + texlive-fonts-recommended texlive-fonts-extra \ + libxml2-utils \ + python3.12 python3-pip python3.12-venv \ + qemu-system-arm qemu-system-misc + +python3.12 -m venv pyenv +./pyenv/bin/pip install --upgrade pip setuptools wheel +./pyenv/bin/pip install -r requirements.txt diff --git a/.github/sdk_version.sh b/.github/sdk_version.sh new file mode 100755 index 000000000..f72f95870 --- /dev/null +++ b/.github/sdk_version.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Copyright 2024, UNSW +# SPDX-License-Identifier: BSD-2-Clause + +set -ex + +VERSION=`cat VERSION` + +HEAD=`git rev-parse --short HEAD` + +if ! LATEST_TAG=`git describe --tags --abbrev=0`; then + VERSION="$VERSION.unknown+$HEAD" +elif ! NUM_COMMITS=`git rev-list --count $LATEST_TAG..HEAD`; then + VERSION="$VERSION.unknown+$HEAD" +elif [[ $NUM_COMMITS -eq 0 ]]; then + echo "$VERSION" +else + VERSION="$VERSION.$NUM_COMMITS+$HEAD" +fi + +echo "SDK Version is '${VERSION}'" + +echo "SDK_VERSION=${VERSION}" >> "${GITHUB_ENV}" +echo "SDK_VERSION=${VERSION}" >> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..02cd3826a --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,257 @@ +# Copyright 2021, Proofcraft Pty Ltd +# Copyright 2026, UNSW +# +# SPDX-License-Identifier: BSD-2-Clause + +# Deploy default.xml to microkit-manifest after successful runs. + +name: Deploy + +on: + push: + # TEMP: remove + branches: [main, julia/ci] + paths-ignore: + - '**.md' + + # allow manual trigger + workflow_dispatch: + + # allow explicit trigger from other repos when dependencies have changed + repository_dispatch: + types: [deps-update] + +jobs: + code: + name: Freeze Code + runs-on: ubuntu-latest + outputs: + xml: ${{ steps.repo.outputs.xml }} + steps: + - id: repo + uses: au-ts/seL4-ci-actions/repo-checkout@julia/microkit + with: + manifest_repo: au-ts/microkit-manifest + manifest_branch: main + manifest: main.xml + use_venv: true + + # TODO: This is a noop that vacuuously succeeds. We should fix that. + sim: + name: Simulation + needs: code + runs-on: ubuntu-latest + strategy: + matrix: + march: [aarch64, x86_64, riscv64] + compiler: [gcc] + steps: + - uses: au-ts/seL4-ci-actions/microkit-sim@julia/microkit + with: + xml: ${{ needs.code.outputs.xml }} + march: ${{ matrix.march }} + compiler: ${{ matrix.compiler }} + + sdk-build: + name: Build SDK (macOS, all targets) + needs: code + runs-on: [self-hosted, macos, ARM64] + outputs: + SDK_VERSION: ${{ steps.version.outputs.SDK_VERSION }} + steps: + - name: Clean build + run: | + rm -rf "$GITHUB_WORKSPACE" + mkdir -p "$GITHUB_WORKSPACE" + - name: Checkout code + uses: au-ts/seL4-ci-actions/repo-checkout@julia/microkit + with: + xml: ${{ needs.code.outputs.xml }} + # needed for reasons... + manifest_repo: au-ts/microkit-manifest + manifest_branch: main + manifest: main.xml + use_venv: true + - name: Set version + id: version + run: | + ./.github/sdk_version.sh + working-directory: ./microkit/ + - name: Get Nix dependencies + run: nix develop -c bash -c 'echo Hello World' + working-directory: ./microkit/ + - name: Build SDK + # TODO: remove boards + run: nix develop --ignore-environment -c bash -c "python3 build_sdk.py --sel4=../seL4 --version ${{ env.SDK_VERSION }} --gcc-toolchain-prefix-x86_64 x86_64-elf --gcc-toolchain-prefix-riscv64 riscv64-none-elf --release-packaging" + working-directory: ./microkit/ + - name: Upload SDK (macos-aarch64) + uses: actions/upload-artifact@v7 + with: + name: microkit-sdk-${{ env.SDK_VERSION }}-macos-aarch64 + path: microkit/release/microkit-sdk-${{ env.SDK_VERSION }}-macos-aarch64.tar.gz + - name: Upload SDK (macos-x86-64) + uses: actions/upload-artifact@v7 + with: + name: microkit-sdk-${{ env.SDK_VERSION }}-macos-x86-64 + path: microkit/release/microkit-sdk-${{ env.SDK_VERSION }}-macos-x86-64.tar.gz + - name: Upload SDK (linux-aarch64) + uses: actions/upload-artifact@v7 + with: + name: microkit-sdk-${{ env.SDK_VERSION }}-linux-aarch64 + path: microkit/release/microkit-sdk-${{ env.SDK_VERSION }}-linux-aarch64.tar.gz + - name: Upload SDK (linux-x86-64) + uses: actions/upload-artifact@v7 + with: + name: microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64 + path: microkit/release/microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64.tar.gz + + # Not used for HW Run, just to confirm it builds on Linux outside of Nix. + sdk-build-linux: + name: Build SDK (Linux x86_64) + runs-on: ubuntu-24.04 + needs: code + steps: + - name: Checkout code + uses: au-ts/seL4-ci-actions/repo-checkout@julia/microkit + with: + xml: ${{ needs.code.outputs.xml }} + # needed for reasons... + manifest_repo: au-ts/microkit-manifest + manifest_branch: main + manifest: main.xml + use_venv: true + - name: Set version + run: | + ./.github/sdk_version.sh + working-directory: ./microkit/ + - name: Install SDK dependencies + run: ./.github/install_ubuntu_deps.sh + working-directory: ./microkit/ + - name: Build SDK (x86-64) + run: ./pyenv/bin/python build_sdk.py --sel4=../seL4 --version ${{ env.SDK_VERSION }}-linux-x86-64 --tool-target-triple="x86_64-unknown-linux-musl" + working-directory: ./microkit/ + + the_matrix: + name: Matrix + needs: sdk-build + runs-on: ubuntu-latest + outputs: + gh_matrix: ${{ steps.matrix.outputs.gh_matrix }} + test_cases: ${{ steps.matrix.outputs.test_cases }} + steps: + - name: Checkout code + uses: au-ts/seL4-ci-actions/repo-checkout@julia/microkit + with: + xml: ${{ needs.code.outputs.xml }} + # needed for reasons... + manifest_repo: au-ts/microkit-manifest + manifest_branch: main + manifest: main.xml + use_venv: true + - id: matrix + uses: au-ts/seL4-ci-actions/microkit-hw-matrix@julia/microkit + env: + # We don't actually care what this is set to, but for the files for + # each platform it expects this path to exist, so we set it up. + MICROKIT_SDK: /dummy-microkit-sdk-for-matrix + + hw-build: + name: HW Test Builds + if: ${{ github.repository_owner == 'au-ts' }} + runs-on: ubuntu-latest + needs: [sim, the_matrix, sdk-build] + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.the_matrix.outputs.gh_matrix) }} + env: + SDK_VERSION: ${{ needs.sdk-build.outputs.SDK_VERSION }} + steps: + - name: Checkout code + uses: au-ts/seL4-ci-actions/repo-checkout@julia/microkit + with: + xml: ${{ needs.code.outputs.xml }} + # needed for reasons... + manifest_repo: au-ts/microkit-manifest + manifest_branch: main + manifest: main.xml + use_venv: true + - name: Download microkit SDK + uses: actions/download-artifact@v8 + with: + name: microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64 + - name: Extract microkit SDK + run: | + tar xzf ./microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64.tar.gz + export "MICROKIT_SDK=$(realpath ./microkit-sdk-${{ env.SDK_VERSION }}/)" + echo "MICROKIT_SDK=${MICROKIT_SDK}" >> "${GITHUB_ENV}" + - name: Install build dependencies + run: ./.github/install_march_build_deps.sh ${{ matrix.march }} + working-directory: ./microkit/ + - name: Build + uses: au-ts/seL4-ci-actions/microkit-hw-build@julia/microkit + with: + board: ${{ matrix.board }} + index: $${{ strategy.job-index }} + env: + TEST_CASES: ${{ needs.the_matrix.outputs.test_cases }} + - name: Upload test case builds + uses: actions/upload-artifact@v7 + with: + name: loader-img-${{ matrix.board }} + path: '*.loader.img' + + hw-run: + name: HW Run + if: ${{ github.repository_owner == 'au-ts' }} + runs-on: ubuntu-latest + needs: [sim, the_matrix, hw-build, sdk-build] + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.the_matrix.outputs.gh_matrix) }} + # do not run concurrently with other workflows, but do run concurrently in the build matrix + concurrency: hw-run-${{ strategy.job-index }} + env: + SDK_VERSION: ${{ needs.sdk-build.outputs.SDK_VERSION }} + steps: + - name: Get machine queue + uses: actions/checkout@v6 + with: + repository: seL4/machine_queue + path: machine_queue + - name: Download test cases builds + uses: actions/download-artifact@v8 + with: + name: loader-img-${{ matrix.board }} + - name: Download microkit SDK + uses: actions/download-artifact@v8 + with: + name: microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64 + - name: Extract microkit SDK + run: | + tar xzf ./microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64.tar.gz + export "MICROKIT_SDK=$(realpath ./microkit-sdk-${{ env.SDK_VERSION }}/)" + echo "MICROKIT_SDK=${MICROKIT_SDK}" >> "${GITHUB_ENV}" + - name: Run + uses: au-ts/seL4-ci-actions/microkit-hw-run@julia/microkit + with: + board: ${{ matrix.board }} + index: $${{ strategy.job-index }} + env: + TEST_CASES: ${{ needs.the_matrix.outputs.test_cases }} + HW_SSH: ${{ secrets.HW_SSH }} + + deploy: + name: Deploy manifest + if: ${{ github.repository_owner == 'au-ts' }} + runs-on: ubuntu-22.04 + needs: [code, hw-run] + # needs: [code, hw-run, sdk-build-linux] + steps: + - name: Deploy + uses: au-ts/seL4-ci-actions/manifest-deploy@julia/microkit + with: + xml: ${{ needs.code.outputs.xml }} + manifest_repo: au-ts/microkit-manifest + manifest_branch: main + env: + GH_SSH: ${{ secrets.CI_SSH }} diff --git a/.github/workflows/sdk.yaml b/.github/workflows/sdk.yaml index 72451d6d0..0234e980c 100644 --- a/.github/workflows/sdk.yaml +++ b/.github/workflows/sdk.yaml @@ -45,34 +45,7 @@ jobs: ref: ${{ env.SEL4_VERSION }} path: seL4 - name: Install SDK dependencies - run: | - rustup install 1.94.0 - rustup default 1.94.0 - rustup target add x86_64-unknown-linux-musl - rustup component add rust-src --toolchain 1.94.0-x86_64-unknown-linux-gnu - rustup target add aarch64-unknown-none - rustup target add riscv64gc-unknown-none-elf - rustup target add x86_64-unknown-none - sudo apt update - sudo apt install software-properties-common - sudo add-apt-repository ppa:deadsnakes/ppa - sudo apt install \ - gcc-x86-64-linux-gnu \ - gcc-riscv64-unknown-elf \ - cmake pandoc device-tree-compiler ninja-build \ - texlive-latex-base texlive-latex-recommended \ - texlive-fonts-recommended texlive-fonts-extra \ - libxml2-utils \ - python3.12 python3-pip python3.12-venv \ - qemu-system-arm qemu-system-misc - python3.12 -m venv pyenv - ./pyenv/bin/pip install --upgrade pip setuptools wheel - ./pyenv/bin/pip install -r requirements.txt - - name: Install AArch64 GCC toolchain - run: | - wget -O aarch64-toolchain.tar.gz https://sel4-toolchains.s3.us-east-2.amazonaws.com/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-elf.tar.xz%3Frev%3D28d5199f6db34e5980aae1062e5a6703%26hash%3DF6F5604BC1A2BBAAEAC4F6E98D8DC35B - tar xf aarch64-toolchain.tar.gz - echo "$(pwd)/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-elf/bin" >> $GITHUB_PATH + run: ./.github/install_ubuntu_deps.sh - name: Set version run: echo "SDK_VERSION=$(./ci/sdk_version.sh)" >> $GITHUB_ENV - name: Build SDK (x86-64) @@ -102,22 +75,22 @@ jobs: - name: Build SDK run: nix develop --ignore-environment -c bash -c "python3 build_sdk.py --sel4=seL4 --version ${{ env.SDK_VERSION }} --gcc-toolchain-prefix-x86_64 x86_64-elf --gcc-toolchain-prefix-riscv64 riscv64-none-elf --release-packaging" - name: Upload SDK (macos-aarch64) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: microkit-sdk-${{ env.SDK_VERSION }}-macos-aarch64 path: release/microkit-sdk-${{ env.SDK_VERSION }}-macos-aarch64.tar.gz - name: Upload SDK (macos-x86-64) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: microkit-sdk-${{ env.SDK_VERSION }}-macos-x86-64 path: release/microkit-sdk-${{ env.SDK_VERSION }}-macos-x86-64.tar.gz - name: Upload SDK (linux-aarch64) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: microkit-sdk-${{ env.SDK_VERSION }}-linux-aarch64 path: release/microkit-sdk-${{ env.SDK_VERSION }}-linux-aarch64.tar.gz - name: Upload SDK (linux-x86-64) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64 path: release/microkit-sdk-${{ env.SDK_VERSION }}-linux-x86-64.tar.gz diff --git a/build_sdk.py b/build_sdk.py index 5ff324b1f..3947d9ed1 100644 --- a/build_sdk.py +++ b/build_sdk.py @@ -18,7 +18,7 @@ import shutil from pathlib import Path from dataclasses import dataclass -from sys import executable +from sys import executable, stderr from tarfile import open as tar_open, TarInfo import platform as host_platform from enum import IntEnum @@ -870,6 +870,20 @@ def build_initialiser( dest.chmod(0o744) +def github_actions_board_matrix( + matrix_file: Path, build_goals: list[tuple[BoardInfo, list[ConfigInfo]]] +) -> None: + + board_matrix = [ + { "board": board.name, "march": board.arch.to_str(), "config": config.name } + for (board, configs) in build_goals + for config in configs + ] + + with open(matrix_file, "w") as f: + json.dump(board_matrix, f) + + def main() -> None: parser = ArgumentParser() parser.add_argument("--sel4", type=Path, required=True) @@ -884,6 +898,7 @@ def main() -> None: parser.add_argument("--skip-docs", action="store_true", help="Docs will not be built") parser.add_argument("--skip-tar", action="store_true", help="SDK and source tarballs will not be built") parser.add_argument("--release-packaging", action="store_true", help="All SDKs for distribution will be produced") + parser.add_argument("--matrix", type=Path, help="Print out elaborated configs to a matrix for GitHub actions") # Read from the version file as unless someone has specified # a version, that is the source of truth with open("VERSION", "r") as f: @@ -895,6 +910,7 @@ def main() -> None: args = parser.parse_args() + global TRIPLE_AARCH64 global TRIPLE_RISCV global TRIPLE_X86_64 @@ -932,6 +948,10 @@ def main() -> None: build_goals.append((board, elaborated_configs)) + if args.matrix is not None: + github_actions_board_matrix(args.matrix, build_goals) + return + sel4_dir = args.sel4.expanduser() if not sel4_dir.exists(): raise Exception(f"sel4_dir: {sel4_dir} does not exist") diff --git a/ci/sdk_version.sh b/ci/sdk_version.sh deleted file mode 100755 index 9c500cf14..000000000 --- a/ci/sdk_version.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Copyright 2024, UNSW -# SPDX-License-Identifier: BSD-2-Clause - -set -e - -VERSION=`cat VERSION` -LATEST_TAG=`git describe --tags --abbrev=0` -NUM_COMMITS=`git rev-list --count $LATEST_TAG..HEAD` -HEAD=`git rev-parse --short HEAD` - -if [[ $NUM_COMMITS -eq 0 ]]; -then - echo "$VERSION" -else - echo "$VERSION.$NUM_COMMITS+$HEAD" -fi