Skip to content

build-test-recipe #7360

build-test-recipe

build-test-recipe #7360

name: build-test-recipe
on:
workflow_dispatch:
pull_request:
merge_group:
jobs:
changed:
name: Get changed recipes
runs-on: ubuntu-latest
outputs:
recipes: ${{ steps.diff.outputs.recipes }}
diff: ${{ steps.diff.outputs.diff }}
release: ${{ steps.get-yocto-release-name.outputs.release }}
steps:
- uses: actions/checkout@v4
- name: Diff files and set variables
id: diff
env:
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
HEAD_REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }}
HEAD_REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }}
REPOSITORY: ${{ github.repository }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
BEFORE_SHA: ${{ github.event.before }}
AFTER_SHA: ${{ github.event.after }}
MERGE_GROUP_BASE_SHA: ${{ github.event.merge_group.base_sha }}
MERGE_GROUP_HEAD_SHA: ${{ github.event.merge_group.head_sha }}
run: |
if [ -n "$BASE_REF" ] && [ -n "$HEAD_REF" ] && [ -n "$HEAD_SHA" ]; then
# Pull Request
git fetch origin "$BASE_REF:$BASE_REF"
if [ "$HEAD_REPO_NAME" != "$REPOSITORY" ] && [ -n "$HEAD_REPO_URL" ]; then
git remote add fork "$HEAD_REPO_URL"
git fetch fork "$HEAD_REF"
else
git fetch origin "$HEAD_REF:$HEAD_REF"
fi
FORK_POINT=$(git merge-base "$BASE_REF" "$HEAD_SHA")
DIFF=$(git diff --name-only --diff-filter=d "$FORK_POINT" "$HEAD_SHA")
echo "Diff between $FORK_POINT and $HEAD_SHA"
elif [ -n "$MERGE_GROUP_BASE_SHA" ] && [ -n "$MERGE_GROUP_HEAD_SHA" ]; then
# Merge Group
git fetch origin "$MERGE_GROUP_BASE_SHA" "$MERGE_GROUP_HEAD_SHA"
DIFF=$(git diff --name-only --diff-filter=d "$MERGE_GROUP_BASE_SHA" "$MERGE_GROUP_HEAD_SHA")
echo "Diff between $MERGE_GROUP_BASE_SHA and $MERGE_GROUP_HEAD_SHA"
elif [ -n "$BEFORE_SHA" ] && [ -n "$AFTER_SHA" ]; then
# Push to a branch
DIFF=$(git diff --name-only --diff-filter=d "$BEFORE_SHA" "$AFTER_SHA")
echo "Diff between $BEFORE_SHA and $AFTER_SHA"
else
echo "No valid diff context found, checking all files"
DIFF=""
fi
echo "$DIFF"
echo "diff=$( echo "$DIFF" | tr '\n' ' ' )" >> $GITHUB_OUTPUT
- name: Get Yocto release name
id: get-yocto-release-name
env:
EVENT_NAME: ${{ github.event_name }}
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
MERGE_GROUP_BASE_REF: ${{ github.event.merge_group.base_ref }}
REF_NAME: ${{ github.ref_name }}
run: |
case "$EVENT_NAME" in
"pull_request")
RELEASE=$(echo "$PR_BASE_REF" | cut -d- -f1)
;;
"merge_group")
RELEASE=$(echo "$MERGE_GROUP_BASE_REF" | sed 's|refs/heads/||' | cut -d- -f1)
;;
*)
RELEASE=$(echo "$REF_NAME" | cut -d- -f1)
;;
esac
echo "Determined release: $RELEASE"
echo "release=${RELEASE}" >> $GITHUB_OUTPUT
build-test:
name: Build, Test ${{ matrix.machine }} ${{ needs.changed.outputs.release }}
needs: changed
strategy:
fail-fast: false
matrix:
machine:
- qemuarm
- qemuarm64
- qemux86-64
runs-on: codebuild-${{ vars.CODEBUILD_RUNNER_NAME || 'meta-aws' }}-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- name: Checkout meta-aws
uses: actions/checkout@v4
with:
path: ${{ github.workspace }}/meta-aws
- name: Checkout meta-oe
uses: actions/checkout@v4
with:
repository: openembedded/meta-openembedded
path: ${{ github.workspace }}/meta-openembedded
ref: ${{ needs.changed.outputs.release }}
- name: Checkout poky
run: |
git clone git://git.yoctoproject.org/poky --single-branch ${{ github.workspace }}/poky -b ${{ needs.changed.outputs.release }}
- name: Get changed Recipes or defaults
id: recipes_to_build_test
shell: bash
run: |
echo diff:
echo ${{ needs.changed.outputs.diff }}
# Map machine to architecture for COMPATIBLE_HOST check
case "${{ matrix.machine }}" in
qemuarm)
ARCH="arm"
;;
qemuarm64)
ARCH="aarch64"
;;
qemux86-64)
ARCH="x86-64"
;;
esac
export RECIPES=$( echo "${{ needs.changed.outputs.diff }}" | tr ' ' '\n' | grep '\.bb.*$' | sed 's!.*/!!' | sed 's!.bb!!' | sed 's!_.*!!' | sort | uniq | sed -z $'s/\\\n/ /g')
if [ "" == "$RECIPES" ]; then
echo "No changed recipes, adding everything with a ptest to test, build"
THINGS_TO_EXCLUDE="! -name aws-lc* ! -name neo-ai-tv* ! -name corretto-17-bin* ! -name corretto-21-bin* ! -name corretto-8-bin* ! -name firecracker-bin* ! -name jailer-bin* ! -name amazon-kvs-producer-sdk-c* ! -name aws-cli-v2* ! -name aws-iot-device-sdk-embedded-c* "
if [ ${{ matrix.machine }} == "qemuarm" ]; then
THINGS_TO_EXCLUDE+="! -name amazon-kvs-webrtc-sdk* ! -name amazon-kvs-producer-pic* ! -name amazon-cloudwatch-agent*"
fi
export RECIPES=$(find meta-aws/ -name *.bb -type f \( ${THINGS_TO_EXCLUDE} \) -print | xargs grep -l 'inherit.*ptest.*'| sed 's!.*/!!' | sed 's!.bb!!' | sed 's!_.*!!' | sort | uniq | sed -z $'s/\\\n/ /g')
echo THINGS_TO_EXCLUDE: $THINGS_TO_EXCLUDE
fi
# Filter out recipes with COMPATIBLE_HOST:$ARCH = "null"
FILTERED_RECIPES=""
for recipe in $RECIPES; do
if ! find meta-aws/ -name "${recipe}.bb" -o -name "${recipe}_*.bb" | xargs grep -q "COMPATIBLE_HOST:${ARCH}[[:space:]]*=[[:space:]]*\"null\"" 2>/dev/null; then
FILTERED_RECIPES+="$recipe "
fi
done
export RECIPES="$FILTERED_RECIPES"
echo RECIPES to build, test: "$RECIPES"
echo "recipes=$RECIPES" >> $GITHUB_OUTPUT
- name: Run build
env:
RECIPES: ${{ steps.recipes_to_build_test.outputs.recipes }}
run: |
echo RECIPES to build: $RECIPES
chown yoctouser /sstate-cache
chown yoctouser /downloads
chown -R yoctouser .
sysctl vm.mmap_min_addr=65536
sudo RECIPES="$RECIPES" -u yoctouser bash -c '
cd ${{ github.workspace }}
source poky/oe-init-build-env build
echo QEMU_USE_KVM = \"\" >> conf/local.conf
# set to max for arm32
echo QB_MEM:arm = \"-m 3G\" >> conf/local.conf
echo QB_MEM = \"-m 8G\" >> conf/local.conf
# use slirp networking instead of TAP interface (require root rights)
echo QEMU_USE_SLIRP = \"1\" >> conf/local.conf
echo TEST_RUNQEMUPARAMS += \"slirp\" >> conf/local.conf
echo TEST_SERVER_IP = \"127.0.0.1\" >> conf/local.conf
echo DISTRO_FEATURES += \"ptest\" >> conf/local.conf
echo DISTRO = \"poky-altcfg\" >> conf/local.conf
# this will specify what test should run when running testimage cmd - oeqa layer tests + ptests:
# Ping and SSH are not required, but do help in debugging. ptest will discover all ptest packages.
echo TEST_SUITES = \" ping ssh ptest parselogs\" >> conf/local.conf
# this will allow - running testimage cmd: bitbake core-image-minimal -c testimage
echo IMAGE_CLASSES += \"testimage\" >> conf/local.conf
cat conf/local.conf
bitbake-layers add-layer ../meta-openembedded/meta-oe
bitbake-layers add-layer ../meta-openembedded/meta-python
bitbake-layers add-layer ../meta-openembedded/meta-networking
bitbake-layers add-layer ../meta-openembedded/meta-multimedia
bitbake-layers add-layer ../meta-aws
export SSTATE_DIR=/sstate-cache
export DL_DIR=/downloads
export MACHINE=${{ matrix.machine }}
export BB_ENV_PASSTHROUGH_ADDITIONS="$BB_ENV_PASSTHROUGH_ADDITIONS SSTATE_DIR DL_DIR"
bitbake $RECIPES -f -k | tee -a $MACHINE-build.log'
set -e
echo RECIPES to build: $RECIPES
if [ -e "build/${{ matrix.machine }}-build.log" ]; then
if grep -A3 -E ' failed| ERROR:' "build/${{ matrix.machine }}-build.log"; then
echo "Found failed or ERROR in build log"
exit 1
fi
else
echo "Build log file not found: build/${{ matrix.machine }}-build.log"
exit 1
fi
- name: Save ${{ matrix.machine }}-build.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.machine }}-build.log
path: build/${{ matrix.machine }}-build.log
- name: Run test
env:
RECIPES: ${{ steps.recipes_to_build_test.outputs.recipes }}
run: |
sudo RECIPES="$RECIPES" -u yoctouser bash -c '
cd ${{ github.workspace }}
source poky/oe-init-build-env build
# PUT = package under test
for recipe in $RECIPES; do PUT+="${recipe}-ptest "; done
echo IMAGE_INSTALL:append = \" ptest-runner ssh ${PUT}\" >> conf/local.conf
export SSTATE_DIR=/sstate-cache
export DL_DIR=/downloads
export MACHINE=${{ matrix.machine }}
export BB_ENV_PASSTHROUGH_ADDITIONS="$BB_ENV_PASSTHROUGH_ADDITIONS SSTATE_DIR DL_DIR"
bitbake core-image-minimal
bitbake core-image-minimal -c testimage
resulttool report tmp/log/oeqa/testresults.json | tee -a ${{ matrix.machine }}-resulttool_report.txt'
set -e
echo RECIPES to test: $RECIPES
test -e build/tmp/log/oeqa/testresults.json && ! grep -B3 "\"FAILED\"" build/tmp/log/oeqa/testresults.json
- name: Save resulttool_report.txt
if: '!cancelled()'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.machine }}-resulttool_report.txt
path: build/${{ matrix.machine }}-resulttool_report.txt