Skip to content
Open
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
40 changes: 33 additions & 7 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ on:
# a branch PRs never target (this said `master`, which does not exist) means
# the workflow never runs at all.
#
# paths-ignore: a kind+cert-manager+Kamaji provisioning run costs ~30-45
# minutes; skip it for PRs that touch nothing the suite exercises
# (docs-only changes). Everything else — Go code, manifests, the harness,
# the workflows themselves — still gates.
# No paths filter on the trigger either: `kamaji-datastore` is a *required*
# status check, and a workflow skipped at the trigger never reports its
# check, leaving the required context stuck in "Expected" — which blocks the
# PR forever (e.g. docs-only PRs). Path filtering instead lives in the
# `changes` job below; a job skipped via `if:` still reports its check as
# "skipped", which branch protection treats as passing.
pull_request:
paths-ignore:
- '**.md'
- 'docs/**'
push:
tags: [ "v*" ]
workflow_dispatch:
Expand All @@ -23,7 +22,34 @@ concurrency:
cancel-in-progress: true

jobs:
changes:
# Cheap (~seconds, no checkout — dorny uses the PR API) gate that decides
# whether the expensive job below needs to run. PR-only: tag pushes and
# manual dispatch always run the suite unconditionally (see the `if` on
# kamaji-datastore).
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: dorny/paths-filter@v3

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pin dorny/paths-filter to a commit SHA.

The action reference dorny/paths-filter@v3 is unpinned. Per static analysis policy, action references should be pinned to a commit SHA to prevent supply-chain attacks.

🔒 Proposed fix
-      - uses: dorny/paths-filter@v3
+      - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36  # v3.0.2
         id: filter

Verify the SHA corresponds to the intended v3.x release in the dorny/paths-filter repository.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: dorny/paths-filter@v3
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
🧰 Tools
🪛 zizmor (1.25.2)

[error] 35-35: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e.yml at line 35, The workflow uses an unpinned action
reference `dorny/paths-filter@v3`; replace that tag with a specific commit SHA
for the intended v3 release to mitigate supply-chain risk. Locate the `uses:
dorny/paths-filter@v3` entry in the e2e.yml workflow, find the corresponding v3
commit SHA from the dorny/paths-filter GitHub releases or tags, and update the
line to `uses: dorny/paths-filter@<commit-sha>` ensuring the SHA matches the
v3.x release you want to pin to.

Source: Linters/SAST tools

id: filter
with:
# `code` is true when the PR touches anything the e2e suite
# exercises. Only-negated patterns get an implicit `**`, so this
# reads as "all files except Markdown and docs/**" — i.e. docs-only
# PRs leave `code` false and the ~30-45 min run below is skipped.
filters: |
code:
- '!**/*.md'
- '!docs/**'
Comment on lines +25 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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Restrict permissions for the changes job.

The changes job uses default repository permissions. Since it only reads PR metadata via the GitHub API (no checkout, no writes), it should declare minimal read-only permissions.

🔐 Proposed permissions block
   changes:
     if: github.event_name == 'pull_request'
     runs-on: ubuntu-latest
+    permissions:
+      pull-requests: read
     outputs:
       code: ${{ steps.filter.outputs.code }}
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 25-45: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 35-35: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e.yml around lines 25 - 45, Add a minimal permissions
block to the "changes" job so it doesn't run with default repo permissions;
under the job named changes (the job that defines outputs from the
dorny/paths-filter step with id filter) add e.g. permissions: pull-requests:
read (and any other specific read-only scopes you need) to limit access to
read-only PR metadata via the GitHub API.

Source: Linters/SAST tools


kamaji-datastore:
needs: changes
# Always run for tag pushes / manual dispatch; for PRs, run only when
# non-docs files changed. When skipped on a docs-only PR the check still
# reports (as "skipped" = passing), so the PR is not blocked.
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.code == 'true' }}
Comment on lines +48 to +52

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.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

Shared root cause: needs: changes breaks non-PR execution in both workflows.

Both .github/workflows/e2e.yml (kamaji-datastore job) and .github/workflows/release-smoke.yml (smoke job) declare needs: changes, but the changes job only runs when github.event_name == 'pull_request'. In GitHub Actions, when a needed job is skipped, the dependent job is skipped by default—regardless of its if: condition. This means:

  • On tag push (e2e.yml trigger line 17), kamaji-datastore will never run
  • On workflow_dispatch (release-smoke.yml trigger line 20), smoke will never run

The shared fix is to wrap both jobs' conditions in always():

e2e.yml:

   kamaji-datastore:
     needs: changes
-    if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.code == 'true' }}
+    if: ${{ always() && (github.event_name != 'pull_request' || needs.changes.outputs.code == 'true') }}

release-smoke.yml:

   smoke:
     needs: changes
