diff options
Diffstat (limited to '.github/workflows')
-rwxr-xr-x | .github/workflows/build_test.sh | 161 | ||||
-rw-r--r-- | .github/workflows/build_test.yml | 38 | ||||
-rw-r--r-- | .github/workflows/cflite_pr.yml | 39 | ||||
-rw-r--r-- | .github/workflows/cifuzz.yml | 74 | ||||
-rw-r--r-- | .github/workflows/codeql.yml | 59 | ||||
-rw-r--r-- | .github/workflows/coverity.yml | 30 | ||||
-rw-r--r-- | .github/workflows/development_freeze.yml | 74 | ||||
-rw-r--r-- | .github/workflows/differential-shellcheck.yml | 35 | ||||
-rw-r--r-- | .github/workflows/gather-pr-metadata.yml | 37 | ||||
-rw-r--r-- | .github/workflows/issue_labeler.yml | 36 | ||||
-rw-r--r-- | .github/workflows/labeler.yml | 119 | ||||
-rw-r--r-- | .github/workflows/linter.yml | 36 | ||||
-rw-r--r-- | .github/workflows/make_release.yml | 24 | ||||
-rw-r--r-- | .github/workflows/mkosi.yml | 143 | ||||
-rw-r--r-- | .github/workflows/requirements.txt | 19 | ||||
-rw-r--r-- | .github/workflows/scorecards.yml | 41 | ||||
-rwxr-xr-x | .github/workflows/unit_tests.sh | 123 | ||||
-rw-r--r-- | .github/workflows/unit_tests.yml | 45 |
18 files changed, 1133 insertions, 0 deletions
diff --git a/.github/workflows/build_test.sh b/.github/workflows/build_test.sh new file mode 100755 index 0000000..c550046 --- /dev/null +++ b/.github/workflows/build_test.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later + +set -ex + +info() { echo -e "\033[33;1m$1\033[0m"; } +fatal() { echo >&2 -e "\033[31;1m$1\033[0m"; exit 1; } +success() { echo >&2 -e "\033[32;1m$1\033[0m"; } + +ARGS=( + "--optimization=0 -Dopenssl=disabled -Dcryptolib=gcrypt -Ddns-over-tls=gnutls -Dtpm=true -Dtpm2=enabled" + "--optimization=s -Dutmp=false" + "--optimization=3 -Db_lto=true -Ddns-over-tls=false" + "--optimization=3 -Db_lto=false -Dtpm2=disabled -Dlibfido2=disabled -Dp11kit=disabled" + "--optimization=3 -Ddns-over-tls=openssl" + "--optimization=3 -Dfexecve=true -Dstandalone-binaries=true -Dstatic-libsystemd=true -Dstatic-libudev=true" + "-Db_ndebug=true" +) +PACKAGES=( + cryptsetup-bin + expect + fdisk + gettext + iputils-ping + isc-dhcp-client + itstool + kbd + libblkid-dev + libbpf-dev + libcap-dev + libcurl4-gnutls-dev + libfdisk-dev + libfido2-dev + libgpg-error-dev + liblz4-dev + liblzma-dev + libmicrohttpd-dev + libmount-dev + libp11-kit-dev + libpwquality-dev + libqrencode-dev + libssl-dev + libtss2-dev + libxen-dev + libxkbcommon-dev + libxtables-dev + libzstd-dev + # mold + mount + net-tools + python3-evdev + python3-jinja2 + python3-lxml + python3-pefile + python3-pip + python3-pyelftools + python3-pyparsing + python3-setuptools + quota + strace + unifont + util-linux + zstd +) +COMPILER="${COMPILER:?}" +COMPILER_VERSION="${COMPILER_VERSION:?}" +LINKER="${LINKER:?}" +CRYPTOLIB="${CRYPTOLIB:?}" +RELEASE="$(lsb_release -cs)" + +# mold-2.2.0+ fixes some bugs breaking bootloader builds. +# TODO: Switch to distro mold with ubuntu-24.04 +if [[ "$LINKER" == mold ]]; then + wget https://github.com/rui314/mold/releases/download/v2.2.0/mold-2.2.0-x86_64-linux.tar.gz + echo "d66e0230c562c2ba0e0b789cc5034e0fa2369cc843d0154920de4269cd94afeb mold-2.2.0-x86_64-linux.tar.gz" | sha256sum -c + sudo tar -xz -C /usr --strip-components=1 -f mold-2.2.0-x86_64-linux.tar.gz +fi + +# Note: As we use postfixed clang/gcc binaries, we need to override $AR +# as well, otherwise meson falls back to ar from binutils which +# doesn't work with LTO +if [[ "$COMPILER" == clang ]]; then + CC="clang-$COMPILER_VERSION" + CXX="clang++-$COMPILER_VERSION" + AR="llvm-ar-$COMPILER_VERSION" + + # Prefer the distro version if available + if ! apt-get -y install --dry-run "llvm-$COMPILER_VERSION" >/dev/null; then + # Latest LLVM stack deb packages provided by https://apt.llvm.org/ + # Following snippet was partly borrowed from https://apt.llvm.org/llvm.sh + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | \ + sudo gpg --yes --dearmor --output /usr/share/keyrings/apt-llvm-org.gpg + echo "deb [signed-by=/usr/share/keyrings/apt-llvm-org.gpg] http://apt.llvm.org/$RELEASE/ llvm-toolchain-$RELEASE-$COMPILER_VERSION main" | \ + sudo tee /etc/apt/sources.list.d/llvm-toolchain.list + fi + + PACKAGES+=("clang-$COMPILER_VERSION" "lldb-$COMPILER_VERSION" "python3-lldb-$COMPILER_VERSION" "lld-$COMPILER_VERSION" "clangd-$COMPILER_VERSION") +elif [[ "$COMPILER" == gcc ]]; then + CC="gcc-$COMPILER_VERSION" + CXX="g++-$COMPILER_VERSION" + AR="gcc-ar-$COMPILER_VERSION" + + if ! apt-get -y install --dry-run "gcc-$COMPILER_VERSION" >/dev/null; then + # Latest gcc stack deb packages provided by + # https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test + sudo add-apt-repository -y --no-update ppa:ubuntu-toolchain-r/test + fi + + PACKAGES+=("gcc-$COMPILER_VERSION" "gcc-$COMPILER_VERSION-multilib") +else + fatal "Unknown compiler: $COMPILER" +fi + +# PPA with some newer build dependencies (like zstd) +sudo add-apt-repository -y --no-update ppa:upstream-systemd-ci/systemd-ci +sudo add-apt-repository -y --no-update --enable-source +sudo apt-get -y update +sudo apt-get -y build-dep systemd +sudo apt-get -y install "${PACKAGES[@]}" +# Install more or less recent meson and ninja with pip, since the distro versions don't +# always support all the features we need (like --optimization=). Since the build-dep +# command above installs the distro versions, let's install the pip ones just +# locally and add the local bin directory to the $PATH. +pip3 install --user -r .github/workflows/requirements.txt --require-hashes +export PATH="$HOME/.local/bin:$PATH" + +$CC --version +meson --version +ninja --version + +for args in "${ARGS[@]}"; do + SECONDS=0 + + info "Checking build with $args" + # shellcheck disable=SC2086 + if ! AR="$AR" \ + CC="$CC" CC_LD="$LINKER" CFLAGS="-Werror" \ + CXX="$CXX" CXX_LD="$LINKER" CXXFLAGS="-Werror" \ + meson setup \ + -Dtests=unsafe -Dslow-tests=true -Dfuzz-tests=true --werror \ + -Dnobody-group=nogroup -Dcryptolib="${CRYPTOLIB:?}" -Ddebug=false \ + $args build; then + + cat build/meson-logs/meson-log.txt + fatal "meson failed with $args" + fi + + if ! meson compile -C build -v; then + fatal "'meson compile' failed with '$args'" + fi + + for loader in build/src/boot/efi/*{.efi,.efi.stub}; do + if [[ "$(sbverify --list "$loader" 2>&1)" != "No signature table present" ]]; then + fatal "$loader: Gaps found in section table" + fi + done + + git clean -dxf + + success "Build with '$args' passed in $SECONDS seconds" +done diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml new file mode 100644 index 0000000..f91ac03 --- /dev/null +++ b/.github/workflows/build_test.yml @@ -0,0 +1,38 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# +name: Build test +on: + pull_request: + paths: + - '**/meson.build' + - '.github/workflows/**' + - 'meson_options.txt' + - 'src/**' + - 'test/fuzz/**' + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-22.04 + concurrency: + group: ${{ github.workflow }}-${{ toJSON(matrix.env) }}-${{ github.ref }} + cancel-in-progress: true + strategy: + fail-fast: false + matrix: + env: + - { COMPILER: "gcc", COMPILER_VERSION: "11", LINKER: "bfd", CRYPTOLIB: "gcrypt" } + - { COMPILER: "gcc", COMPILER_VERSION: "13", LINKER: "mold", CRYPTOLIB: "openssl" } + - { COMPILER: "clang", COMPILER_VERSION: "14", LINKER: "mold", CRYPTOLIB: "gcrypt" } + - { COMPILER: "clang", COMPILER_VERSION: "15", LINKER: "bfd", CRYPTOLIB: "openssl" } + - { COMPILER: "clang", COMPILER_VERSION: "17", LINKER: "lld", CRYPTOLIB: "auto" } + env: ${{ matrix.env }} + steps: + - name: Repository checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - name: Build check + run: .github/workflows/build_test.sh diff --git a/.github/workflows/cflite_pr.yml b/.github/workflows/cflite_pr.yml new file mode 100644 index 0000000..707ea0b --- /dev/null +++ b/.github/workflows/cflite_pr.yml @@ -0,0 +1,39 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# +name: ClusterFuzzLite PR fuzzing +on: + pull_request: + branches: + - main + - v[0-9]+-stable + +permissions: read-all + +jobs: + PR: + runs-on: ubuntu-latest + if: github.repository != 'systemd/systemd' || github.event.pull_request.user.login == 'dependabot[bot]' + concurrency: + group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }} + cancel-in-progress: true + strategy: + fail-fast: false + matrix: + sanitizer: [address, undefined, memory] + steps: + - name: Build Fuzzers + id: build + uses: google/clusterfuzzlite/actions/build_fuzzers@v1 + with: + sanitizer: ${{ matrix.sanitizer }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Run Fuzzers + id: run + uses: google/clusterfuzzlite/actions/run_fuzzers@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + fuzz-seconds: 1200 + mode: 'code-change' + sanitizer: ${{ matrix.sanitizer }} diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 0000000..66714c2 --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,74 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# See: https://google.github.io/oss-fuzz/getting-started/continuous-integration/ + +name: CIFuzz + +permissions: + contents: read + +on: + pull_request: + paths: + - '**/meson.build' + - '.github/workflows/**' + - 'meson_options.txt' + - 'src/**' + - 'test/fuzz/**' + - 'tools/oss-fuzz.sh' + push: + branches: + - main +jobs: + Fuzzing: + runs-on: ubuntu-latest + if: github.repository == 'systemd/systemd' + concurrency: + group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ matrix.architecture }}-${{ github.ref }} + cancel-in-progress: true + strategy: + fail-fast: false + matrix: + sanitizer: [address, undefined, memory] + architecture: [x86_64] + include: + - sanitizer: address + architecture: i386 + permissions: + security-events: write + + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'systemd' + dry-run: false + allowed-broken-targets-percentage: 0 + # keep-unaffected-fuzz-targets should be removed once https://github.com/google/oss-fuzz/issues/7011 is fixed + keep-unaffected-fuzz-targets: true + sanitizer: ${{ matrix.sanitizer }} + architecture: ${{ matrix.architecture }} + output-sarif: true + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'systemd' + fuzz-seconds: 600 + dry-run: false + sanitizer: ${{ matrix.sanitizer }} + output-sarif: true + - name: Upload Crash + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce + if: failure() && steps.build.outcome == 'success' + with: + name: ${{ matrix.sanitizer }}-${{ matrix.architecture }}-artifacts + path: ./out/artifacts + - name: Upload Sarif + if: always() && steps.build.outcome == 'success' + uses: github/codeql-action/upload-sarif@407ffafae6a767df3e0230c3df91b6443ae8df75 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: cifuzz-sarif/results.sarif + checkout_path: cifuzz-sarif diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..2c02ef5 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,59 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# +name: "CodeQL" + +on: + pull_request: + branches: + - main + - v[0-9]+-stable + paths: + - '**/meson.build' + - '.github/**/codeql*' + - 'src/**' + - 'test/**' + - 'tools/**' + push: + branches: + - main + - v[0-9]+-stable + +permissions: + contents: read + +jobs: + analyze: + name: Analyze + if: github.repository != 'systemd/systemd-security' + runs-on: ubuntu-22.04 + concurrency: + group: ${{ github.workflow }}-${{ matrix.language }}-${{ github.ref }} + cancel-in-progress: true + permissions: + actions: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: ['cpp', 'python'] + + steps: + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + + - name: Initialize CodeQL + uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql-config.yml + + - run: sudo -E .github/workflows/unit_tests.sh SETUP + + - name: Autobuild + uses: github/codeql-action/autobuild@407ffafae6a767df3e0230c3df91b6443ae8df75 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75 diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 0000000..1545d59 --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,30 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# +name: Coverity + +on: + schedule: + # Run Coverity daily at midnight + - cron: '0 0 * * *' + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-22.04 + if: github.repository == 'systemd/systemd' + env: + # Set in repo settings -> secrets -> actions + COVERITY_SCAN_TOKEN: "${{ secrets.COVERITY_SCAN_TOKEN }}" + COVERITY_SCAN_NOTIFICATION_EMAIL: "${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}" + steps: + - name: Repository checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + # Reuse the setup phase of the unit test script to avoid code duplication + - name: Install build dependencies + run: sudo -E .github/workflows/unit_tests.sh SETUP + - name: Build & upload the results + run: tools/coverity.sh diff --git a/.github/workflows/development_freeze.yml b/.github/workflows/development_freeze.yml new file mode 100644 index 0000000..e371e19 --- /dev/null +++ b/.github/workflows/development_freeze.yml @@ -0,0 +1,74 @@ +# doc: https://github.com/redhat-plumbers-in-action/devel-freezer#readme +--- + +name: Development Freeze +on: + workflow_run: + workflows: [ Gather Pull Request Metadata ] + types: + - completed + +env: + PULL_REQUEST_METADATA_DIR: pull_request + PULL_REQUEST_METADATA_FILE: metadata + +permissions: + contents: read + +jobs: + freezer: + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' && + github.repository == 'systemd/systemd' + runs-on: ubuntu-22.04 + + permissions: + pull-requests: write + + steps: + - name: Download Pull Request Metadata artifact + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + with: + script: | + const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.event.workflow_run.id }}, + }); + + const matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "${{ env.PULL_REQUEST_METADATA_FILE }}" + })[0]; + + const download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + + const fs = require('fs'); + fs.writeFileSync('${{ github.workspace }}/${{ env.PULL_REQUEST_METADATA_FILE }}.zip', Buffer.from(download.data)); + + - run: unzip ${{ env.PULL_REQUEST_METADATA_FILE }}.zip + + - name: 'Get Pull Request number' + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const pr_number = Number(fs.readFileSync('./${{ env.PULL_REQUEST_METADATA_FILE }}')); + core.exportVariable('pr_number', pr_number); + + - name: Repository checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + fetch-depth: 0 + + - name: Development Freezer + uses: redhat-plumbers-in-action/devel-freezer@67aec4a153bd9fca5322e1c4dd4d7c419fb36362 + with: + pr-number: ${{ env.pr_number }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml new file mode 100644 index 0000000..b04aabb --- /dev/null +++ b/.github/workflows/differential-shellcheck.yml @@ -0,0 +1,35 @@ +--- +# https://github.com/redhat-plumbers-in-action/differential-shellcheck#readme + +name: Differential ShellCheck +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + lint: + if: github.event.repository.name != 'systemd-security' + runs-on: ubuntu-latest + + permissions: + security-events: write + + steps: + - name: Repository checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + fetch-depth: 0 + + - name: Differential ShellCheck + uses: redhat-plumbers-in-action/differential-shellcheck@91e2582e40236f831458392d905578d680baa138 + with: + # exclude all `.in` files because they may contain unsupported syntax, and they have to be preprocessed first + exclude-path: '**/*.in' + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/gather-pr-metadata.yml b/.github/workflows/gather-pr-metadata.yml new file mode 100644 index 0000000..5b3c360 --- /dev/null +++ b/.github/workflows/gather-pr-metadata.yml @@ -0,0 +1,37 @@ +--- + +name: Gather Pull Request Metadata + +on: + pull_request: + branches: [ main ] + +env: + PULL_REQUEST_METADATA_DIR: pull_request + PULL_REQUEST_METADATA_FILE: metadata + +permissions: + contents: read + +jobs: + gather-metadata: + if: github.repository == 'systemd/systemd' + runs-on: ubuntu-22.04 + + steps: + - name: Repository checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + fetch-depth: 0 + + - name: Store PR number in file + run: | + mkdir -p ./${{ env.PULL_REQUEST_METADATA_DIR }} + echo ${{ github.event.number }} >./${{ env.PULL_REQUEST_METADATA_DIR }}/${{ env.PULL_REQUEST_METADATA_FILE }} + + - name: Upload Pull Request Metadata artifact + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce + with: + name: ${{ env.PULL_REQUEST_METADATA_FILE }} + path: ${{ env.PULL_REQUEST_METADATA_DIR }} + retention-days: 1 diff --git a/.github/workflows/issue_labeler.yml b/.github/workflows/issue_labeler.yml new file mode 100644 index 0000000..d8ba0a5 --- /dev/null +++ b/.github/workflows/issue_labeler.yml @@ -0,0 +1,36 @@ +--- + +name: Issue labeler +on: + issues: + types: [ opened ] + +permissions: + contents: read + +jobs: + label-component: + runs-on: ubuntu-22.04 + + permissions: + issues: write + + strategy: + matrix: + template: [ bug_report.yml, feature_request.yml ] + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + + - name: Parse issue form + uses: stefanbuck/github-issue-parser@c1a559d78bfb8dd05216dab9ffd2b91082ff5324 + id: issue-parser + with: + template-path: .github/ISSUE_TEMPLATE/${{ matrix.template }} + + - name: Set labels based on component field + uses: redhat-plumbers-in-action/advanced-issue-labeler@71bcf99aef4b9ea844db9a43755e8ac02c8e661e + with: + issue-form: ${{ steps.issue-parser.outputs.jsonString }} + template: ${{ matrix.template }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000..7f66a53 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,119 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# +name: "Pull Request Labeler" + +on: + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review, closed] + issue_comment: + types: [created] + +permissions: + contents: read + +jobs: + triage: + if: github.repository == 'systemd/systemd' + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - name: Label PR based on policy in labeler.yml + uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 + if: github.event_name == 'pull_request_target' && github.event.action != 'closed' + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: .github/labeler.yml + sync-labels: "" # This is a workaround for issue 18671 + + - name: Set or remove labels based on systemd development workflow + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + if: github.event_name == 'pull_request_target' && github.event.action != 'closed' && !github.event.pull_request.draft + with: + script: | + response = await github.rest.issues.listLabelsOnIssue({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + }); + + good_to_merge = [ + "good-to-merge/waiting-for-ci 👍", + "good-to-merge/after-next-release", + "good-to-merge/with-minor-suggestions", + "good-to-merge/waiting-for-reporter-feedback 👍", + ]; + + if (response.data.every(l => !good_to_merge.includes(l.name))) { + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ["please-review"] + }); + } + + for (const label of ["reviewed/needs-rework 🔨", + "ci-fails/needs-rework 🔥", + "ci-failure-appears-unrelated", + "needs-rebase"]) { + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: label, + }); + } catch (err) { + if (err.status != 404) { + throw err; + } + } + } + + - name: Add please-review label on command in issue comment + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + if: github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/please-review') + with: + script: | + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ["please-review"] + }) + + - name: Remove specific labels when PR is closed or merged + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + if: github.event_name == 'pull_request_target' && github.event.action == 'closed' + with: + script: | + for (const label of ["please-review", + "reviewed/needs-rework 🔨", + "ci-fails/needs-rework 🔥", + "needs-rebase", + "good-to-merge/waiting-for-ci 👍", + "good-to-merge/after-next-release", + "good-to-merge/with-minor-suggestions", + "good-to-merge/waiting-for-reporter-feedback 👍", + "needs-discussion 🤔", + "needs-reporter-feedback ❓", + "dont-merge 💣", + "squash-on-merge", + "quick-review 🏃♂️"]) { + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: label, + }); + } catch (err) { + if (err.status != 404) { + throw err; + } + } + } diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml new file mode 100644 index 0000000..fd1a7a4 --- /dev/null +++ b/.github/workflows/linter.yml @@ -0,0 +1,36 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# https://github.com/marketplace/actions/super-linter +name: Lint Code Base + +on: + pull_request: + branches: + - main + - v[0-9]+-stable + +permissions: + contents: read + +jobs: + build: + name: Lint Code Base + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + steps: + - name: Repo checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + # We need a full repo clone + fetch-depth: 0 + + - name: Lint Code Base + uses: github/super-linter/slim@45fc0d88288beee4701c62761281edfee85655d7 + env: + DEFAULT_BRANCH: main + VALIDATE_ALL_CODEBASE: false + VALIDATE_GITHUB_ACTIONS: true diff --git a/.github/workflows/make_release.yml b/.github/workflows/make_release.yml new file mode 100644 index 0000000..9902a6c --- /dev/null +++ b/.github/workflows/make_release.yml @@ -0,0 +1,24 @@ +name: Make a Github release + +on: + push: + tags: + - "v*" + +permissions: + contents: read + +jobs: + release: + if: github.repository == 'systemd/systemd' || github.repository == 'systemd/systemd-stable' + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - name: Release + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 + with: + prerelease: ${{ contains(github.ref_name, '-rc') }} + draft: ${{ github.repository == 'systemd/systemd' }} diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml new file mode 100644 index 0000000..8b32ec8 --- /dev/null +++ b/.github/workflows/mkosi.yml @@ -0,0 +1,143 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# Simple boot tests that build and boot the mkosi images generated by the mkosi config files in mkosi.conf.d/. +name: mkosi + +on: + push: + branches: + - main + - v[0-9]+-stable + paths: + - '**' + - '!README*' + - '!LICENSE*' + - '!LICENSES/**' + - '!TODO' + - '!docs/**' + - '!man/**' + - '!catalog/**' + - '!shell-completion/**' + - '!po/**' + - '!.**' + - '.github/**' + + pull_request: + branches: + - main + - v[0-9]+-stable + paths: + - '**' + - '!README*' + - '!LICENSE*' + - '!LICENSES/**' + - '!TODO' + - '!docs/**' + - '!man/**' + - '!catalog/**' + - '!shell-completion/**' + - '!po/**' + - '!.**' + - '.github/**' + +permissions: + contents: read + +jobs: + ci: + runs-on: ubuntu-22.04 + concurrency: + group: ${{ github.workflow }}-${{ matrix.distro }}-${{ matrix.release }}-${{ github.ref }} + cancel-in-progress: true + strategy: + fail-fast: false + matrix: + include: + - distro: arch + release: rolling + - distro: debian + release: testing + - distro: ubuntu + release: jammy + - distro: fedora + release: "39" + - distro: fedora + release: rawhide + - distro: opensuse + release: tumbleweed + - distro: centos + release: "9" + - distro: centos + release: "8" + + env: + SYSTEMD_LOG_LEVEL: debug + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: systemd/mkosi@bbe715f42911f9660712377a5b39335b9391ae22 + + - name: Configure + run: | + tee mkosi.local.conf <<- EOF + [Distribution] + Distribution=${{ matrix.distro }} + Release=${{ matrix.release }} + EOF + + tee mkosi.conf.d/99-ci.conf <<- EOF + [Content] + Environment=CI_BUILD=1 + SLOW_TESTS=true + + [Host] + KernelCommandLineExtra=systemd.unit=mkosi-check-and-shutdown.service + systemd.journald.max_level_console=debug + # udev's debug log output is very verbose, so up it to info in CI. + udev.log_level=info + # Root device can take a long time to appear, so let's bump the timeout. + systemd.default_device_timeout_sec=180 + QemuVsock=yes + # Sometimes we run on a host with /dev/kvm, but it is broken, so explicitly disable it + QemuKvm=no + Ephemeral=yes + EOF + + # For erofs, we have to install linux-modules-extra-azure, but that doesn't match the running kernel + # version, so we can't load the erofs module. squashfs is a builtin module so we use that instead. + + mkdir -p mkosi.images/system/mkosi.repart/10-usr.conf.d + tee mkosi.images/system/mkosi.repart/10-usr.conf.d/squashfs.conf <<- EOF + [Partition] + Format=squashfs + EOF + + # The emergency shell is not useful in the CI, as it just blocks for a long time before the job + # eventually times out. Override it to just shutdown immediately. + mkdir -p mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/ + mkdir -p mkosi.images/system/mkosi.extra/usr/lib/systemd/system/emergency.service.d/ + tee mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf <<- EOF + [Unit] + FailureAction=exit + [Service] + ExecStartPre= + ExecStart= + ExecStart=false + EOF + cp mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf mkosi.images/system/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf + + - name: Generate secure boot key + run: mkosi --debug genkey + + - name: Show image summary + run: mkosi summary + + - name: Build + run: mkosi --debug + + - name: Boot systemd-nspawn + run: test "$(sudo mkosi --debug boot 1>&2; echo $?)" -eq 123 + + - name: Boot QEMU + run: timeout -k 30 10m test "$(mkosi --debug qemu 1>&2; echo $?)" -eq 123 diff --git a/.github/workflows/requirements.txt b/.github/workflows/requirements.txt new file mode 100644 index 0000000..b42b98e --- /dev/null +++ b/.github/workflows/requirements.txt @@ -0,0 +1,19 @@ +meson==1.3.0 \ + --hash=sha256:4ba253ef60e454e23234696119cbafa082a0aead0bd3bbf6991295054795f5dc \ + --hash=sha256:e9f54046ce5b9a1f3024f7a7d52f19f085fd57c9d26a5db0cfcf0750572a8fd8 +ninja==1.11.1.1 \ + --hash=sha256:18302d96a5467ea98b68e1cae1ae4b4fb2b2a56a82b955193c637557c7273dbd \ + --hash=sha256:185e0641bde601e53841525c4196278e9aaf4463758da6dd1e752c0a0f54136a \ + --hash=sha256:376889c76d87b95b5719fdd61dd7db193aa7fd4432e5d52d2e44e4c497bdbbee \ + --hash=sha256:3e0f9be5bb20d74d58c66cc1c414c3e6aeb45c35b0d0e41e8d739c2c0d57784f \ + --hash=sha256:73b93c14046447c7c5cc892433d4fae65d6364bec6685411cb97a8bcf815f93a \ + --hash=sha256:7563ce1d9fe6ed5af0b8dd9ab4a214bf4ff1f2f6fd6dc29f480981f0f8b8b249 \ + --hash=sha256:76482ba746a2618eecf89d5253c0d1e4f1da1270d41e9f54dfbd91831b0f6885 \ + --hash=sha256:84502ec98f02a037a169c4b0d5d86075eaf6afc55e1879003d6cab51ced2ea4b \ + --hash=sha256:95da904130bfa02ea74ff9c0116b4ad266174fafb1c707aa50212bc7859aebf1 \ + --hash=sha256:9d793b08dd857e38d0b6ffe9e6b7145d7c485a42dcfea04905ca0cdb6017cc3c \ + --hash=sha256:9df724344202b83018abb45cb1efc22efd337a1496514e7e6b3b59655be85205 \ + --hash=sha256:aad34a70ef15b12519946c5633344bc775a7656d789d9ed5fdb0d456383716ef \ + --hash=sha256:d491fc8d89cdcb416107c349ad1e3a735d4c4af5e1cb8f5f727baca6350fdaea \ + --hash=sha256:ecf80cf5afd09f14dcceff28cb3f11dc90fb97c999c89307aea435889cb66877 \ + --hash=sha256:fa2ba9d74acfdfbfbcf06fad1b8282de8a7a8c481d9dee45c859a8c93fcc1082 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 0000000..e2a9f27 --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,41 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +name: Scorecards supply-chain security +on: + # Only the default branch is supported. + branch_protection_rule: + schedule: + - cron: '15 21 * * 6' + push: + branches: + - main + pull_request: + branches: + - main + paths: + - '.github/workflows/scorecards.yml' + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecards analysis + if: github.repository == 'systemd/systemd' + runs-on: ubuntu-latest + permissions: + id-token: write # Used to receive a badge. + + steps: + - name: Checkout code + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false + + - name: Run analysis + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + with: + results_file: results.sarif + results_format: sarif + publish_results: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh new file mode 100755 index 0000000..c1a5ede --- /dev/null +++ b/.github/workflows/unit_tests.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later + +# shellcheck disable=SC2206 +PHASES=(${@:-SETUP RUN RUN_ASAN_UBSAN CLEANUP}) +ADDITIONAL_DEPS=( + clang + expect + fdisk + jekyll + libbpf-dev + libfdisk-dev + libfido2-dev + libp11-kit-dev + libpwquality-dev + libqrencode-dev + libssl-dev + libtss2-dev + libxkbcommon-dev + libzstd-dev + python3-libevdev + python3-pefile + python3-pyelftools + python3-pyparsing + python3-pytest + rpm + zstd +) + +function info() { + echo -e "\033[33;1m$1\033[0m" +} + +function run_meson() { + if ! meson "$@"; then + find . -type f -name meson-log.txt -exec cat '{}' + + return 1 + fi +} + +set -ex + +MESON_ARGS=(-Dcryptolib=${CRYPTOLIB:-auto}) + +for phase in "${PHASES[@]}"; do + case $phase in + SETUP) + info "Setup phase" + # PPA with some newer build dependencies + add-apt-repository -y --no-update ppa:upstream-systemd-ci/systemd-ci + add-apt-repository -y --no-update --enable-source + apt-get -y update + apt-get -y build-dep systemd + apt-get -y install "${ADDITIONAL_DEPS[@]}" + pip3 install -r .github/workflows/requirements.txt --require-hashes + ;; + RUN|RUN_GCC|RUN_CLANG|RUN_CLANG_RELEASE) + if [[ "$phase" =~ ^RUN_CLANG ]]; then + export CC=clang + export CXX=clang++ + if [[ "$phase" == RUN_CLANG ]]; then + # The docs build is slow and is not affected by compiler/flags, so do it just once + MESON_ARGS+=(-Dman=enabled) + else + MESON_ARGS+=(-Dmode=release --optimization=2) + fi + + # Some variation: remove machine-id, like on Debian builders to ensure unit tests still work. + if [ -w /etc/machine-id ]; then + mv /etc/machine-id /etc/machine-id.bak + fi + fi + MESON_ARGS+=(--fatal-meson-warnings) + run_meson -Dnobody-group=nogroup --werror -Dtests=unsafe -Dslow-tests=true -Dfuzz-tests=true "${MESON_ARGS[@]}" build + ninja -C build -v + # Ensure setting a timezone (like the reproducible build tests do) does not break time/date unit tests + TZ=GMT+12 meson test -C build --print-errorlogs + ;; + RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN_NO_DEPS) + MESON_ARGS=(--optimization=1) + + if [[ "$phase" =~ ^RUN_CLANG_ASAN_UBSAN ]]; then + export CC=clang + export CXX=clang++ + # Build fuzzer regression tests only with clang (for now), + # see: https://github.com/systemd/systemd/pull/15886#issuecomment-632689604 + # -Db_lundef=false: See https://github.com/mesonbuild/meson/issues/764 + MESON_ARGS+=(-Db_lundef=false -Dfuzz-tests=true) + + if [[ "$phase" == "RUN_CLANG_ASAN_UBSAN_NO_DEPS" ]]; then + MESON_ARGS+=(--auto-features=disabled) + fi + fi + MESON_ARGS+=(--fatal-meson-warnings) + run_meson -Dnobody-group=nogroup --werror -Dtests=unsafe -Db_sanitize=address,undefined "${MESON_ARGS[@]}" build + ninja -C build -v + + export ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 + # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb. + export UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 + + # FIXME + # For some strange reason the GH Actions VM stops responding after + # executing first ~150 tests, _unless_ there's something producing + # output (either running `meson test` in verbose mode, or something + # else in background). Despite my efforts so far I haven't been able + # to identify the culprit (since the issue is not reproducible + # during debugging, wonderful), so let's at least keep a workaround + # here to make the builds stable for the time being. + (set +x; while :; do echo -ne "\n[WATCHDOG] $(date)\n"; sleep 30; done) & + meson test --timeout-multiplier=3 -C build --print-errorlogs + ;; + CLEANUP) + info "Cleanup phase" + if [ ! -f /etc/machine-id ] && [ -w /etc/machine-id.bak ]; then + mv /etc/machine-id.bak /etc/machine-id + fi + ;; + *) + echo >&2 "Unknown phase '$phase'" + exit 1 + esac +done diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 0000000..d2164cc --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,45 @@ +--- +# vi: ts=2 sw=2 et: +# SPDX-License-Identifier: LGPL-2.1-or-later +# +name: Unit tests +on: + pull_request: + branches: + - main + - v[0-9]+-stable + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-22.04 + concurrency: + group: ${{ github.workflow }}-${{ matrix.run_phase }}-${{ matrix.cryptolib }}-${{ github.ref }} + cancel-in-progress: true + strategy: + fail-fast: false + matrix: + run_phase: [GCC, GCC_ASAN_UBSAN, CLANG, CLANG_RELEASE, CLANG_ASAN_UBSAN, CLANG_ASAN_UBSAN_NO_DEPS] + cryptolib: [auto] + include: + - run_phase: GCC + cryptolib: openssl + - run_phase: CLANG + cryptolib: gcrypt + steps: + - name: Repository checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - name: Install build dependencies + run: | + # Drop XDG_* stuff from /etc/environment, so we don't get the user + # XDG_* variables when running under sudo + sudo sed -i '/^XDG_/d' /etc/environment + # Pass only specific env variables through sudo, to avoid having + # the already existing XDG_* stuff on the "other side" + sudo --preserve-env=CRYPTOLIB,GITHUB_ACTIONS,CI .github/workflows/unit_tests.sh SETUP + - name: Build & test + run: sudo --preserve-env=CRYPTOLIB,GITHUB_ACTIONS,CI .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }} + env: + CRYPTOLIB: ${{ matrix.cryptolib }} |