Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
578479b
ci(workflows): consolidate PR checks and add /e2e command runner
abhijith-darshan May 19, 2026
8b49602
ci(workflows): auto-skip when no e2e suites match and trim info comment
abhijith-darshan May 19, 2026
668dbe7
(chore): test e2e on code change
abhijith-darshan May 19, 2026
7a4051e
ci(workflows): grant contents:write to lint-license and tighten info …
abhijith-darshan May 19, 2026
d54ddb6
ci(workflows): rename info step and always recreate the info comment
abhijith-darshan May 19, 2026
c448e2c
ci(workflows): simplify info comment and restore CC0 SPDX tag
abhijith-darshan May 19, 2026
f0962f6
ci(workflows): list detected suites as runnable commands
abhijith-darshan May 19, 2026
ef2dfc6
(chore): use existing workflow name
abhijith-darshan May 19, 2026
73f2acf
(chore): rename file to old name
abhijith-darshan May 19, 2026
2d84b91
(chore): reduce ci pr jobs and restore ci-e2e-test
abhijith-darshan May 19, 2026
307b944
(chore): add comment driven E2E flow diagram
abhijith-darshan May 19, 2026
2acb56d
ci(workflows): replace pull_request e2e with comment-driven runner
abhijith-darshan May 25, 2026
2e8b1a4
ci(workflows): fix reactions permission for e2e runner
abhijith-darshan May 25, 2026
d4dffab
ci(workflows): drop acknowledge step from e2e runner
abhijith-darshan May 25, 2026
4c20e79
ci(workflows): pin common e2e action to f87e1e6 (main)
abhijith-darshan May 26, 2026
733b8b2
ci(workflows): add per-suite commit status to e2e runner
abhijith-darshan May 29, 2026
73c015c
(chore): undo test changes
abhijith-darshan May 29, 2026
ce721b6
ci(workflows): remove markers from auto-skip and renovate e2e comments
abhijith-darshan May 29, 2026
ba0b71d
ci(workflows): use GitHub App token for auto e2e comments
abhijith-darshan May 29, 2026
87bbf41
ci(workflows): fix app token permission for PR comments
abhijith-darshan May 29, 2026
7112633
ci(workflows): allow cloud-operator-bot to trigger e2e runner
abhijith-darshan May 29, 2026
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
21 changes: 21 additions & 0 deletions .github/paths-filters-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Path filters consumed by .github/workflows/ci-pr.yaml via dorny/paths-filter.
# Edit this file to change which paths trigger which lint/test/build jobs β€”
# no workflow YAML changes required.

go:
- 'internal/**'
- 'cmd/**'
- 'pkg/**'
- 'api/**'
- 'go.mod'
- 'go.sum'
- '.golangci.yaml'
- 'Dockerfile*'
- 'Makefile'

api:
- 'api/**'
- 'charts/manager/crds/**'

charts:
- 'charts/**'
55 changes: 55 additions & 0 deletions .github/paths-filters-e2e.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Path filters consumed by .github/workflows/ci-e2e-info.yaml via dorny/paths-filter.
# Each top-level key (other than `shared`) is an e2e suite name. The info workflow
# uses these to suggest `/e2e <suite>` comments on a PR.
# Edit this file to change suite scoping β€” no workflow YAML changes required.

# Shared changes affect every suite β€” info workflow recommends `/e2e all`.
shared:
- 'go.mod'
- 'go.sum'
- 'Dockerfile*'
- 'cmd/greenhouse/**'
- 'internal/helm/**'
- 'internal/flux/**'
- 'internal/clientutil/**'
- 'charts/**'
- 'e2e/shared/**'

organization:
- 'internal/controller/organization/**'
- 'api/v1alpha1/organization*.go'
- 'e2e/organization/**'

cluster:
- 'internal/controller/cluster/**'
- 'api/v1alpha1/cluster*.go'
- 'api/v1alpha2/cluster*.go'
- 'e2e/cluster/**'

catalog:
- 'internal/controller/catalog/**'
- 'internal/flux/**'
- 'api/v1alpha1/catalog*.go'
- 'e2e/catalog/**'

