[GHA][CVS-112829] Public Dockerfile (#23064)

Co-authored-by: Ilya Lavrenov <ilya.lavrenov@intel.com>
Co-authored-by: Mikhail Ryzhov <mikhail.ryzhov@intel.com>
This commit is contained in:
Alina Kladieva 2024-05-02 19:44:03 +02:00 committed by GitHub
parent d16ce024d5
commit e4670660a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 588 additions and 59 deletions

3
.dockerignore Normal file
View File

@ -0,0 +1,3 @@
*
!install_build_dependencies.sh
!scripts/install_dependencies/install_openvino_dependencies.sh

View File

@ -0,0 +1,72 @@
name: 'Handle Docker images'
description: 'Builds, tags and pushes a given Docker image when needed'
inputs:
images:
description: 'Image names (registry name + namespace + base name)'
required: true
registry:
description: 'Docker registry'
required: true
dockerfiles_root_dir:
description: 'Path to dockerfiles root dir relative to repository root'
required: true
push:
description: 'Push built images to registry'
required: false
default: 'true'
changed_components:
description: 'Components changed by a pull request'
required: true
outputs:
images:
description: "Images to use in workflow"
value: ${{ steps.handle_images.outputs.images }}
runs:
using: 'composite'
steps:
- name: Checkout head
uses: actions/checkout@v4
- name: Checkout base
uses: actions/checkout@v4
with:
ref: ${{ github.base_ref || github.event.merge_group.base_ref }}
sparse-checkout: ${{ inputs.dockerfiles_root_dir }}/docker_tag
path: base
- name: Install Python dependencies
uses: py-actions/py-dependency-install@v4
with:
path: "${{ github.action_path }}/requirements.txt"
update-setuptools: "false"
update-wheel: "false"
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Handle docker images
id: handle_images
shell: bash
run: |
images=$(echo "${{ inputs.images }}" | tr '\n' ',' | sed 's/,*$//')
pr="${{ github.event.pull_request.number }}"
python3 .github/actions/handle_docker/get_images_to_build.py \
-d "${{ inputs.dockerfiles_root_dir }}" \
-r "${{ inputs.registry }}" \
--images "$images" \
--head_tag_file "${{ inputs.dockerfiles_root_dir }}/docker_tag" \
--base_tag_file "base/${{ inputs.dockerfiles_root_dir }}/docker_tag" \
--docker_env_changed "${{ fromJSON(inputs.changed_components).docker_env }}" \
--dockerfiles_changed "${{ fromJSON(inputs.changed_components).dockerfiles }}" \
--docker_builder "${{ steps.buildx.outputs.name}}" \
--repo "${{ github.repository }}" \
--ref_name "${{ github.ref_name }}" \
$([[ -n $pr ]] && echo "--pr $pr" || echo '-s ${{ github.sha }}') \
$([[ -n "${{ inputs.push }}" ]] && echo "--push" || echo '')
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@ -0,0 +1,126 @@
import argparse
import json
import re
import sys
from distutils.util import strtobool
from helpers import *
from images_api import *
def parse_args():
parser = argparse.ArgumentParser(description='Returns list of Docker images to build for a given workflow')
parser.add_argument('-i', '--images', required=True, help='Comma-separated docker images')
parser.add_argument('-d', '--dockerfiles_root', required=True, help='Path to dockerfiles')
parser.add_argument('-r', '--registry', required=True, help='Docker registry name')
parser.add_argument('-s', '--commit', required=False, help='Commit SHA. If not set, --pr is used')
parser.add_argument('-b', '--docker_builder', required=False, help='Docker buildx builder name')
parser.add_argument('--pr', type=int, required=False, help='PR number, if event is pull_request')
parser.add_argument('--head_tag_file', default='.github/dockerfiles/docker_tag', help='Head docker tag file path')
parser.add_argument('--base_tag_file', default=None, required=False, help='Base docker tag file path')
parser.add_argument('--ref_name', required=False, default='', help='GitHub ref name')
parser.add_argument('--repo', default='openvinotoolkit/openvino', help='GitHub repository')
parser.add_argument('--docker_env_changed', type=lambda x: bool(strtobool(x)), default=True,
help='Whether PR changes docker env')
parser.add_argument('--dockerfiles_changed', type=lambda x: bool(strtobool(x)), default=True,
help='Whether PR changes dockerfiles')
parser.add_argument('--action_path', default='.github/actions/handle_docker', help='Path to this GitHub action')
parser.add_argument('--push', action='store_true', required=False, help='Whether to push images to registry')
parser.add_argument('--dry_run', action='store_true', required=False, help='Dry run')
args = parser.parse_args()
return args
def main():
init_logger()
logger = logging.getLogger(__name__)
args = parse_args()
for arg, value in sorted(vars(args).items()):
logger.info(f"Argument {arg}: {value}")
head_tag = Path(args.head_tag_file).read_text().strip()
base_tag_exists = args.base_tag_file and Path(args.base_tag_file).exists()
base_tag = Path(args.base_tag_file).read_text().strip() if base_tag_exists else None
all_dockerfiles = Path(args.dockerfiles_root).rglob('**/*/Dockerfile')
images = ImagesHandler(args.dry_run)
for image in all_dockerfiles:
images.add_from_dockerfile(image, args.dockerfiles_root, args.registry, head_tag, base_tag)
requested_images = set(args.images.split(','))
skip_workflow = False
missing_only = False
merge_queue_target_branch = next(iter(re.findall(f'^gh-readonly-queue/(.*)/', args.ref_name)), None)
if args.pr:
environment_affected = args.docker_env_changed or args.dockerfiles_changed
if environment_affected:
expected_tag = f'pr-{args.pr}'
if head_tag != expected_tag:
logger.error(f"Please update docker tag in {args.head_tag_file} to {expected_tag}")
sys.exit(1)
elif merge_queue_target_branch:
environment_affected = head_tag != base_tag
if environment_affected:
logger.info(f"Environment is affected by PR(s) in merge group")
else:
environment_affected = False
if environment_affected:
changeset = get_changeset(args.repo, args.pr, merge_queue_target_branch, args.commit)
changed_dockerfiles = [p for p in changeset if p.startswith(args.dockerfiles_root) and p.endswith('Dockerfile')]
if args.docker_env_changed:
logger.info(f"Common docker environment is modified, will build all requested images")
changed_images = requested_images
else:
logger.info(f"Common docker environment is not modified, will build only changed and missing images")
changed_images = set([name_from_dockerfile(d, args.dockerfiles_root) for d in changed_dockerfiles])
unchanged_images = requested_images - changed_images
unchanged_with_no_base = images.get_missing(unchanged_images, base=True)
if unchanged_with_no_base:
logger.info("The following images were unchanged, but will be built anyway since the base for them "
f"is missing in registry: {unchanged_with_no_base}")
images_to_tag = unchanged_images.difference(unchanged_with_no_base)
images_to_build = requested_images.intersection(changed_images).union(unchanged_with_no_base)
only_dockerfiles_changed = len(changeset) == len(changed_dockerfiles)
if only_dockerfiles_changed and not images_to_build:
skip_workflow = True
else:
logger.info(f"Environment is not affected, will build only missing images, if any")
images_to_build = requested_images
images_to_tag = []
missing_only = True
if not images_to_build:
logger.info(f"No images to build, will return the list of pre-built images with a new tag")
built_images = images.build(images_to_build, missing_only, args.push, args.docker_builder)
if not built_images:
logger.info(f"No images were built, a new tag will be applied to a pre-built base image if needed")
# When a custom builder is used, it allows to push the image automatically once built. Otherwise, pushing manually
if args.push and not args.docker_builder:
images.push(images_to_build, missing_only)
if environment_affected and base_tag:
images.tag(images_to_tag)
images_output = images_to_output(images.get(requested_images))
set_github_output("images", json.dumps(images_output))
if skip_workflow:
logger.info(f"Docker image changes are irrelevant for current workflow, workflow may be skipped")
set_github_output("skip_workflow", str(skip_workflow))
main()

View File

@ -0,0 +1,72 @@
import logging
import os
import subprocess
from ghapi.all import GhApi
from pathlib import Path
def init_logger():
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(name)-15s %(levelname)-8s %(message)s',
datefmt='%m-%d-%Y %H:%M:%S')
def set_github_output(name: str, value: str, github_output_var_name: str = 'GITHUB_OUTPUT'):
"""Sets output variable for a GitHub Action"""
logger = logging.getLogger(__name__)
# In an environment variable "GITHUB_OUTPUT" GHA stores path to a file to write outputs to
with open(os.environ.get(github_output_var_name), 'a+') as file:
logger.info(f"Add {name}={value} to {github_output_var_name}")
print(f'{name}={value}', file=file)
def images_to_output(images: list):
images_output = {}
for image in images:
image_name, os_name = image.name.split('/', 1)
if image_name not in images_output:
images_output[image_name] = {}
images_output[image_name][os_name] = image.ref()
return images_output
def get_changeset(repo: str, pr: str, target_branch: str, commit_sha: str):
"""Returns changeset either from PR or commit"""
owner, repository = repo.split('/')
gh_api = GhApi(owner=owner, repo=repository, token=os.getenv("GITHUB_TOKEN"))
if pr:
changed_files = gh_api.pulls.list_files(pr)
elif target_branch:
target_branch_head_commit = gh_api.repos.get_branch(target_branch).commit.sha
changed_files = gh_api.repos.compare_commits(f'{target_branch_head_commit}...{commit_sha}').get('files', [])
else:
raise ValueError(f'Either "pr" or "target_branch" parameter must be non-empty')
return set([f.filename for f in changed_files])
def run(cmd: str, dry_run: bool = False, fail_on_error: bool = True):
logger = logging.getLogger('run')
logger.info(cmd)
if dry_run:
return 0, ''
with subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) as proc:
for line in proc.stdout:
logger.info(line.strip())
proc.communicate()
if proc.returncode != 0:
msg = f"Command '{cmd}' returned non-zero exit status {proc.returncode}"
if fail_on_error:
raise RuntimeError(msg)
logger.warning(msg)
return proc.returncode
def name_from_dockerfile(dockerfile: str | Path, dockerfiles_root: str | Path) -> str:
image_name = str(Path(dockerfile).relative_to(dockerfiles_root).parent.as_posix())
return image_name

