name: Build on: push: pull_request: workflow_dispatch: env: MAKEFLAGS: "-j4 GITVERSION=${{ github.sha }}" jobs: bios: name: BIOS / ${{ matrix.arch }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: arch: - i386 - x86_64 container: image: ghcr.io/ipxe/ipxe-builder-${{ matrix.arch }} env: bindir: >- ${{ matrix.arch == 'i386' && 'bin' || 'bin-x86_64-pcbios' }} steps: - name: Check out code uses: actions/checkout@v6 - name: Build working-directory: src run: | make ${{ env.bindir }}/10ec8139.rom \ ${{ env.bindir }}/8086100e.mrom \ ${{ env.bindir }}/ipxe.dsk \ ${{ env.bindir }}/ipxe.iso \ ${{ env.bindir }}/ipxe.lkrn \ ${{ env.bindir }}/ipxe.pxe \ ${{ env.bindir }}/ipxe.usb \ ${{ env.bindir }}/ipxe-legacy.lkrn \ ${{ env.bindir }}/ipxe-legacy.pxe \ ${{ env.bindir }}/undionly.kpxe \ ${{ env.bindir }}/errors - name: Hardware list working-directory: src run: | ./util/niclist.pl \ --format dokuwiki \ --sort bus-,vendor_id,device_id,device_name \ --output ${{ env.bindir }}/niclist.txt - name: Upload uses: actions/upload-artifact@v6 with: name: ${{ env.bindir }} if-no-files-found: error path: | src/${{ env.bindir }}/ipxe.lkrn src/${{ env.bindir }}/ipxe.pxe src/${{ env.bindir }}/ipxe-legacy.lkrn src/${{ env.bindir }}/ipxe-legacy.pxe src/${{ env.bindir }}/undionly.kpxe src/${{ env.bindir }}/errors src/${{ env.bindir }}/niclist.txt sbi: name: SBI / ${{ matrix.arch }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: arch: - riscv32 - riscv64 container: image: ghcr.io/ipxe/ipxe-builder-${{ matrix.arch }} env: bindir: bin-${{ matrix.arch }} steps: - name: Check out code uses: actions/checkout@v6 - name: Build working-directory: src run: | make ${{ env.bindir }}/ipxe.pf32 \ ${{ env.bindir }}/ipxe.lkrn \ ${{ env.bindir }}/ipxe.sbi \ ${{ env.bindir }}/errors - name: Upload uses: actions/upload-artifact@v6 with: name: ${{ env.bindir }} if-no-files-found: error path: | src/${{ env.bindir }}/ipxe.lkrn src/${{ env.bindir }}/ipxe.sbi src/${{ env.bindir }}/errors uefi: name: UEFI / ${{ matrix.arch }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: arch: - arm32 - arm64 - i386 - loong64 - riscv32 - riscv64 - x86_64 container: image: ghcr.io/ipxe/ipxe-builder-${{ matrix.arch }} env: bindir: bin-${{ matrix.arch }}-efi steps: - name: Check out code uses: actions/checkout@v6 - name: Build working-directory: src run: | make ${{ env.bindir }}/ipxe.efi \ ${{ env.bindir }}/ipxe.iso \ ${{ env.bindir }}/ipxe.usb \ ${{ env.bindir }}/ipxe-legacy.efi \ ${{ env.bindir }}/snponly.efi \ ${{ env.bindir }}/errors - name: Upload uses: actions/upload-artifact@v6 with: name: ${{ env.bindir }} if-no-files-found: error path: | src/${{ env.bindir }}/ipxe.efi src/${{ env.bindir }}/ipxe-legacy.efi src/${{ env.bindir }}/snponly.efi src/${{ env.bindir }}/errors uefi-sb: name: UEFI SB / ${{ matrix.arch }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: arch: - arm64 - x86_64 container: image: ghcr.io/ipxe/ipxe-builder-${{ matrix.arch }} env: bindir: bin-${{ matrix.arch }}-efi-sb outputs: sbsignenv: ${{ steps.sbsignenv.outputs.sbsignenv }} steps: - name: Check out code uses: actions/checkout@v6 - name: Build working-directory: src run: | make ${{ env.bindir }}/ipxe.efi \ ${{ env.bindir }}/snponly.efi - name: Upload uses: actions/upload-artifact@v6 with: name: unsigned-${{ env.bindir }} if-no-files-found: error path: | src/${{ env.bindir }}/ipxe.efi src/${{ env.bindir }}/snponly.efi - name: Select environment id: sbsignenv if: >- github.ref == 'refs/heads/sbsign' || startsWith ( github.ref, 'refs/tags/v' ) run: | echo "sbsignenv=${{ vars.SBSIGN_ENVIRONMENT }}" >> $GITHUB_OUTPUT sbsign: name: SB Sign / ${{ matrix.arch }} runs-on: ${{ needs.uefi-sb.outputs.sbsignenv || 'ubuntu-latest' }} needs: - uefi-sb strategy: fail-fast: false matrix: arch: - arm64 - x86_64 container: image: ghcr.io/ipxe/ipxe-signer volumes: - run-pcscd:/run/pcscd services: pcscd: image: ghcr.io/ipxe/ipxe-signer-pcscd volumes: - run-pcscd:/run/pcscd options: >- ${{ needs.uefi-sb.outputs.sbsignenv && '--device /dev/bus/usb' }} --label OPTIONS_VALUE_CANNOT_BE_EMPTY=1 env: binaries: >- ipxe.efi snponly.efi bindir: bin-${{ matrix.arch }}-efi-sb cacert: ${{ vars.SBSIGN_CA_CERT || 'testsign.crt' }} pkcs11: ${{ secrets.SBSIGN_PASSWORD && 'true' }} signcerts: ${{ vars.SBSIGN_CERTS || 'testsign.crt' }} signkey: ${{ vars.SBSIGN_KEY || 'testsign.key' }} signpass: ${{ secrets.SBSIGN_PASSWORD || 'testpw' }} environment: ${{ needs.uefi-sb.outputs.sbsignenv }} steps: - name: Check out code uses: actions/checkout@v6 with: repository: ipxe/secure-boot-ca - name: Download uses: actions/download-artifact@v7 with: name: unsigned-${{ env.bindir }} path: unsigned - name: Test certificate run: | COMMITID=$(echo ${{ github.sha }} | cut -c1-9) SUBJECT="iPXE Test Signing (${COMMITID}, ${{ matrix.arch }})" openssl req \ -newkey rsa:2048 -passout 'pass:testpw' -keyout testsign.key \ -subj "/CN=${SUBJECT}/" -x509 -out testsign.crt - name: Certificate chain run: | for cert in ${{ env.signcerts }} ; do openssl x509 -in ${cert} -noout -text cat ${cert} >> chain.crts done - name: Sign run: | for binary in ${{ env.binaries }} ; do osslsigncode sign \ ${{ env.pkcs11 && '-pkcs11module' }} \ ${{ env.pkcs11 && '/usr/lib64/opensc-pkcs11.so' }} \ -certs chain.crts \ -key ${{ env.signkey }} \ -pass ${{ env.signpass }} \ -ts http://timestamp.digicert.com \ -in unsigned/${binary} \ -out ${binary} done - name: Verify run: | for binary in ${{ env.binaries }} ; do osslsigncode verify -CAfile ${{ env.cacert }} ${binary} done - name: Upload uses: actions/upload-artifact@v6 with: name: ${{ env.bindir }} if-no-files-found: error path: | ${{ env.cacert }} ipxe.efi snponly.efi linux: name: Linux / ${{ matrix.arch }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - arch: arm32 exec: qemu-arm-static - arch: arm64 exec: qemu-aarch64-static - arch: i386 exec: valgrind - arch: loong64 exec: qemu-loongarch64-static - arch: riscv32 exec: qemu-riscv32-static - arch: riscv64 exec: qemu-riscv64-static - arch: x86_64 exec: valgrind container: image: ghcr.io/ipxe/ipxe-builder-${{ matrix.arch }} env: bindir: bin-${{ matrix.arch }}-linux steps: - name: Check out code uses: actions/checkout@v6 - name: Build working-directory: src run: | make ${{ env.bindir }}/ipxe.linux \ ${{ env.bindir }}/tests.linux \ ${{ env.bindir }}/errors - name: Upload uses: actions/upload-artifact@v6 with: name: ${{ env.bindir }} if-no-files-found: error path: | src/${{ env.bindir }}/ipxe.linux src/${{ env.bindir }}/tests.linux src/${{ env.bindir }}/errors - name: Test working-directory: src run: | ${{ matrix.exec }} ${{ env.bindir }}/tests.linux shim: name: UEFI shim runs-on: ubuntu-latest env: shims: >- shimaa64.efi shimx64.efi shimurl: >- https://github.com/ipxe/shim/releases/latest/download steps: - name: Download run: | for shim in ${{ env.shims }} ; do curl -L ${{ env.shimurl }}/ipxe-${shim} -o ${shim} done - name: Upload uses: actions/upload-artifact@v6 with: name: shim if-no-files-found: error path: | shimaa64.efi shimx64.efi combine: name: Combine runs-on: ubuntu-latest needs: - bios - uefi - sbsign - shim container: image: ghcr.io/ipxe/ipxe-builder-utils env: efishims: >- -e shim/shimaa64.efi -e shim/shimx64.efi fsbinaries: >- bin-x86_64-pcbios/${DRIVERS}.lkrn bin-arm32-efi/${DRIVERS}.efi bin-arm64-efi/${DRIVERS}.efi bin-i386-efi/${DRIVERS}.efi bin-loong64-efi/${DRIVERS}.efi bin-riscv32-efi/${DRIVERS}.efi bin-riscv64-efi/${DRIVERS}.efi bin-x86_64-efi/${DRIVERS}.efi sbarchs: >- arm64 x86_64 sbbinaries: >- bin-${ARCH}-efi-sb/ipxe.efi srvbinaries: >- bin/ipxe.pxe bin/ipxe-legacy.pxe bin/undionly.kpxe bin-arm32-efi/ipxe.efi bin-arm32-efi/ipxe-legacy.efi bin-arm32-efi/snponly.efi bin-arm64-efi/ipxe.efi bin-arm64-efi/ipxe-legacy.efi bin-arm64-efi/snponly.efi bin-arm64-efi-sb/ipxe.efi bin-arm64-efi-sb/snponly.efi bin-i386-efi/ipxe.efi bin-i386-efi/ipxe-legacy.efi bin-i386-efi/snponly.efi bin-loong64-efi/ipxe.efi bin-loong64-efi/ipxe-legacy.efi bin-loong64-efi/snponly.efi bin-riscv32-efi/ipxe.efi bin-riscv32-efi/ipxe-legacy.efi bin-riscv32-efi/snponly.efi bin-riscv64-efi/ipxe.efi bin-riscv64-efi/ipxe-legacy.efi bin-riscv64-efi/snponly.efi bin-x86_64-efi/ipxe.efi bin-x86_64-efi/ipxe-legacy.efi bin-x86_64-efi/snponly.efi bin-x86_64-efi-sb/ipxe.efi bin-x86_64-efi-sb/snponly.efi bin-x86_64-pcbios/ipxe.pxe bin-x86_64-pcbios/ipxe-legacy.pxe bin-x86_64-pcbios/undionly.kpxe steps: - name: Check out code uses: actions/checkout@v6 - name: Download uses: actions/download-artifact@v7 with: pattern: "{bin,bin-x86_64-pcbios,bin-*-efi,bin-*-efi-sb,shim}" - name: Autoexec run: | # Provide an editable placeholder autoexec.ipxe for the USB image cat > autoexec.ipxe <<'EOF' #!ipxe echo prompt --key 0x02 --timeout 2000 \ Press Ctrl-B for the iPXE command line... \ && shell || autoboot EOF - name: ISO + USB run: | for DRIVERS in ipxe ipxe-legacy ; do ./src/util/genfsimg -o ${DRIVERS}.iso ${{ env.fsbinaries }} ./src/util/genfsimg -o ${DRIVERS}.usb -s autoexec.ipxe \ ${{ env.fsbinaries }} done - name: ISO + USB (SB) run: | for ARCH in ${{ env.sbarchs }} ; do ./src/util/genfsimg -o ipxe-${ARCH}-sb.iso \ ${{ env.efishims }} ${{ env.sbbinaries }} ./src/util/genfsimg -o ipxe-${ARCH}-sb.usb -s autoexec.ipxe \ ${{ env.efishims }} ${{ env.sbbinaries }} done - name: Server run: | ./src/util/gensrvimg -o ipxeboot.tar.gz ${{ env.efishims }} \ ${{ env.srvbinaries }} - name: Upload uses: actions/upload-artifact@v6 with: name: bin-combi if-no-files-found: error path: | ipxe.iso ipxe.usb ipxe-legacy.iso ipxe-legacy.usb ipxe-arm64-sb.iso ipxe-arm64-sb.usb ipxe-x86_64-sb.iso ipxe-x86_64-sb.usb ipxeboot.tar.gz version: name: Version runs-on: ubuntu-latest container: image: ghcr.io/ipxe/ipxe-builder-utils env: bindir: bin steps: - name: Check out code uses: actions/checkout@v6 - name: Build working-directory: src run: | make REPOURL=${{ github.server_url }}/${{ github.repository }} \ ${{ env.bindir }}/version.txt \ ${{ env.bindir }}/relname.txt \ ${{ env.bindir }}/reltitle.txt \ ${{ env.bindir }}/relnotes.md - name: Upload uses: actions/upload-artifact@v6 with: name: version if-no-files-found: error path: | src/${{ env.bindir }}/version.txt src/${{ env.bindir }}/relname.txt src/${{ env.bindir }}/reltitle.txt src/${{ env.bindir }}/relnotes.md publish: name: Publish runs-on: ubuntu-latest needs: - bios - sbi - uefi - sbsign - linux - shim - combine - version if: >- github.ref == 'refs/heads/master' && vars.PAGES_REPO_NAME env: workflow_url: >- ${{ github.server_url }}/${{ vars.PAGES_REPO_OWNER }}/${{ '' }}${{ vars.PAGES_REPO_NAME }}/actions/workflows/build.yml environment: name: publish url: ${{ env.workflow_url }} steps: - name: Get token id: token uses: actions/create-github-app-token@v2 with: app-id: ${{ vars.WORKFLOW_DISPATCHER_ID }} private-key: ${{ secrets.WORKFLOW_DISPATCHER_KEY }} owner: ${{ vars.PAGES_REPO_OWNER }} repositories: ${{ vars.PAGES_REPO_NAME }} - name: Dispatch env: GH_REPO: ${{ vars.PAGES_REPO_OWNER }}/${{ vars.PAGES_REPO_NAME }} GH_TOKEN: ${{ steps.token.outputs.token }} run: | gh workflow run build.yml -f run_id=${{ github.run_id }} echo "Results at ${{ env.workflow_url }}" release: name: Release runs-on: ubuntu-latest needs: - bios - sbi - uefi - sbsign - linux - shim - combine - version if: >- startsWith ( github.ref, 'refs/tags/v' ) steps: - name: Download uses: actions/download-artifact@v7 with: pattern: "{bin-combi,version}" - name: Tag check run: | RELNAME=$(cat version/relname.txt) if [ "${{ github.ref_name }}" != "${RELNAME}" ] ; then echo "ERROR: Tag does not match release name ${RELNAME}" >&2 exit 1 fi - name: Release env: GH_REPO: ${{ github.repository }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh release create "${{ github.ref_name }}" --verify-tag --draft \ --title "$(cat version/relname.txt)" \ --notes-file version/relnotes.md \ bin-combi/ipxe.iso bin-combi/ipxe.usb \ bin-combi/ipxe-arm64-sb.iso bin-combi/ipxe-arm64-sb.usb \ bin-combi/ipxe-x86_64-sb.iso bin-combi/ipxe-x86_64-sb.usb \ bin-combi/ipxeboot.tar.gz