plugin:
- 'internal/controller/plugin/**'
- 'internal/controller/pluginpreset/**'
- 'internal/ocimirror/**'
- 'api/v1alpha1/plugin*.go'
- 'e2e/plugin/**'

plugindefinition:
- 'internal/controller/plugindefinition/**'
- 'api/v1alpha1/plugindefinition*.go'
- 'e2e/plugindefinition/**'

clusterplugindefinition:
- 'internal/controller/clusterplugindefinition/**'
- 'api/v1alpha1/clusterplugindefinition*.go'
- 'e2e/clusterplugindefinition/**'

teamrolebinding:
- 'internal/controller/teamrolebinding/**'
- 'api/v1alpha1/teamrole*.go'
- 'e2e/teamrolebinding/**'
50 changes: 0 additions & 50 deletions .github/workflows/check-changes-crd-api.yaml

This file was deleted.

145 changes: 145 additions & 0 deletions .github/workflows/ci-e2e-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: CI E2E Info

on:
pull_request:
types: [opened, synchronize, reopened]

permissions:
contents: read
pull-requests: write

jobs:
detect:
name: Detect relevant suites
runs-on: [ubuntu-latest]
outputs:
changes: ${{ steps.filter.outputs.changes }}
has-suites: ${{ steps.classify.outputs.has-suites }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Filter e2e suites
id: filter
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with:
filters: .github/paths-filters-e2e.yaml

- name: Check e2e suites
id: classify
env:
CHANGES: ${{ steps.filter.outputs.changes }}
run: |
# has-suites = true if the changes array is non-empty
if [ "${CHANGES:-[]}" = "[]" ]; then
echo "has-suites=false" >> "$GITHUB_OUTPUT"
else
echo "has-suites=true" >> "$GITHUB_OUTPUT"
fi

info-comment:
name: Info comment
needs: [detect]
if: needs.detect.outputs.has-suites == 'true' && github.event.pull_request.user.login != 'renovate[bot]'
runs-on: [ubuntu-latest]
steps:
- name: E2E Info
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v8.0.0
env:
CHANGES: ${{ needs.detect.outputs.changes }}
with:
script: |
const marker = '<!-- ci-e2e:info -->';
const matched = JSON.parse(process.env.CHANGES || '[]');
const sharedHit = matched.includes('shared');
const suites = matched.filter(s => s !== 'shared');

let body = `${marker}\n## E2E Info\n\n`;

if (sharedHit) {
body += `Shared code changed β€” full E2E run is recommended.\n\n`;
body += `Comment \`/e2e all\` to run all suites.\n`;
} else {
const suiteList = suites.map(s => `/e2e ${s}`).join('\n');
body += `<details><summary><b>Detected E2E Suites</b></summary>\n\n\`\`\`\n${suiteList}\n\`\`\`\n\n</details>\n\n`;
body += `Comment \`/e2e all\` to run all suites.\n`;
}

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
for (const c of comments) {
if (c.body && c.body.startsWith(marker)) {
await github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: c.id,
});
}
}
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});

auto-skip-e2e:
name: Auto-skip e2e
needs: [detect]
if: needs.detect.outputs.has-suites == 'false' && github.event.pull_request.user.login != 'renovate[bot]'
runs-on: [ubuntu-latest]
steps:
- name: Generate GitHub App token
id: app-token
if: ${{ !github.event.pull_request.head.repo.fork }}
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.CLOUDOPERATOR_APP_ID }}
private-key: ${{ secrets.CLOUDOPERATOR_APP_PRIVATE_KEY }}
permission-pull-requests: write

- name: Post /e2e skip comment
if: ${{ !github.event.pull_request.head.repo.fork }}
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v8.0.0
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '/e2e skip',
});

auto-run-e2e-renovate:
name: Auto-run e2e for renovate
needs: [detect]
if: github.event.pull_request.user.login == 'renovate[bot]'
runs-on: [ubuntu-latest]
steps:
- name: Generate GitHub App token
id: app-token
if: ${{ !github.event.pull_request.head.repo.fork }}
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.CLOUDOPERATOR_APP_ID }}
private-key: ${{ secrets.CLOUDOPERATOR_APP_PRIVATE_KEY }}
permission-pull-requests: write