View File

@ -0,0 +1,134 @@
import logging
import os
import subprocess
from pathlib import Path
from typing import Iterable
from helpers import run, name_from_dockerfile
class Image:
def __init__(self, name: str, dockerfile: Path, registry: str):
self.logger = logging.getLogger(self.__class__.__name__)
self.name = name
self.dockerfile = dockerfile
self.registry = registry
self.tag = 'latest'
self.base_tag = None
def __str__(self):
return self.name
def __eq__(self, img):
return img.name == self.name if img else False
def with_tag(self, tag: str):
self.tag = tag
return self
def with_base_tag(self, tag: str):
self.base_tag = tag
return self
def ref(self):
return f"{self.registry}/{self.name}:{self.tag}"
def base_ref(self):
if not self.base_tag:
return None
return f"{self.registry}/{self.name}:{self.base_tag}"
def push(self, dry: bool = False):
cmd = f"docker push {self.ref()} "
run(cmd, dry)
def build(self, dry: bool = False, push: bool = True, docker_builder: str = None, import_cache: bool = True,
export_cache: bool = True):
cache_cmd = ""
if import_cache:
cache_cmd += f"--cache-from type=registry,ref={self.ref()}-cache "
if self.base_tag:
cache_cmd += f"--cache-from type=registry,ref={self.base_ref()}-cache "
if export_cache:
cache_cmd += f"--cache-to type=registry,ref={self.ref()}-cache,mode=max "
build_cmd = f"docker buildx build --builder={docker_builder}" if docker_builder else "docker build"
push_cmd = f"--push" if push else ""
cmd = f"{build_cmd} " \
f"--file {self.dockerfile} " \
f"--tag {self.ref()} " \
f"{cache_cmd} " \
f"{push_cmd} " \
"."
run(cmd, dry)
def tag_base(self, dry: bool = False):
if not self.base_tag:
raise AttributeError("Tag for base image is not specified")
cmd = f"docker buildx imagetools create -t {self.ref()} {self.base_ref()}"
run(cmd, dry)
def is_missing(self, dry: bool = False, base: bool = False) -> bool:
image = self.base_ref() if base else self.ref()
if base and not image:
self.logger.warning(f"Base ref for image {self.ref()} is missing")
return True
cmd = f"docker manifest inspect {image}"
is_missing = False
self.logger.info(cmd)
if not dry:
try:
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True, text=True)
except subprocess.CalledProcessError:
self.logger.warning(f"{image} is missing in registry")
is_missing = True
return is_missing
# Making it a class, so it's a little easier to switch to a tree structure for building inherited images if we want
class ImagesHandler:
def __init__(self, dry_run: bool = False):
self.logger = logging.getLogger(self.__class__.__name__)
self.images = dict()
self.dry_run = dry_run
def add_from_dockerfile(self, dockerfile: str | Path, dockerfiles_root: str | Path, registry: str, tag: str,
base_tag: str = None):
image_name = name_from_dockerfile(dockerfile, dockerfiles_root)
image = Image(image_name, Path(dockerfile), registry).with_tag(tag).with_base_tag(base_tag)
self.add(image)
def add(self, image: Image):
self.images[image.name] = image
def get(self, image_names: Iterable = None) -> list:
images = [self.images[name] for name in image_names] if image_names is not None else self.images.values()
return images
def get_missing(self, image_names: Iterable = None, base: bool = False) -> list:
missing_images = [image.name for image in self.get(image_names) if image.is_missing(self.dry_run, base)]
return missing_images
def build(self, image_names: Iterable = None, missing_only: bool = False, push: bool = True, builder: str = None,
import_cache: bool = True, export_cache: bool = True):
to_build = self.get(self.get_missing(image_names)) if missing_only else self.get(image_names)
for image in to_build:
image.build(self.dry_run, push, builder, import_cache, export_cache)
return to_build
def push(self, image_names: Iterable = None, missing_only: bool = False):
to_push = self.get(self.get_missing(image_names)) if missing_only else self.get(image_names)
for image in to_push:
image.push(self.dry_run)
def tag(self, image_names: Iterable = None):
for image in self.get(image_names):
image.tag_base(self.dry_run)

