From 8f8b26e5ede3749ae4368fac7d8cd66f8de5bb6a Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Wed, 14 Jan 2026 15:34:17 +0100 Subject: [PATCH 01/11] Pair the ATEX tests with the packit testing farm tests. --- .github/workflows/atex-test.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/atex-test.yaml b/.github/workflows/atex-test.yaml index 86bb59cbaa46..90496ff3133a 100644 --- a/.github/workflows/atex-test.yaml +++ b/.github/workflows/atex-test.yaml @@ -105,8 +105,7 @@ jobs: python3 tests/run_tests_testingfarm.py \ --contest-dir contest \ --content-dir content-centos-stream${CS_MAJOR} \ - --plan "/plans/daily" \ - --tests "/hardening/host-os/oscap/stig" \ + --plan "/plans/upstream" \ --compose "CentOS-Stream-${CS_MAJOR}" \ --arch x86_64 \ --os-major-version "${CS_MAJOR}" \ From b4f060de2675a79aee00f30acfc7b2ad48817fa1 Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Wed, 14 Jan 2026 16:08:41 +0100 Subject: [PATCH 02/11] Remove obsolete packit testing farm tests. Those tests should now be covered by ATEX testing. --- .packit.yaml | 129 +----------------------------------- tests/tmt/plans/contest.fmf | 116 -------------------------------- 2 files changed, 3 insertions(+), 242 deletions(-) diff --git a/.packit.yaml b/.packit.yaml index 2e9ab02c8b3a..ecbdaf531210 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -15,144 +15,21 @@ jobs: trigger: pull_request targets: - fedora-all-x86_64 - - centos-stream-8-x86_64 - - centos-stream-9-x86_64 - - centos-stream-10-x86_64 - <<: *build trigger: commit branch: "gh-readonly-queue/.*" -- &test-static-checks +# when modifying this, modify also tests/tmt-plans/ +- &fedora-tests job: tests trigger: pull_request fmf_path: tests/tmt - identifier: /static-checks - tmt_plan: /plans/contest/static-checks$ - targets: - centos-stream-8: {} - centos-stream-9: {} - centos-stream-10: {} - -# when modifying this, modify also tests/tmt-plans/ - -- <<: *test-static-checks identifier: /rpmbuild-ctest-fedora tmt_plan: /plans/contest/rpmbuild-ctest-fedora$ targets: fedora-all: {} -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/anssi_bp28_high - tmt_plan: /plans/contest/hardening/host-os/ansible/anssi_bp28_high$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/bsi - tmt_plan: /plans/contest/hardening/host-os/ansible/bsi$ - targets: - centos-stream-9: {} -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/ccn_advanced - tmt_plan: /plans/contest/hardening/host-os/ansible/ccn_advanced$ - targets: - centos-stream-9: {} -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/cis - tmt_plan: /plans/contest/hardening/host-os/ansible/cis$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/cis_server_l1 - tmt_plan: /plans/contest/hardening/host-os/ansible/cis_server_l1$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/cis_workstation_l1 - tmt_plan: /plans/contest/hardening/host-os/ansible/cis_workstation_l1$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/cis_workstation_l2 - tmt_plan: /plans/contest/hardening/host-os/ansible/cis_workstation_l2$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/cui - tmt_plan: /plans/contest/hardening/host-os/ansible/cui$ - targets: - centos-stream-8: {} - centos-stream-9: {} -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/e8 - tmt_plan: /plans/contest/hardening/host-os/ansible/e8$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/hipaa - tmt_plan: /plans/contest/hardening/host-os/ansible/hipaa$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/ism_o - tmt_plan: /plans/contest/hardening/host-os/ansible/ism_o$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/ism_o_top_secret - tmt_plan: /plans/contest/hardening/host-os/ansible/ism_o_top_secret$ - targets: - centos-stream-10: {} -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/ospp - tmt_plan: /plans/contest/hardening/host-os/ansible/ospp$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/pci-dss - tmt_plan: /plans/contest/hardening/host-os/ansible/pci-dss$ -- <<: *test-static-checks - identifier: /hardening/host-os/ansible/stig - tmt_plan: /plans/contest/hardening/host-os/ansible/stig$ - -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/anssi_bp28_high - tmt_plan: /plans/contest/hardening/host-os/oscap/anssi_bp28_high$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/bsi - tmt_plan: /plans/contest/hardening/host-os/oscap/bsi$ - targets: - centos-stream-9: {} -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/ccn_advanced - tmt_plan: /plans/contest/hardening/host-os/oscap/ccn_advanced$ - targets: - centos-stream-9: {} -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/cis - tmt_plan: /plans/contest/hardening/host-os/oscap/cis$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/cis_server_l1 - tmt_plan: /plans/contest/hardening/host-os/oscap/cis_server_l1$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/cis_workstation_l1 - tmt_plan: /plans/contest/hardening/host-os/oscap/cis_workstation_l1$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/cis_workstation_l2 - tmt_plan: /plans/contest/hardening/host-os/oscap/cis_workstation_l2$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/cui - tmt_plan: /plans/contest/hardening/host-os/oscap/cui$ - targets: - centos-stream-8: {} - centos-stream-9: {} -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/e8 - tmt_plan: /plans/contest/hardening/host-os/oscap/e8$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/hipaa - tmt_plan: /plans/contest/hardening/host-os/oscap/hipaa$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/ism_o - tmt_plan: /plans/contest/hardening/host-os/oscap/ism_o$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/ism_o_top_secret - tmt_plan: /plans/contest/hardening/host-os/oscap/ism_o_top_secret$ - targets: - centos-stream-10: {} -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/ospp - tmt_plan: /plans/contest/hardening/host-os/oscap/ospp$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/pci-dss - tmt_plan: /plans/contest/hardening/host-os/oscap/pci-dss$ -- <<: *test-static-checks - identifier: /hardening/host-os/oscap/stig - tmt_plan: /plans/contest/hardening/host-os/oscap/stig$ -- <<: *test-static-checks +- <<: *fedora-tests identifier: fedora-cis tmt_plan: /plans/fedora-cis$ - targets: - fedora-all: {} diff --git a/tests/tmt/plans/contest.fmf b/tests/tmt/plans/contest.fmf index 39056e491125..f2c02fcee583 100644 --- a/tests/tmt/plans/contest.fmf +++ b/tests/tmt/plans/contest.fmf @@ -9,122 +9,6 @@ adjust: report: how: html -# -# Hardening via ansible-playbook remediation -# - -/hardening/host-os/ansible/anssi_bp28_high: - discover+: {test: /hardening/host-os/ansible/anssi_bp28_high$} - -/hardening/host-os/ansible/bsi: - discover+: {test: /hardening/host-os/ansible/bsi$} - -/hardening/host-os/ansible/ccn_advanced: - discover+: {test: /hardening/host-os/ansible/ccn_advanced$} - -/hardening/host-os/ansible/cis: - discover+: {test: /hardening/host-os/ansible/cis$} - -/hardening/host-os/ansible/cis_server_l1: - discover+: {test: /hardening/host-os/ansible/cis_server_l1$} - -/hardening/host-os/ansible/cis_workstation_l1: - discover+: {test: /hardening/host-os/ansible/cis_workstation_l1$} - -/hardening/host-os/ansible/cis_workstation_l2: - discover+: {test: /hardening/host-os/ansible/cis_workstation_l2$} - -/hardening/host-os/ansible/cui: - discover+: {test: /hardening/host-os/ansible/cui$} - -/hardening/host-os/ansible/e8: - discover+: {test: /hardening/host-os/ansible/e8$} - -/hardening/host-os/ansible/hipaa: - discover+: {test: /hardening/host-os/ansible/hipaa$} - -/hardening/host-os/ansible/ism_o: - discover+: {test: /hardening/host-os/ansible/ism_o$} - -/hardening/host-os/ansible/ism_o_top_secret: - discover+: {test: /hardening/host-os/ansible/ism_o_top_secret$} - -/hardening/host-os/ansible/ospp: - discover+: {test: /hardening/host-os/ansible/ospp$} - -/hardening/host-os/ansible/pci-dss: - discover+: {test: /hardening/host-os/ansible/pci-dss$} - -/hardening/host-os/ansible/stig: - discover+: {test: /hardening/host-os/ansible/stig$} - -# -# Hardening via oscap xccdf eval --remediate -# - -/hardening/host-os/oscap/anssi_bp28_high: - discover+: {test: /hardening/host-os/oscap/anssi_bp28_high$} - -/hardening/host-os/oscap/bsi: - discover+: {test: /hardening/host-os/oscap/bsi$} - -/hardening/host-os/oscap/ccn_advanced: - discover+: {test: /hardening/host-os/oscap/ccn_advanced$} - -/hardening/host-os/oscap/cis: - discover+: {test: /hardening/host-os/oscap/cis$} - -/hardening/host-os/oscap/cis_server_l1: - discover+: {test: /hardening/host-os/oscap/cis_server_l1$} - -/hardening/host-os/oscap/cis_workstation_l1: - discover+: {test: /hardening/host-os/oscap/cis_workstation_l1$} - -/hardening/host-os/oscap/cis_workstation_l2: - discover+: {test: /hardening/host-os/oscap/cis_workstation_l2$} - -/hardening/host-os/oscap/cui: - discover+: {test: /hardening/host-os/oscap/cui$} - -/hardening/host-os/oscap/e8: - discover+: {test: /hardening/host-os/oscap/e8$} - -/hardening/host-os/oscap/hipaa: - discover+: {test: /hardening/host-os/oscap/hipaa$} - -/hardening/host-os/oscap/ism_o: - discover+: {test: /hardening/host-os/oscap/ism_o$} - -/hardening/host-os/oscap/ism_o_top_secret: - discover+: {test: /hardening/host-os/oscap/ism_o_top_secret$} - -/hardening/host-os/oscap/ospp: - discover+: {test: /hardening/host-os/oscap/ospp$} - -/hardening/host-os/oscap/pci-dss: - discover+: {test: /hardening/host-os/oscap/pci-dss$} - -/hardening/host-os/oscap/stig: - discover+: {test: /hardening/host-os/oscap/stig$} - -# -# Misc smoke/sanity tests -# - -/static-checks: - discover+: - test: /static-checks - exclude: - # exclude here due to the test failing frequently for short periods - # of time, as many websites have temporary availability issues - - /static-checks/html-links - # these always fail, meant for manual review - - /static-checks/diff - # The value of this test is debatable and therefore it should not delay upstream gating. - # Our SCAP datastream is often noncompliant from the start, for example by containing SCE checks. - - /static-checks/nist-validation - - # Fedora specific plan /rpmbuild-ctest-fedora: discover+: {test: /static-checks/rpmbuild-ctest} From 62cdb04c3d8120481c78fb061df2998d3ec4d42d Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Fri, 16 Jan 2026 12:13:26 +0100 Subject: [PATCH 03/11] Re-enable centos stream packit builds. --- .packit.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.packit.yaml b/.packit.yaml index ecbdaf531210..9692e98b6610 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -15,6 +15,9 @@ jobs: trigger: pull_request targets: - fedora-all-x86_64 + - centos-stream-8-x86_64 + - centos-stream-9-x86_64 + - centos-stream-10-x86_64 - <<: *build trigger: commit From 19487c6fb9655faecb7335986f0d7da71399e588 Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Fri, 16 Jan 2026 14:50:26 +0100 Subject: [PATCH 04/11] Detect failing tests in ATEX execution --- tests/run_tests_testingfarm.py | 38 +++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/tests/run_tests_testingfarm.py b/tests/run_tests_testingfarm.py index 310b6fcc4dbd..5913993bfece 100644 --- a/tests/run_tests_testingfarm.py +++ b/tests/run_tests_testingfarm.py @@ -3,6 +3,10 @@ import sys import time import gzip +import json +import lzma +import atexit +import signal import logging import argparse import contextlib @@ -34,10 +38,12 @@ def parse_args(): def setup_logging(): """Setup logging configuration with console and file handlers.""" + # Log brief info to console, but be verbose in a separate file-based log (uploaded as artifact) console_log = logging.StreamHandler(sys.stderr) console_log.setLevel(logging.INFO) debug_log_fobj = gzip.open("atex_debug.log.gz", "wt") + atexit.register(debug_log_fobj.close) file_log = logging.StreamHandler(debug_log_fobj) file_log.setLevel(logging.DEBUG) @@ -49,11 +55,22 @@ def setup_logging(): force=True, ) - return debug_log_fobj + +def setup_signal_handlers(): + """Setup signal handlers for graceful abort.""" + def abort_on_signal(signum, _): + logger.error(f"got signal {signum}, aborting") + raise SystemExit(1) + + signal.signal(signal.SIGTERM, abort_on_signal) + signal.signal(signal.SIGHUP, abort_on_signal) def main(): """Main function to run tests on Testing Farm.""" + setup_logging() + setup_signal_handlers() + args = parse_args() # Variables exported to tests @@ -63,10 +80,6 @@ def main(): } with contextlib.ExitStack() as stack: - # Setup logging - debug_log_fobj = setup_logging() - stack.enter_context(contextlib.closing(debug_log_fobj)) - # Load FMF tests from contest directory fmf_tests = FMFTests( args.contest_dir, @@ -133,9 +146,18 @@ def main(): logger.info("Test execution completed!") - # Log final output locations - logger.info(f"Results written to: {output_results}") - logger.info(f"Test files in: {output_files}") + # Log final output locations + logger.info(f"Results written to: {output_results}") + logger.info(f"Test files in: {output_files}") + + # Read back the compressed JSON results and exit with non-0 if anything failed + with lzma.open(output_results, "rt") as results: + for line in results: + fields = json.loads(line) + # [platform, status, test name, subtest name, files, note] + if fields[1] in ("fail", "error", "infra"): + logger.warning("failures found in the results, exiting with 1") + sys.exit(1) if __name__ == "__main__": From b4d7dfa76388b7ff4a4fc4815ac6283b1f6f45e4 Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Mon, 19 Jan 2026 12:54:23 +0100 Subject: [PATCH 05/11] Do not fail fast on ATEX testing. This is to prevent from completing all the major versions testing, otherwise if any of the Centosstream fail, it would stop any other major version testing, preventing to get all the tests finished. --- .github/workflows/atex-test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/atex-test.yaml b/.github/workflows/atex-test.yaml index 90496ff3133a..7fd786a79225 100644 --- a/.github/workflows/atex-test.yaml +++ b/.github/workflows/atex-test.yaml @@ -67,6 +67,7 @@ jobs: runs-on: ubuntu-latest needs: check_build strategy: + fail-fast: false matrix: centos_stream_major: [8, 9, 10] container: From 5d886c5dbd7fa28354916fd5970111a2fc5e17bc Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Mon, 19 Jan 2026 13:01:21 +0100 Subject: [PATCH 06/11] Make sure the ATEX check reports the right status. Test results based on the tests from the Centos Stream tests step. --- .github/workflows/atex-test.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/atex-test.yaml b/.github/workflows/atex-test.yaml index 7fd786a79225..f87a9b254a48 100644 --- a/.github/workflows/atex-test.yaml +++ b/.github/workflows/atex-test.yaml @@ -311,6 +311,7 @@ jobs: check_id: ${{ needs.check_build.outputs.check_id }} sha: ${{ needs.check_build.outputs.pr_sha }} status: completed - conclusion: ${{ job.status }} + # Use test job result to determine conclusion - needs.test.result will be 'failure' if any matrix job failed + conclusion: ${{ needs.test.result }} output: | {"summary":"ATEX tests completed. Job: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}. View results: ${{ steps.testing_farm_request.outputs.HTML_LINK }}","title":"ATEX Testing Complete"} From 3067497b1db11ec841bb9abb07d8b38bf724e60f Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Fri, 16 Jan 2026 14:51:20 +0100 Subject: [PATCH 07/11] Fix permissions of executable files when downloading the artifacts. Whenever github workflows download an artifact, it strips the executable bit from files, which are essential for our ctest that in some cases execute directly python/bash files --- .github/workflows/atex-build.yaml | 11 +++++++++++ .github/workflows/atex-test.yaml | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/.github/workflows/atex-build.yaml b/.github/workflows/atex-build.yaml index bfc295674bc4..7cc2d7b475d7 100644 --- a/.github/workflows/atex-build.yaml +++ b/.github/workflows/atex-build.yaml @@ -63,6 +63,17 @@ jobs: # Clean up temporary metadata rm -rf jinja2_cache + - name: Save file permissions before artifact upload + run: | + # GitHub Actions artifact upload/download strips execute permissions + # Save all file permissions so they can be restored after download + echo "=== Saving file permissions ===" + find . -type f -printf '%m %p\n' > file-permissions.txt + echo "Saved permissions for $(wc -l < file-permissions.txt) files" + # Show sample of executable files being saved + echo "=== Sample executable files ===" + grep -E '^[0-7]*[1357][0-7]* ' file-permissions.txt | head -10 || true + - name: Upload build artifacts uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: diff --git a/.github/workflows/atex-test.yaml b/.github/workflows/atex-test.yaml index f87a9b254a48..3e4ab623ad96 100644 --- a/.github/workflows/atex-test.yaml +++ b/.github/workflows/atex-test.yaml @@ -85,6 +85,33 @@ jobs: name: content-centos-stream${{ matrix.centos_stream_major }} path: content-centos-stream${{ matrix.centos_stream_major }}/ + - name: Restore file permissions lost during artifact download + run: | + # GitHub Actions artifact download strips execute permissions + # Restore permissions from the saved file created during build + CONTENT_DIR="content-centos-stream${{ matrix.centos_stream_major }}" + PERMS_FILE="${CONTENT_DIR}/file-permissions.txt" + + if [ -f "${PERMS_FILE}" ]; then + echo "=== Restoring file permissions from ${PERMS_FILE} ===" + cd "${CONTENT_DIR}" + while IFS=' ' read -r mode filepath; do + # Remove leading ./ from filepath if present + filepath="${filepath#./}" + if [ -f "${filepath}" ]; then + chmod "${mode}" "${filepath}" + fi + done < file-permissions.txt + echo "Restored permissions for $(wc -l < file-permissions.txt) files" + # Show sample of restored executable files + echo "=== Sample executable files after restore ===" + find . -type f -executable -name "*.py" 2>/dev/null | head -5 || true + find . -type f -executable -name "*.sh" 2>/dev/null | head -5 || true + else + echo "WARNING: ${PERMS_FILE} not found, permissions may be incorrect" + exit 1 + fi + - name: Checkout Contest Test Suite uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: From 2ca2d4d5b4cf27287b1eab49ef4822e73378d493 Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Tue, 20 Jan 2026 17:01:50 +0100 Subject: [PATCH 08/11] Include hidden files in the upload artifact for ATEX integration. --- .github/workflows/atex-build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/atex-build.yaml b/.github/workflows/atex-build.yaml index 7cc2d7b475d7..84aa1400ff96 100644 --- a/.github/workflows/atex-build.yaml +++ b/.github/workflows/atex-build.yaml @@ -80,6 +80,7 @@ jobs: name: content-centos-stream${{ matrix.centos_stream_major }} path: . retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }} + include-hidden-files: true # make sure all .dot files are included e.g. .cmakelintrc save_pr_info: name: Save PR information for workflow_run From 82322b19628ec1f77487d852015e596d8cad0e71 Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Wed, 21 Jan 2026 19:49:50 +0100 Subject: [PATCH 09/11] Add a header.html for the ATEX testing. --- .github/workflows/atex-test.yaml | 92 +++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/.github/workflows/atex-test.yaml b/.github/workflows/atex-test.yaml index 3e4ab623ad96..45e86e17b70b 100644 --- a/.github/workflows/atex-test.yaml +++ b/.github/workflows/atex-test.yaml @@ -12,6 +12,9 @@ env: CONTEST_REPO: RHSecurityCompliance/contest ARTIFACT_RETENTION_DAYS: 1 TEST_TIMEOUT: 1440 # 24 hours + # CentOS Stream versions to test (space-separated for shell loops) + # NOTE: Keep in sync with matrix.centos_stream_major in the test job + CS_VERSIONS: "8 9 10" permissions: contents: read @@ -66,9 +69,14 @@ jobs: name: Test on CentOS Stream ${{ matrix.centos_stream_major }} runs-on: ubuntu-latest needs: check_build + outputs: + # Contest SHA from any matrix job (all use same ref, so same SHA) + contest_sha: ${{ steps.get_contest.outputs.contest_sha }} + contest_ref: ${{ steps.get_contest.outputs.contest_ref }} strategy: fail-fast: false matrix: + # NOTE: Keep in sync with env.CS_VERSIONS at the top of this file centos_stream_major: [8, 9, 10] container: image: fedora:latest @@ -112,6 +120,9 @@ jobs: exit 1 fi + - name: Install git for checkout + run: dnf -y install git + - name: Checkout Contest Test Suite uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: @@ -120,9 +131,18 @@ jobs: path: contest fetch-depth: 1 + - name: Get Contest SHA + id: get_contest + run: | + CONTEST_SHA=$(cd contest && git rev-parse HEAD) + CONTEST_REF="main" + echo "contest_sha=${CONTEST_SHA}" >> $GITHUB_OUTPUT + echo "contest_ref=${CONTEST_REF}" >> $GITHUB_OUTPUT + echo "Contest: ${CONTEST_SHA:0:12} (${CONTEST_REF})" + - name: Install test dependencies run: | - dnf -y install python3-pip git rsync + dnf -y install python3-pip rsync pip install fmf atex==0.11 - name: Run tests on Testing Farm @@ -244,7 +264,7 @@ jobs: mkdir -p atex-results-testing-farm/files_dir/ # Process and merge results for all CentOS Stream versions - for version in 8 9 10; do + for version in ${{ env.CS_VERSIONS }}; do results_file="test-results/cs${version}/results-centos-stream-${version}-x86_64.json.xz" files_dir="test-results/cs${version}/files-centos-stream-${version}-x86_64" @@ -265,6 +285,74 @@ jobs: run: | cp -rf atex-html/index.html atex-html/sqljs/ atex-results-testing-farm/ + - name: Generate header.html for results page + if: always() + env: + PR_NUMBER: ${{ needs.check_build.outputs.pr_number }} + PR_SHA: ${{ needs.check_build.outputs.pr_sha }} + CONTEST_SHA: ${{ needs.test.outputs.contest_sha }} + CONTEST_REF: ${{ needs.test.outputs.contest_ref }} + WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + REPO_URL: ${{ github.server_url }}/${{ github.repository }} + ACTOR: ${{ github.actor }} + RUN_STARTED: ${{ github.event.workflow_run.created_at }} + CS_VERSIONS: ${{ env.CS_VERSIONS }} + run: | + cat > atex-results-testing-farm/header.html <<'HEADER_EOF' + + HEADER_EOF + + # Add dynamic content - header section + cat >> atex-results-testing-farm/header.html <ATEX Upstream Testing +

