Test installing ca-certificates temporarily #3867
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: QA & sanity checks | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - '.github/workflows/automatic-doc-checks.yml' | |
| - '.readthedocs.yaml' | |
| - 'docs/**' | |
| tags: | |
| - "*" | |
| pull_request: | |
| paths-ignore: | |
| - '.github/workflows/automatic-doc-checks.yml' | |
| - '.readthedocs.yaml' | |
| - 'docs/**' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| GO_TESTS_TIMEOUT: 20m | |
| c_build_dependencies: >- | |
| clang-tools | |
| clang | |
| libglib2.0-dev | |
| libpam-dev | |
| go_build_dependencies: >- | |
| libglib2.0-dev | |
| libpam-dev | |
| libpwquality-dev | |
| go_test_dependencies: >- | |
| apparmor-profiles | |
| bubblewrap | |
| cracklib-runtime | |
| git-delta | |
| openssh-client | |
| openssh-server | |
| jobs: | |
| go-sanity: | |
| name: "Go: Code sanity" | |
| permissions: {} | |
| runs-on: ubuntu-24.04 # ubuntu-latest-runner | |
| steps: | |
| - uses: canonical/desktop-engineering/gh-actions/common/dpkg-install-speedup@main | |
| - name: Install dependencies | |
| run: | | |
| # Install dependencies | |
| set -eu | |
| sudo apt-get update | |
| sudo apt-get install -y ${{ env.go_build_dependencies }} | |
| - uses: actions/checkout@v5 | |
| - name: Go code sanity check | |
| uses: canonical/desktop-engineering/gh-actions/go/code-sanity@v2 | |
| with: | |
| golangci-lint-configfile: ".golangci.yaml" | |
| tools-directory: "tools" | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build cmd/authd with withexamplebroker tag | |
| run: | | |
| set -eu | |
| go build -tags withexamplebroker ./cmd/authd | |
| - name: Run PAM client for interactive testing purposes | |
| run: | | |
| set -eu | |
| go run -tags withpamrunner ./pam/tools/pam-runner login --exec-debug | |
| - name: Generate PAM module | |
| run: | | |
| set -eu | |
| find pam -name '*.so' -print -delete | |
| go generate -C pam -x | |
| test -e pam/pam_authd.so | |
| test -e pam/go-exec/pam_authd_exec.so | |
| - name: Generate PAM module with pam_debug tag | |
| run: | | |
| set -eu | |
| find pam -name '*.so' -print -delete | |
| go generate -C pam -x -tags pam_debug | |
| test -e pam/pam_authd.so | |
| test -e pam/go-exec/pam_authd_exec.so | |
| rust-sanity: | |
| name: "Rust: Code sanity" | |
| permissions: {} | |
| runs-on: ubuntu-24.04 # ubuntu-latest-runner | |
| steps: | |
| - uses: canonical/desktop-engineering/gh-actions/common/dpkg-install-speedup@main | |
| - name: Install dependencies | |
| run: | | |
| # Install dependencies | |
| set -eu | |
| sudo apt-get update | |
| # In Rust the grpc stubs are generated at build time | |
| # so we always need to install the protobuf compilers | |
| # when building the NSS crate. | |
| sudo apt-get install -y protobuf-compiler | |
| - uses: actions/checkout@v5 | |
| - name: Rust code sanity check | |
| uses: canonical/desktop-engineering/gh-actions/rust/code-sanity@main | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| c-sanity: | |
| name: "C Code sanity" | |
| runs-on: ubuntu-24.04 # ubuntu-latest-runner | |
| env: | |
| CFLAGS: "-Werror" | |
| steps: | |
| - uses: canonical/desktop-engineering/gh-actions/common/dpkg-install-speedup@main | |
| - name: Install dependencies | |
| run: | | |
| # Install dependencies | |
| set -eu | |
| sudo apt-get update | |
| sudo apt-get install -y ${{ env.c_build_dependencies }} | |
| - name: Prepare report dir | |
| run: | | |
| set -eu | |
| scan_build_dir=$(mktemp -d --tmpdir scan-build-dir-XXXXXX) | |
| echo SCAN_BUILD_REPORTS_PATH="${scan_build_dir}" >> $GITHUB_ENV | |
| - uses: actions/checkout@v5 | |
| - name: Run scan build on GDM extensions | |
| run: | | |
| set -eu | |
| scan-build -v -o "${SCAN_BUILD_REPORTS_PATH}" clang ${CFLAGS} \ | |
| -Wno-gnu-variable-sized-type-not-at-end \ | |
| pam/internal/gdm/extension.h | |
| - name: Run scan build on go-exec module | |
| run: | | |
| set -eu | |
| scan-build -v -o "${SCAN_BUILD_REPORTS_PATH}" clang ${CFLAGS} \ | |
| -DAUTHD_TEST_MODULE=1 \ | |
| $(pkg-config --cflags --libs gio-unix-2.0 gio-2.0) \ | |
| -lpam -shared -fPIC \ | |
| pam/go-exec/module.c | |
| - name: Upload scan build reports | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: authd-${{ github.job }}-artifacts-${{ github.run_attempt }} | |
| path: ${{ env.SCAN_BUILD_REPORTS_PATH }} | |
| go-tests: | |
| name: "Go: Tests" | |
| runs-on: ubuntu-24.04 # ubuntu-latest-runner | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| test: ["coverage", "race", "asan"] | |
| steps: | |
| - uses: canonical/desktop-engineering/gh-actions/common/dpkg-install-speedup@main | |
| - name: Install dependencies | |
| run: | | |
| # Install dependencies | |
| set -eu | |
| sudo apt-get update | |
| # The integration tests build the NSS crate, so we need the cargo build dependencies in order to run them. | |
| sudo apt-get install -y protobuf-compiler | |
| sudo apt-get install -y ${{ env.go_build_dependencies }} ${{ env.go_test_dependencies}} | |
| # Load the apparmor profile for bubblewrap. | |
| sudo ln -s /usr/share/apparmor/extra-profiles/bwrap-userns-restrict /etc/apparmor.d/ | |
| sudo apparmor_parser /etc/apparmor.d/bwrap-userns-restrict | |
| - name: Install glibc, PAM and GLib debug symbols | |
| continue-on-error: true | |
| run: | | |
| set -eu | |
| sudo apt-get install -y ubuntu-dbgsym-keyring libc6-dbg | |
| echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse | |
| deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse | |
| deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \ | |
| sudo tee -a /etc/apt/sources.list.d/ddebs.list | |
| # Sometimes ddebs archive is stuck, so in case of failure we need to go manual | |
| sudo apt-get update -y || true | |
| if ! sudo apt-get install -y libpam-modules-dbgsym libpam0*-dbgsym libglib2.0-0*-dbgsym; then | |
| sudo apt-get install -y ubuntu-dev-tools | |
| for pkg in pam glib2.0; do | |
| pull-lp-debs "${pkg}" $(lsb_release -cs) | |
| pull-lp-ddebs "${pkg}" $(lsb_release -cs) | |
| done | |
| sudo apt-get install -y ./libpam0*.*deb ./libpam-modules*.*deb ./libglib2.0-0*-dbgsym*.ddeb | |
| sudo apt-get remove -y ubuntu-dev-tools | |
| sudo apt-get autoremove -y | |
| fi | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Install gotestfmt and our wrapper script | |
| uses: canonical/desktop-engineering/gh-actions/go/gotestfmt@main | |
| - name: Install VHS and ttyd for integration tests | |
| run: | | |
| set -eu | |
| go install github.com/charmbracelet/vhs@latest | |
| # VHS requires ttyd >= 1.7.2 to work properly. | |
| wget https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64 | |
| chmod +x ttyd.x86_64 | |
| sudo mv ttyd.x86_64 /usr/bin/ttyd | |
| # VHS doesn't really use ffmpeg anymore now, but it still checks for it. | |
| # Drop this when https://github.com/charmbracelet/vhs/pull/591 is released. | |
| sudo ln -s /usr/bin/true /usr/local/bin/ffmpeg | |
| - name: Install latest Rust version | |
| run: rustup update stable | |
| - name: Install grcov | |
| if: matrix.test == 'coverage' | |
| uses: baptiste0928/cargo-install@v3 | |
| with: | |
| crate: grcov | |
| - name: Prepare tests artifacts path | |
| run: | | |
| set -eu | |
| artifacts_dir=$(mktemp -d --tmpdir authd-test-artifacts-XXXXXX) | |
| echo AUTHD_TESTS_ARTIFACTS_PATH="${artifacts_dir}" >> $GITHUB_ENV | |
| echo ASAN_OPTIONS="log_path=${artifacts_dir}/asan.log:print_stats=true" >> $GITHUB_ENV | |
| - name: Install coverage collection dependencies | |
| if: matrix.test == 'coverage' | |
| run: | | |
| set -eu | |
| # Dependendencies for C coverage collection | |
| sudo apt-get install -y gcovr | |
| # Dependendencies for Go coverage collection | |
| go install github.com/AlekSi/gocov-xml@latest | |
| go install github.com/axw/gocov/gocov@latest | |
| dotnet tool install -g dotnet-reportgenerator-globaltool | |
| - name: Run tests (with coverage collection) | |
| if: matrix.test == 'coverage' | |
| env: | |
| G_DEBUG: "fatal-criticals" | |
| run: | | |
| set -euo pipefail | |
| # The coverage is not written if the output directory does not exist, so we need to create it. | |
| cov_dir=${PWD}/coverage | |
| codecov_dir=${cov_dir}/codecov | |
| raw_cov_dir=${cov_dir}/raw | |
| mkdir -p "${raw_cov_dir}" "${codecov_dir}" | |
| # Print executed commands to ease debugging | |
| set -x | |
| # Work around https://github.com/golang/go/issues/75031 | |
| go env -w GOTOOLCHAIN="$(go version | awk '{ print $3 }')+auto" | |
| # Overriding the default coverage directory is not an exported flag of go test (yet), so | |
| # we need to override it using the test.gocoverdir flag instead. | |
| #TODO: Update when https://go-review.googlesource.com/c/go/+/456595 is merged. | |
| go test -json -timeout ${GO_TESTS_TIMEOUT} -cover -covermode=set ./... -coverpkg=./... \ | |
| -shuffle=on -failfast -args -test.gocoverdir="${raw_cov_dir}" | \ | |
| gotestfmt --logfile "${AUTHD_TESTS_ARTIFACTS_PATH}/gotestfmt.cover.log" | |
| # Convert the raw coverage data into textfmt so we can merge the Rust one into it | |
| go tool covdata textfmt -i="${raw_cov_dir}" -o="${cov_dir}/coverage.out" | |
| # Append the Rust coverage data to the Go one | |
| cat "${raw_cov_dir}/rust-cov/rust2go_coverage" >>"${cov_dir}/coverage.out" | |
| # Filter out the testutils package and the pb.go file | |
| grep -v -e "testutils" -e "pb.go" -e "testsdetection" "${cov_dir}/coverage.out" >"${cov_dir}/coverage.out.filtered" | |
| # Generate the Cobertura report for Go and Rust | |
| gocov convert "${cov_dir}/coverage.out.filtered" | gocov-xml > "${cov_dir}/coverage.xml" | |
| reportgenerator -reports:"${cov_dir}/coverage.xml" -targetdir:"${cov_dir}" -reporttypes:Cobertura | |
| # Generate the Cobertura report for C | |
| gcovr --cobertura "${cov_dir}/Cobertura_C.xml" "${raw_cov_dir}" | |
| # Merge Cobertura reports into a single one | |
| reportgenerator -reports:"${cov_dir}/Cobertura.xml;${cov_dir}/Cobertura_C.xml" \ | |
| -targetdir:"${codecov_dir}" -reporttypes:Cobertura | |
| # Store the coverage directory for the next steps | |
| echo COVERAGE_DIR="${codecov_dir}" >> ${GITHUB_ENV} | |
| - name: Run tests (with race detector) | |
| if: matrix.test == 'race' | |
| env: | |
| GO_TESTS_TIMEOUT: 35m | |
| AUTHD_TESTS_SLEEP_MULTIPLIER: 3 | |
| GORACE: log_path=${{ env.AUTHD_TESTS_ARTIFACTS_PATH }}/gorace.log | |
| run: | | |
| go test -json -timeout ${GO_TESTS_TIMEOUT} -race -failfast ./... | \ | |
| gotestfmt --logfile "${AUTHD_TESTS_ARTIFACTS_PATH}/gotestfmt.race.log" || exit_code=$? | |
| if [ "${exit_code:-0}" -ne 0 ]; then | |
| cat "${AUTHD_TESTS_ARTIFACTS_PATH}"/gorace.log* || true | |
| exit ${exit_code} | |
| fi | |
| - name: Run PAM tests (with Address Sanitizer) | |
| if: matrix.test == 'asan' | |
| env: | |
| # Do not optimize, keep debug symbols and frame pointer for better | |
| # stack trace information in case of ASAN errors. | |
| CGO_CFLAGS: "-O0 -g3 -fno-omit-frame-pointer" | |
| G_DEBUG: "fatal-criticals" | |
| GO_TESTS_TIMEOUT: 30m | |
| AUTHD_TESTS_SLEEP_MULTIPLIER: 1.5 | |
| # Use these flags to give ASAN a better time to unwind the stack trace | |
| GO_GC_FLAGS: -N -l | |
| run: | | |
| # Print executed commands to ease debugging | |
| set -x | |
| # For llvm-symbolizer | |
| sudo apt-get install -y llvm | |
| go test -C ./pam/internal -json -asan -gcflags=all="${GO_GC_FLAGS}" -failfast -timeout ${GO_TESTS_TIMEOUT} ./... | \ | |
| gotestfmt --logfile "${AUTHD_TESTS_ARTIFACTS_PATH}/gotestfmt.pam-internal-asan.log" || exit_code=$? | |
| if [ -n "${exit_code:-}" ]; then | |
| cat "${AUTHD_TESTS_ARTIFACTS_PATH}"/asan.log* || true | |
| exit ${exit_code} | |
| fi | |
| echo "Running PAM integration tests" | |
| pushd ./pam/integration-tests | |
| go test -asan -gcflags=all="${GO_GC_FLAGS}" -c | |
| go tool test2json -p pam/integrations-test ./integration-tests.test \ | |
| -test.v=test2json \ | |
| -test.failfast \ | |
| -test.timeout ${GO_TESTS_TIMEOUT} | \ | |
| gotestfmt --logfile "${AUTHD_TESTS_ARTIFACTS_PATH}/gotestfmt.pam-integration-tests-asan.log" || \ | |
| exit_code=$? | |
| popd | |
| # We don't need the xtrace output after this point | |
| set +x | |
| # We're logging to a file, and this is useful for having artifacts, but we still may want to see it in logs: | |
| for f in "${AUTHD_TESTS_ARTIFACTS_PATH}"/asan.log*; do | |
| if ! [ -e "${f}" ]; then | |
| continue | |
| fi | |
| if [ -s "${f}" ]; then | |
| echo "::group::${f} ($(wc -l < "${f}") lines)" | |
| cat "${f}" | |
| echo "::endgroup::" | |
| else | |
| echo "${f}: empty" | |
| fi | |
| done | |
| exit ${exit_code} | |
| - name: Upload coverage to Codecov | |
| if: matrix.test == 'coverage' | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| directory: ${{ env.COVERAGE_DIR }} | |
| files: ${{ env.COVERAGE_DIR }}/Cobertura.xml | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Upload coverage artifacts | |
| if: matrix.test == 'coverage' && github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage | |
| path: ${{ env.COVERAGE_DIR }} | |
| - name: Upload test artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: authd-${{ github.job }}-${{ matrix.test }}-artifacts-${{ github.run_attempt }} | |
| path: ${{ env.AUTHD_TESTS_ARTIFACTS_PATH }} |