version: 2.1

commands:
  build_board:
    parameters:
      arch:
        type: string
      target:
        type: string
      subcommand:
        type: string
    steps:
      - run:
          name: Install dependencies
          command: |
            ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
            apt update
            apt install -y build-essential zlib1g-dev uuid-dev libdigest-sha-perl libelf-dev bc bzip2 bison flex git gnupg gawk iasl m4 nasm patch python python2 python3 wget gnat cpio ccache pkg-config cmake libusb-1.0-0-dev autoconf texinfo ncurses-dev doxygen graphviz udev libudev1 libudev-dev automake libtool rsync innoextract sudo libssl-dev device-tree-compiler u-boot-tools sharutils e2fsprogs parted curl unzip
      - run:
          name: Make Board (FULL ORDERED BUILD LOGS HERE UNTIL JOB FAILED)
          command: |
            rm -rf build/<<parameters.arch>>/<<parameters.target>>/* build/<<parameters.arch>>/log/* && make V=1 BOARD=<<parameters.target>> <<parameters.subcommand>> || touch ./tmpDir/failed_build
          no_output_timeout: 3h
      - run:
          name: Output hashes
          command: |
            cat build/<<parameters.arch>>/<<parameters.target>>/hashes.txt || echo "No hashes for this build step..."\
      - run:
          name: Archiving build logs.
          command: |
             tar zcvf build/<<parameters.arch>>/<<parameters.target>>/logs.tar.gz $(find build/ -name "*.log")
      - run:
          name: Output build failing logs
          command: |
            if [[ -f ./tmpDir/failed_build ]]; then find ./build/<<parameters.arch>>/ -name "*.log" -type f -mmin -1|while read log; do echo ""; echo '==>' "$log" '<=='; echo ""; cat $log;done; exit 1;else echo "Step hasn't failed. Continuing with next step..."; fi \
      - store_artifacts:
          path: build/<<parameters.arch>>/<<parameters.target>>

jobs:
  prep_env:
    docker:
      - image: debian:11
    resource_class: large
    steps:
      - run:
          name: Install dependencies
          command: |
            ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime 
            apt update
            apt install -y build-essential zlib1g-dev uuid-dev libdigest-sha-perl libelf-dev bc bzip2 bison flex git gnupg gawk iasl m4 nasm patch python python2 python3 wget gnat cpio ccache pkg-config cmake libusb-1.0-0-dev autoconf texinfo ncurses-dev doxygen graphviz udev libudev1 libudev-dev automake libtool rsync innoextract sudo
      - checkout

      - run:
          name: git reset
          command: |
            git reset --hard "$CIRCLE_SHA1" \

      - run:
          name: Make tmp dir
          command: |
            mkdir ./tmpDir \

      - run:
          name: Creating all modules and patches digest (All modules cache digest)
          command: |
            find ./Makefile ./patches/ ./modules/ -type f | sort -h |xargs sha256sum > ./tmpDir/all_modules_and_patches.sha256sums \

      - run:
          name: Creating coreboot (and associated patches) and musl-cross-make modules digest (musl-cross-make and coreboot cache digest)
          command: |
            find ./Makefile ./modules/coreboot ./modules/musl-cross* ./patches/coreboot* -type f | sort -h | xargs sha256sum > ./tmpDir/coreboot_musl-cross.sha256sums \

      - run:
          name: Creating musl-cross-make and musl-cross-make patches digest (musl-cross-make cache digest)
          command: |
            find ./Makefile modules/musl-cross* -type f | sort -h | xargs sha256sum > ./tmpDir/musl-cross.sha256sums \

      - restore_cache:
          keys:
            #Restore existing cache for matching modules digest, validated to be exactly the same as in github current commit.
            #This cache was made on top of below caches, if previously existing. If no module definition changed, we reuse this one. Otherwise...
            - heads-modules-and-patches-{{ checksum "./tmpDir/all_modules_and_patches.sha256sums" }}{{ .Environment.CACHE_VERSION }}
            #If precedent cache not found, restore cache for coreboot module (and patches) and musl-cross-make digests (coreboot: triannual release)
            #Otehrwise....
            - heads-coreboot-musl-cross-{{ checksum "./tmpDir/coreboot_musl-cross.sha256sums" }}{{ .Environment.CACHE_VERSION }}
            #If precedent cache not found. Restore cache for musl-cross-make module digest (rarely modified).
            #Otherwise, we build cleanly.
            - heads-musl-cross-{{ checksum "./tmpDir/musl-cross.sha256sums" }}{{ .Environment.CACHE_VERSION }}
      - run:
          name: Download and neuter xx20 ME (keep generated GBE and extracted IFD in tree)
          command: |
            ./blobs/xx20/download_parse_me.sh

      - run:
          name: Download and neuter xx30 ME (keep generated GBE and extracted IFD in tree)
          # me_cleaner.py present under heads xx30 blobs dir comes from https://github.com/corna/me_cleaner/blob/43612a630c79f3bc6f2653bfe90dfe0b7b137e08/me_cleaner.py
          command: |
            ./blobs/xx30/download_clean_me.sh -m $(readlink -f ./blobs/xx30/me_cleaner.py)

      - run:
          name: Download and extract t530 vbios roms for dgpu boards
          command: |
            ./blobs/xx30/vbios_t530.sh

      - run:
          name: Download and extract w530 vbios roms for dgpu boards
          command: |
            ./blobs/xx30/vbios_w530.sh

      - persist_to_workspace:
          root: ~/
          paths:
            - .

  build_and_persist:
    docker:
      - image: debian:11
    resource_class: large
    parameters:
      arch:
        type: string
        default: x86
      target:
        type: string
      subcommand:
        type: string
    steps:
      - attach_workspace:
          at: ~/
      - build_board:
          arch: <<parameters.arch>>
          target: <<parameters.target>>
          subcommand: <<parameters.subcommand>>
      - persist_to_workspace:
          root: ~/
          paths:
            - project/packages/<<parameters.arch>>
            - project/build/<<parameters.arch>>
            - project/crossgcc/<<parameters.arch>>
            - project/install/<<parameters.arch>>

  build:
    docker:
      - image: debian:11
    resource_class: large
    parameters:
      arch:
        type: string
        default: x86
      target:
        type: string
      subcommand:
        type: string
    steps:
      - attach_workspace:
          at: ~/
      - build_board:
          arch: <<parameters.arch>>
          target: <<parameters.target>> 
          subcommand: <<parameters.subcommand>>

  save_cache:
    docker:
      - image: debian:11
    resource_class: large
    steps:
      - attach_workspace:
          at: ~/
      - save_cache:
          #Generate cache for the same musl-cross module definition if hash is not previously existing
          #CircleCI removed their wildcard support, so we have to list precise versions to cache in directory names
          key: heads-musl-cross-{{ checksum "./tmpDir/musl-cross.sha256sums" }}{{ .Environment.CACHE_VERSION }}
          paths:
            - crossgcc
            - build/x86/musl-cross-38e52db8358c043ae82b346a2e6e66bc86a53bc1
            - build/ppc64/musl-cross-38e52db8358c043ae82b346a2e6e66bc86a53bc1
            - packages
      - save_cache:
          #Generate cache for the same coreboot mnd musl-cross-make modules definition if hash is not previously existing
          #CircleCI removed their wildcard support, so we have to list precise versions to cache in directory names
          key: heads-coreboot-musl-cross-{{ checksum "./tmpDir/coreboot_musl-cross.sha256sums" }}{{ .Environment.CACHE_VERSION }}
          paths:
            - crossgcc
            - build/x86/musl-cross-38e52db8358c043ae82b346a2e6e66bc86a53bc1
            - build/ppc64/musl-cross-38e52db8358c043ae82b346a2e6e66bc86a53bc1
            - packages
            - build/x86/coreboot-4.11
            - build/x86/coreboot-4.13
            - build/x86/coreboot-4.14
            - build/x86/coreboot-4.15
            - build/x86/coreboot-4.17
            - build/ppc64/coreboot-git
      - save_cache:
          #Generate cache for the exact same modules definitions if hash is not previously existing
          key: heads-modules-and-patches-{{ checksum "./tmpDir/all_modules_and_patches.sha256sums" }}{{ .Environment.CACHE_VERSION }}
          paths:
            - crossgcc
            - build
            - packages
            - install

workflows:
  version: 2
  build_and_test:
    jobs:
      - prep_env

# Below, sequentially build one board for each coreboot
# version. The last board in the sequence is the dependency
# for the parallel boards built at the end, and also save_cache.

      # Coreboot 4.13
      - build_and_persist:
          name: x230-hotp-maximized
          target: x230-hotp-maximized
          subcommand: ""
          requires:
            - prep_env

      # Coreboot 4.17
      - build_and_persist:
          name: librem_14
          target: librem_14
          subcommand: ""
          requires:
            - x230-hotp-maximized

      # Coreboot for Talos (PPC)
      - build_and_persist:
          name: talos-2_server
          arch: ppc64
          target: talos-2_server
          subcommand: ""
          requires:
            - prep_env

      #Cache one workspace per architecture. Make sure workspace caches are chainloaded and the last in chain for an arch is saved.
      - save_cache:
          requires:
            - librem_14
            - talos-2_server

#
#
# Those onboarding new boards should add their entries below.
#
#

      - build:
          name: x220-hotp-maximized
          target: x220-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x220-maximized
          target: x220-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t420-hotp-maximized
          target: t420-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t520-hotp-maximized
          target: t520-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t420-maximized
          target: t420-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t520-maximized
          target: t520-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x230-legacy-flash
          target: x230-legacy-flash
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t430-legacy-flash
          target: t430-legacy-flash
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t430-legacy
          target: t430-legacy
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t430-hotp-legacy
          target: t430-hotp-legacy
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x230-legacy
          target: x230-legacy
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x230-hotp-legacy
          target: x230-hotp-legacy
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x230-hotp-maximized_usb-kb
          target: x230-hotp-maximized_usb-kb
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t430-hotp-maximized
          target: t430-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x230-maximized
          target: x230-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x230-maximized-fhd_edp
          target: x230-maximized-fhd_edp
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: x230-hotp-maximized-fhd_edp
          target: x230-hotp-maximized-fhd_edp
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t530-hotp-maximized
          target: t530-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t530-dgpu-hotp-maximized
          target: t530-dgpu-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: w530-hotp-maximized
          target: w530-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: w530-dgpu-K1000m-hotp-maximized
          target: w530-dgpu-K1000m-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized  

      - build:
          name: w530-dgpu-K2000m-hotp-maximized
          target: w530-dgpu-K2000m-hotp-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized  
            
      - build:
          name: t430-maximized
          target: t430-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t530-maximized
          target: t530-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t530-dgpu-maximized
          target: t530-dgpu-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: w530-maximized
          target: w530-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: w530-dgpu-K1000m-maximized
          target: w530-dgpu-K1000m-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: w530-dgpu-K2000m-maximized
          target: w530-dgpu-K2000m-maximized
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: t440p-maximized
          target: t440p-maximized
          subcommand: ""
          requires:
            - librem_14

      - build:
          name: t440p-hotp-maximized
          target: t440p-hotp-maximized
          subcommand: ""
          requires:
            - librem_14

      - build:
          name: qemu-coreboot
          target: qemu-coreboot
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: qemu-coreboot-fbwhiptail
          target: qemu-coreboot-fbwhiptail
          subcommand: ""
          requires:
            - x230-hotp-maximized

      - build:
          name: librem_13v2
          target: librem_13v2
          subcommand: ""
          requires:
            - librem_14

      - build:
          name: librem_15v3
          target: librem_15v3
          subcommand: ""
          requires:
            - librem_14

      - build:
          name: librem_13v4
          target: librem_13v4
          subcommand: ""
          requires:
            - librem_14

      - build:
          name: librem_15v4
          target: librem_15v4
          subcommand: ""
          requires:
            - librem_14

      - build:
          name: librem_mini
          target: librem_mini
          subcommand: ""
          requires:
            - librem_14

      - build:
          name: librem_mini_v2
          target: librem_mini_v2
          subcommand: ""
          requires:
            - librem_14

#      - build:
#          name: kgpe-d16_workstation-usb_keyboard
#          target: kgpe-d16_workstation-usb_keyboard
#          subcommand: ""
#          requires:
#            - kgpe-d16_workstation

#      - build:
#          name: kgpe-d16_server
#          target: kgpe-d16_server
#          subcommand: ""
#          requires:
#            - kgpe-d16_workstation

#      - build:
#          name: kgpe-d16_server-whiptail
#          target: kgpe-d16_server-whiptail
#          subcommand: ""
#          requires:
#            - kgpe-d16_workstation

#      - build:
#          name: librem_l1um
#          target: librem_l1um
#          subcommand: ""
#          requires:
#            - librem_14

      - build:
          name: talos-2_workstation
          arch: ppc64
          target: talos-2_workstation
          subcommand: ""
          requires:
            - talos-2_server

########################
########################
###    OLD STUFF     ###
########################
########################
# linuxboot steps need something to pass in the kernel header path
# skipping for now
#      - run:
#          name: qemu-linuxboot-edk2
#          command: |
#            ./build/make-4.2.1/make \
#                CROSS=/cross/bin/x86_64-linux-musl- \
#                BOARD=qemu-linuxboot \
#                `/bin/pwd`/build/linuxboot-git/build/qemu/.configured \
#                # Run first to avoid too many processes
#
#      - run:
#          name: qemu-linuxboot
#          command: |
#            ./build/make-4.2.1/make \
#                CROSS=/cross/bin/x86_64-linux-musl- \
#                CPUS=16 \
#                V=1 \
#                BOARD=qemu-linuxboot \
#
#      - store-artifacts:
#          path: build/qemu-linuxboot/linuxboot.rom
#      - store-artifacts:
#          path: build/qemu-linuxboot/hashes.txt