From patchwork Wed Feb 28 22:55:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helen Koike X-Patchwork-Id: 208067 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6358:a1a:b0:17b:cd04:e0c6 with SMTP id 26csp245438rwa; Wed, 28 Feb 2024 15:04:00 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXcN4fVVhJ5iQ0fA83C+RotLr/hrTsZpUI0nSdjbdhpMsM6cbhKPYTrArRcGpq7E2u20i/0JY8Fh91Y1K4UVyIkDWZTRw== X-Google-Smtp-Source: AGHT+IHlS04mBBMHsYXlWQZT40BEsg6+/u4c0gO/PzNgbTRk++DY6tea6mQvQsCW+c0En5stQXQ6 X-Received: by 2002:a17:90a:dc18:b0:299:879a:7da7 with SMTP id i24-20020a17090adc1800b00299879a7da7mr638567pjv.34.1709161440646; Wed, 28 Feb 2024 15:04:00 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709161440; cv=pass; d=google.com; s=arc-20160816; b=QQw50jNFdRywyUr9WNrvDLIP5bsFpDL03U2/BOsH5x4f2L4WHzsvIpcGysh7MHwcN3 OCWTDCD+WlB8YDNUK9g2J91cGiIdCMUmBZO6PmhgrIJ0K7TKZKAa+QVp2R9IaWtAsY+F Po5Cc/AOG0BKEyHj8kfKl7LyZOsHolCNwMlimRJLdyjOu9192hdBgaQ9bZCL6hBp0QnB nqVGfzsvdI2beRpZRGiNyF7bPOmpJ2AAzzWkbst9xGifH5dN7jP+9vMyTaUIuFopa32+ kUjG1LZ8BCAemZ8oSVpGp9c7YbP/8vMJDXYO3MGpg643jilXTW5saCTl69RDh1qeKBZf sUGA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:to:from:dkim-signature; bh=i8av0rCo9J7tFidxXELtYd0cNy2nBlfOlU7EWva8/+8=; fh=0m8BcSIN6jnEGrXYezAni7jiBLFEw9oBT48Gar0OTdk=; b=FuqrNBhOUOXqb4YXejoXTXtZkNmpHH/73zFJOwzejiWLbZ69Y1FLfOWwvkmvthpZe5 aKChMczR5HEYiegFCEu8K1kvyzIw1I0FmUdJzNyMzACCzuPK0ZdC3kHHHZRyUHvENG/T ktWHt4fgnWSZ1az293CAK57/BAombtMqLroogXWXeZWXXJtjTcNaMytJds1oL8KKHZLf 5A9HhK5XK06NdtcauPuskVoKxgRAEFDDnCFN6ULGCTBmQrei95itsHR4wXy+HBTH5/rb mMaZu02R3uqcvHxQ8sXUa+JEFhvCtyDlIoz++spkG50rJY/oDcC8PUZs8ZSG0qUbfAZ8 5Yvg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=XE2QzdTG; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-85810-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-85810-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id v1-20020a17090a088100b00297305f7b3fsi2161565pjc.48.2024.02.28.15.04.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 15:04:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-85810-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=XE2QzdTG; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-85810-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-85810-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 81713B26739 for ; Wed, 28 Feb 2024 22:56:20 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C741476EEA; Wed, 28 Feb 2024 22:55:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="XE2QzdTG" Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4864671EA1; Wed, 28 Feb 2024 22:55:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709160950; cv=none; b=qhOM0aDfpUuyayDLfHt7oGLjF86DTfC3nYsjNqh/XRcHzPW5YoG/wXtU2J8jhUMMFZMKYbbvx1ioKhpl2PUw74Wb/trVyCOPELq9yfvok6yuU3jKZ65nHawngjcyDpI0nkA1U4Qcyah9DwZyYSYZtayMa90EcO1K7dpOGNqd6rU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709160950; c=relaxed/simple; bh=hHHXqInms8Ik0LQiKPyZlJZuiftwiFOtRHazgtBxh2E=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ty8ahXsRCF2vMvLnU8SJmF4St9K06fKBCDM0uyR8Qc0cGY6xH+O8bFQudva1PitByzSC1h9e9ZDBbUsxXSI8YdmRFGQOazpRRsfDOrP9zVGXkIylF8ICLJ/gqpeHDYu8MgdA+m2x+JLmTf7R4dno57ZDIK5J79cA244q7zKiGrw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=XE2QzdTG; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1709160945; bh=hHHXqInms8Ik0LQiKPyZlJZuiftwiFOtRHazgtBxh2E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XE2QzdTGqOcKDieGZNMT30fi5vx6rxmmFmVX6gIP9TE87v2tQthAMl/7eXUxyDPKh LS3vmj68a3vRiRJL676QGTsFVzl/Sj/FPgEIWJ871bUDn0aXkrR3CtLz5+mZ3/TapY hdI6n9GxIiUJ93nkTPWtDVebtT8sabQikhN7CEk2G8JyYpnzIqieUHJL+h/p3Gwag9 jd5rk22q87Og6MemggVBmMbh1n9xCPPHC4bEIGqvrqfkiPY+xP1YruVTLdNw6JqnaU n6GemkU1JZnPIwRszBvi4pzahVrHbRF97exc9cMsuIO+gGB54RWcTOBI+EIldykEA7 OGYKNUyRNr4pA== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: koike) by madrid.collaboradmins.com (Postfix) with ESMTPSA id E311D37820D9; Wed, 28 Feb 2024 22:55:38 +0000 (UTC) From: Helen Koike To: linuxtv-ci@linuxtv.org, dave.pigott@collabora.com, mripard@kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kselftest@vger.kernel.org, gustavo.padovan@collabora.com, pawiecz@collabora.com, spbnick@gmail.com, tales.aparecida@gmail.com, workflows@vger.kernel.org, kernelci@lists.linux.dev, skhan@linuxfoundation.org, kunit-dev@googlegroups.com, nfraprado@collabora.com, davidgow@google.com, cocci@inria.fr, Julia.Lawall@inria.fr, laura.nao@collabora.com, ricardo.canuelo@collabora.com, kernel@collabora.com, torvalds@linuxfoundation.org, gregkh@linuxfoundation.org Subject: [PATCH 1/3] kci-gitlab: Introducing GitLab-CI Pipeline for Kernel Testing Date: Wed, 28 Feb 2024 19:55:25 -0300 Message-Id: <20240228225527.1052240-2-helen.koike@collabora.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240228225527.1052240-1-helen.koike@collabora.com> References: <20240228225527.1052240-1-helen.koike@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792185646530891936 X-GMAIL-MSGID: 1792185666550201431 This patch introduces a `.gitlab-ci` file along with a `ci/` folder, defininga basic test pipeline triggered by code pushes to a GitLab-CI instance. This initial version includes static checks (checkpatch and smatch for now) and build tests across various architectures and configurations. It leverages an integrated cache for efficient build times and introduces a flexible 'scenarios' mechanism for subsystem-specific extensions. [ci: add prerequisites to run check-patch on MRs] Co-developed-by: Tales Aparecida Signed-off-by: Tales Aparecida Signed-off-by: Helen Koike --- Hey all, You can check the validation of this patchset on: https://gitlab.collabora.com/koike/linux/-/pipelines/87035 I would appreciate your feedback on this work, what do you think? If you would rate from 0 to 5, where: [ ] 0. I don't think this is useful at all, and I doubt it will ever be. It doesn't seem worthwhile. [ ] 1. I don't find it useful in its current form. [ ] 2. It might be useful to others, but not for me. [ ] 3. It has potential, but it's not yet something I can incorporate into my workflow. [ ] 4. This is useful, but it needs some adjustments before I can include it in my workflow. [ ] 5. This is really useful! I'm eager to start using it right away. Why didn't you send this earlier? :) Which rating would you select? --- .gitlab-ci.yml | 2 + MAINTAINERS | 8 ++ ci/gitlab-ci/bootstrap-gitlab-runner.sh | 55 +++++++++ ci/gitlab-ci/ci-scripts/build-docs.sh | 35 ++++++ ci/gitlab-ci/ci-scripts/build-kernel.sh | 35 ++++++ ci/gitlab-ci/ci-scripts/ici-functions.sh | 104 ++++++++++++++++++ ci/gitlab-ci/ci-scripts/install-smatch.sh | 13 +++ .../ci-scripts/parse_commit_message.sh | 27 +++++ ci/gitlab-ci/ci-scripts/run-checkpatch.sh | 20 ++++ ci/gitlab-ci/ci-scripts/run-smatch.sh | 45 ++++++++ ci/gitlab-ci/docker-compose.yaml | 18 +++ ci/gitlab-ci/linux.code-workspace | 11 ++ ci/gitlab-ci/yml/build.yml | 43 ++++++++ ci/gitlab-ci/yml/cache.yml | 26 +++++ ci/gitlab-ci/yml/container.yml | 36 ++++++ ci/gitlab-ci/yml/gitlab-ci.yml | 71 ++++++++++++ ci/gitlab-ci/yml/kernel-combinations.yml | 18 +++ ci/gitlab-ci/yml/scenarios.yml | 12 ++ ci/gitlab-ci/yml/scenarios/file-systems.yml | 21 ++++ ci/gitlab-ci/yml/scenarios/media.yml | 21 ++++ ci/gitlab-ci/yml/scenarios/network.yml | 21 ++++ ci/gitlab-ci/yml/static-checks.yml | 21 ++++ 22 files changed, 663 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100755 ci/gitlab-ci/bootstrap-gitlab-runner.sh create mode 100755 ci/gitlab-ci/ci-scripts/build-docs.sh create mode 100755 ci/gitlab-ci/ci-scripts/build-kernel.sh create mode 100644 ci/gitlab-ci/ci-scripts/ici-functions.sh create mode 100755 ci/gitlab-ci/ci-scripts/install-smatch.sh create mode 100755 ci/gitlab-ci/ci-scripts/parse_commit_message.sh create mode 100755 ci/gitlab-ci/ci-scripts/run-checkpatch.sh create mode 100755 ci/gitlab-ci/ci-scripts/run-smatch.sh create mode 100644 ci/gitlab-ci/docker-compose.yaml create mode 100644 ci/gitlab-ci/linux.code-workspace create mode 100644 ci/gitlab-ci/yml/build.yml create mode 100644 ci/gitlab-ci/yml/cache.yml create mode 100644 ci/gitlab-ci/yml/container.yml create mode 100644 ci/gitlab-ci/yml/gitlab-ci.yml create mode 100644 ci/gitlab-ci/yml/kernel-combinations.yml create mode 100644 ci/gitlab-ci/yml/scenarios.yml create mode 100644 ci/gitlab-ci/yml/scenarios/file-systems.yml create mode 100644 ci/gitlab-ci/yml/scenarios/media.yml create mode 100644 ci/gitlab-ci/yml/scenarios/network.yml create mode 100644 ci/gitlab-ci/yml/static-checks.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000..fac523bb86866 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,2 @@ +include: + - ci/gitlab-ci/yml/gitlab-ci.yml diff --git a/MAINTAINERS b/MAINTAINERS index 716b2e22598c8..aa0f65791c2ee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4998,6 +4998,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/chrontel,ch7322.yaml F: drivers/media/cec/i2c/ch7322.c +CI AUTOMATED TESTING +M: Helen Koike +L: linux-kernel@vger.kernel.org +S: Maintained +T: git https://gitlab.collabora.com/koike/linux.git +F: .gitlab-ci.yml +F: ci/ + CIRRUS LOGIC AUDIO CODEC DRIVERS M: James Schulman M: David Rhodes diff --git a/ci/gitlab-ci/bootstrap-gitlab-runner.sh b/ci/gitlab-ci/bootstrap-gitlab-runner.sh new file mode 100755 index 0000000000000..73238960d0880 --- /dev/null +++ b/ci/gitlab-ci/bootstrap-gitlab-runner.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -eo pipefail + +# Define variables +CONFIG_VOLUME="/srv/gitlab-runner/config" # Path to your GitLab Runner config + +# Check if RUNNER_REGISTRATION_TOKEN is set +if [ -z "${RUNNER_REGISTRATION_TOKEN}" ]; then + echo "Error: RUNNER_REGISTRATION_TOKEN is not set." + echo "Please set the RUNNER_REGISTRATION_TOKEN environment variable and try again." + exit 1 +fi + +# Check if GITLAB_URL is set +if [ -z "${GITLAB_URL}" ]; then + GITLAB_URL="https://gitlab.com/" + echo "Info: GITLAB_URL is not set. Using the default $GITLAB_URL" + echo "Please set the RUNNER_REGISTRATION_TOKEN environment variable and try again." +fi + +# Check if docker-compose is installed +if ! command -v docker-compose &> /dev/null +then + echo "docker-compose could not be found. Please install it first." + exit 1 +fi + +# Start the GitLab Runner using Docker Compose +echo "Starting GitLab Runner..." +docker-compose up -d + +# Wait for a few seconds to ensure the service is up +sleep 5 + +# Register the GitLab Runner +echo "Registering GitLab Runner..." +docker run --rm -v ${CONFIG_VOLUME}:/etc/gitlab-runner gitlab/gitlab-runner register \ + --non-interactive \ + --url ${GITLAB_URL} \ + --token ${RUNNER_REGISTRATION_TOKEN} \ + --executor docker \ + --docker-image "alpine:latest" \ + --description "Docker Runner" \ + --docker-privileged + +echo "" +echo "INFO: To configure the number of concurrent jobs, edit the value of" +echo "INFO: concurrent in ${CONFIG_VOLUME}/config.toml, than restart the GitLab" +echo "INFO: Runner using docker-compose restart" +echo "" +echo "GitLab Runner setup complete." diff --git a/ci/gitlab-ci/ci-scripts/build-docs.sh b/ci/gitlab-ci/ci-scripts/build-docs.sh new file mode 100755 index 0000000000000..2053cb8794acf --- /dev/null +++ b/ci/gitlab-ci/ci-scripts/build-docs.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -exo pipefail + +source ci/gitlab-ci/ci-scripts/ici-functions.sh + +ici_get_patch_series_size + +# Get the list of modified files in the last $ICI_PATCH_SERIES_SIZE commits +MODIFIED_DOC_FILES=$(git diff HEAD~$ICI_PATCH_SERIES_SIZE --name-only -- Documentation/) + +make -j$(nproc) "$ICI_DOC_TYPE" 2>&1 | tee output.txt + +mkdir -p "${CI_PROJECT_DIR}/artifacts" +mv Documentation/output "${CI_PROJECT_DIR}/artifacts/Documentation-output" + +# Check if any of the MODIFIED_DOC_FILES generated a warning +# NOTE: the alternative solution was to touch the modified files and run make +# again, but too much warnings still appears +for file in $MODIFIED_DOC_FILES; do + if grep -qi "warning" output.txt && grep -q "$file" output.txt; then + echo "Warning found in $file" + exit 101 + fi +done + +if [ -n "$ICI_UNABLE_TO_DETECT_PATCH_SERIES_SIZE" ]; then + # If the patch series size was not detected, exit with a warning + echo -n "The patch series size was not detected, we probably didn't check the" + echo " whole series. Exiting with a warning." + exit 101 +fi diff --git a/ci/gitlab-ci/ci-scripts/build-kernel.sh b/ci/gitlab-ci/ci-scripts/build-kernel.sh new file mode 100755 index 0000000000000..361826368a573 --- /dev/null +++ b/ci/gitlab-ci/ci-scripts/build-kernel.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -exo pipefail + +source ci/gitlab-ci/ci-scripts/ici-functions.sh + +ici_prepare_build + +pushd build + +# compile the entire kernel +make CF=-D__CHECK_ENDIAN__ -C "$ICI_KERNEL_DIR" O=$(pwd) -j$(nproc) 2>&1 | tee output.txt + +export INSTALL_PATH="${CI_PROJECT_DIR}/artifacts/" +INSTALL_PATH+="kernel-install-${KCI_KERNEL_ARCH}-${KCI_DEFCONFIG}_config" +mkdir -p "$INSTALL_PATH" + +# install the kernel image to artifacts/kernel-install +make -C "$ICI_KERNEL_DIR" O=$(pwd) install INSTALL_PATH="$INSTALL_PATH" + +# install kernel modules to artifacts/kernel-install +make -C "$ICI_KERNEL_DIR" O=$(pwd) modules_install INSTALL_MOD_PATH="$INSTALL_PATH" + +# export config as artifact +cp .config "${CI_PROJECT_DIR}/artifacts/${KCI_KERNEL_ARCH}-${KCI_DEFCONFIG}_config" + +# if the compilation has warnings, exit with the warning code +if grep -iq "warning" output.txt; then + exit 101 +fi + +popd diff --git a/ci/gitlab-ci/ci-scripts/ici-functions.sh b/ci/gitlab-ci/ci-scripts/ici-functions.sh new file mode 100644 index 0000000000000..df133b4d00103 --- /dev/null +++ b/ci/gitlab-ci/ci-scripts/ici-functions.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -exo pipefail + +# internal CI bash functions + +# convention: +# KCI_ for variables defined by the user (outside of this script) +# ICI_ for variables defined internally for usage between scripts +# CI_ for variables defined by GitLab CI + + +ici_prepare_build() { + BUILD_DIR="${1:-build}" + + echo "" + echo "Architecture: $KCI_KERNEL_ARCH" + echo "Defconfig: $KCI_DEFCONFIG" + echo "" + + # Get the current directory if KCI_KERNEL_DIR is not set + ICI_KERNEL_DIR="${KCI_KERNEL_DIR:-$(pwd)}" + + cd "$ICI_KERNEL_DIR" || { echo "Kernel directory not found"; exit 1; } + + # Clean up stale rebases that GitLab might not have removed when reusing a checkout dir + rm -rf .git/rebase-apply + + if [[ "$KCI_KERNEL_ARCH" = "arm64" ]]; then + GCC_ARCH="aarch64-linux-gnu" + elif [[ "$KCI_KERNEL_ARCH" = "arm" ]]; then + GCC_ARCH="arm-linux-gnueabihf" + else + GCC_ARCH="x86_64-linux-gnu" + fi + + # do not set ARCH and CROSS_COMPILE if KCI_KERNEL_ARCH is not set, useful for local run + if [ -n "$KCI_KERNEL_ARCH" ]; then + export ARCH=${KCI_KERNEL_ARCH} + export CROSS_COMPILE="${GCC_ARCH}-" + fi + + mkdir -p "$BUILD_DIR" + + pushd "$BUILD_DIR" || { echo "Failed to create $BUILD_DIR directory"; exit 1; } + + # generate defconfig + make -C "$ICI_KERNEL_DIR" O=$(pwd) $(basename ${KCI_DEFCONFIG-"defconfig"}) + + # add extra configs from variable KCI_KCONFIGS_{ENABLE,DISABLE,MODULE} + for opt in $KCI_KCONFIGS_ENABLE; do + ../scripts/config --file .config --enable CONFIG_$opt + done + for opt in $KCI_KCONFIGS_DISABLE; do + ../scripts/config --file .config --disable CONFIG_$opt + done + for opt in $KCI_KCONFIGS_MODULE; do + ../scripts/config --file .config --module CONFIG_$opt + done + + if [ -n "$KCI_KCONFIGS_DISABLE" ] || [ -n "$KCI_KCONFIGS_ENABLE" ] || + [ -n "$KCI_KCONFIGS_MODULE" ]; then + # execude olddefconfig only if we changed the default config, otherwise, + # let it raise warnings if any + make -C "$ICI_KERNEL_DIR" O=$(pwd) olddefconfig + fi + + popd +} + +ici_get_patch_series_size() +{ + local CLONE_DEPTH + CLONE_DEPTH=$(git rev-list --count HEAD) + echo "The depth of the clone is $CLONE_DEPTH" + + # If this is in the context of a merge request, calculate the patch series + # size comparing to the target branch + if [ -n "$CI_MERGE_REQUEST_IID" ]; then + git fetch origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" --depth $CLONE_DEPTH + BASE_COMMIT="origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" + ICI_PATCH_SERIES_SIZE=$(git rev-list --count ${BASE_COMMIT}.."$CI_COMMIT_SHA") + + # if KCI_PATCH_SERIES_SIZE is set, use it + elif [ -n "$KCI_PATCH_SERIES_SIZE" ]; then + ICI_PATCH_SERIES_SIZE="$KCI_PATCH_SERIES_SIZE" + else + ICI_PATCH_SERIES_SIZE=1 + echo "WARNING: unable to detect the patch series size, using the default value of 1." + # shellcheck disable=SC2034 + ICI_UNABLE_TO_DETECT_PATCH_SERIES_SIZE=true + fi + + # Check if the clone depth is smaller than or equal to KCI_PATCH_SERIES_SIZE, + # otherwise the checkpatch.pl hangs + if [ "$ICI_PATCH_SERIES_SIZE" -ge "$CLONE_DEPTH" ]; then + echo -n "ERROR: the depth of the clone is $CLONE_DEPTH, smaller than or equal to the patch" + echo " series size. Update your GitLab configuration to increase the size of the clone." + return 1 + fi +} diff --git a/ci/gitlab-ci/ci-scripts/install-smatch.sh b/ci/gitlab-ci/ci-scripts/install-smatch.sh new file mode 100755 index 0000000000000..cae16a0e90fa8 --- /dev/null +++ b/ci/gitlab-ci/ci-scripts/install-smatch.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -exo pipefail + +pushd / +git clone --depth 1 https://repo.or.cz/smatch.git +pushd smatch +make +popd +popd diff --git a/ci/gitlab-ci/ci-scripts/parse_commit_message.sh b/ci/gitlab-ci/ci-scripts/parse_commit_message.sh new file mode 100755 index 0000000000000..c9792c64ad51e --- /dev/null +++ b/ci/gitlab-ci/ci-scripts/parse_commit_message.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -exo pipefail + +# Get the last commit message +commit_message=$(git log -1 --pretty=%B) + +pattern='(KCI_[A-Za-z_]+)=("[^"]*"|[^ ]+)' + +while read -r line; do + if [[ $line =~ $pattern ]]; then + variable_name="${BASH_REMATCH[1]}" + variable_value="${BASH_REMATCH[2]}" + + # Remove quotes if present + variable_value="${variable_value%\"}" + variable_value="${variable_value#\"}" + + # Export the variable + export "$variable_name=$variable_value" + + echo "Exported $variable_name=$variable_value" + fi +done <<< "$commit_message" diff --git a/ci/gitlab-ci/ci-scripts/run-checkpatch.sh b/ci/gitlab-ci/ci-scripts/run-checkpatch.sh new file mode 100755 index 0000000000000..98585ec18be2b --- /dev/null +++ b/ci/gitlab-ci/ci-scripts/run-checkpatch.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -exo pipefail + +source ci/gitlab-ci/ci-scripts/ici-functions.sh + +ici_get_patch_series_size + +# shellcheck disable=SC2086 +scripts/checkpatch.pl $KCI_CHECKPATCH_OPTIONS --git HEAD-"$ICI_PATCH_SERIES_SIZE" + +if [ -n "$ICI_UNABLE_TO_DETECT_PATCH_SERIES_SIZE" ]; then + # If the patch series size was not detected, exit with a warning + echo -n "The patch series size was not detected, we probably didn't check the whole series." + echo " Exiting with a warning." + exit 101 +fi diff --git a/ci/gitlab-ci/ci-scripts/run-smatch.sh b/ci/gitlab-ci/ci-scripts/run-smatch.sh new file mode 100755 index 0000000000000..ec054df9ef179 --- /dev/null +++ b/ci/gitlab-ci/ci-scripts/run-smatch.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +set -exo pipefail + +source ci/gitlab-ci/ci-scripts/ici-functions.sh + +ls -l +pwd + +# generate config file +ici_prepare_build + +ici_get_patch_series_size + +cp build/.config . + +# Get a list of modified .c files in the last ICI_PATCH_SERIES_SIZE commits +MODIFIED_C_FILES=$(git diff --name-only HEAD~$ICI_PATCH_SERIES_SIZE HEAD | grep '\.c$' || true) + +# Check if any .c files were modified +if [ -z "$MODIFIED_C_FILES" ]; then + echo "No .c files were modified in the last $ICI_PATCH_SERIES_SIZE commits." +else + echo "Running kchecker on modified .c files..." + mkdir -p "$CI_PROJECT_DIR"/artifacts +fi + +# Run kchecker on each modified .c file +for file in $MODIFIED_C_FILES; do + if [ -f "$file" ]; then + /smatch/smatch_scripts/kchecker "$file" | tee "$CI_PROJECT_DIR"/artifacts/smatch_warns.txt + else + echo "File not found: $file" + fi +done + +if [ -n "$ICI_UNABLE_TO_DETECT_PATCH_SERIES_SIZE" ]; then + # If the patch series size was not detected, exit with a warning + echo -n "The patch series size was not detected, we probably didn't check the whole series." + echo " Exiting with a warning." + exit 101 +fi diff --git a/ci/gitlab-ci/docker-compose.yaml b/ci/gitlab-ci/docker-compose.yaml new file mode 100644 index 0000000000000..7edf8055ca375 --- /dev/null +++ b/ci/gitlab-ci/docker-compose.yaml @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +version: '3.8' + +services: + gitlab-runner: + image: gitlab/gitlab-runner:latest + container_name: gitlab-runner + restart: always + privileged: true + volumes: + - /srv/gitlab-runner/config:/etc/gitlab-runner + - /var/run/docker.sock:/var/run/docker.sock + +# To register the GitLab Runner, run the following command: +# docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register --url https://gitlab.com --token YOUR_REGISTRATION_TOKEN diff --git a/ci/gitlab-ci/linux.code-workspace b/ci/gitlab-ci/linux.code-workspace new file mode 100644 index 0000000000000..dd76698e38c2c --- /dev/null +++ b/ci/gitlab-ci/linux.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../.." + }, + { + "path": "../../../../../mesa" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/ci/gitlab-ci/yml/build.yml b/ci/gitlab-ci/yml/build.yml new file mode 100644 index 0000000000000..f81410c293f35 --- /dev/null +++ b/ci/gitlab-ci/yml/build.yml @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +.build: + extends: .use-debian/x86_64_build + stage: build + +build-kernel: + extends: + - .build + - .kernel-combinations + variables: + # ccache in gitlab-runner to speed up builds + CCACHE_BASEDIR: $CI_PROJECT_DIR + CCACHE_DIR: $CI_PROJECT_DIR/ccache + CCACHE_COMPILERCHECK: content + cache: + - key: ccache-$CI_JOB_NAME + paths: + - $CCACHE_DIR + before_script: + - export PATH="/usr/lib/ccache:$PATH" + - ccache --zero-stats || true + - ccache --show-stats || true + after_script: + - ccache --show-stats + script: + - ./ci/gitlab-ci/ci-scripts/build-kernel.sh + +build-docs: + extends: + - .build + parallel: + matrix: + - ICI_DOC_TYPE: "htmldocs" + # TODO: re-add pdfdocs once build errors are fixed + # - ICI_DOC_TYPE: "pdfdocs" + - ICI_DOC_TYPE: "latexdocs" + - ICI_DOC_TYPE: "epubdocs" + script: + - ./ci/gitlab-ci/ci-scripts/build-docs.sh + when: manual \ No newline at end of file diff --git a/ci/gitlab-ci/yml/cache.yml b/ci/gitlab-ci/yml/cache.yml new file mode 100644 index 0000000000000..efe4fc69b11ca --- /dev/null +++ b/ci/gitlab-ci/yml/cache.yml @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +# Smatch db is saved to a cached folder, so it can be used by other jobs and pipelines. +# It is set to manual so it can be run when needed + +.use-cache-smatch-db: + cache: + # TODO: check if this cache shouldn't be per architecture + - key: smatch-db + paths: + - /smatch/smatch_data + +smatch-db-generate: + stage: cache + extends: + - .kernel-combinations + - .use-debian/x86_64_build + - .use-cache-smatch-db + script: + - source ci/gitlab-ci/ci-scripts/ici-functions.sh + - ici_prepare_build + - cp build/.config . + - /smatch/smatch_scripts/build_kernel_data.sh + when: manual \ No newline at end of file diff --git a/ci/gitlab-ci/yml/container.yml b/ci/gitlab-ci/yml/container.yml new file mode 100644 index 0000000000000..eecca95caca0e --- /dev/null +++ b/ci/gitlab-ci/yml/container.yml @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +.prep-debian/x86_64_build: + variables: + FDO_DISTRIBUTION_VERSION: bookworm-slim + FDO_DISTRIBUTION_TAG: "2024-02-28-ci-test-1" + + +debian/x86_64_build: + extends: + - ".fdo.container-build@debian" + - ".prep-debian/x86_64_build" + variables: + FDO_DISTRIBUTION_PACKAGES: > + make bc flex bison pahole mount build-essential + libcairo-dev libdw-dev libjson-c-dev libkmod2 + libkmod-dev libpciaccess-dev libproc2-dev libudev-dev + libunwind-dev python3-docutils bc python3-ply + libssl-dev ccache + gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu + gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf + perl git kmod python3-git python3-yaml python3-dulwich + sqlite3 libsqlite3-dev libdbd-sqlite3-perl libssl-dev libtry-tiny-perl + python3-sphinx imagemagick graphviz dvipng python3-venv fonts-noto-cjk + latexmk librsvg2-bin texlive-lang-chinese texlive-xetex + FDO_DISTRIBUTION_EXEC: ./ci/gitlab-ci/ci-scripts/install-smatch.sh + stage: container + + +.use-debian/x86_64_build: + extends: + - ".fdo.distribution-image@debian" + - ".prep-debian/x86_64_build" + needs: [debian/x86_64_build] \ No newline at end of file diff --git a/ci/gitlab-ci/yml/gitlab-ci.yml b/ci/gitlab-ci/yml/gitlab-ci.yml new file mode 100644 index 0000000000000..57b9c02904713 --- /dev/null +++ b/ci/gitlab-ci/yml/gitlab-ci.yml @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +workflow: + name: $PIPELINE_NAME + rules: + # when triggered as a multi-project pipeline for an MR + - if: $CI_PIPELINE_SOURCE == 'pipeline' && $PARENT_MERGE_REQUEST_IID != null && $PARENT_MERGE_REQUEST_IID != "" + variables: + PIPELINE_NAME: 'Downstream pipeline for $PARENT_PROJECT_PATH!$PARENT_MERGE_REQUEST_IID' + # when triggered as a multi-project pipeline + - if: $CI_PIPELINE_SOURCE == 'pipeline' + variables: + PIPELINE_NAME: 'Downstream pipeline for $PARENT_PROJECT_PATH' + # when triggered via a schedule + - if: $CI_PIPELINE_SOURCE == 'schedule' + variables: + PIPELINE_NAME: 'Scheduled pipeline for $ONLY_JOB_NAME' + # for merge requests + - if: $CI_MERGE_REQUEST_ID + # when triggered via the REST api + - if: $CI_PIPELINE_SOURCE == 'api' + # for the tip of the default branch + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # when triggered via a trigger token + - if: $CI_PIPELINE_SOURCE == 'trigger' + # when triggered from a button press in the web interface + - if: $CI_PIPELINE_SOURCE == 'web' + # for branch tips without open MRs, ignoring special branches + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_OPEN_MERGE_REQUESTS == null + # when forced via '-o ci.variable="FORCE_CI=true"' during pushing + - if: $FORCE_CI == 'true' + +variables: + FDO_UPSTREAM_REPO: helen.fornazier/linux # The repo where to look for cached images + # ccache builds in gitlab-runner to speed up builds + SMATCH_DB_DIR: /smatch/smatch_data + # exit code of bash script on `script` will be the exit code of the job + FF_USE_NEW_BASH_EVAL_STRATEGY: "true" + +default: + artifacts: + paths: + - artifacts/ + when: always + +include: + - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/16bc29078de5e0a067ff84a1a199a3760d3b3811/templates/ci-fairy.yml' + - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/16bc29078de5e0a067ff84a1a199a3760d3b3811/templates/debian.yml' + + - ci/gitlab-ci/yml/kernel-combinations.yml + - ci/gitlab-ci/yml/container.yml + - ci/gitlab-ci/yml/cache.yml + - ci/gitlab-ci/yml/build.yml + - ci/gitlab-ci/yml/static-checks.yml + - ci/gitlab-ci/yml/scenarios.yml + +before_script: + - source ci/gitlab-ci/ci-scripts/parse_commit_message.sh + +.use-debian/x86_64_build: + allow_failure: + # Code to exit with a warning + exit_codes: 101 + +stages: + - container + - static-checks + - build + - cache \ No newline at end of file diff --git a/ci/gitlab-ci/yml/kernel-combinations.yml b/ci/gitlab-ci/yml/kernel-combinations.yml new file mode 100644 index 0000000000000..87f08579ffd62 --- /dev/null +++ b/ci/gitlab-ci/yml/kernel-combinations.yml @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +.kernel-combinations: + parallel: + matrix: + - KCI_KERNEL_ARCH: "x86_64" + KCI_DEFCONFIG: "x86_64_defconfig" + KCI_KCONFIGS_ENABLE: "PROVE_LOCKING DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT CONFIG_DEBUG_SECTION_MISMATCH" + + - KCI_KERNEL_ARCH: "arm64" + KCI_DEFCONFIG: "defconfig" + KCI_KCONFIGS_ENABLE: "PROVE_LOCKING DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT CONFIG_DEBUG_SECTION_MISMATCH" + + - KCI_KERNEL_ARCH: "arm" + KCI_DEFCONFIG: "multi_v7_defconfig" + KCI_KCONFIGS_ENABLE: "PROVE_LOCKING DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT CONFIG_DEBUG_SECTION_MISMATCH" \ No newline at end of file diff --git a/ci/gitlab-ci/yml/scenarios.yml b/ci/gitlab-ci/yml/scenarios.yml new file mode 100644 index 0000000000000..11598c3b6f2a9 --- /dev/null +++ b/ci/gitlab-ci/yml/scenarios.yml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +# Extend the CI by including a test scenario here. The scenario will be +# activated if KCI_SCENARIO is set to the scenario name. KCI_SCENARIO can be +# defined in the gitlab-ci.yml file, or through GitLab UI. + +include: + - local: 'ci/gitlab-ci/yml/scenarios/$KCI_SCENARIO.yml' + rules: + - if: '$KCI_SCENARIO' \ No newline at end of file diff --git a/ci/gitlab-ci/yml/scenarios/file-systems.yml b/ci/gitlab-ci/yml/scenarios/file-systems.yml new file mode 100644 index 0000000000000..66456600a9dd3 --- /dev/null +++ b/ci/gitlab-ci/yml/scenarios/file-systems.yml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +# Write here specific configurations and extensions for the given scenario + +# Example - overwrite kernel combinations in the pipeline +# .kernel-combinations: +# parallel: +# matrix: +# - KCI_KERNEL_ARCH: "x86_64" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." +# +# - KCI_KERNEL_ARCH: "arm64" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." +# +# - KCI_KERNEL_ARCH: "arm" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." \ No newline at end of file diff --git a/ci/gitlab-ci/yml/scenarios/media.yml b/ci/gitlab-ci/yml/scenarios/media.yml new file mode 100644 index 0000000000000..66456600a9dd3 --- /dev/null +++ b/ci/gitlab-ci/yml/scenarios/media.yml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +# Write here specific configurations and extensions for the given scenario + +# Example - overwrite kernel combinations in the pipeline +# .kernel-combinations: +# parallel: +# matrix: +# - KCI_KERNEL_ARCH: "x86_64" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." +# +# - KCI_KERNEL_ARCH: "arm64" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." +# +# - KCI_KERNEL_ARCH: "arm" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." \ No newline at end of file diff --git a/ci/gitlab-ci/yml/scenarios/network.yml b/ci/gitlab-ci/yml/scenarios/network.yml new file mode 100644 index 0000000000000..66456600a9dd3 --- /dev/null +++ b/ci/gitlab-ci/yml/scenarios/network.yml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +# Write here specific configurations and extensions for the given scenario + +# Example - overwrite kernel combinations in the pipeline +# .kernel-combinations: +# parallel: +# matrix: +# - KCI_KERNEL_ARCH: "x86_64" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." +# +# - KCI_KERNEL_ARCH: "arm64" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." +# +# - KCI_KERNEL_ARCH: "arm" +# KCI_DEFCONFIG: "path/to/my/config/file_config" +# KCI_ENABLE_KCONFIGS: "CONFIG1 CONFIG2 CONFIG3 ..." \ No newline at end of file diff --git a/ci/gitlab-ci/yml/static-checks.yml b/ci/gitlab-ci/yml/static-checks.yml new file mode 100644 index 0000000000000..a99a1ea910f40 --- /dev/null +++ b/ci/gitlab-ci/yml/static-checks.yml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2024 Collabora, Helen Koike + +.static-checks: + stage: static-checks + extends: + - .use-debian/x86_64_build + +checkpatch: + extends: .static-checks + script: + - ci/gitlab-ci/ci-scripts/run-checkpatch.sh + +smatch: + extends: + - .static-checks + - .kernel-combinations + - .use-cache-smatch-db + script: + - ci/gitlab-ci/ci-scripts/run-smatch.sh \ No newline at end of file From patchwork Wed Feb 28 22:55:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helen Koike X-Patchwork-Id: 208064 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6358:a1a:b0:17b:cd04:e0c6 with SMTP id 26csp241853rwa; Wed, 28 Feb 2024 14:56:30 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXmy15qN8Y+Dr9f4fCSh/rVsjRu+pKQI/dTJZ/7vsgvV1/LXzIQsdG6XdvZyjpfYqJnZDADA7nladI9wLHWcxiDVAz9NQ== X-Google-Smtp-Source: AGHT+IFTqQ7sHMYNS2JTzXZCSA/gDdHwrhtU4YPOT1DW8UAVvsNnxtipo/1XcX47mXrnNpY7MYgv X-Received: by 2002:a17:906:f6da:b0:a43:80e2:98dc with SMTP id jo26-20020a170906f6da00b00a4380e298dcmr188954ejb.32.1709160990617; Wed, 28 Feb 2024 14:56:30 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709160990; cv=pass; d=google.com; s=arc-20160816; b=n5ACWrH91XQt9sWCSXc4Scgz3mbhREmYzAFhh5mYO2BUoHhy9d16y1rqxSvcqN3kmG kClkBIAg+dQVVOZ6lRtVK1XTfF4pPuK2NwnTQ6dMbW+my5AmF/EGXBMiokW4/H3Ocy3T KBHghOBelpWZzsKvi7XzdoAT1VSEAKAoX+z9DE3faoNwwL6/a2Dq5Z7Iy/GgEbKz1wRy ZgRzmVrlhb/6rA8RcyehpG435OZTC1y6RUvN2rGNK5084moCUZLHHfMonDV68iAvO2+U XqVKnb6D6qSyRJCZZ7JF72D4htNawRMon31RaRI+nVYnqGpcoJfNeIvDcXIoa1l60vcq fF6w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:to:from:dkim-signature; bh=n5QutyxdUwM3U4aKRW3qlEW7/svZTA98ByoG182i7Hw=; fh=0m8BcSIN6jnEGrXYezAni7jiBLFEw9oBT48Gar0OTdk=; b=KJFvhv+uRlZrIA9bUsGHd9dUHYQ1k50LlrcdDZtesnAO3u+xpnNkIwnZDsFjuQh/gB rRBYoOx4b/gmThUGGU8nYhMgAo9kFjcbGIvKJ7RNrrvj91vShNGsS3ZulrzvR0xhG5Le N9rmc5y/Z5ydu8BWqvj4mcize72bNzP9VZ+L0BnRzZEl+hq9tPreLcClTuoZFYOhroYv /TOVw/3m0fM02R/m0RUROmIUon2QBxUf5pIV6cPmFXgfd9WSbngWBbSZXSSiwdaCIgDp 8nNP08Et4Ui84GzWxS7Obuq0/j+aVYRIjVpJoOabtXmci0EahsAJjN8nuy+us1DYsWG+ 4fLg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b="Ztcfiq/n"; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-85811-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-85811-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id qb28-20020a1709077e9c00b00a4418815f6dsi4313ejc.114.2024.02.28.14.56.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 14:56:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-85811-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b="Ztcfiq/n"; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-85811-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-85811-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 1C5E31F2775E for ; Wed, 28 Feb 2024 22:56:30 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9579B76EEF; Wed, 28 Feb 2024 22:56:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="Ztcfiq/n" Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CF2A72936; Wed, 28 Feb 2024 22:55:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709160956; cv=none; b=Z9smRS3czlI8WfEDXsfbCJfymKvS8I7OsQDFndqqK945frEanLVp3hedM0FpefNhnXBOLAWKag2ZLWJq53aSG2UakTX/j4av8IFqBU4/L+7ZlYQrfkPw8uWCKR1vAOhxd6rwCtcRwWJALZd1YyVK1Dc5a7M9n2nofb66BsxypoU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709160956; c=relaxed/simple; bh=FpJMfFLb7RI2hPRJguM7WRGYTcIgvbeDtXM2KpoFr80=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DYQiZkOeyHbZZIoNcjVS0Pgzd+cTfuctLlJjlqBiEarxq7yfflZPcuST7BeAeCbgL+M+DWe7SDoNrFRO51OGcDdjFoI04rYkEK18ExjgidhxkTSkRdqhuuNB5IFzk4cOzzUFJgkpyH8Zm1VkSkU6M7nK9V94FWrPziqH651ZASw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=Ztcfiq/n; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1709160952; bh=FpJMfFLb7RI2hPRJguM7WRGYTcIgvbeDtXM2KpoFr80=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Ztcfiq/nY1NQv8uHl+Nm6NOaAU4iFZw6qLJwYRkGCXs6nTJWfJBvHFlvetKSafJ09 ebOeERquONkTdEeUtTjYNzSJQkoaNOf13AIZJtt9NV9Y+ATL1X2n+GYnXFMZYDUeZW 6b1UtbV4ElY195NJlnZa5B8yJkcw+1AXHfUVeBjcpFMkXzvhMYhPAR8soEE2FYX/w6 SmemBGCQw/cyaNr+HzTAGCgZUCkuyzc2tGIXAtOWzfHj5t8xCytd4L589nis4hK6yR jH+a/6pnCGmn40ioAcO41MFIIFZ44cOR+2fYl2HhQPmykNKe6/FV9EjS2+LUKAgKb2 FaP0QyADyzXMw== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: koike) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 332C137820DD; Wed, 28 Feb 2024 22:55:45 +0000 (UTC) From: Helen Koike To: linuxtv-ci@linuxtv.org, dave.pigott@collabora.com, mripard@kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kselftest@vger.kernel.org, gustavo.padovan@collabora.com, pawiecz@collabora.com, spbnick@gmail.com, tales.aparecida@gmail.com, workflows@vger.kernel.org, kernelci@lists.linux.dev, skhan@linuxfoundation.org, kunit-dev@googlegroups.com, nfraprado@collabora.com, davidgow@google.com, cocci@inria.fr, Julia.Lawall@inria.fr, laura.nao@collabora.com, ricardo.canuelo@collabora.com, kernel@collabora.com, torvalds@linuxfoundation.org, gregkh@linuxfoundation.org Subject: [PATCH 2/3] kci-gitlab: Add documentation Date: Wed, 28 Feb 2024 19:55:26 -0300 Message-Id: <20240228225527.1052240-3-helen.koike@collabora.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240228225527.1052240-1-helen.koike@collabora.com> References: <20240228225527.1052240-1-helen.koike@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792185194603948384 X-GMAIL-MSGID: 1792185194603948384 Add documentation of kci-gitlab. Signed-off-by: Helen Koike --- Documentation/ci/gitlab-ci/gitlab-ci.rst | 404 +++++++++++++++++++++++ Documentation/index.rst | 7 + MAINTAINERS | 1 + 3 files changed, 412 insertions(+) create mode 100644 Documentation/ci/gitlab-ci/gitlab-ci.rst diff --git a/Documentation/ci/gitlab-ci/gitlab-ci.rst b/Documentation/ci/gitlab-ci/gitlab-ci.rst new file mode 100644 index 0000000000000..4f7ef03cca95c --- /dev/null +++ b/Documentation/ci/gitlab-ci/gitlab-ci.rst @@ -0,0 +1,404 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +========================================= +Automated Testing with GitLab CI/CD +========================================= + +This documentation outlines the GitLab CI/CD workflow for the Linux Kernel. The +workflow is designed to simplify testing for developers, allowing tests to be +run on any branch at any time, without the need for specific infrastructure. +Tests are automatically triggered on each `git push`, with results displayed in +the GitLab UI. + +.. image:: images/the-pipeline.png + :alt: GitLab-CI pipeline for kernel testing + :align: center + +Customizations and extensions of the pipeline are possible through the +scenarios. Scenarios can override existing jobs, change configurations, or +define new jobs and stages. See :ref:`extending-the-ci` section. + +.. note:: If you are unfamiliar with GitLab CI/CD basic concepts, please check + the `official documentation `_. + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` + +Setup +----- + +The GitLab CI pipeline is configured for **"out-of-the-box"** use. Pushing code to a +GitLab repository automatically triggers the pipeline. + + .. code-block:: bash + + # Download the Linux kernel source code + git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git + # Create a repository on GitLab and add it as a remote + git remote add gitlab https://gitlab.yourinstance.com/your-username/your-repo.git + # Push the code to GitLab + git push gitlab + +.. image:: images/pipelines-on-push.png + :alt: Pipeline triggered on push + :align: center + +Troubleshooting +--------------- + +If the pipeline doesn't trigger automatically, check the following: + +1. **Enable CI/CD in Project Settings:** + + - Go to `Settings > General > Visibility, project features, permissions`. + - Under `Repository`, ensure the `CI/CD` toggle is enabled. + +2. **Enable Container Registry:** + + - Still in `Settings`, find the `Container Registry` section. + - Enable the `Container Registry` toggle. + +3. **CI Minutes and Resources:** + + - If you've exhausted CI minutes or other resources on the Free Tier, + consider setting up a local GitLab runner (see below). + +Setting Up a Local GitLab Runner +-------------------------------- + +You can use your own machine as a runner, instead of the shared runners provided +by your GitLab instance. + +1. **Generate a GitLab Runner Token:** + + - Navigate to `Settings > CI/CD > Runners`. + - Expand the `Runners` section and click on "New project runner". + - Choose "Run untagged jobs" and click "Create runner". + - Copy the provided token. + +.. image:: images/new-project-runner.png + :alt: New project runner button + :align: center + +2. **Launch the Runner:** + + - Ensure Docker is installed and your user is added to the Docker group: + + .. code-block:: bash + + sudo usermod -aG docker + + - Log in again to apply the changes. + - Set up the runner: + + .. code-block:: bash + + export GITLAB_RUNNER_TOKEN= + export GITLAB_URL=https://gitlab.yourinstance.com # Use this for instances other than gitlab.com + cd ci/gitlab-ci + ./bootstrap-gitlab-runner.sh + + +Current Pipeline Jobs +--------------------- + +stage: container +^^^^^^^^^^^^^^^^ + +**job: debian/x86_64_build** + +This job prepares the container used by subsequent jobs. It starts from a base +Debian image, installing necessary tools for building the kernel and running +tests. The resulting image is pushed to the project registry and cached. If the +image already exists in the registry, it won't be rebuilt. + +To force a rebuild, update the `FDO_DISTRIBUTION_TAG` variable in the +`container.yml` file. + +stage: static-checks +^^^^^^^^^^^^^^^^^^^^ + +**job: checkpatch** + +Runs the `checkpatch.pl` script on the last `$ICI_PATCH_SERIES_SIZE` commits. +This variable is determined by: + +- `ICI_PATCH_SERIES_SIZE=` The number of differing patches between target and + source branches for merge requests; Or +- `ICI_PATCH_SERIES_SIZE=$KCI_PATCH_SERIES_SIZE` if `KCI_PATCH_SERIES_SIZE` is + set (see :ref:`how-to-set-variables` below). + +Defaults to 1 and raises a GitLab warning if unable to identify the number of +commits. + +**job: smatch** + +Checks `.c` files in the last `$ICI_PATCH_SERIES_SIZE` commits. Spawns a +"sub-job" for each architecture and configuration in `kernel-combinations.yml`. +If a smatch database exists (see `job: smatch-db-generate` below), it reuses it. + +stage: build +^^^^^^^^^^^^ + +**job: build-kernel** + +Compiles the kernel. Spawns a "sub-job" for each architecture and configuration +in `kernel-combinations.yml`. Uses `ccache` to speed up builds, with its +database shared inside the runner or across runners if configured with S3. + +Raises a GitLab warning if "warning" is found in the build log. + +.. image:: images/job-matrix.png + :alt: Matrix of jobs under build-kernel + :align: center + +**job: build-docs** + +Builds documentation. Spawns a "sub-job" for each documentation type. Not run +automatically; requires manual triggering. + +stage: cache +^^^^^^^^^^^^ + +**job: smatch-db-generate** + +Generates a smatch database for use by the `smatch` job. Not run automatically; +requires manual triggering. + +.. _extending-the-ci: + +Extending the CI - Test Scenarios (KCI_SCENARIO) +------------------------------------------------ + +The pipeline offers flexibility and adaptability through the use of scenarios, +enhancing the CI/CD process with broad customization options. Key capabilities +include: + +- **Overriding Existing Jobs:** Tailor existing jobs to meet specific needs or + conditions. + +- **Changing Configurations:** Dynamically adapt job settings to suit various + environments or subsystem requirements. + +- **Defining New Jobs and Stages:** Introduce new jobs and stages for additional + tests, build processes, or deployment strategies. + +These features are particularly useful when a subsystem has distinct +requirements. For instance, to enable testing different configurations for a +specific architecture, running static checks with varied arguments, or +installing specialized tools to conduct targeted tests. + +Writing a test scenario +^^^^^^^^^^^^^^^^^^^^^^^ + +The GitLab CI pipeline configuration allows for the inclusion of additional +`.yml` files based on the `KCI_SCENARIO` variable. For example, setting +`KCI_SCENARIO` to `media` includes `media.yml` from the `scenarios/` folder. + +To illustrate, building a specific architecture with a custom config can be +achieved by overriding the `.kernel-combinations` hidden job in the +`scenarios/my-scenario.yml` file: + +.. code-block:: yaml + + .kernel-combinations: + parallel: + matrix: + - KCI_KERNEL_ARCH: "arm64" + KCI_DEFCONFIG: "my/custom/config1" + KCI_KCONFIGS_ENABLE: "CONFIG1 CONFIG2 CONFIG3" + + - KCI_KERNEL_ARCH: "arm64" + KCI_DEFCONFIG: "my/custom/config2" + KCI_KCONFIGS_ENABLE: "CONFIG4 CONFIG5" + +This modifies builds and static checks for `arm64` with different +configurations. + +To select this scenario, trigger the pipeline with KCI_SCENARIO=my-scenario. See +:ref:`how-to-set-variables` below. + +Variables +--------- + +GitLab CI/CD supports various variables to modify pipeline behavior or for use +in jobs. + +- **CI_ Prefix:** Standard GitLab CI/CD variables (see GitLab documentation). +- **KCI_ Prefix:** Custom variables defined for kernel CI. +- **ICI_ Prefix:** Internal variables used between scripts (not for external + use). + +.. _how-to-set-variables: + +How to Set Variables +-------------------- + +Variables can be set in several ways: + +- **Project Settings:** Under `CI/CD > Variables`. +- **Pipeline UI:** When triggering a pipeline manually. +- **Command Line:** When triggering a pipeline manually (see + :ref:`triggering-pipelines-from-command-line` below). +- **YML Files:** Using the `variables` keyword. +- **Commit Message:** For runtime variables only (see + :ref:`setting-variables-in-the-commit-message` below). + +.. image:: images/variables.png + :alt: Manual creation of pipeline + :align: center + +Variables Precedence +-------------------- + +- **Commit Message Variables:** Highest precedence if evaluated at runtime. +- **Pipeline Variables:** Next in precedence. +- **Project Variables:** Follow pipeline variables. +- **YML File Variables:** Considered after the above levels. + +.. _setting-variables-in-the-commit-message: + +Setting Variables in the Commit Message +--------------------------------------- + +Runtime variables can be set in the commit message. Patterns like +`KCI_VARIABLE=value` are extracted and exported to the job. To avoid including +variables in the git history, add them after three dashes (`---`) in the commit +message, as `git am` ignores text after this line. + +Example: + +.. code-block:: + + Title of my awesome commit + + This is the commit message description of my awesome patch + --- + KCI_PATCH_SERIES_SIZE=4 + +Description of Each Variable +---------------------------- + +**KCI_KERNEL_ARCH** + Defines the architecture to be used in the build-kernel and static checks + jobs. Usually set in the `.kernel-combinations` hidden job. + +**KCI_DEFCONFIG** + Defines the config file to be used in the build-kernel and static checks + jobs. Usually set in the `.kernel-combinations` hidden job. + +**KCI_KCONFIGS_{ENABLE,DISABLE,MODULE}** + Defines the extra configs to be enabled, disabled or set as a module, used + in the build-kernel and static checks jobs. Usually set in the + `.kernel-combinations` hidden job. + +**KCI_SCENARIO** + Used to select which extra scenario file to include in the pipeline. See + :ref:`extending-the-ci` section above. Usually set by the user at project or + pipeline level. + +**KCI_CHECKPATCH_OPTIONS** + Used in `checkpatch.pl "$KCI_CHECKPATCH_OPTIONS"` (see checkpatch + documentation). It is commonly used with the --ignore flag to suppress + specific warnings generated by checkpatch.pl. It can also be defined in the + commit message, since it is evaluated in run time. + +**KCI_PATCH_SERIES_SIZE** + Used to define the size of the patch series, see `job: checkpatch` section + above. It is evaluated in run time, and can be set in the commit message. + +.. _triggering-pipelines-from-command-line: + +Triggering Pipelines from Command Line +-------------------------------------- + +Pipelines can be triggered from the command line with custom variables using the +`GitLab CLI tool `_. + +Example: + +.. code-block:: bash + + glab auth login + glab ci run -b gitlab-draft -R https://gitlab.collabora.com/koike/linux/ --variables-env KCI_PATCH_SERIES_SIZE:4 + + +Debugging and Replicating Jobs Locally +-------------------------------------- + +When a job fails in GitLab CI/CD, it's handy to replicate the issue in the +same environment used by the GitLab CI/CD runner. This allows for interactive +execution of each step and the use of debugging tools to pinpoint the failure's +root cause. + +Rather than repeatedly modifying scripts and running the entire pipeline for +debugging, you can download the specific Docker image used by the job and run it +locally. + +To do this, first inspect the failed job in GitLab CI/CD. Look for a message +indicating the Docker image used, typically in this format: + + Pulling docker image registry.gitlab.collabora.com/koike/linux/debian/bookworm-slim:2024-02-6-ci-test-1 + +You can then use this image to run the job locally. For example: + +.. code-block:: bash + + IMAGE=registry.gitlab.collabora.com/koike/linux/debian/bookworm-slim:2024-02-6-ci-test-1 + docker pull $IMAGE + docker run --rm -v `pwd`:/linux -w /linux $IMAGE bash + + +Suggestions +----------- + +Send Pipeline Links with Your Patch +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When submitting patches or merge requests, it's highly beneficial to include +links to the related GitLab CI pipelines. This practice enhances the review +process in several ways: + +1. **Immediate Visibility:** Reviewers can immediately see the results of + automated tests, making it easier to assess the patch's impact. + +2. **Increased Confidence:** Successful pipeline runs increase confidence in the + changes, demonstrating that they pass existing tests. + +3. **Efficient Troubleshooting:** If there are issues, pipeline links allow both + authors and reviewers to quickly access logs and test results, facilitating + faster troubleshooting and iteration. + +4. **Transparency:** Providing pipeline links promotes transparency in the + development process, making it clear how changes have been verified. + +To include a pipeline link in your patch or merge request, simply copy the URL +of the pipeline from your GitLab project's CI/CD pipeline page and paste it into +your commit description after three dashes (`---`) or as a reply to your email +patch. + +Always Green Pipeline +^^^^^^^^^^^^^^^^^^^^^ + +Maintaining an "always green" pipeline refers to the practice of ensuring that +the main branch's pipeline is always in a passing state. This approach has +several advantages: + +1. **Reliable Main Branch:** A green pipeline indicates a stable and reliable + main branch, which is crucial for continuous integration practices. + +2. **Immediate Feedback:** Developers receive immediate feedback on their + changes. If a merge causes the pipeline to fail, it's a clear signal that the + change introduced an issue. + +3. **Faster Iteration:** An always green pipeline facilitates faster development + and iteration, as developers can confidently build on top of the latest main + branch without worrying about hidden failures. + +4. **Culture of Responsibility:** It fosters a culture of responsibility, where + developers are encouraged to fix broken builds promptly and avoid merging + changes that could disrupt the pipeline. \ No newline at end of file diff --git a/Documentation/index.rst b/Documentation/index.rst index 36e61783437c1..cc96548ea8ef0 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -101,6 +101,13 @@ Architecture-specific documentation arch/index +CI: Automated testing documentation +=================================== + +.. toctree:: + :maxdepth: 2 + + ci/gitlab-ci/gitlab-ci Other documentation =================== diff --git a/MAINTAINERS b/MAINTAINERS index aa0f65791c2ee..5627300397e23 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5004,6 +5004,7 @@ L: linux-kernel@vger.kernel.org S: Maintained T: git https://gitlab.collabora.com/koike/linux.git F: .gitlab-ci.yml +F: Documentation/ci/ F: ci/ CIRRUS LOGIC AUDIO CODEC DRIVERS From patchwork Wed Feb 28 22:55:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helen Koike X-Patchwork-Id: 208068 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6358:a1a:b0:17b:cd04:e0c6 with SMTP id 26csp245864rwa; Wed, 28 Feb 2024 15:04:56 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW5vO6Fx7EtEisMeXnPJDqTJ+uYCEMUajRGX1tDD0sRhkYUnjWyWbjEId1O8f37DgSn3udHsZBciAlwTsyU7fBoI5nyow== X-Google-Smtp-Source: AGHT+IET5+o4ryBZBBKdunAiuDhp7M7yX+EoQ9NsCxlhFGngDqVACxn7EYAtXXom7seFOmfce6Cl X-Received: by 2002:a17:906:4e95:b0:a3f:47de:66bb with SMTP id v21-20020a1709064e9500b00a3f47de66bbmr161271eju.70.1709161496071; Wed, 28 Feb 2024 15:04:56 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709161496; cv=pass; d=google.com; s=arc-20160816; b=qkH+E8PUPMJirhPaBK0PEewt3a4Fi1Xn/6kwoLq3bzhfNNJzhwtvgiYr5uBf8gRULw m5wEcoZwlygzKWqK1WpJRa/k1WFemNZA9Rh6/IRhkLrfOdCVyuW9td7ViCnI/2UBULBd v50mZGGDVuYS2+ooP5P4uY1yXLXhDRAX77hjVHDGNj8eWJaQ79O3Y7RB4AFMHokWz/94 JN1s7Ymu2higdDScWNUHFrNEnQ05Mx89q9H+DV+2FHAeNp43/F9+Mm9j3x+yL58Wc7vC jPUp6OZw4ukOPbb6uEP2ndEmaZ6ePo/PE54Mtpn85U4k/+mrYFmpzEjkq6GbUhGCQhdr tJYA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:to:from:dkim-signature; bh=AtoUoX+h1hw9AqnZwX+Vbx4tH56aqAu4ci3jh7iH1nA=; fh=0m8BcSIN6jnEGrXYezAni7jiBLFEw9oBT48Gar0OTdk=; b=sl0Qvhz8xQCtwHJOVHpPHdnpVxb2Ka028NlRD8sD43yp99Ra5qsixnP2NrIazTWfk1 4bG+iUV9eMggd9+S5iqYc45YfY2tz+5Xq2cxt+cfrlgcB7vdpbVcJzVGdbT4tcHQNGSZ MBtCcX90HOeNHmGqT3Ipp4bpw0OmBl5aR8fN/CbxaJJn4gf0+/txHasMeLm78GAR+wGb IrPcCez3/0FY7NQlYEbNuOKva0OhSgV35XLzRd/tGwGlpaDEB6n8y2VmdnA7ikdXCio+ f6046g3RJTylfXVWxonC5Owxyg3hyRRstt814Zhe5/G4oP4VVTwCF/xaqQrArV24kdNi o+Nw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=Xx5aeFt1; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-85813-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-85813-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id mc5-20020a170906eb4500b00a43c5d522a7si10162ejb.103.2024.02.28.15.04.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 15:04:55 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-85813-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=Xx5aeFt1; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-85813-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-85813-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 0FEEE1F29DAD for ; Wed, 28 Feb 2024 23:04:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C726472910; Wed, 28 Feb 2024 23:03:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="Xx5aeFt1" Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8701E70045; Wed, 28 Feb 2024 22:56:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709161056; cv=none; b=MHcZPHdUjyTUoV0StsdIjRiLWAzJ5w55bSGi4A6YJpWzq08vMAwptW79bhQF6sBvACimxaGEzzhSMOnEM2FcYhVTsxxkl6NWEvLe8IGTpNeXlyB4TaBK8foyS0TbG1ZW5//Z6jc5QD2FoQwIJdTE2wFP9PJnCs1G3oFzxDDGU/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709161056; c=relaxed/simple; bh=Llz0eThFps7p6aVomBGfllnBrjXag+I7x4oQ4z0TeiM=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=L2OWHCPdVTpJwuxTr7QQIO6TDEhB3qf6ij6B4cJ2NVBWpez+WkzuZZIwG0qqAGV/12i1nbWQYljUFGCX25RSP2qWkoAfFq0eW9xt00oD2tr0lBaVfa2huDOlvbWfU81MupU3iXN6HsAxKt429zxOyx/axXf9HWN6xQv9pL4Kxxo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=Xx5aeFt1; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1709160966; bh=Llz0eThFps7p6aVomBGfllnBrjXag+I7x4oQ4z0TeiM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Xx5aeFt18dPc6bqohO9ECoYCyMgO3nPs7GOIO2eu4OSeeWAC6grRUMHCac2E4YSGN nyYjpCeBa8ydyqDi2DnbBz8gBxyOYsSC0kw9Wyzyrmjrx0SjlJtFZZ1Tm6voI+TlQO mzMV5TFcavwQGLWV69zH8nn1GF1tPJhvZWEuX4nsxAn7ly5r0D0n4aOzTuU6bnQC3A 3z835YSLHWd7yRg2Z5RRf/Po9L96SK3wFNQBdQtIb5CU2TrFmuprrbD9fCWQtTcMEX 0JMdFhzIg1jmjpPwfrzt2Kn6owxmUqsbcXYsoW3COtrcJC7fJbv5XSjQ86kqo1M4Jo qRFfUAhf1zZpg== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: koike) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 530A137820CB; Wed, 28 Feb 2024 22:55:53 +0000 (UTC) From: Helen Koike To: linuxtv-ci@linuxtv.org, dave.pigott@collabora.com, mripard@kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kselftest@vger.kernel.org, gustavo.padovan@collabora.com, pawiecz@collabora.com, spbnick@gmail.com, tales.aparecida@gmail.com, workflows@vger.kernel.org, kernelci@lists.linux.dev, skhan@linuxfoundation.org, kunit-dev@googlegroups.com, nfraprado@collabora.com, davidgow@google.com, cocci@inria.fr, Julia.Lawall@inria.fr, laura.nao@collabora.com, ricardo.canuelo@collabora.com, kernel@collabora.com, torvalds@linuxfoundation.org, gregkh@linuxfoundation.org Subject: [PATCH 3/3] kci-gitlab: docs: Add images Date: Wed, 28 Feb 2024 19:55:27 -0300 Message-Id: <20240228225527.1052240-4-helen.koike@collabora.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240228225527.1052240-1-helen.koike@collabora.com> References: <20240228225527.1052240-1-helen.koike@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792185724508809794 X-GMAIL-MSGID: 1792185724508809794 Add images to kci-gitlab documentation. Signed-off-by: Helen Koike --- KCI_PATCH_SERIES_SIZE=3 KCI_CHECKPATCH_OPTIONS="--ignore FILE_PATH_CHANGES" --- .../ci/gitlab-ci/images/job-matrix.png | Bin 0 -> 159752 bytes .../ci/gitlab-ci/images/new-project-runner.png | Bin 0 -> 607737 bytes .../ci/gitlab-ci/images/pipelines-on-push.png | Bin 0 -> 532143 bytes .../ci/gitlab-ci/images/the-pipeline.png | Bin 0 -> 91675 bytes .../ci/gitlab-ci/images/variables.png | Bin 0 -> 277518 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Documentation/ci/gitlab-ci/images/job-matrix.png create mode 100644 Documentation/ci/gitlab-ci/images/new-project-runner.png create mode 100644 Documentation/ci/gitlab-ci/images/pipelines-on-push.png create mode 100644 Documentation/ci/gitlab-ci/images/the-pipeline.png create mode 100644 Documentation/ci/gitlab-ci/images/variables.png new file mode 100644 index 0000000000000000000000000000000000000000..d59de9f7eeab8982a61e872824c1a69c1027c532 GIT binary patch literal 607737 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