View File

@ -0,0 +1 @@
ghapi~=1.0.5

View File

@ -51,6 +51,9 @@ outputs:
affected_components: affected_components:
description: "Affected components to run validation for and their validation scope" description: "Affected components to run validation for and their validation scope"
value: ${{ steps.smart_ci.outputs.affected_components }} value: ${{ steps.smart_ci.outputs.affected_components }}
changed_components:
description: "Actually changed components (for push events everything is marked as changed)"
value: ${{ steps.smart_ci.outputs.changed_components }}
skip_workflow: skip_workflow:
description: "Whether the workflow should be run with Smart CI rules applied or skipped completely" description: "Whether the workflow should be run with Smart CI rules applied or skipped completely"
value: ${{ steps.smart_ci.outputs.skip_workflow }} value: ${{ steps.smart_ci.outputs.skip_workflow }}

View File

@ -212,8 +212,8 @@ def main():
# In post-commits - validate all components regardless of changeset # In post-commits - validate all components regardless of changeset
# In pre-commits - validate only changed components with their dependencies # In pre-commits - validate only changed components with their dependencies
all_defined_components = components_config.keys() all_defined_components = components_config.keys()
changed_component_names = set(all_defined_components) if run_full_scope else \ changed_by_pr = get_changed_component_names(pr, all_possible_components, args.pattern) if pr else None
get_changed_component_names(pr, all_possible_components, args.pattern) changed_component_names = set(all_defined_components) if run_full_scope else changed_by_pr
logger.info(f"changed_component_names: {changed_component_names}") logger.info(f"changed_component_names: {changed_component_names}")
@ -244,6 +244,12 @@ def main():
affected_components_output = {name: {s: True for s in scope} for name, scope in affected_components.items()} affected_components_output = {name: {s: True for s in scope} for name, scope in affected_components.items()}
set_github_output("affected_components", json.dumps(affected_components_output)) set_github_output("affected_components", json.dumps(affected_components_output))
# Components actually changed by a pull request are marked as True (if event is PR;
# otherwise all components considered changed).
changed_components_output = {name: True if not pr or name in changed_by_pr else False
for name in all_possible_components}
set_github_output("changed_components", json.dumps(changed_components_output))
if __name__ == '__main__': if __name__ == '__main__':
main() main()