PR #${PR_NUMBER} + - Workflow #${{ github.run_id }} + started on + by ${ACTOR}

+ +
+ + + EOF + + # List each CentOS Stream version that was tested + for version in ${CS_VERSIONS}; do + echo " " >> atex-results-testing-farm/header.html + done + + # Add commit info table + cat >> atex-results-testing-farm/header.html < +
CentOS Stream
${version}
+ + + +
RepoCommit used
Content${PR_SHA:0:12}
Contest (${CONTEST_REF})${CONTEST_SHA:0:12}
+
+ EOF + + echo "=== Generated header.html ===" + cat atex-results-testing-farm/header.html + - name: Commit and tag results in ATEX repository if: always() working-directory: atex-results-testing-farm From ab3c9a00fb77aee29f8ae36ab8813de3e8375984 Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Thu, 22 Jan 2026 16:02:40 +0100 Subject: [PATCH 10/11] Bump version of ATEX in the ATEX workflow integration. --- .github/workflows/atex-test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/atex-test.yaml b/.github/workflows/atex-test.yaml index 45e86e17b70b..5ec62c53f9b2 100644 --- a/.github/workflows/atex-test.yaml +++ b/.github/workflows/atex-test.yaml @@ -143,7 +143,7 @@ jobs: - name: Install test dependencies run: | dnf -y install python3-pip rsync - pip install fmf atex==0.11 + pip install fmf atex==0.12 - name: Run tests on Testing Farm env: @@ -186,7 +186,7 @@ jobs: if: always() run: | dnf -y install python3-pip git rsync - pip install fmf atex==0.11 + pip install fmf atex==0.12 - name: Checkout ATEX results repository if: always() From 5685d59c8d3bac79edc7fefe1d79354bda82c9fc Mon Sep 17 00:00:00 2001 From: Gabriel Becker Date: Fri, 23 Jan 2026 16:39:38 +0100 Subject: [PATCH 11/11] ATEX: Set filtering query to show failing tests by default. --- .github/workflows/atex-test.yaml | 6 +++--- tests/submit_results_to_testing_farm.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/atex-test.yaml b/.github/workflows/atex-test.yaml index 5ec62c53f9b2..b0f229fa2874 100644 --- a/.github/workflows/atex-test.yaml +++ b/.github/workflows/atex-test.yaml @@ -202,16 +202,16 @@ jobs: working-directory: atex-results-testing-farm run: fmf init - - name: Create TMT dummy plan for artifact transport + - name: Create TMT atex_results plan for artifact transport if: always() working-directory: atex-results-testing-farm run: | cat > main.fmf <<'EOF' - /dummy_plan: + /atex_results_plan: discover: how: shell tests: - - name: /dummy_test + - name: /atex_results_test test: mv * "$TMT_TEST_DATA/." execute: how: tmt diff --git a/tests/submit_results_to_testing_farm.py b/tests/submit_results_to_testing_farm.py index 477035f69297..b9c11d06c7ed 100644 --- a/tests/submit_results_to_testing_farm.py +++ b/tests/submit_results_to_testing_farm.py @@ -20,7 +20,7 @@ def parse_args(): parser = argparse.ArgumentParser(description="Submit TMT test to Testing Farm") parser.add_argument("--repo-url", required=True, help="GitHub repository URL") parser.add_argument("--pr-number", required=True, help="Pull request number") - parser.add_argument("--plan-name", default="/dummy_plan", help="TMT plan name to run") + parser.add_argument("--plan-name", default="/atex_results_plan", help="TMT plan name to run") parser.add_argument("--os", default=None, help="OS to test on (e.g., rhel-9)") parser.add_argument("--arch", default="x86_64", help="Architecture to test on") return parser.parse_args() @@ -82,7 +82,7 @@ def get_html_link(artifacts_url): # {workdir_url}/testing-farm/sanity/execute/results.yaml # as YAML and look for the test name and get its 'data-path' # relative to the /execute/ dir - return f"{workdir_url}/dummy_plan/execute/data/guest/default-0/dummy_test-1/data/index.html?q=TRUE" + return f"{workdir_url}/atex_results_plan/execute/data/guest/default-0/atex_results_test-1/data/index.html?q=status%20IN%20%28%27fail%27%2C%20%27error%27%2C%20%27infra%27%29%20OR%20subtest%20IS%20NULL" def main():