diff --git a/.github/workflows/ocp-test-profiles.yaml b/.github/workflows/ocp-test-profiles.yaml new file mode 100644 index 000000000000..e61875c35761 --- /dev/null +++ b/.github/workflows/ocp-test-profiles.yaml @@ -0,0 +1,125 @@ +name: Trigger OCP Tests When Relevant +on: + pull_request: + branches: [ master, 'stabilization*' ] +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.run_id }} + cancel-in-progress: true +jobs: + check-and-trigger-ocp-prow-tests: + name: Identify rules changed in PR and test them in OCP Prow + runs-on: ubuntu-latest + container: + image: fedora:latest + steps: + - name: Install Deps + run: dnf install -y cmake make openscap-utils python3-pyyaml python3-jinja2 git python3-deepdiff python3-requests jq python3-pip nodejs + - name: Install deps python + run: pip install gitpython xmldiff + - name: Checkout + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + with: + fetch-depth: 0 + - name: Checkout (CTF) + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + with: + repository: ComplianceAsCode/content-test-filtering + path: ctf + # https://github.com/actions/checkout/issues/766 + - name: Set git safe directory + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - name: Find forking point + env: + BASE_BRANCH: ${{ github.base_ref }} + run: echo "FORK_POINT=$(git merge-base origin/$BASE_BRANCH ${{ github.event.pull_request.head.sha }})" >> $GITHUB_OUTPUT + id: fork_point + - name: Detect content changes in the PR + run: python3 ./ctf/content_test_filtering.py pr --base ${{ steps.fork_point.outputs.FORK_POINT }} --remote_repo ${{ github.server_url }}/${{ github.repository }} --verbose --rule --output json ${{ github.event.pull_request.number }} > ctf-output.json + - name: Test if there are no content changes + run: echo "CTF_OUTPUT_SIZE=$(stat --printf="%s" output.json)" >> $GITHUB_OUTPUT + id: ctf + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 + if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} + with: + name: ctf-output + path: ctf-output.json + - name: Print changes to content detected if any + if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} + run: cat ctf-output.json + - name: Get product attribute + if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} + id: product + uses: notiz-dev/github-action-json-property@a5a9c668b16513c737c3e1f8956772c99c73f6e8 # v0.2.0 + with: + path: 'ctf-output.json' + prop_path: 'product' + + - name: Build product OCP and RHCOS content + if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' && (contains(steps.product.outputs.prop, 'ocp4') || contains(steps.product.outputs.prop, 'rhcos4')) }} + run: ./build_product -d ocp4 rhcos4 + + - name: Process list of rules into a list of product-profiles to test + if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' && (contains(steps.product.outputs.prop, 'ocp4') || contains(steps.product.outputs.prop, 'rhcos4')) }} + id: profiles_to_test + run: | + OCP_VERSION=4.17 + RULES=$(cat ctf-output.json | jq -r '.rules[]') + + # Let's grab one profile for each changed rule + PROFILES=() + ALL_PROFILES=() + + # Let's consistently grab a random profile for each rule, in order to do that we use the + # PR number as the seed + RANDOM=${{ github.event.pull_request.number }} + for r in $RULES; do + readarray -t TEMP <<< $(grep -lr -e "$r\$" build/*/profiles | sort) + ALL_PROFILES+=(${TEMP}) + PROFILES+=(${TEMP[$(($RANDOM%(${#TEMP[@]})))]}) + done + + # Sort and ensure that the profiles are unique + readarray -t UNIQUE_PROFILES <<< $(echo ${PROFILES[@]} | tr ' ' '\n' | sort -u | tr '\n' ' ') + readarray -t ALL_UNIQUE_PROFILES <<< $(echo ${ALL_PROFILES[@]} | tr ' ' '\n' | sort -u | tr '\n' ' ') + + # Craft a command to trigger tests + COMMAND=$(for up in ${UNIQUE_PROFILES[@]}; do + echo $up | sed "s/build\/\(.*\)\/profiles\/\(.*\)\.profile/\/test ${OCP_VERSION}-e2e-aws-\1-\2/" + done + ) + + # COMMAND is a multiline string, so we need to set it this way + { + echo 'TEST_PROFILES_COMMAND<> $GITHUB_OUTPUT + + # Format all identified profiles for display + ALL_PROFILES_FORMATTED=$(for up in ${ALL_UNIQUE_PROFILES[@]}; do + echo $up | sed "s/build\/\(.*\)\/profiles\/\(.*\)\.profile/- `${OCP_VERSION}-e2e-aws-\1-\2`/" + done + ) + { + echo 'ALL_PROFILES_COMMENT<> $GITHUB_OUTPUT + - uses: thollander/actions-comment-pull-request@e2c37e53a7d2227b61585343765f73a9ca57eda9 # v2 + if: ${{ steps.profiles_to_test.outputs.TEST_PROFILES_COMMAND != '' }} + with: + message: | + :robot: Trigger prow tests based on changed rules + + ${{ steps.profiles_to_test.outputs.TEST_PROFILES_COMMAND }} + + Note: if a test is not started it can be that a CI Job is not configure for that particular profile or product. + +
+ Click here to see all the relevant profiles + + ${{ steps.profiles_to_test.outputs.ALL_PROFILES_COMMENT}} + +
+ comment_tag: kubernetes_start_prow_tests + pr_number: ${{ github.event.pull_request.number }}