1
.github/dockerfiles/docker_tag vendored Normal file
View File

@ -0,0 +1 @@
pr-23064

View File

@ -0,0 +1,72 @@
FROM openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04
USER root
# APT configuration
RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf && \
echo 'APT::Get::Assume-Yes "true";' >> /etc/apt/apt.conf && \
echo 'APT::Get::Fix-Broken "true";' >> /etc/apt/apt.conf && \
echo 'APT::Get::no-install-recommends "true";' >> /etc/apt/apt.conf
ENV DEBIAN_FRONTEND="noninteractive" \
TZ="Europe/London"
RUN apt-get update && \
apt-get install software-properties-common && \
add-apt-repository --yes --no-update ppa:git-core/ppa && \
add-apt-repository --yes --no-update ppa:deadsnakes/ppa && \
apt-get update && \
apt-get install \
curl \
git \
ca-certificates \
gpg-agent \
tzdata \
# Pythons
python3.8-dev \
python3.8-venv \
python3.8-distutils \
python3.11-dev \
python3.11-venv \
python3.11-distutils \
# For Java API
default-jdk \
# Compiler
gcc-10 \
g++-10 \
&& \
rm -rf /var/lib/apt/lists/*
# Install build dependencies
ADD install_build_dependencies.sh /install_build_dependencies.sh
RUN chmod +x /install_build_dependencies.sh && \
/install_build_dependencies.sh && \
rm -rf /var/lib/apt/lists/*
# Set gcc-10 as a default compiler
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 30 && \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 30
# Install sscache
ARG SCCACHE_VERSION="v0.7.5"
ENV SCCACHE_HOME="/opt/sccache" \
SCCACHE_PATH="/opt/sccache/sccache"
RUN mkdir ${SCCACHE_HOME} && cd ${SCCACHE_HOME} && \
SCCACHE_ARCHIVE="sccache-${SCCACHE_VERSION}-aarch64-unknown-linux-musl.tar.gz" && \
curl -SLO https://github.com/mozilla/sccache/releases/download/${SCCACHE_VERSION}/${SCCACHE_ARCHIVE} && \
tar -xzf ${SCCACHE_ARCHIVE} --strip-components=1 && rm ${SCCACHE_ARCHIVE}
# Setup pip
ENV PIP_VERSION="24.0"
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
python3.8 get-pip.py --no-cache-dir pip==${PIP_VERSION} && \
python3.11 get-pip.py --no-cache-dir pip==${PIP_VERSION} && \
rm -f get-pip.py
# Use Python 3.11 as default instead of Python 3.8
# Using venv here 'cause other methods to switch the default Python on Ubuntu 20 break both system and wheels build
RUN python3.11 -m venv venv
ENV PATH="/venv/bin:$SCCACHE_HOME:$PATH"
ENV PIP_CACHE_DIR=/mount/caches/pip/linux/${PIP_VERSION}

View File

@ -0,0 +1,49 @@
FROM openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04
USER root
# APT configuration
RUN echo 'Acquire::Retries "10";' > /etc/apt/apt.conf && \
echo 'APT::Get::Assume-Yes "true";' >> /etc/apt/apt.conf && \
echo 'APT::Get::Fix-Broken "true";' >> /etc/apt/apt.conf && \
echo 'APT::Get::no-install-recommends "true";' >> /etc/apt/apt.conf
ENV DEBIAN_FRONTEND="noninteractive" \
TZ="Europe/London"
RUN apt-get update && \
apt-get install software-properties-common && \
add-apt-repository --yes --no-update ppa:git-core/ppa && \
add-apt-repository --yes --no-update ppa:deadsnakes/ppa && \
apt-get update && \
apt-get install \
curl \
git \
ca-certificates \
gpg-agent \
tzdata \
# Python
python3.11-dev \
python3.11-venv \
python3.11-distutils \
&& \
rm -rf /var/lib/apt/lists/*
# Install openvino dependencies
ADD scripts/install_dependencies/install_openvino_dependencies.sh /install_openvino_dependencies.sh
RUN chmod +x /install_openvino_dependencies.sh && \
/install_openvino_dependencies.sh && \
rm -rf /var/lib/apt/lists/*
# Setup pip
ENV PIP_VERSION="24.0"
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
python3.11 get-pip.py --no-cache-dir pip==${PIP_VERSION} && \
rm -f get-pip.py
# Use Python 3.11 as default instead of Python 3.8
# Using venv here 'cause other methods to switch the default Python on Ubuntu 20 break both system and wheels build
RUN python3.11 -m venv venv
ENV PATH="/venv/bin:$PATH"
ENV PIP_CACHE_DIR=/mount/caches/pip/linux/${PIP_VERSION}

View File

@ -80,10 +80,10 @@ jobs:
sparse-checkout: | sparse-checkout: |
.github/actions/setup_python/action.yml .github/actions/setup_python/action.yml
sparse-checkout-cone-mode: false sparse-checkout-cone-mode: false
path: 'openvino' path: 'action_root'
- name: Setup Python ${{ env.PYTHON_VERSION }} - name: Setup Python ${{ env.PYTHON_VERSION }}
uses: ./openvino/.github/actions/setup_python uses: ./action_root/.github/actions/setup_python
with: with:
version: ${{ env.PYTHON_VERSION }} version: ${{ env.PYTHON_VERSION }}
pip-cache-path: ${{ runner.os == 'Linux' && env.PIP_CACHE_PATH || '' }} pip-cache-path: ${{ runner.os == 'Linux' && env.PIP_CACHE_PATH || '' }}
@ -277,7 +277,7 @@ jobs:
if: runner.os != 'macOS' if: runner.os != 'macOS'
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
sparse-checkout: openvino/docs/snippets sparse-checkout: docs/snippets
path: ${{ env.OPENVINO_REPO }} path: ${{ env.OPENVINO_REPO }}
submodules: 'false' submodules: 'false'

View File

@ -22,6 +22,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
affected_components: "${{ steps.smart_ci.outputs.affected_components }}" affected_components: "${{ steps.smart_ci.outputs.affected_components }}"
changed_components: "${{ steps.smart_ci.outputs.changed_components }}"
skip_workflow: "${{ steps.smart_ci.outputs.skip_workflow }}" skip_workflow: "${{ steps.smart_ci.outputs.skip_workflow }}"
steps: steps:
- name: checkout action - name: checkout action
@ -47,20 +48,42 @@ jobs:
echo "${{ toJSON(steps.smart_ci.outputs.affected_components) }}" echo "${{ toJSON(steps.smart_ci.outputs.affected_components) }}"
shell: bash shell: bash
Build: Docker:
needs: Smart_CI needs: Smart_CI
runs-on: aks-linux-16-cores-arm-docker-build
container:
image: openvinogithubactions.azurecr.io/docker_build:0.2
volumes:
- /mount:/mount
outputs:
images: "${{ steps.handle_docker.outputs.images }}"
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: ./.github/actions/handle_docker
id: handle_docker
with:
images: |
ov_build/ubuntu_20_04_arm64
ov_test/ubuntu_20_04_arm64
registry: 'openvinogithubactions.azurecr.io'
dockerfiles_root_dir: '.github/dockerfiles'
changed_components: ${{ needs.Smart_CI.outputs.changed_components }}
Build:
needs: [ Smart_CI, Docker ]
timeout-minutes: 150 timeout-minutes: 150
defaults: defaults:
run: run:
shell: bash shell: bash
runs-on: 'aks-linux-16-cores-arm' runs-on: 'aks-linux-16-cores-arm'
container: container:
image: openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04 image: ${{ fromJSON(needs.docker.outputs.images).ov_build.ubuntu_20_04_arm64 }}
volumes: volumes:
- /mount:/mount - /mount:/mount
options: -e SCCACHE_AZURE_BLOB_CONTAINER -e SCCACHE_AZURE_CONNECTION_STRING options: -e SCCACHE_AZURE_BLOB_CONTAINER -e SCCACHE_AZURE_CONNECTION_STRING
env: env:
DEBIAN_FRONTEND: noninteractive # to prevent apt-get from waiting user input
CMAKE_BUILD_TYPE: 'Release' CMAKE_BUILD_TYPE: 'Release'
CMAKE_GENERATOR: 'Ninja Multi-Config' CMAKE_GENERATOR: 'Ninja Multi-Config'
CMAKE_CXX_COMPILER_LAUNCHER: sccache CMAKE_CXX_COMPILER_LAUNCHER: sccache
@ -82,12 +105,6 @@ jobs:
if: "!needs.smart_ci.outputs.skip_workflow" if: "!needs.smart_ci.outputs.skip_workflow"
steps: steps:
- name: Set apt retries
run: echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80-retries
- name: Install git
run: apt-get update && apt-get install --assume-yes --no-install-recommends git ca-certificates
- name: Clone OpenVINO - name: Clone OpenVINO
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
@ -114,33 +131,6 @@ jobs:
# Dependencies # Dependencies
# #
- name: Install build dependencies
run: |
bash ${OPENVINO_REPO}/install_build_dependencies.sh
# default-jdk - Java API
apt install --assume-yes --no-install-recommends default-jdk gcc-10 g++-10
# Set gcc-10 as a default one
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 30
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 30
# For building the latest h5py
apt install --assume-yes --no-install-recommends libhdf5-dev
- name: Install sccache
uses: mozilla-actions/sccache-action@v0.0.4
with:
version: "v0.7.5"
- name: Setup Python ${{ env.PYTHON_VERSION }}
uses: ./openvino/.github/actions/setup_python
with:
version: ${{ env.PYTHON_VERSION }}
pip-cache-path: ${{ env.PIP_CACHE_PATH }}
should-setup-pip-paths: 'true'
show-cache-info: 'true'
- name: Install python dependencies - name: Install python dependencies
run: | run: |
# For Python API: build and wheel packaging # For Python API: build and wheel packaging
@ -314,22 +304,22 @@ jobs:
image: 'openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04' image: 'openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04'
Samples: Samples:
needs: [ Build, Smart_CI ] needs: [ Build, Docker, Smart_CI ]
if: fromJSON(needs.smart_ci.outputs.affected_components).samples if: fromJSON(needs.smart_ci.outputs.affected_components).samples
uses: ./.github/workflows/job_samples_tests.yml uses: ./.github/workflows/job_samples_tests.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
image: 'openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04' image: ${{ fromJSON(needs.docker.outputs.images).ov_test.ubuntu_20_04_arm64 }}
affected-components: ${{ needs.smart_ci.outputs.affected_components }} affected-components: ${{ needs.smart_ci.outputs.affected_components }}
JS_API: JS_API:
name: OpenVINO JS API name: OpenVINO JS API
needs: [ Build, Smart_CI ] needs: [ Build, Docker, Smart_CI ]
if: fromJSON(needs.smart_ci.outputs.affected_components).JS_API if: fromJSON(needs.smart_ci.outputs.affected_components).JS_API
uses: ./.github/workflows/job_openvino_js.yml uses: ./.github/workflows/job_openvino_js.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
container: '{"image": "openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04"}' container: '{"image": "${{ fromJSON(needs.docker.outputs.images).ov_build.ubuntu_20_04_arm64 }}"}'
ONNX_Runtime: ONNX_Runtime:
name: ONNX Runtime Integration name: ONNX Runtime Integration
@ -344,73 +334,73 @@ jobs:
Openvino_tokenizers: Openvino_tokenizers:
name: OpenVINO tokenizers extension name: OpenVINO tokenizers extension
needs: [ Build, Smart_CI ] needs: [ Build, Docker, Smart_CI ]
uses: ./.github/workflows/job_tokenizers.yml uses: ./.github/workflows/job_tokenizers.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
shell: bash shell: bash
container: '{"image": "openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04", "volumes": ["/mount:/mount"]}' container: '{"image": "${{ fromJSON(needs.docker.outputs.images).ov_build.ubuntu_20_04_arm64 }}", "volumes": ["/mount:/mount"]}'
affected-components: ${{ needs.smart_ci.outputs.affected_components }} affected-components: ${{ needs.smart_ci.outputs.affected_components }}
if: fromJSON(needs.smart_ci.outputs.affected_components).TOKENIZERS if: fromJSON(needs.smart_ci.outputs.affected_components).TOKENIZERS
CXX_Unit_Tests: CXX_Unit_Tests:
name: C++ unit tests name: C++ unit tests
needs: [ Build, Smart_CI ] needs: [ Build, Docker, Smart_CI ]
uses: ./.github/workflows/job_cxx_unit_tests.yml uses: ./.github/workflows/job_cxx_unit_tests.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
image: 'openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04' image: ${{ fromJSON(needs.docker.outputs.images).ov_test.ubuntu_20_04_arm64 }}
affected-components: ${{ needs.smart_ci.outputs.affected_components }} affected-components: ${{ needs.smart_ci.outputs.affected_components }}
Python_Unit_Tests: Python_Unit_Tests:
name: Python unit tests name: Python unit tests
needs: [ Build, Smart_CI ] needs: [ Build, Docker, Smart_CI ]
uses: ./.github/workflows/job_python_unit_tests.yml uses: ./.github/workflows/job_python_unit_tests.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
container: '{"image": "openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04", "volumes": ["/mount:/mount"]}' container: '{"image": "${{ fromJSON(needs.docker.outputs.images).ov_test.ubuntu_20_04_arm64 }}", "volumes": ["/mount:/mount"]}'
affected-components: ${{ needs.smart_ci.outputs.affected_components }} affected-components: ${{ needs.smart_ci.outputs.affected_components }}
TensorFlow_Layer_Tests: TensorFlow_Layer_Tests:
name: TensorFlow Layer Tests name: TensorFlow Layer Tests
needs: [ Build, Smart_CI, Openvino_tokenizers ] needs: [ Build, Docker, Smart_CI, Openvino_tokenizers ]
uses: ./.github/workflows/job_tensorflow_layer_tests.yml uses: ./.github/workflows/job_tensorflow_layer_tests.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
shell: bash shell: bash
container: '{"image": "openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04", "volumes": ["/mount:/mount"]}' container: '{"image": "${{ fromJSON(needs.docker.outputs.images).ov_test.ubuntu_20_04_arm64 }}", "volumes": ["/mount:/mount"]}'
affected-components: ${{ needs.smart_ci.outputs.affected_components }} affected-components: ${{ needs.smart_ci.outputs.affected_components }}
CPU_Functional_Tests: CPU_Functional_Tests:
name: CPU functional tests name: CPU functional tests
if: fromJSON(needs.smart_ci.outputs.affected_components).CPU.test if: fromJSON(needs.smart_ci.outputs.affected_components).CPU.test
needs: [ Build, Smart_CI ] needs: [ Build, Docker, Smart_CI ]
uses: ./.github/workflows/job_cpu_functional_tests.yml uses: ./.github/workflows/job_cpu_functional_tests.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
image: 'openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04' image: ${{ fromJSON(needs.docker.outputs.images).ov_test.ubuntu_20_04_arm64 }}
TensorFlow_Models_Tests: TensorFlow_Models_Tests:
name: TensorFlow Models tests name: TensorFlow Models tests
if: ${{ 'false' }} # TODO: Enable once the dependencies are ready for arm (no tensorflow-text available for arm from PyPI) if: ${{ 'false' }} # TODO: Enable once the dependencies are ready for arm (no tensorflow-text available for arm from PyPI)
# if: fromJSON(needs.smart_ci.outputs.affected_components).TF_FE.test || # if: fromJSON(needs.smart_ci.outputs.affected_components).TF_FE.test ||
# fromJSON(needs.smart_ci.outputs.affected_components).TFL_FE.test # fromJSON(needs.smart_ci.outputs.affected_components).TFL_FE.test
needs: [ Build, Smart_CI, Openvino_tokenizers] needs: [ Build, Docker, Smart_CI, Openvino_tokenizers]
uses: ./.github/workflows/job_tensorflow_models_tests.yml uses: ./.github/workflows/job_tensorflow_models_tests.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
container: '{"image": "openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04"}' container: '{"image": "${{ fromJSON(needs.docker.outputs.images).ov_test.ubuntu_20_04_arm64 }}"}'
model_scope: 'precommit' model_scope: 'precommit'
PyTorch_Models_Tests: PyTorch_Models_Tests:
name: PyTorch Models tests name: PyTorch Models tests
if: ${{ 'false' }} # TODO: Enable once the dependencies are ready for arm (no tensorflow-text available for arm from PyPI) if: ${{ 'false' }} # TODO: Enable once the dependencies are ready for arm (no tensorflow-text available for arm from PyPI)
# if: fromJSON(needs.smart_ci.outputs.affected_components).PyTorch_FE.test # if: fromJSON(needs.smart_ci.outputs.affected_components).PyTorch_FE.test
needs: [ Build, Smart_CI ] needs: [ Build, Docker, Smart_CI ]
uses: ./.github/workflows/job_pytorch_models_tests.yml uses: ./.github/workflows/job_pytorch_models_tests.yml
with: with:
runner: 'aks-linux-16-cores-arm' runner: 'aks-linux-16-cores-arm'
container: '{"image": "openvinogithubactions.azurecr.io/dockerhub/ubuntu:20.04"}' container: '{"image": "${{ fromJSON(needs.docker.outputs.images).ov_test.ubuntu_20_04_arm64 }}"}'
event: ${{ github.event_name }} event: ${{ github.event_name }}
Overall_Status: Overall_Status: