Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .github/workflows/check-crd-compatibility.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ on:
- opened
- reopened
- synchronize
- labeled
- unlabeled

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
Expand All @@ -20,15 +22,31 @@ jobs:
detect-changes:
uses: ./.github/workflows/detect-changes.yml

plan:
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: read
uses: ./.github/workflows/dispatcher-plan.yaml

check-crd-compatibility:
needs: detect-changes
if: ${{ !needs.detect-changes.outputs.ui_only }}
needs: [detect-changes, plan]
if: >-
always() && !cancelled() && needs.detect-changes.result == 'success' && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && !needs.detect-changes.outputs.ui_only
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['check-crd-compatibility']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
Comment on lines +34 to +39

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be simplified to

Suggested change
if: >-
always() && !cancelled() && needs.detect-changes.result == 'success' && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && !needs.detect-changes.outputs.ui_only
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['check-crd-compatibility']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
if: >-
always() && !cancelled() && needs.detect-changes.result == 'success' && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && !needs.detect-changes.outputs.ui_only
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && (needs.plan.result != 'success' || fromJSON(needs.plan.outputs.jobs)['check-crd-compatibility'])
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for looking at it. This is my playground with dirty code :) It would be a pitty to waste cycles on reviewing it in this state. You can however get a rough direction that in which I am going (still not sure this is the right one).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree on watching out not to spam the CI with flipping the labels too frequently. However, there are some situations in which we may want to react to labels changing. We need to think about this.

runs-on: ubuntu-latest
container:
image: quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.11@sha256:df3459cf038e73775314b3a5d36d14dda41e6df438a0273c9efa8d23e0f2358a # ratchet:quay.io/stackrox-io/apollo-ci:stackrox-test-0.5.11
outputs:
released_version: ${{ steps.get_previous_released_version.outputs.released_version }}
steps:
- name: Fail closed when the dispatcher plan did not succeed
if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
run: echo "The dispatcher plan did not succeed, so this job is not running its tests." && exit 1

- name: Checkout stackrox/stackrox
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # ratchet:actions/checkout@v7.0.0
with:
Expand Down
86 changes: 86 additions & 0 deletions .github/workflows/dispatcher-plan.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Dispatcher plan

# Called by the test workflows. Prints the plan and returns, for each
# GitHub Actions job, whether the dispatcher would start it.
# The label ci-dispatcher-enforce is what makes a caller obey that answer.
# Without the label the caller keeps starting jobs the way it does today.

on:
workflow_call:
outputs:
enforce:
description: true when the pull request has ci-dispatcher-enforce
value: ${{ jobs.plan.outputs.enforce }}
jobs:
description: JSON object of job id to whether the dispatcher would start it
value: ${{ jobs.plan.outputs.jobs }}

permissions:
contents: read
pull-requests: read

jobs:
plan:
runs-on: ubuntu-latest
outputs:
enforce: ${{ steps.out.outputs.enforce }}
jobs: ${{ steps.out.outputs.jobs }}
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # ratchet:actions/checkout@v7.0.0

- name: Install PyYAML
run: |
python3 -m venv "${RUNNER_TEMP}/selector"
"${RUNNER_TEMP}/selector/bin/pip" install 'PyYAML==6.0.3'

- name: Plan GitHub Actions jobs
id: out
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }}
DRAFT: ${{ github.event.pull_request.draft }}
FORK: ${{ github.event.pull_request.head.repo.fork }}
ENFORCE: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') }}
run: |
set -euo pipefail
py="${RUNNER_TEMP}/selector/bin/python"
flags=()
if [[ "${DRAFT}" == "true" ]]; then flags+=(--draft); fi
if [[ "${FORK}" == "true" ]]; then flags+=(--fork); fi
if [[ "${ENFORCE}" == "true" ]]; then flags+=(--enforce); fi

files="$(mktemp)"
if ! gh api "repos/${GH_REPO}/pulls/${PR_NUMBER}/files" --paginate --jq '.[].filename' > "${files}"; then
echo "Could not list changed files. Showing the run-everything result."
: > "${files}"
elif [[ "$(wc -l < "${files}")" -ge 3000 ]]; then
echo "3000 or more changed files. Showing the run-everything result."
: > "${files}"
fi

common=(
"${py}" ci/exploration/dispatcher.py
--mapping ci/test-domains.toml
--defaults ci/exploration/gha_defaults.yaml
--labels "${LABELS}"
"${flags[@]}"
)

"${common[@]}" --title "This pull request" - < "${files}"
"${common[@]}" --format json - < "${files}" > "${RUNNER_TEMP}/plan.json"

python3 - << 'PY'
import json
import os

