Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ This folder contains workflows that are helpful for maintaining a smooth and sec
Workflows:
1. `qcom-preflight-checks.yml` - This workflow runs several preflight checks, including copyight, email, repolinter, and security checks. See [qualcomm/qcom-actions](https://github.com/qualcomm/qcom-actions)
2. `stale-issues.yaml` - This workflow will periodically run every 30 days to check for stalled issues and PRs. If the workflow detects any stalled issues and/or PRs, it will automatically leave just a comment to draw attention.
3. `build-yocto.yml` - Reusable build workflow. Runs a kas build matrix (`nodistro` × `qemuarm`/`qemuarm64`/`qemux86-64`) on the shared `qcom-u2404` self-hosted runner pool, reusing `qualcomm-linux/meta-qcom`'s `compile` action directly rather than a local copy. Called by `pr.yml` and `push.yml`.
4. `pr.yml` / `push.yml` - Trigger `build-yocto.yml` on pull requests to `main` and on pushes to `main`/`wrynose`.
5. `lava-test.yml` - Disabled placeholder for future on-device LAVA testing (see the TODO block in that file). `workflow_dispatch`-only; not wired into `pr.yml`/`push.yml` yet.
205 changes: 205 additions & 0 deletions .github/workflows/build-yocto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
name: Build Yocto

on:
workflow_call:
inputs:
profile:
required: false
type: string
default: "full" # values: pr | full
git_ref:
required: false
type: string
default: ""
outputs:
artifacts_url:
description: "URL to retrieve build artifacts"
value: ${{ jobs.create-output.outputs.url }}

# Concurrency is used to prevent multiple workflows from running for the same PR
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('push-{0}', github.sha) }}
cancel-in-progress: true

env:
CACHE_DIR: /efs/qli/meta-qcom
KAS_CLONE_DEPTH: 1

