diff --git a/.github/workflows/codeowners-validation.yml b/.github/workflows/codeowners-validation.yml new file mode 100644 index 000000000..81ecc72b4 --- /dev/null +++ b/.github/workflows/codeowners-validation.yml @@ -0,0 +1,25 @@ +name: CODEOWNERS Validation +run-name: ${{ github.actor }} is validating CODEOWNERS +on: + pull_request: + branches: + - main + +jobs: + CheckDockerfileCodeowners: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Ensure each CODEOWNER is a team + if: always() + run: ./eng/validate-codeowners.sh ownersAreTeams + + - name: Check each Dockerfile for a CODEOWNER + if: always() + run: ./eng/validate-codeowners.sh dockerfilesHaveOwners + + - name: Check for unused CODEOWNER paths + if: always() + run: ./eng/validate-codeowners.sh pathsAreUsed diff --git a/CODEOWNERS b/CODEOWNERS index 5980d1648..cf2d7ee74 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,50 @@ # Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths. # See https://help.github.com/articles/about-code-owners/ +### General infra ### * @dotnet/dotnet-docker-reviewers + +### Dockerfiles ### + +# common paths +src/**/helix/ @dotnet/dnceng +src/**/cross*/ @dotnet/runtime-infrastructure +src/**/webassembly*/ @dotnet/runtime-infrastructure + +# almalinux +src/almalinux/**/source-build/ @dotnet/source-build-internal + +# alpine +src/alpine/**/amd64/ @dotnet/source-build-internal + +# azurelinux +src/azurelinux/**/android/ @dotnet/runtime-infrastructure +src/azurelinux/**/fpm/ @dotnet/runtime-infrastructure +src/azurelinux/**/opt/ @dotnet/runtime-infrastructure + +# cbl-mariner +src/cbl-mariner/**/android/ @dotnet/runtime-infrastructure +src/cbl-mariner/**/fpm/ @dotnet/runtime-infrastructure +src/cbl-mariner/**/opt/ @dotnet/runtime-infrastructure +src/cbl-mariner/**/docker-testrunner/ @dotnet/dotnet-docker-reviewers +src/cbl-mariner/2.0/amd64/ @dotnet/runtime-infrastructure + +# centos +src/centos/stream9/amd64/ @dotnet/source-build-internal + +# debian +src/debian/11/amd64/ @dotnet/source-build-internal +src/debian/11/opt/arm64v8/ @dotnet/runtime-infrastructure +src/debian/12/gcc14/amd64/ @dotnet/runtime-infrastructure + +# fedora +src/fedora/**/amd64/ @dotnet/source-build-internal + +# ubuntu +src/ubuntu/**/debpkg/ @dotnet/runtime-infrastructure +src/ubuntu/22.04/mlnet/ @dotnet/runtime-infrastructure +src/ubuntu/22.04/opt/arm64v8/ @dotnet/runtime-infrastructure +src/ubuntu/common/coredeps/ @dotnet/runtime-infrastructure +src/ubuntu/20.04/Dockerfile @dotnet/source-build-internal +src/ubuntu/22.04/Dockerfile @dotnet/source-build-internal +src/ubuntu/24.04/Dockerfile @dotnet/source-build-internal diff --git a/eng/validate-codeowners.sh b/eng/validate-codeowners.sh new file mode 100755 index 000000000..4486e028f --- /dev/null +++ b/eng/validate-codeowners.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash + +set -e + +if [ $# -eq 0 ]; then + echo "No function name provided. Usage: ./validate-codeowners.sh " + exit 1 +fi + +declare -A codeOwnerEntries +readCodeOwnersFile() { + codeOwnersFilePath="CODEOWNERS" + + # A newline is needed at the end of the file for the last line to be read + # but git likes to remove trailing newlines so we add one if it is missing + if [ "$(tail -c 1 "$codeOwnersFilePath")" != "" ]; then + echo "" >> "$codeOwnersFilePath" + fi + + while IFS= read -r line; do + + # Skip blank lines, comments, and * paths + if [[ "$line" =~ ^[[:space:]]*# ]] || [[ "$line" =~ ^[[:space:]]*$ ]] || [[ "$line" =~ ^\*[[:space:]] ]]; then + continue + fi + + path=$(echo "$line" | awk '{print $1}' | awk '{$1=$1};1') + owner=$(echo "$line" | awk '{print $2}' | awk '{$1=$1};1') + + # Escape periods + path=$(echo "$path" | sed 's/\./\\./g') + + # A single asterisk matches anything that is not a slash (as long as it is not at the beginning of a pattern) + if [[ ! "$path" =~ ^\* ]]; then + path=$(echo "$path" | sed -E 's/([^*]|^)\*([^*]|$)/\1[^\/]*\2/g') + fi + + # Trailing /** and leading **/ should match anything in all directories + path=$(echo "$path" | sed 's/\/\*\*$/\/.*/g') + path=$(echo "$path" | sed 's/^\*\*\//.*\//g') + + # /**/ matches zero or more directories + path=$(echo "$path" | sed 's/\/\*\*\//\/.*/g') + + # If the asterisk is at the beginning of the pattern or the pattern does not start with a slash, then match everything + if [[ "$path" =~ ^\* ]]; then + path=".$path" + elif [[ ! "$path" =~ ^/ && ! "$path" =~ ^\.\* ]]; then + path=".*$path" + fi + + # If there is a trailing slash, then match everything below the directory + if [[ "${path: -1}" == "/" ]]; then + path="$path.*" + fi + + path="^$path$" + + codeOwnerEntries["$path"]="$owner" + done < "$codeOwnersFilePath" +} + +ownersAreTeams() { + nonTeamOwners=() + + for codeOwner in "${codeOwnerEntries[@]}"; do + if [[ "$codeOwner" != *"/"* ]]; then + nonTeamOwners+=("$codeOwner") + fi + done + + if [[ ${#nonTeamOwners[@]} -gt 0 ]]; then + echo "The following CODEOWNERS are not teams:" + printf "%s\n" "${nonTeamOwners[@]}" + exit 1 + fi + + exit 0 +} + +pathsAreUsed() { + allFiles=$(find . -type f | sed 's/^\.//') + unusedPaths=() + + for path in "${!codeOwnerEntries[@]}"; do + pathUsed=false + for file in $allFiles; do + if [[ "$file" =~ $path ]]; then + pathUsed=true + break + fi + done + + if [[ "$pathUsed" == false ]]; then + # Undo regex changes + path=$(echo "$path" | sed 's/\[\^\/\]\*/\*/g' | sed 's/^\^//' | sed 's/\$$//') + unusedPaths+=("$path") + fi + done + + if [[ ${#unusedPaths[@]} -gt 0 ]]; then + echo "The following paths in the CODEOWNERS file are not used by any file in the repository:" + printf "%s\n" "${unusedPaths[@]}" + exit 1 + fi + + exit 0 +} + +dockerfilesHaveOwners() { + dockerfiles=$(find . -type f -name "Dockerfile" | sed 's/^\.//') + filesWithoutOwner=() + + for file in $dockerfiles; do + ownerFound=false + for pattern in "${!codeOwnerEntries[@]}"; do + if [[ "$file" =~ $pattern ]]; then + ownerFound=true + break + fi + done + if [ "$ownerFound" = false ]; then + filesWithoutOwner+=("$file") + fi + done + + if [[ ${#filesWithoutOwner[@]} -gt 0 ]]; then + echo "The following Dockerfiles do not have an owner in the CODEOWNERS file:" + printf "%s\n" "${filesWithoutOwner[@]}" + exit 1 + fi + + exit 0 +} + +# Call the function passed as an argument +readCodeOwnersFile +"$1" \ No newline at end of file diff --git a/src/alpine/3.17/helix/Dockerfile b/src/alpine/3.17/helix/Dockerfile index de82cb113..de373aa17 100644 --- a/src/alpine/3.17/helix/Dockerfile +++ b/src/alpine/3.17/helix/Dockerfile @@ -15,7 +15,7 @@ RUN apk add --upgrade --no-cache \ openssl-dev \ perl -RUN git clone --depth 1 --single-branch --branch main --recursive https://github.com/microsoft/msquic /tmp/msquic +RUN git clone --depth 1 --single-branch --branch v2.4.1 --recursive https://github.com/microsoft/msquic /tmp/msquic WORKDIR /tmp/msquic diff --git a/src/alpine/3.18/helix/Dockerfile b/src/alpine/3.18/helix/Dockerfile index bbd5c2a8d..b40d79d76 100644 --- a/src/alpine/3.18/helix/Dockerfile +++ b/src/alpine/3.18/helix/Dockerfile @@ -15,7 +15,7 @@ RUN apk add --upgrade --no-cache \ openssl-dev \ perl -RUN git clone --depth 1 --single-branch --branch main --recursive https://github.com/microsoft/msquic /tmp/msquic +RUN git clone --depth 1 --single-branch --branch v2.4.1 --recursive https://github.com/microsoft/msquic /tmp/msquic WORKDIR /tmp/msquic diff --git a/src/alpine/3.20/helix/Dockerfile b/src/alpine/3.20/helix/Dockerfile index 2ba10d82c..368dfc4d2 100644 --- a/src/alpine/3.20/helix/Dockerfile +++ b/src/alpine/3.20/helix/Dockerfile @@ -15,7 +15,7 @@ RUN apk add --upgrade --no-cache \ openssl-dev \ perl -RUN git clone --depth 1 --single-branch --branch main --recursive https://github.com/microsoft/msquic /tmp/msquic +RUN git clone --depth 1 --single-branch --branch v2.4.1 --recursive https://github.com/microsoft/msquic /tmp/msquic WORKDIR /tmp/msquic diff --git a/src/debian/11/arm64v8/Dockerfile b/src/debian/11/arm64v8/Dockerfile deleted file mode 100644 index 81b5b3ca0..000000000 --- a/src/debian/11/arm64v8/Dockerfile +++ /dev/null @@ -1,49 +0,0 @@ -FROM library/debian:bullseye - -# Dependencies for generic .NET Core builds and the base toolchain we need to -# build anything (clang, cmake, make and the like) -RUN apt-get update \ - && apt-get install -y \ - autoconf \ - automake \ - build-essential \ - clang \ - cmake \ - curl \ - elfutils \ - file \ - g++ \ - gettext \ - gdb \ - git \ - gnupg \ - jq \ - libcurl4-openssl-dev \ - libgdiplus \ - libicu-dev \ - libkrb5-dev \ - liblldb-dev \ - liblttng-ust-dev \ - libnuma-dev \ - libssl-dev \ - libssl1.1 \ - libtool \ - libunwind8-dev \ - lldb \ - llvm \ - locales \ - make \ - python-lldb \ - sudo \ - tar \ - uuid-dev \ - zip \ - zlib1g-dev \ - && rm -rf /var/lib/apt/lists/* - -# .NET SDK MSBuild requires US.UTF-8 locale to execute tasks -# These commands are from https://askubuntu.com/a/1027038 -RUN echo "locales locales/default_environment_locale select en_US.UTF-8" | debconf-set-selections \ - && echo "locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8" | debconf-set-selections \ - && rm "/etc/locale.gen" \ - && dpkg-reconfigure --frontend noninteractive locales diff --git a/src/debian/manifest.json b/src/debian/manifest.json index 0662762a7..caf663b13 100644 --- a/src/debian/manifest.json +++ b/src/debian/manifest.json @@ -61,21 +61,6 @@ } ] }, - { - "platforms": [ - { - "architecture": "arm64", - "dockerfile": "src/debian/11/arm64v8", - "os": "linux", - "osVersion": "bullseye", - "tags": { - "debian-11-arm64v8-$(System:TimeStamp)-$(System:DockerfileGitCommitSha)": {}, - "debian-11-arm64v8$(FloatingTagSuffix)": {} - }, - "variant": "v8" - } - ] - }, { "platforms": [ { diff --git a/src/ubuntu/24.04/helix/Dockerfile b/src/ubuntu/24.04/helix/Dockerfile index a0f40e2e5..8cbc99125 100644 --- a/src/ubuntu/24.04/helix/Dockerfile +++ b/src/ubuntu/24.04/helix/Dockerfile @@ -64,17 +64,22 @@ RUN LIBCURL=libcurl4 && \ ENV LANG=en_US.utf8 +# Installing `libxdp1 libnl-3-dev libnl-route-3-dev` packages as a temporary workaround delete them once the issue is fixed +# For ARM, we need to download the libmsquic package and install it manually because it still depends on libssl3 instead of libssl3t64 # Add MsQuic -# MsQuic does not yet publish packages for 24.04 -# Manually install 22.04 package for now -RUN DEPS= && \ - ARCH=$TARGETARCH && \ +RUN curl -LO https://packages.microsoft.com/keys/microsoft.asc && \ + echo 2cfd20a306b2fa5e25522d78f2ef50a1f429d35fd30bd983e2ebffc2b80944fa microsoft.asc| sha256sum --check - && \ + apt-key add microsoft.asc && \ + rm microsoft.asc && \ + apt-add-repository https://packages.microsoft.com/ubuntu/24.04/prod && \ + apt-get update && \ + apt-get install -y libxdp1 libnl-3-dev libnl-route-3-dev && \ if [ "$TARGETARCH" = "arm" ]; then \ - DEPS=--ignore-depends=libssl3 && \ - ARCH=armhf ; fi && \ - curl -LO https://packages.microsoft.com/ubuntu/22.04/prod/pool/main/libm/libmsquic/libmsquic_2.3.6_$ARCH.deb && \ - dpkg $DEPS -i libmsquic_*.deb && \ - rm -f libmsquic_*.deb + apt-get download libmsquic && \ + dpkg --ignore-depends=libssl3 -i libmsquic_*.deb && \ + rm -f libmsquic_*.deb ; \ + else apt-get install -y libmsquic ; fi && \ + rm -rf /var/lib/apt/lists/* # create helixbot user and give rights to sudo without password RUN /usr/sbin/adduser --disabled-password --gecos '' --uid 1001 --shell /bin/bash --ingroup adm helixbot && \