plan = json.load(open(os.environ["RUNNER_TEMP"] + "/plan.json"))
selected = {item["job"]: bool(item["would_run"]) for item in plan["jobs"]}
with open(os.environ["GITHUB_OUTPUT"], "a") as handle:
handle.write(f"enforce={os.environ['ENFORCE']}\n")
handle.write("jobs<<EOF\n")
json.dump(selected, handle, separators=(",", ":"))
handle.write("\nEOF\n")
PY
28 changes: 24 additions & 4 deletions .github/workflows/e2e-dispatch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ on:
- reopened
- synchronize
- ready_for_review
- labeled
- unlabeled

permissions:
contents: read
Expand All @@ -26,10 +28,19 @@ jobs:
detect-changes:
uses: ./.github/workflows/detect-changes.yml

plan:
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: read
uses: ./.github/workflows/dispatcher-plan.yaml

# Determines whether we should dispatch jobs that call real E2E workflows.
# This allows to skip running E2E tests on draft PRs without corresponding labels or on untrusted forks.
# ci-dispatcher-enforce replaces that decision with the dispatcher plan.
should-dispatch:
needs: [ detect-changes ]
needs: [ detect-changes, plan ]
if: always() && !cancelled() && needs.detect-changes.result == 'success'
runs-on: ubuntu-slim
outputs:
wait-for-gha-images: ${{ steps.determine.outputs.wait-for-gha-images }}
Expand All @@ -48,6 +59,9 @@ jobs:
input__ui_only_change: ${{ needs.detect-changes.outputs.ui_only }}
input__repo: ${{ github.repository }}
input__pr_number: ${{ github.event.pull_request.number }}
input__enforce: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') }}
input__plan_result: ${{ needs.plan.result }}
input__plan_jobs: ${{ needs.plan.outputs.jobs }}
run: |
import json
import os
Expand All @@ -65,6 +79,13 @@ jobs:
if input.is_fork == 'true':
return False

# The label makes the dispatcher the only starter for these jobs.
if input.enforce == 'true':
if input.plan_result != 'success':
raise SystemExit('dispatcher plan did not succeed')
selected = json.loads(input.plan_jobs or '{}')
return bool(selected.get(self.name, False))

if input.event_name != 'pull_request':
return True
elif self.name in input.pr_labels:
Expand Down Expand Up @@ -124,9 +145,8 @@ jobs:

write('jobs', json.dumps(jobs))

# Find out when we can complete the workflow early by not even waiting for GHA-built images.
wait_for_gha_images = input.event_name != 'pull_request' or input.is_draft != 'true' or any(jobs.values())
write('wait-for-gha-images', str(wait_for_gha_images).lower())
# Image-backed tests need this job. A skipped need skips those tests.
write('wait-for-gha-images', 'true')

# Waiting for konflux-built images in PR request context requires the 'konflux-build' PR label.
wait_for_konflux_images = input.event_name != 'pull_request' or ('konflux-build' in input.pr_labels and any(jobs.values()))
Expand Down
22 changes: 20 additions & 2 deletions .github/workflows/emailsender-central-compatibility.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
- '.github/workflows/emailsender-central-compatibility.yaml'

pull_request:
types: [opened, synchronize, reopened, ready_for_review]
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we only need to run this when the label is added, not when it's removed.

Suggested change
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
types: [opened, synchronize, reopened, ready_for_review, labeled]

paths:
- 'central/notifiers/email/**'
- 'central/notifiers/acscsemail/**'
Expand All @@ -24,15 +24,33 @@ concurrency:
cancel-in-progress: true

jobs:
plan:
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: read
uses: ./.github/workflows/dispatcher-plan.yaml

e2e-test-on-kind:
timeout-minutes: 60
name: "Test on kind cluster"
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.head.repo.fork }} # do not run for PRs from forks
needs: plan
# Forks stay off. The dispatcher does not get to start a job from an untrusted fork.
if: >-
always() && !cancelled() && !github.event.pull_request.head.repo.fork && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce'))
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['e2e-test-on-kind']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
Comment on lines +40 to +45

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified:

Suggested change
if: >-
always() && !cancelled() && !github.event.pull_request.head.repo.fork && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce'))
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['e2e-test-on-kind']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
if: >-
always() && !cancelled() && !github.event.pull_request.head.repo.fork && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce'))
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && (needs.plan.result != 'success' || fromJSON(needs.plan.outputs.jobs)['e2e-test-on-kind'])
)

permissions:
id-token: write
contents: read
steps:
- name: Fail closed when the dispatcher plan did not succeed
if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
run: echo "The dispatcher plan did not succeed, so this job is not running its tests." && exit 1

- name: Login to Quay.io
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # ratchet:docker/login-action@v4
with:
Expand Down
22 changes: 20 additions & 2 deletions .github/workflows/scanner-db-integration-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,36 @@ on:
- opened
- reopened
- synchronize
- labeled
- unlabeled

