-
Notifications
You must be signed in to change notification settings - Fork 79
feat(helm): add Artifact Hub distribution and multi-arch builds #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Sanjaykumar-2005
wants to merge
15
commits into
optiqor:main
Choose a base branch
from
Sanjaykumar-2005:feat/distribution-multi-arch
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
1e32e7a
feat(release): Helm chart distribution to Artifact Hub and multi-arch…
Sanjaykumar-2005 b8402a8
feat(github): welcome first-time commenters with /assign nudge and st…
btwshivam eb7ed7f
feat(github): GSSoC auto-labels for difficulty and mentor attribution
btwshivam 161c902
fix(github): grant issues:write to GSSoC label workflows
btwshivam bdfe9a6
feat(cli): add --no-banner flag to suppress ASCII header (#71)
shine-sri 7a08799
feat: implement Helm chart packaging and automated release workflow v…
Sanjaykumar-2005 88b00cd
feat(cli): add shell completion for bash, zsh, fish, powershell (#55)
Kshitij-K-Singh c66b7b3
feat(cli): add no-color support for CLI output (#57)
Vidheendu bffb27a
feat(cli): add man page generation via make manpage (#73)
Kshitij-K-Singh 27025a5
build(deps): bump actions/github-script from 7 to 9 in the actions gr…
dependabot[bot] 57efe1f
feat: add initial Helm chart for Kerno and configure Artifact Hub met…
Sanjaykumar-2005 ebbdff8
feat(release): Helm chart distribution to Artifact Hub and multi-arch…
Sanjaykumar-2005 b9662e5
feat: implement Helm chart packaging and automated release workflow v…
Sanjaykumar-2005 ca08b99
feat: add initial Helm chart for Kerno and configure Artifact Hub met…
Sanjaykumar-2005 5501b86
Merge branch 'feat/distribution-multi-arch' of https://github.com/San…
Sanjaykumar-2005 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| # Copyright 2026 Optiqor contributors | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Auto-applies a level:* difficulty label to every PR. One label per PR. | ||
| # Re-runs on synchronize, so a PR that grows out of its initial bucket | ||
| # gets re-classified on each push. | ||
| # | ||
| # Classification (strict; checked top-to-bottom, first match wins): | ||
| # | ||
| # level:critical — touches BPF C, AI, daemon entry, release tooling, | ||
| # install script, Dockerfile, security workflows, | ||
| # or K8s RBAC / security context. Size-independent. | ||
| # | ||
| # level:beginner — ONLY trivial paths (docs, templates, fixtures, | ||
| # .gitignore) AND ≤ 5 files. Any size in that scope. | ||
| # A README rewrite is beginner. A typo is beginner. | ||
| # | ||
| # level:advanced — 400+ total lines OR 9+ files; OR a code path | ||
| # (internal/, pkg/, cmd/) with 100+ lines or 5+ files. | ||
| # | ||
| # level:intermediate — everything else. Default bucket for code work | ||
| # under 100 lines, and for non-code config tweaks | ||
| # that aren't trivial docs. | ||
| # | ||
| # If you need to override, comment with /level <bucket> — not wired yet | ||
| # but the override path is reserved. | ||
|
|
||
| name: GSSoC difficulty label | ||
|
|
||
| on: | ||
| pull_request_target: | ||
| types: [opened, synchronize, reopened] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: write # /issues/:n/labels endpoint is under the issues resource | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
| classify: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/github-script@v9 | ||
| with: | ||
| script: | | ||
| const repo = { owner: context.repo.owner, repo: context.repo.repo }; | ||
| const pr = context.payload.pull_request; | ||
| const prNumber = pr.number; | ||
|
|
||
| const files = await github.paginate(github.rest.pulls.listFiles, { | ||
| ...repo, pull_number: prNumber, per_page: 100, | ||
| }); | ||
| const paths = files.map(f => f.filename); | ||
|
|
||
| // ── Critical surface (size-independent) ──────────────────── | ||
| // | ||
| // A bug here can cause kernel-verifier rejection, capability | ||
| // widening, secret leakage, or a bad release artifact. | ||
| const criticalPatterns = [ | ||
| /^internal\/bpf\/c\//, // BPF C source — verifier risk | ||
| /^internal\/bpf\/.*loader\.go$/, // BPF program loaders | ||
| /^internal\/ai\//, // privacy + API key handling | ||
| /^internal\/cli\/start\.go$/, // daemon entry + capabilities | ||
| /^Dockerfile/, // production image | ||
| /^scripts\/install\.sh$/, // root install + supply chain | ||
| /^SECURITY\.md$/, | ||
| /^\.goreleaser/, | ||
| /^\.github\/workflows\/(release|codeql|cosign|security)/, | ||
| /^deploy\/.*(rbac|security[Cc]ontext|securitycontext)/, | ||
| ]; | ||
|
|
||
| // ── Code paths (intermediate floor) ──────────────────────── | ||
| // | ||
| // Any non-trivial change in these paths is at least intermediate. | ||
| // Touching the doctor engine, a collector, or a CLI command | ||
| // requires understanding the codebase — not beginner work. | ||
| const codePathPatterns = [ | ||
| /^internal\//, | ||
| /^pkg\//, | ||
| /^cmd\//, | ||
| ]; | ||
|
|
||
| // ── Trivial paths (beginner ceiling) ──────────────────────── | ||
| // | ||
| // PRs that touch ONLY these paths qualify for beginner regardless | ||
| // of line count. Docs, config, fixtures, issue/PR templates. | ||
| const trivialPatterns = [ | ||
| /\.md$/, | ||
| /\.gitignore$/, | ||
| /\.editorconfig$/, | ||
| /^docs\//, | ||
| /^testdata\//, | ||
| /^demo\./, | ||
| /^\.github\/ISSUE_TEMPLATE\//, | ||
| /^\.github\/PULL_REQUEST_TEMPLATE\.md$/, | ||
| /^\.github\/mlc-config\.json$/, | ||
| /^\.github\/labeler\.yml$/, | ||
| /^\.github\/dependabot\.yml$/, | ||
| /^LICENSE$/, | ||
| /^CODE_OF_CONDUCT\.md$/, | ||
| /^GOVERNANCE\.md$/, | ||
| ]; | ||
|
|
||
| const lines = (pr.additions || 0) + (pr.deletions || 0); | ||
| const fileCount = paths.length; | ||
| const touchesCritical = paths.some(p => criticalPatterns.some(re => re.test(p))); | ||
| const touchesCode = paths.some(p => codePathPatterns.some(re => re.test(p))); | ||
| const allTrivial = paths.length > 0 && paths.every(p => trivialPatterns.some(re => re.test(p))); | ||
|
|
||
| let level; | ||
| if (touchesCritical) { | ||
| level = 'level:critical'; | ||
| } else if (allTrivial && fileCount <= 5) { | ||
| level = 'level:beginner'; | ||
| } else if (lines >= 400 || fileCount >= 9) { | ||
| level = 'level:advanced'; | ||
| } else if (touchesCode && (lines >= 100 || fileCount >= 5)) { | ||
| level = 'level:advanced'; | ||
| } else if (touchesCode) { | ||
| level = 'level:intermediate'; | ||
| } else { | ||
| level = 'level:intermediate'; | ||
| } | ||
|
|
||
| core.info( | ||
| `PR #${prNumber}: ${lines} lines, ${fileCount} files, ` + | ||
| `critical=${touchesCritical}, code=${touchesCode}, allTrivial=${allTrivial} → ${level}` | ||
| ); | ||
|
|
||
| // Strip any other level:* label, then apply the chosen one. | ||
| const currentLabels = (pr.labels || []).map(l => l.name); | ||
| for (const old of currentLabels) { | ||
| if (old.startsWith('level:') && old !== level) { | ||
| await github.rest.issues.removeLabel({ | ||
| ...repo, issue_number: prNumber, name: old, | ||
| }).catch(() => {}); | ||
| } | ||
| } | ||
| await github.rest.issues.addLabels({ | ||
| ...repo, issue_number: prNumber, labels: [level], | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Copyright 2026 Optiqor contributors | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # When a maintainer (repo collaborator with write+) submits an APPROVED | ||
| # review, apply `mentor:<their-username>` to the PR. The scoring engine | ||
| # uses this label to credit the reviewing mentor with points. | ||
| # | ||
| # Multiple maintainers approving = multiple mentor:* labels. That is | ||
| # intentional: every reviewer who signed off gets credit. | ||
|
|
||
| name: GSSoC mentor attribution | ||
|
|
||
| on: | ||
| pull_request_review: | ||
| types: [submitted] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: write # /repos/:o/:r/labels and /issues/:n/labels live under the issues resource | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
| attribute: | ||
| if: github.event.review.state == 'approved' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/github-script@v9 | ||
| with: | ||
| script: | | ||
| const repo = { owner: context.repo.owner, repo: context.repo.repo }; | ||
| const reviewer = context.payload.review.user.login; | ||
| const prNumber = context.payload.pull_request.number; | ||
|
|
||
| // Only collaborators with write+ count as mentors. | ||
| let isMaintainer = false; | ||
| try { | ||
| const perm = await github.rest.repos.getCollaboratorPermissionLevel({ | ||
| ...repo, username: reviewer, | ||
| }); | ||
| const lvl = perm.data.permission; | ||
| isMaintainer = (lvl === 'admin' || lvl === 'write' || lvl === 'maintain'); | ||
| } catch (e) { | ||
| core.info(`@${reviewer} not a collaborator; skipping mentor attribution`); | ||
| return; | ||
| } | ||
| if (!isMaintainer) { | ||
| core.info(`@${reviewer} lacks write+; skipping`); | ||
| return; | ||
| } | ||
|
|
||
| const label = `mentor:${reviewer}`; | ||
|
|
||
| // Create the label on the fly so we don't need to pre-register | ||
| // every maintainer's username. Pastel gray so they don't shout. | ||
| await github.rest.issues.createLabel({ | ||
| ...repo, | ||
| name: label, | ||
| color: 'C5C5C5', | ||
| description: `Reviewed and approved by @${reviewer}`, | ||
| }).catch(() => {}); // label may already exist | ||
|
|
||
| await github.rest.issues.addLabels({ | ||
| ...repo, issue_number: prNumber, labels: [label], | ||
| }); | ||
|
|
||
| core.info(`applied ${label} to PR #${prNumber}`); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # Copyright 2026 Optiqor contributors | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| name: Helm Chart Release | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - "v*" | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| jobs: | ||
| release-chart: | ||
| name: Release Chart | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Configure Git | ||
| run: | | ||
| git config user.name "$GITHUB_ACTOR" | ||
| git config user.email "$GITHUB_ACTOR@users.noreply.github.com" | ||
|
|
||
| - name: Install Helm | ||
| uses: azure/setup-helm@v4 | ||
|
|
||
| - name: Run chart-releaser | ||
| uses: helm/chart-releaser-action@v1 | ||
| with: | ||
| charts_dir: deploy/helm | ||
| env: | ||
| CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" | ||
|
|
||
| # After chart-releaser finishes, it has updated gh-pages. | ||
| # We need to ensure artifacthub-repo.yml is in the root of gh-pages. | ||
| - name: Push Artifact Hub metadata | ||
| run: | | ||
| cp artifacthub-repo.yml /tmp/ahr.yml | ||
| git checkout gh-pages | ||
| cp /tmp/ahr.yml ./artifacthub-repo.yml | ||
| git add artifacthub-repo.yml | ||
| git commit -m "chore: update artifacthub-repo.yml" || echo "No changes to commit" | ||
| git push origin gh-pages | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Copyright 2026 Optiqor contributors | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Welcomes a contributor on their first issue comment. Sister to | ||
| # welcome.yml, which only fires on issue/PR open. | ||
|
|
||
| name: Welcome first-time commenters | ||
|
|
||
| on: | ||
| issue_comment: | ||
| types: [created] | ||
|
|
||
| permissions: | ||
| issues: write | ||
|
|
||
| jobs: | ||
| welcome: | ||
| if: | | ||
| github.event.comment.user.type != 'Bot' && | ||
| github.event.comment.user.login != github.repository_owner && | ||
| github.event.comment.user.login != github.event.issue.user.login && | ||
| !github.event.issue.pull_request | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/github-script@v9 | ||
| with: | ||
| script: | | ||
| const repo = { owner: context.repo.owner, repo: context.repo.repo }; | ||
| const commenter = context.payload.comment.user.login; | ||
| const issueNumber = context.payload.issue.number; | ||
|
|
||
| // Skip if the user has already commented on a different issue. | ||
| const res = await github.rest.search.issuesAndPullRequests({ | ||
| q: `repo:${repo.owner}/${repo.repo} commenter:${commenter} is:issue`, | ||
| per_page: 10, | ||
| }); | ||
| if ((res.data.items || []).some(i => i.number !== issueNumber)) { | ||
| core.info(`@${commenter} is not a first-time commenter; skipping`); | ||
| return; | ||
| } | ||
|
|
||
| const body = | ||
| `Hey @${commenter}, welcome. Looks like this is your first comment in the repo.\n\n` + | ||
| `Want to work on this issue? Reply with \`/assign\` or \`/take\` to claim it.\n\n` + | ||
| `If the work's been useful, two quick ways to help:\n\n` + | ||
| `⭐ [Star kerno](https://github.com/optiqor/kerno): eBPF kernel diagnosis engine\n` + | ||
| `⭐ [Star optiqor-cli](https://github.com/optiqor/optiqor-cli): Kubernetes cost remediation that lives in the pull request\n\n` + | ||
| `Thanks for showing up.`; | ||
|
|
||
| await github.rest.issues.createComment({ | ||
| ...repo, issue_number: issueNumber, body, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
git checkout gh-pageshere is fragile. chart-releaser-action pushes gh-pages over the api and doesn't leave a local gh-pages branch, so after a freshcheckout@v6this either fails withpathspec gh-pages did not matchor races chart-releaser's own push and hits a non-fast-forward. the job only runs on tag, so ci never exercised it. simpler: commitartifacthub-repo.ymlto the gh-pages root once by hand, or use chart-releaser's own index/pages options instead of a manual checkout+push.