--- name: CI env: LC_ALL: "C.UTF-8" # prevent ERROR: Ansible could not initialize the preferred locale: unsupported locale setting CI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DEV_DOCKER_OWNER: ${{ github.repository_owner }} COMPOSE_TAG: ${{ github.base_ref || 'devel' }} UPSTREAM_REPOSITORY_ID: 91594105 on: pull_request: push: branches: - devel # needed to publish code coverage post-merge jobs: common-tests: name: ${{ matrix.tests.name }} runs-on: ubuntu-latest timeout-minutes: 60 permissions: packages: write contents: read strategy: fail-fast: false matrix: tests: - name: api-test command: /start_tests.sh test_coverage coverage-upload-name: "" - name: api-migrations command: /start_tests.sh test_migrations coverage-upload-name: "" - name: api-lint command: /var/lib/awx/venv/awx/bin/tox -e linters coverage-upload-name: "" - name: awx-collection command: /start_tests.sh test_collection_all coverage-upload-name: "awx-collection" steps: - uses: actions/checkout@v4 with: show-progress: false - name: Build awx_devel image for running checks uses: ./.github/actions/awx_devel_image with: github-token: ${{ secrets.GITHUB_TOKEN }} private-github-key: ${{ secrets.PRIVATE_GITHUB_KEY }} - name: Run check ${{ matrix.tests.name }} id: make-run run: >- AWX_DOCKER_ARGS='-e GITHUB_ACTIONS -e GITHUB_OUTPUT -v "${GITHUB_OUTPUT}:${GITHUB_OUTPUT}:rw,Z"' AWX_DOCKER_CMD='${{ matrix.tests.command }}' make docker-runner - name: Inject PR number into coverage.xml if: >- !cancelled() && github.event_name == 'pull_request' && steps.make-run.outputs.cov-report-files != '' run: | if [ -f "reports/coverage.xml" ]; then sed -i '2i' reports/coverage.xml echo "Injected PR number ${{ github.event.pull_request.number }} into coverage.xml" fi - name: Upload test coverage to Codecov if: >- !cancelled() && steps.make-run.outputs.cov-report-files != '' uses: codecov/codecov-action@v4 with: fail_ci_if_error: >- ${{ toJSON(env.UPSTREAM_REPOSITORY_ID == github.repository_id) }} files: >- ${{ steps.make-run.outputs.cov-report-files }} flags: >- CI-GHA, pytest, OS-${{ runner.os }} token: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov if: >- !cancelled() && steps.make-run.outputs.test-result-files != '' uses: codecov/test-results-action@v1 with: fail_ci_if_error: >- ${{ toJSON(env.UPSTREAM_REPOSITORY_ID == github.repository_id) }} files: >- ${{ steps.make-run.outputs.test-result-files }} flags: >- CI-GHA, pytest, OS-${{ runner.os }} token: ${{ secrets.CODECOV_TOKEN }} - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 with: name: ${{ matrix.tests.name }}-artifacts path: reports/coverage.xml retention-days: 5 - name: Upload awx jUnit test reports if: >- !cancelled() && steps.make-run.outputs.test-result-files != '' && github.event_name == 'push' && env.UPSTREAM_REPOSITORY_ID == github.repository_id && github.ref_name == github.event.repository.default_branch run: | for junit_file in $(echo '${{ steps.make-run.outputs.test-result-files }}' | sed 's/,/ /') do curl \ -v \ --user "${{ vars.PDE_ORG_RESULTS_AGGREGATOR_UPLOAD_USER }}:${{ secrets.PDE_ORG_RESULTS_UPLOAD_PASSWORD }}" \ --form "xunit_xml=@${junit_file}" \ --form "component_name=${{ matrix.tests.coverage-upload-name || 'awx' }}" \ --form "git_commit_sha=${{ github.sha }}" \ --form "git_repository_url=https://github.com/${{ github.repository }}" \ "${{ vars.PDE_ORG_RESULTS_AGGREGATOR_UPLOAD_URL }}/api/results/upload/" done dev-env: runs-on: ubuntu-latest timeout-minutes: 60 steps: - uses: actions/checkout@v4 with: show-progress: false - uses: ./.github/actions/setup-python with: python-version: '3.13' - uses: ./.github/actions/run_awx_devel id: awx with: build-ui: false github-token: ${{ secrets.GITHUB_TOKEN }} private-github-key: ${{ secrets.PRIVATE_GITHUB_KEY }} - name: Run live dev env tests run: docker exec tools_awx_1 /bin/bash -c "make live_test" - uses: ./.github/actions/upload_awx_devel_logs if: always() with: log-filename: live-tests.log awx-operator: runs-on: ubuntu-latest timeout-minutes: 60 env: DEBUG_OUTPUT_DIR: /tmp/awx_operator_molecule_test steps: - name: Checkout awx uses: actions/checkout@v4 with: show-progress: false path: awx - uses: ./awx/.github/actions/setup-ssh-agent with: ssh-private-key: ${{ secrets.PRIVATE_GITHUB_KEY }} - name: Checkout awx-operator uses: actions/checkout@v4 with: show-progress: false\ repository: ansible/awx-operator path: awx-operator - name: Setup python, referencing action at awx relative path uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 with: python-version: '3.12' - name: Install playbook dependencies run: | python -m pip install docker - name: Check Python version working-directory: awx run: | make print-PYTHON - name: Build AWX image working-directory: awx run: | VERSION=`make version-for-buildyml` make awx-kube-build env: COMPOSE_TAG: ci DEV_DOCKER_TAG_BASE: local HEADLESS: yes - name: Run test deployment with awx-operator working-directory: awx-operator run: | python -m pip install -r molecule/requirements.txt python -m pip install PyYAML # for awx/tools/scripts/rewrite-awx-operator-requirements.py $(realpath ../awx/tools/scripts/rewrite-awx-operator-requirements.py) molecule/requirements.yml $(realpath ../awx) ansible-galaxy collection install -r molecule/requirements.yml sudo rm -f $(which kustomize) make kustomize KUSTOMIZE_PATH=$(readlink -f bin/kustomize) molecule -v test -s kind -- --skip-tags=replicas env: AWX_TEST_IMAGE: local/awx AWX_TEST_VERSION: ci AWX_EE_TEST_IMAGE: quay.io/ansible/awx-ee:latest STORE_DEBUG_OUTPUT: true - name: Upload debug output if: failure() uses: actions/upload-artifact@v4 with: name: awx-operator-debug-output path: ${{ env.DEBUG_OUTPUT_DIR }} collection-sanity: name: awx_collection sanity runs-on: ubuntu-latest timeout-minutes: 30 strategy: fail-fast: false matrix: ansible: - stable-2.17 # - devel steps: - name: Perform sanity testing uses: ansible-community/ansible-test-gh-action@release/v1 with: ansible-core-version: ${{ matrix.ansible }} codecov-token: ${{ secrets.CODECOV_TOKEN }} collection-root: awx_collection pre-test-cmd: >- ansible-playbook -i localhost, tools/template_galaxy.yml -e collection_package=awx -e collection_namespace=awx -e collection_version=1.0.0 -e '{"awx_template_version": false}' testing-type: sanity - name: Upload awx jUnit test reports to the unified dashboard if: >- !cancelled() && steps.make-run.outputs.test-result-files != '' && github.event_name == 'push' && env.UPSTREAM_REPOSITORY_ID == github.repository_id && github.ref_name == github.event.repository.default_branch run: | for junit_file in $(echo '${{ steps.make-run.outputs.test-result-files }}' | sed 's/,/ /') do curl \ -v \ --user "${{ vars.PDE_ORG_RESULTS_AGGREGATOR_UPLOAD_USER }}:${{ secrets.PDE_ORG_RESULTS_UPLOAD_PASSWORD }}" \ --form "xunit_xml=@${junit_file}" \ --form "component_name=awx" \ --form "git_commit_sha=${{ github.sha }}" \ --form "git_repository_url=https://github.com/${{ github.repository }}" \ "${{ vars.PDE_ORG_RESULTS_AGGREGATOR_UPLOAD_URL }}/api/results/upload/" done collection-integration: name: awx_collection integration runs-on: ubuntu-latest timeout-minutes: 60 strategy: fail-fast: false matrix: target-regex: - name: a-h regex: ^[a-h] - name: i-p regex: ^[i-p] - name: r-z0-9 regex: ^[r-z0-9] steps: - uses: actions/checkout@v4 with: show-progress: false - uses: ./.github/actions/setup-python with: python-version: '3.13' - name: Remove system ansible to avoid conflicts run: | python -m pip uninstall -y ansible ansible-core || true - uses: ./.github/actions/run_awx_devel id: awx with: build-ui: false github-token: ${{ secrets.GITHUB_TOKEN }} private-github-key: ${{ secrets.PRIVATE_GITHUB_KEY }} - name: Install dependencies for running tests run: | python -m pip install -e ./awxkit/ python -m pip install -r awx_collection/requirements.txt hash -r # Rehash to pick up newly installed scripts - name: Run integration tests id: make-run run: | echo "::remove-matcher owner=python::" # Disable annoying annotations from setup-python echo '[general]' > ~/.tower_cli.cfg echo 'host = https://${{ steps.awx.outputs.ip }}:8043' >> ~/.tower_cli.cfg echo 'username = admin' >> ~/.tower_cli.cfg echo 'password = password' >> ~/.tower_cli.cfg echo 'verify_ssl = false' >> ~/.tower_cli.cfg TARGETS="$(ls awx_collection/tests/integration/targets | grep '${{ matrix.target-regex.regex }}' | tr '\n' ' ')" export PYTHONPATH="$(python -c 'import site; print(":".join(site.getsitepackages()))')${PYTHONPATH:+:$PYTHONPATH}" make COLLECTION_VERSION=100.100.100-git COLLECTION_TEST_TARGET="--requirements $TARGETS" test_collection_integration env: ANSIBLE_TEST_PREFER_PODMAN: 1 - name: Upload test coverage to Codecov if: >- !cancelled() && steps.make-run.outputs.cov-report-files != '' uses: codecov/codecov-action@v4 with: fail_ci_if_error: >- ${{ toJSON(env.UPSTREAM_REPOSITORY_ID == github.repository_id) }} files: >- ${{ steps.make-run.outputs.cov-report-files }} flags: >- CI-GHA, ansible-test, integration, OS-${{ runner.os }} token: ${{ secrets.CODECOV_TOKEN }} # Upload coverage report as artifact - uses: actions/upload-artifact@v4 if: always() with: name: coverage-${{ matrix.target-regex.name }} path: ~/.ansible/collections/ansible_collections/awx/awx/tests/output/coverage/ retention-days: 1 - uses: ./.github/actions/upload_awx_devel_logs if: always() with: log-filename: collection-integration-${{ matrix.target-regex.name }}.log collection-integration-coverage-combine: name: combine awx_collection integration coverage runs-on: ubuntu-latest timeout-minutes: 10 needs: - collection-integration strategy: fail-fast: false steps: - uses: actions/checkout@v4 with: persist-credentials: false show-progress: false - uses: ./.github/actions/setup-python with: python-version: '3.13' - name: Remove system ansible to avoid conflicts run: | python -m pip uninstall -y ansible ansible-core || true - name: Upgrade ansible-core run: python -m pip install --upgrade ansible-core - name: Download coverage artifacts uses: actions/download-artifact@v4 with: merge-multiple: true path: coverage pattern: coverage-* - name: Combine coverage run: | make COLLECTION_VERSION=100.100.100-git install_collection mkdir -p ~/.ansible/collections/ansible_collections/awx/awx/tests/output/coverage cp -rv coverage/* ~/.ansible/collections/ansible_collections/awx/awx/tests/output/coverage/ cd ~/.ansible/collections/ansible_collections/awx/awx hash -r # Rehash to pick up newly installed scripts PATH="$(python -c 'import sys; import os; print(os.path.dirname(sys.executable))'):$PATH" ansible-test coverage combine --requirements PATH="$(python -c 'import sys; import os; print(os.path.dirname(sys.executable))'):$PATH" ansible-test coverage html echo '## AWX Collection Integration Coverage' >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY PATH="$(python -c 'import sys; import os; print(os.path.dirname(sys.executable))'):$PATH" ansible-test coverage report >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY echo >> $GITHUB_STEP_SUMMARY echo '## AWX Collection Integration Coverage HTML' >> $GITHUB_STEP_SUMMARY echo 'Download the HTML artifacts to view the coverage report.' >> $GITHUB_STEP_SUMMARY - name: Upload coverage report as artifact uses: actions/upload-artifact@v4 with: name: awx-collection-integration-coverage-html path: ~/.ansible/collections/ansible_collections/awx/awx/tests/output/reports/coverage