Push Tracker
RIA_Example/.riahub/workflows/build-applications_example_application_json.yml

253 lines
11 KiB
YAML
Raw Permalink Normal View History

name: Build and Push Holoscan Application
on:
push:
paths:
- '.riahub/workflows/**'
env:
REGISTRY_HOST:
NAMESPACE: ${{ gitea.repository_owner }}
REGISTRY_USER: ${{ gitea.actor }}
REGISTRY_TOKEN: ${{ secrets.TOKEN_DEV }}
SOURCE_REPO: qoherent/RIA_Example
SOURCE_BRANCH: main
SOURCE_FILE: Applications/Example_Application.json
APP_NAME: applications_example_application_json
DOCKER_IMAGE_NAME: applications-example-application-json
TARGET_IMAGE_TAG: /${{ gitea.repository_owner }}/ria-applications-example-application-json-runtime:latest
BUILD_TOOLS_REPO: ${{ gitea.repository_owner }}/qac-mvp
RIA_CORE_REPO: ${{ gitea.repository_owner }}/ria-core
ENABLE_HOLOSCAN: true
jobs:
build:
name: Build and Push RIA
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Verify Docker is available
run: docker info --format '{{.ServerVersion}}'
- name: Login to RIA Hub Container Registry
run: |
LOWERCASE_USER=$(echo "$REGISTRY_USER" | tr '[:upper:]' '[:lower:]')
echo "$REGISTRY_TOKEN" | docker login $REGISTRY_HOST -u "$LOWERCASE_USER" --password-stdin
- name: Checkout build tools repository
run: |
git clone "http://riahub.ai/${{ env.BUILD_TOOLS_REPO }}.git" build-tools
cd build-tools && git checkout main
- name: Checkout ria_core library
run: |
git clone "http://riahub.ai/${{ env.RIA_CORE_REPO }}.git" ria-core
cd ria-core && git checkout main
- name: Checkout source repository with application
run: |
ENCODED_USER=$(printf '%s' "$REGISTRY_USER" | sed 's/:/%3A/g; s/@/%40/g; s/#/%23/g; s/?/%3F/g')
ENCODED_TOKEN=$(printf '%s' "$REGISTRY_TOKEN" | sed 's/:/%3A/g; s/@/%40/g; s/#/%23/g; s/?/%3F/g')
git clone "http://$ENCODED_USER:$ENCODED_TOKEN@riahub.ai/qoherent/RIA_Example.git" source-app
cd source-app && git checkout $SOURCE_BRANCH
- name: Install dependencies
run: |
command -v jq >/dev/null || { apt-get update && apt-get install -y python3 python3-pip python3-venv jq; }
pip install -r build-tools/requirements.txt || true
- name: Parse Application Config
id: parse_config
run: |
CONFIG_PATH="source-app/$SOURCE_FILE"
BACKEND=$(jq -r '.ops[] | select(.type=="inference") | .specs[] | select(.key=="backend") | .default // "onnxrt"' $CONFIG_PATH | head -n 1)
MODEL_VAL=$(jq -r '.ops[] | select(.type=="inference") | .specs[] | select(.key=="model_path_map" or .key=="model_path" or .key=="model_file") | .default' $CONFIG_PATH | head -n 1)
if [ -z "$MODEL_VAL" ] || [ "$MODEL_VAL" == "null" ]; then
if [ "$BACKEND" == "trt" ]; then TARGET_NAME="model.engine"; else TARGET_NAME="model.onnx"; fi
else
TARGET_NAME=$(basename "$MODEL_VAL")
fi
if [ "$ENABLE_HOLOSCAN" = "false" ]; then
BACKEND="onnxrt"
fi
echo "INFERENCE_BACKEND=$BACKEND" >> $GITHUB_ENV
echo "TARGET_MODEL_NAME=$TARGET_NAME" >> $GITHUB_ENV
- name: Generate C++ code and CMakeLists.txt
id: codegen
run: |
APP_DIR="apps/$APP_NAME"
mkdir -p "$APP_DIR"
cp "source-app/$SOURCE_FILE" "$APP_DIR/app_flow_graph.json"
if [ "$ENABLE_HOLOSCAN" = "false" ]; then
python3 build-tools/src/patch_for_cpu.py "$APP_DIR/app_flow_graph.json"
fi
python build-tools/src/full_generator.py --config "$APP_DIR/app_flow_graph.json" --output-dir "$APP_DIR"
if [ -f "$APP_DIR/src/CMakeLists.txt" ]; then
mv "$APP_DIR/src/CMakeLists.txt" "$APP_DIR/CMakeLists.txt"
fi
TARGET_NAME=$(grep "add_executable" "$APP_DIR/CMakeLists.txt" | head -1 | cut -d'(' -f2 | cut -d' ' -f1)
echo "cmake_target=$TARGET_NAME" >> $GITEA_OUTPUT
- name: Generate YAML config file
run: |
python build-tools/src/yaml_generator.py --input apps/$APP_NAME/app_flow_graph.json --output apps/$APP_NAME/config.yaml
- name: Stage Inference Model
run: |
APP_DIR="apps/$APP_NAME"
mkdir -p "$APP_DIR/assets"
FOUND_FILE=""
if [ -f "source-app/$TARGET_MODEL_NAME" ]; then
FOUND_FILE="source-app/$TARGET_MODEL_NAME"
else
if [ "$INFERENCE_BACKEND" == "trt" ]; then
FOUND_FILE=$(find source-app -name "*.trt" -o -name "*.engine" -o -name "*.onnx" | head -n 1)
else
FOUND_FILE=$(find source-app -name "*.onnx" | head -n 1)
fi
fi
if [ -n "$FOUND_FILE" ]; then
echo "Staging model: $FOUND_FILE -> $APP_DIR/assets/$TARGET_MODEL_NAME"
cp "$FOUND_FILE" "$APP_DIR/assets/$TARGET_MODEL_NAME"
else
HAS_INFERENCE=$(jq '[.ops[] | select(.type=="inference")] | length' "source-app/$SOURCE_FILE")
if [ "$HAS_INFERENCE" -gt 0 ]; then
echo "ERROR: Pipeline has inference operator(s) but no model file found in source repository."
echo "Looked for: $TARGET_MODEL_NAME, *.onnx, *.trt, *.engine"
exit 1
fi
echo "No inference model needed for this pipeline."
fi
- name: Prepare Docker Context
run: |
APP_DIR="apps/$APP_NAME"
cp -r ria-core "$APP_DIR/ria_core"
rm -rf "$APP_DIR/ria_core/.git" "$APP_DIR/ria_core/build"
if [ "$ENABLE_HOLOSCAN" = "false" ]; then
cp build-tools/src/install_dummy_driver.py "$APP_DIR/"
fi
- name: Generate Dockerfile
run: |
APP_DIR="apps/$APP_NAME"
CMAKE_TARGET="${{ steps.codegen.outputs.cmake_target }}"
DF="$APP_DIR/Dockerfile"
cat > "$DF" <<'DOCKERFILE_BUILD'
# syntax=docker/dockerfile:1
FROM nvcr.io/nvidia/clara-holoscan/holoscan:v3.4.0-dgpu AS build
WORKDIR /workspace
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get -y install --no-install-recommends pkg-config build-essential cmake git wget libiio-dev libiio0 libad9361-dev libad9361-0 libfftw3-dev && apt-get clean
RUN wget -q https://github.com/microsoft/onnxruntime/releases/download/v1.14.1/onnxruntime-linux-x64-1.14.1.tgz && \
tar -xzf onnxruntime-linux-x64-1.14.1.tgz && \
mkdir -p /usr/include/onnxruntime && \
cp -r onnxruntime-linux-x64-1.14.1/include/* /usr/include/onnxruntime/ && \
cp -r onnxruntime-linux-x64-1.14.1/lib/* /usr/lib/ && \
rm -rf onnxruntime-linux-x64-1.14.1*
RUN wget -q https://github.com/Kitware/CMake/releases/download/v3.31.0/cmake-3.31.0-linux-x86_64.tar.gz && \
tar -xzf cmake-3.31.0-linux-x86_64.tar.gz -C /opt && \
mv /opt/cmake-3.31.0-linux-x86_64 /opt/cmake && \
rm cmake-3.31.0-linux-x86_64.tar.gz
DOCKERFILE_BUILD
if [ "$CPU_ONLY_MODE" = "true" ]; then
echo 'COPY install_dummy_driver.py .' >> "$DF"
echo 'RUN python3 install_dummy_driver.py && rm install_dummy_driver.py' >> "$DF"
fi
cat >> "$DF" <<DOCKERFILE_APP
COPY CMakeLists.txt .
COPY src/ src/
COPY ria_core/ ria_core/
COPY app_flow_graph.json .
COPY assets/ assets/
RUN /opt/cmake/bin/cmake -S . -B build && /opt/cmake/bin/cmake --build build --target "$CMAKE_TARGET" --parallel
RUN cp \$(find build -name "$CMAKE_TARGET" -type f | head -n 1) .
DOCKERFILE_APP
cat >> "$DF" <<'DOCKERFILE_RUNTIME'
FROM nvcr.io/nvidia/clara-holoscan/holoscan:v3.4.0-dgpu
WORKDIR /app
ENV DEBIAN_FRONTEND=noninteractive
LABEL ria.app="applications_example_application_json" ria.profile="nvidia-x86" ria.hardware="pluto" ria.operators="PlutoTXOp,inference_builtin,model_mapper,pluto_source,postprocessor,preprocessor,spectrogram,spectrogram_dashboard" ria.version="${{ gitea.sha }}"
RUN (CODENAME=$(. /etc/os-release && echo $VERSION_CODENAME) && grep -q 'universe' /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null && true || sed -i '/^Components:/ s/$/ universe/' /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null || echo "deb http://archive.ubuntu.com/ubuntu $CODENAME universe" >> /etc/apt/sources.list) && apt-get update && apt-get -y install --no-install-recommends libiio-dev libiio0 libad9361-dev libad9361-0 libfftw3-3 && apt-get clean && rm -rf /var/lib/apt/lists/*
COPY --from=build /usr/lib/libonnxruntime* /usr/lib/
ENV LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu
DOCKERFILE_RUNTIME
echo 'USER root' >> "$DF"
cat >> "$DF" <<DOCKERFILE_FINAL
COPY --from=build /workspace/$CMAKE_TARGET /app/$CMAKE_TARGET
COPY app_flow_graph.json .
COPY config.yaml .
COPY --from=build /workspace/assets/$TARGET_MODEL_NAME /app/$TARGET_MODEL_NAME
RUN chmod +x /app/$CMAKE_TARGET
ENTRYPOINT ["/app/$CMAKE_TARGET"]
DOCKERFILE_FINAL
- name: Build Docker image
run: |
APP_DIR="apps/$APP_NAME"
TAG="${{ gitea.run_number }}"
echo "Building Docker image: $DOCKER_IMAGE_NAME:$TAG"
docker build -t "$DOCKER_IMAGE_NAME:$TAG" -f "$APP_DIR/Dockerfile" "$APP_DIR" 2>&1 | tee build.log
- name: Push to Registry
run: |
TAG="${{ gitea.run_number }}"
TARGET_LATEST="${{ env.TARGET_IMAGE_TAG }}"
TARGET_SHA="${REGISTRY_HOST}/${NAMESPACE}/ria-${DOCKER_IMAGE_NAME}-runtime:${{ gitea.sha }}"
docker tag "$DOCKER_IMAGE_NAME:$TAG" "$TARGET_LATEST"
docker tag "$DOCKER_IMAGE_NAME:$TAG" "$TARGET_SHA"
echo "Pushing: $TARGET_LATEST"
docker push "$TARGET_LATEST"
echo "Pushing: $TARGET_SHA"
docker push "$TARGET_SHA"
- name: Build Summary
if: always()
run: |
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Application | $APP_NAME |" >> $GITHUB_STEP_SUMMARY
echo "| Source | $SOURCE_REPO/$SOURCE_FILE ($SOURCE_BRANCH) |" >> $GITHUB_STEP_SUMMARY
echo "| Image | ${{ env.TARGET_IMAGE_TAG }} |" >> $GITHUB_STEP_SUMMARY
echo "| Mode | Holoscan |" >> $GITHUB_STEP_SUMMARY
echo "| Run | #${{ gitea.run_number }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "$ENABLE_HOLOSCAN" = "false" ]; then
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ env.TARGET_IMAGE_TAG }}" >> $GITHUB_STEP_SUMMARY
echo "docker run -it --rm --net=host --privileged ${{ env.TARGET_IMAGE_TAG }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
else
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ env.TARGET_IMAGE_TAG }}" >> $GITHUB_STEP_SUMMARY
echo "docker run --runtime=nvidia --gpus all -it --rm --net=host --privileged ${{ env.TARGET_IMAGE_TAG }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
fi
- uses: actions/upload-artifact@v3
with:
name: deployment_instructions_${{ gitea.run_number }}
path: build.log