- name: Post /e2e command comment
if: ${{ !github.event.pull_request.head.repo.fork }}
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v8.0.0
env:
HAS_SUITES: ${{ needs.detect.outputs.has-suites }}
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const cmd = process.env.HAS_SUITES === 'true' ? '/e2e all' : '/e2e skip';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: cmd,
});
47 changes: 41 additions & 6 deletions .github/workflows/ci-e2e-run.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ jobs:
suites: ${{ steps.suites.outputs.suites }}
run: ${{ steps.cmd.outputs.run }}
steps:
- name: Check commenter is a collaborator
- name: Check Collaborator Permission
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
if (context.actor === 'cloud-operator-bot[bot]') {
return;
}
try {
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
Expand All @@ -37,7 +40,7 @@ jobs:
core.setFailed(`e2e trigger denied β€” @${context.actor} is not a maintainer.`);
}

- name: Resolve PR head SHA
- name: Resolve PR SHA
id: pr
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
Expand All @@ -46,7 +49,7 @@ jobs:
const pr = await github.rest.pulls.get({ owner, repo, pull_number: number });
core.setOutput('sha', pr.data.head.sha);

- name: Parse comment body
- name: Parse Command
id: cmd
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
Expand Down Expand Up @@ -85,13 +88,13 @@ jobs:
core.setOutput('discover', 'false');
core.setOutput('explicit', JSON.stringify([...new Set(tokens)]));

- name: Checkout PR head (for suite discovery)
- name: Checkout PR
if: steps.cmd.outputs.discover == 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ steps.pr.outputs.sha }}

- name: Resolve suite list
- name: Resolve Suites
id: suites
env:
DISCOVER: ${{ steps.cmd.outputs.discover }}
Expand All @@ -115,9 +118,23 @@ jobs:
matrix:
suite: ${{ fromJson(needs.parse.outputs.suites) }}
steps:
- name: "Set e2e/${{ matrix.suite }} Pending"
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: '${{ needs.parse.outputs.sha }}',
state: 'pending',
context: 'e2e / ${{ matrix.suite }}',
description: 'running',
target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
});

- name: Run ${{ matrix.suite }} e2e
id: e2e
uses: cloudoperators/common/workflows/e2e@f87e1e6b7889707a9c10d1a8a9f9f481eb311c06
uses: cloudoperators/common/workflows/e2e@f87e1e6b7889707a9c10d1a8a9f9f481eb311c06 # main
env:
RUNTIME_ENV: "CI"
GH_APP_ID: ${{ secrets.CLOUDOPERATOR_APP_ID }}
Expand All @@ -139,6 +156,24 @@ jobs:
E2E_RESULT_DIR: ${{ github.workspace }}/bin
run: make show-e2e-logs

- name: "Set e2e/${{ matrix.suite }} Status"
if: always()
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
E2E_RESULT: ${{ steps.e2e.conclusion }}
with:
script: |
const ok = process.env.E2E_RESULT === 'success';
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: '${{ needs.parse.outputs.sha }}',
state: ok ? 'success' : 'failure',
context: 'e2e / ${{ matrix.suite }}',
description: ok ? 'passed' : 'failed',
target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
});

e2eOK:
name: e2eOK
needs: [parse, e2e]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-e2e-test-nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
GH_APP_PRIVATE_KEY: ${{ secrets.CLOUDOPERATOR_APP_PRIVATE_KEY }}
GH_APP_INSTALLATION_ID: ${{ secrets.CLOUDOPERATOR_APP_INSTALLATION_ID }}
with:
admin-k8s-version: "v1.33.7"
admin-k8s-version: "v1.34.3"
remote-k8s-version: ${{ matrix.k8s-version }}
scenario: ${{ matrix.e2es }}
admin-config: ${{ github.workspace }}/e2e/greenhouse-admin-cluster.yaml
Expand Down
Loading
Loading