jobs:
kas-setup:
if: github.repository_owner == 'qualcomm-linux'
runs-on: [self-hosted, qcom-u2404, amd64]
steps:
- name: Setting up kas-container
run: |
KAS_CONTAINER=$RUNNER_TEMP/kas-container
echo "KAS_CONTAINER=$KAS_CONTAINER" >> $GITHUB_ENV
LATEST=$(git ls-remote --tags --refs --sort="v:refname" https://github.com/siemens/kas | tail -n1 | sed 's/.*\///')
wget -qO ${KAS_CONTAINER} https://raw.githubusercontent.com/siemens/kas/refs/tags/$LATEST/kas-container
chmod +x ${KAS_CONTAINER}

- uses: actions/checkout@v6
with:
persist-credentials: false
ref: ${{ inputs.git_ref }}

- name: Run kas lock
if: ${{ hashFiles('ci/base.lock.yml') == '' }}
run: |
${KAS_CONTAINER} lock --update ci/base.yml

- name: Upload kas lockfile
uses: actions/upload-artifact@v6
with:
name: kas-lockfile
path: ci/*.lock.yml

- name: Upload kas-container
uses: actions/upload-artifact@v6
with:
name: kas-container
path: ${{ env.KAS_CONTAINER }}

yocto-run-checks:
needs: kas-setup
if: github.repository_owner == 'qualcomm-linux'
runs-on: [self-hosted, qcom-u2404, amd64]
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
ref: ${{ inputs.git_ref }}

- name: Download kas lockfile
uses: actions/download-artifact@v7
with:
name: kas-lockfile
path: ci

- name: Download kas-container
uses: actions/download-artifact@v7
with:
name: kas-container
path: ${{ runner.temp }}

- name: Setting up kas-container
run: |
KAS_CONTAINER=$RUNNER_TEMP/kas-container
echo "KAS_CONTAINER=$KAS_CONTAINER" >> $GITHUB_ENV
chmod +x $KAS_CONTAINER

- name: Run Yocto patchreview
run: |
ci/kas-container-shell-helper.sh ci/yocto-patchreview.sh

- name: Run yocto-check-layer
run: |
ci/kas-container-shell-helper.sh ci/yocto-check-layer.sh

compile:
needs: kas-setup
if: github.repository_owner == 'qualcomm-linux'
runs-on: [self-hosted, qcom-u2404, amd64]
outputs:
url: ${{ steps.compile_kas.outputs.url }}
strategy:
fail-fast: false
matrix:
machine:
- qemuarm
- qemuarm64
- qemux86-64
distro:
- name: nodistro
yamlfile: ""
kernel:
- type: default
dirname: ""
yamlfile: ""
name: ${{ matrix.machine }}/${{ matrix.distro.name }}${{ matrix.kernel.dirname }}
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
ref: ${{ inputs.git_ref }}

- name: Run kas build
uses: qualcomm-linux/meta-qcom/.github/actions/compile@master
id: compile_kas
with:
machine: ${{matrix.machine}}
distro_yaml: ${{matrix.distro.yamlfile}}
distro_name: ${{matrix.distro.name}}
kernel_yaml: ${{matrix.kernel.yamlfile}}
kernel_dirname: ${{matrix.kernel.dirname}}
cache_dir: ${{env.CACHE_DIR}}

publish_summary:
needs: compile
if: ${{ always() && github.repository_owner == 'qualcomm-linux' }}
runs-on: ubuntu-latest
steps:
- name: 'Download build URLs'
uses: actions/download-artifact@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
pattern: build-url*
path: urlfiles
merge-multiple: true

- name: "Print output"
shell: python
id: print-output
run: |
import os
ftable = {}
oslist = set()
machinelist = set()
for fname in os.listdir("./urlfiles"):
if fname.startswith("build-url"):
b, m, o = fname.split("_", 2)
oslist.add(o)
machinelist.add(m)
url = ""
with open(f"./urlfiles/{fname}", "r") as urlfile:
url = urlfile.read()
if not o in ftable:
ftable.update({o:{m: url}})
else:
ftable[o].update({m: url})

table_str = "| |"

for m in sorted(machinelist):
table_str += f" {m} |"

table_str += "\n|"
for i in range(len(machinelist) + 1):
table_str += " ---- |"

table_str += "\n"

for o in sorted(ftable.keys()):
table_str += f"| {o} |"
for m in sorted(machinelist):
url = ftable[o].get(m)
if url:
url = url.strip()
table_str += f" [Files]({url}/{o}/{m}/) |"
else:
table_str += " |"
table_str += "\n"
summary_file_name = os.environ.get("GITHUB_STEP_SUMMARY")
if summary_file_name:
with open(summary_file_name, "a") as summaryfile:
summaryfile.write("## Download URLs\n")
summaryfile.write(table_str)
print(table_str)

build_successful:
if: github.repository_owner == 'qualcomm-linux'
needs: compile
runs-on: ubuntu-latest
steps:
- name: Build completed successfully
run: echo "All compile matrix jobs succeeded and artifacts uploaded to S3 bucket"
46 changes: 46 additions & 0 deletions .github/workflows/lava-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# DISABLED PLACEHOLDER — on-device LAVA testing is not yet implemented for meta-ai.
#
# This workflow only runs via manual `workflow_dispatch` (no `push`/
# `pull_request` triggers), so it never fires automatically. It exists to
# document the intended shape of on-device testing before it is built.
#
# TODO: enable on-device testing of the AI runtimes (litert, onnxruntime,
# tensorflow-lite, llama-cpp) against simple models, on real hardware, via
# LAVA. See meta-qcom's test.yml / test-distro.yml and the
# `qualcomm-linux/meta-qcom/.github/actions/lava-test-plans` action for the
# pattern to follow (job definitions generated via the
# `qualcomm-linux/lava-test-plans` tool, submitted via
# `foundriesio/lava-action`).
#
# Target machines:
# - rb1-core-kit (qualcomm-linux/meta-qcom)
# - rb3gen2-core-kit (qualcomm-linux/meta-qcom)
# - uno-q (qualcomm-linux/meta-qcom-3rdparty, merged)
# - ventuno-q (qualcomm-linux/meta-qcom-3rdparty, NOT yet merged —
# see PR #16 "Add ventuno-q support"; blocked on that
# landing upstream before this machine can be added)
#
# To enable: add `push`/`pull_request` triggers (mirroring push.yml/pr.yml),
# wire this into push.yml/pr.yml as a needs: [build] job, remove this TODO
# block, and fill in the lava-test-plans invocation per target machine.

name: LAVA on-device tests (disabled placeholder)

on:
workflow_dispatch:
inputs:
build_id:
required: true
type: string
description: "Run ID of the build-yocto.yml workflow run to test"

jobs:
test-nodistro:
name: "Test nodistro (placeholder — not implemented)"
runs-on: ubuntu-latest
steps:
- name: Not implemented
run: |
echo "On-device LAVA testing is not yet implemented for meta-ai."
echo "See the TODO block at the top of this workflow file."
exit 1
34 changes: 34 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Build on PR
run-name: "${{ github.base_ref }}: ${{ github.event.pull_request.title }}"

on:
pull_request:
branches:
- main
paths-ignore:
- 'README.md'
- 'README'
- 'SECURITY.md'

permissions:
checks: write
pull-requests: write
contents: read
packages: read
actions: read

jobs:
event-file:
name: "Upload event file"
runs-on: ubuntu-latest
steps:
- name: Upload
uses: actions/upload-artifact@v6
with:
name: Event File
path: ${{ github.event_path }}

build-pr:
uses: ./.github/workflows/build-yocto.yml
with:
profile: pr
18 changes: 18 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Build on push
run-name: "${{ github.ref_name }}: ${{ github.event.head_commit.message }}"

on:
push:
branches:
- main
- wrynose

permissions:
checks: write
pull-requests: write
contents: read
packages: read

jobs:
build:
uses: ./.github/workflows/build-yocto.yml
50 changes: 50 additions & 0 deletions ci/base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/siemens/kas/master/kas/schema-kas.json

header:
version: 14

distro: nodistro

defaults:
repos:
branch: main

repos:
meta-ai:

openembedded-core:
url: https://github.com/openembedded/openembedded-core
layers:
meta:

meta-openembedded:
url: https://github.com/openembedded/meta-openembedded
layers:
meta-oe:

bitbake:
url: https://github.com/openembedded/bitbake
layers:
.: disabled

local_conf_header:
base: |
INHERIT += "buildstats buildstats-summary"
INHERIT += "buildhistory"
INHERIT += "rm_work"
diskmon: |
BB_DISKMON_DIRS ??= "\
STOPTASKS,${TMPDIR},1G,100K \
STOPTASKS,${DL_DIR},1G,100K \
STOPTASKS,${SSTATE_DIR},10G,100K \
STOPTASKS,/tmp,100M,100K \
HALT,${TMPDIR},100M,1K \
HALT,${DL_DIR},100M,1K \
HALT,${SSTATE_DIR},1G,1K \
HALT,/tmp,10M,1K"

machine: unset

target:
- llama-cpp
- tensorflow-lite
8 changes: 8 additions & 0 deletions ci/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/siemens/kas/master/kas/schema-kas.json

header:
version: 14

local_conf_header:
ci: |
BB_SIGNATURE_HANDLER = "OEBasicHash"
20 changes: 20 additions & 0 deletions ci/kas-container-shell-helper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh -e
# Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
# SPDX-License-Identifier: MIT

TOPDIR=$(realpath $(dirname $(readlink -f $0))/..)
SCRIPT=$(realpath $1)

if ! [ -f $SCRIPT ]; then
echo "The script path argument is missing, please run it with:"
echo " $0 /path/to/script"
exit 1
fi

# make it relative to the TOPDIR
SCRIPT=${SCRIPT#$TOPDIR/}

# on ci the kas-container is not on the default path
KAS_CONTAINER=${KAS_CONTAINER:-$(which kas-container)}

exec $KAS_CONTAINER shell $TOPDIR/ci/base.yml --command "/repo/$SCRIPT /repo /work"
Loading
Loading