jobs:
detect-changes:
uses: ./.github/workflows/detect-changes.yml

plan:
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: read
uses: ./.github/workflows/dispatcher-plan.yaml

db-integration-tests:
needs: detect-changes
if: ${{ !needs.detect-changes.outputs.ui_only }}
needs: [detect-changes, plan]
if: >-
always() && !cancelled() && needs.detect-changes.result == 'success' && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && !needs.detect-changes.outputs.ui_only
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['db-integration-tests']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
Comment on lines +31 to +36

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simpler:

Suggested change
if: >-
always() && !cancelled() && needs.detect-changes.result == 'success' && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && !needs.detect-changes.outputs.ui_only
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['db-integration-tests']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
if: >-
always() && !cancelled() && needs.detect-changes.result == 'success' && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && !needs.detect-changes.outputs.ui_only
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && (needs.plan.result != 'success' || fromJSON(needs.plan.outputs.jobs)['db-integration-tests'])
)

runs-on: ubuntu-latest
container:
image: quay.io/stackrox-io/apollo-ci:scanner-test-0.5.11@sha256:cea78f2b3a5a38c9ccda678712daaed90b7c372d6b5df963feb758b32dccebe1 # ratchet:quay.io/stackrox-io/apollo-ci:scanner-test-0.5.11
steps:
- name: Fail closed when the dispatcher plan did not succeed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit]: I'd word this differently

Suggested change
- name: Fail closed when the dispatcher plan did not succeed
- name: Fail: Stopped after the dispatcher plan did not succeed

if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
run: echo "The dispatcher plan did not succeed, so this job is not running its tests." && exit 1

- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # ratchet:actions/checkout@v7.0.0
with:
Expand Down
39 changes: 36 additions & 3 deletions .github/workflows/scanner-e2e-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,35 @@ on:
- opened
- reopened
- synchronize
- labeled
- unlabeled

jobs:
plan:
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: read
uses: ./.github/workflows/dispatcher-plan.yaml

scanner-ft-images:
name: Wait for images
if: >
github.event_name != 'pull_request'
|| contains(github.event.pull_request.labels.*.name, 'scanner-functional-tests')
needs: plan
if: >-
always() && !cancelled() && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && (
github.event_name != 'pull_request'
|| contains(github.event.pull_request.labels.*.name, 'scanner-functional-tests')
)
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['scanner-ft-images']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
Comment on lines +24 to +32

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simpler:

Suggested change
if: >-
always() && !cancelled() && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && (
github.event_name != 'pull_request'
|| contains(github.event.pull_request.labels.*.name, 'scanner-functional-tests')
)
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['scanner-ft-images']
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
if: >-
always() && !cancelled() && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce')) && (
github.event_name != 'pull_request'
|| contains(github.event.pull_request.labels.*.name, 'scanner-functional-tests')
)
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && (needs.plan.result != 'success' || fromJSON(needs.plan.outputs.jobs)['scanner-ft-images'])
)

runs-on: ubuntu-latest
steps:
- name: Fail closed when the dispatcher plan did not succeed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit]

Suggested change
- name: Fail closed when the dispatcher plan did not succeed
- name: Fail: Stopped after the dispatcher plan did not succeed

if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
run: echo "The dispatcher plan did not succeed, so this job is not running its tests." && exit 1

- name: Checkout repo
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # ratchet:actions/checkout@v7.0.0
with:
Expand All @@ -36,6 +56,15 @@ jobs:
name: Deploy and run
needs:
- scanner-ft-images
- plan
if: >-
always() && !cancelled() && (
needs.scanner-ft-images.result == 'success' && (
(github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce'))
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result == 'success' && fromJSON(needs.plan.outputs.jobs)['scanner-ft-run']
)
|| github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
)
runs-on: ubuntu-latest
env:
SCANNER_E2E_QUAY_USERNAME: ${{ secrets.QUAY_RHACS_ENG_RO_USERNAME }}
Expand All @@ -44,6 +73,10 @@ jobs:
SCANNER_E2E_REDHAT_USERNAME: ${{ secrets.REDHAT_USERNAME }}
SCANNER_E2E_REDHAT_PASSWORD: ${{ secrets.REDHAT_PASSWORD }}
steps:
- name: Fail closed when the dispatcher plan did not succeed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit]

Suggested change
- name: Fail closed when the dispatcher plan did not succeed
- name: Fail: Stopped after the dispatcher plan did not succeed

if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci-dispatcher-enforce') && needs.plan.result != 'success'
run: echo "The dispatcher plan did not succeed, so this job is not running its tests." && exit 1

- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # ratchet:actions/checkout@v7.0.0
with:
Expand Down
Loading
Loading