-    if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.release == 'true' }}
+    if: ${{ always() && (github.event_name != 'pull_request' || needs.changes.outputs.release == 'true') }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
needs: changes
# Always run for tag pushes / manual dispatch; for PRs, run only when
# non-docs files changed. When skipped on a docs-only PR the check still
# reports (as "skipped" = passing), so the PR is not blocked.
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.code == 'true' }}
needs: changes
# Always run for tag pushes / manual dispatch; for PRs, run only when
# non-docs files changed. When skipped on a docs-only PR the check still
# reports (as "skipped" = passing), so the PR is not blocked.
if: ${{ always() && (github.event_name != 'pull_request' || needs.changes.outputs.code == 'true') }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e.yml around lines 48 - 52, The dependent jobs
'kamaji-datastore' (in e2e.yml) and 'smoke' (in release-smoke.yml) currently
declare needs: changes but their existing if: condition is skipped when the
'changes' job itself is skipped; update each job's if to guard with always(),
e.g. if: ${{ always() && (github.event_name != 'pull_request' ||
needs.changes.outputs.code == 'true') }}, so the job evaluates the condition
even when 'changes' is skipped and will run correctly for tag pushes and
workflow_dispatch; keep the needs: changes declaration and only change the if
expression to include always().

runs-on: ubuntu-latest
timeout-minutes: 45
steps:
Expand Down
47 changes: 37 additions & 10 deletions .github/workflows/release-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,52 @@ name: Release install smoke
# introduces them, not on the first real tag. The image is loaded into kind,
# never pushed — no registry credentials.
on:
# No paths filter on the trigger: `smoke (helm)` and `smoke (manifest)` are
# *required* status checks, and a workflow skipped at the trigger never
# reports them, leaving the required contexts stuck in "Expected" and
# blocking the PR forever (e.g. docs-only PRs). Path filtering lives in the
# `changes` job below instead; the matrix job is skipped via `if:` when
# nothing release-relevant changed, and a skipped check counts as passing.
pull_request:
paths:
- '.github/workflows/release-smoke.yml'
- '.github/workflows/docker-publish.yml'
- '.github/workflows/release-assets.yml'
- '.github/workflows/helm-publish.yml'
- 'hack/release-smoke.sh'
- 'charts/**'
- 'Makefile'
- 'Dockerfile'
- 'api/**'
workflow_dispatch:

concurrency:
group: release-smoke-${{ github.ref }}
cancel-in-progress: true

jobs:
changes:
# Cheap (~seconds, no checkout) gate. PR-only: manual dispatch always runs
# the smoke matrix unconditionally (see the `if` on smoke).
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
outputs:
release: ${{ steps.filter.outputs.release }}
steps:
- uses: dorny/paths-filter@v3

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pin dorny/paths-filter to a commit SHA.

The action reference dorny/paths-filter@v3 is unpinned. Per static analysis policy, action references should be pinned to a commit SHA to prevent supply-chain attacks.

🔒 Proposed fix
-      - uses: dorny/paths-filter@v3
+      - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36  # v3.0.2
         id: filter

Verify the SHA corresponds to the intended v3.x release in the dorny/paths-filter repository.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: dorny/paths-filter@v3
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
🧰 Tools
🪛 zizmor (1.25.2)

[error] 35-35: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-smoke.yml at line 35, The workflow uses an
unpinned action reference "dorny/paths-filter@v3" which must be replaced with a
commit SHA to mitigate supply-chain risks; update the "uses:
dorny/paths-filter@v3" line to "uses: dorny/paths-filter@<commit-sha>" where
<commit-sha> is the full SHA of the v3 release commit (verify the SHA matches
the intended v3.x tag on the dorny/paths-filter repository before committing).

Source: Linters/SAST tools

id: filter
with:
# True when the PR touches the tag-release machinery or anything it
# ships. Matches the paths this workflow used to filter on at the
# trigger; PRs that touch none of these skip the two kind smokes.
filters: |
release:
- '.github/workflows/release-smoke.yml'
- '.github/workflows/docker-publish.yml'
- '.github/workflows/release-assets.yml'
- '.github/workflows/helm-publish.yml'
- 'hack/release-smoke.sh'
- 'charts/**'
- 'Makefile'
- 'Dockerfile'
- 'api/**'
Comment on lines +27 to +51

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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Restrict permissions for the changes job.

The changes job uses default repository permissions. Since it only reads PR metadata via the GitHub API (no checkout, no writes), it should declare minimal read-only permissions.

🔐 Proposed permissions block
   changes:
     if: github.event_name == 'pull_request'
     runs-on: ubuntu-latest
+    permissions:
+      pull-requests: read
     outputs:
       release: ${{ steps.filter.outputs.release }}
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 27-51: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 35-35: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-smoke.yml around lines 27 - 51, In the "changes"
job (the job block labeled changes that runs the dorny/paths-filter step with id
"filter"), replace the default repository permissions by adding a minimal
permissions block that grants only what is needed to read PR metadata (e.g., set
pull-requests: read and contents: none) so the job has explicit read-only access
and no write permissions; ensure the permissions block is placed at the same
indentation level as runs-on and steps within the "changes" job.

Source: Linters/SAST tools


smoke:
needs: changes
# Always run on manual dispatch; for PRs, run only when release-relevant
# files changed. When skipped, each matrix leg's required check still
# reports as "skipped" (= passing), so the PR is not blocked.
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.release == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
Expand Down
Loading