Skip to content

Koanf, commitlint-scope self-food#18

Merged
thumbrise merged 3 commits into
mainfrom
self-food
May 30, 2026
Merged

Koanf, commitlint-scope self-food#18
thumbrise merged 3 commits into
mainfrom
self-food

Conversation

@thumbrise
Copy link
Copy Markdown
Owner

@thumbrise thumbrise commented May 30, 2026

Summary by CodeRabbit

  • New Features

    • Automated commit scope validation integrated into CI pipeline
    • Configuration template added for customizing scope validation rules
  • Chores

    • Dependencies updated for improved configuration handling
    • Build and linting infrastructure enhanced with scope validation support

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Warning

Review limit reached

@thumbrise, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 48 minutes and 33 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f60a668c-73bd-4057-bc9b-571d941eaf6d

📥 Commits

Reviewing files that changed from the base of the PR and between bf290f4 and 6a20ae6.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (8)
  • .commitlint-scope.yaml
  • .github/workflows/ci.yml
  • README.md
  • Taskfile.yaml
  • cmd/commands/init.go
  • go.mod
  • pkg/validator/config.go
  • pkg/validator/config_test.go
📝 Walkthrough

Walkthrough

This pull request migrates the configuration system from spf13/viper to koanf with YAML file provider support. Dependencies are updated, config struct tags are changed, and the loading logic is rewritten. A configuration template is added, and CI/CD integration for scope validation is introduced.

Changes

Configuration System Migration from Viper to Koanf

Layer / File(s) Summary
Dependencies and imports
go.mod, pkg/validator/config.go
Direct dependencies switched from spf13/viper to koanf/v2 with YAML and file providers. Indirect dependencies updated accordingly. Import statements in config.go updated and ConfigName constant changed to .commitlint-scope.yaml.
Config structures and decode hooks
pkg/validator/config.go
PatternItem and Config struct field tags migrated from mapstructure: to koanf: annotations. Error variables reorganized into grouped var block. Regex decode hook refactored from a regexDecode function mutating decoder config to a regexDecodeHook function accepting reflect.Type parameters.
LoadConfig implementation
pkg/validator/config.go, pkg/validator/config_test.go
LoadConfig rewritten to use koanf's file provider with YAML parser, set default scopeRegex, and unmarshal via koanf.UnmarshalWithConf with the custom decode hook. Error handling updated for missing config via os.IsNotExist. Test updated to use validator.ConfigName constant instead of hard-coded filename.
Configuration template and CI/CD integration
.commitlint-scope.yml, .github/workflows/ci.yml, Taskfile.yaml
Configuration template file added with schema reference and patterns documentation. GitHub Actions workflow extended with commitlint-scope job for PR scope validation using Docker image. Taskfile lint task includes Docker-based commitlint-scope command for local development linting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • thumbrise/commitlint-scope#5: Prior viper-to-koanf migration work in config.go that this PR directly extends with complete LoadConfig rewrite and decode hook refactoring.
  • thumbrise/commitlint-scope#17: Configuration data model changes introducing PatternItem with scopes/files mapping that integrate with this PR's koanf-based config loading and field tag updates.
  • thumbrise/commitlint-scope#1: Initial CLI implementation that depends on LoadConfig functionality being stable; this migration changes how configuration is loaded and parsed during CLI execution.

Poem

🐰 From Viper's coils to Koanf's grace,
YAML files find their rightful place,
Struct tags dance their merry koanf,
Decode hooks compile with gentle wink,
Config migration, clean and bright,
Our scope validator shines with might! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and does not clearly convey the main objective of the changeset. Use a more descriptive title that explains the primary change, such as 'Migrate config loading from Viper to Koanf' or 'Add commitlint-scope integration and switch config provider'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch self-food

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.commitlint-scope.yml (1)

1-22: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Config template filename does not match loader’s expected config name.

pkg/validator/config.go loads only .commitlint-scope.yaml (see validator.ConfigName), but this repository-level template is .commitlint-scope.yml. As written, this can cause the config to be ignored in normal runs.

Suggested fix
- .commitlint-scope.yml
+ .commitlint-scope.yaml

Or pass an explicit config path wherever the tool is invoked.

🤖 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 @.commitlint-scope.yml around lines 1 - 22, The repository template file is
named .commitlint-scope.yml but validator.ConfigName expects
.commitlint-scope.yaml, so the loader will ignore it; fix by either renaming
this file to .commitlint-scope.yaml to match the loader or update the loader's
constant (validator.ConfigName) to accept ".commitlint-scope.yml" (or support
both names) and ensure any callers that pass an explicit path are updated
accordingly.
🧹 Nitpick comments (1)
Taskfile.yaml (1)

13-13: ⚡ Quick win

Pin the Docker image digest for reproducible local linting.

Using latest-alpine makes results drift over time across machines. Pinning a digest keeps local task lint behavior stable.

Suggested fix
-      - docker run --rm -v "$(pwd):/repo" -w /repo thumbrise/commitlint-scope:latest-alpine run --from main --to HEAD
+      - docker run --rm -v "$(pwd):/repo" -w /repo thumbrise/commitlint-scope@sha256:<image_digest> run --from main --to HEAD
🤖 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 `@Taskfile.yaml` at line 13, Replace the floating image tag in the Taskfile
lint command so local runs are reproducible: change the image reference in the
command string that currently uses "thumbrise/commitlint-scope:latest-alpine" to
the same image pinned by digest (e.g.,
"thumbrise/commitlint-scope@sha256:<digest>"). Obtain the correct sha256 by
pulling the desired image version and inspecting it (docker pull
thumbrise/commitlint-scope:latest-alpine && docker inspect --format='{{index
.RepoDigests 0}}' ...) or via the registry manifest, then update the Taskfile
command "docker run --rm -v \"$(pwd):/repo\" -w /repo
thumbrise/commitlint-scope:latest-alpine run --from main --to HEAD" to use the
`@sha256` pin instead of :latest-alpine.
🤖 Prompt for all review comments with 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.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 66-79: Update the "actions/checkout" step to use a fixed commit
SHA instead of the v6 tag and add persist-credentials: false to disable
credential persistence; in the "Lint commit scopes" step replace the mutable
Docker image thumbrise/commitlint-scope:latest-alpine with its immutable image
digest (sha256@...) so the run uses a pinned image; ensure these changes are
applied in the checkout step and the Lint commit scopes docker run invocation
(the two unique identifiers to edit are the actions/checkout usage and the
thumbrise/commitlint-scope image reference).

In `@pkg/validator/config.go`:
- Line 16: ConfigName was turned into a full filename which conflicts with
cmd/commands/init.go appending ".yml" and drops legacy support; change
ConfigName back to the basename ".commitlint-scope" and update LoadConfig() to
look for ConfigName+".yaml", then ConfigName+".yml", then the legacy ConfigName
(no extension) so both init (which can continue using ConfigName+".yml") and
existing repos are supported. Ensure references use the ConfigName symbol and
keep the search order so ".yaml" takes precedence, then ".yml", then the legacy
filename.

---

Outside diff comments:
In @.commitlint-scope.yml:
- Around line 1-22: The repository template file is named .commitlint-scope.yml
but validator.ConfigName expects .commitlint-scope.yaml, so the loader will
ignore it; fix by either renaming this file to .commitlint-scope.yaml to match
the loader or update the loader's constant (validator.ConfigName) to accept
".commitlint-scope.yml" (or support both names) and ensure any callers that pass
an explicit path are updated accordingly.

---

Nitpick comments:
In `@Taskfile.yaml`:
- Line 13: Replace the floating image tag in the Taskfile lint command so local
runs are reproducible: change the image reference in the command string that
currently uses "thumbrise/commitlint-scope:latest-alpine" to the same image
pinned by digest (e.g., "thumbrise/commitlint-scope@sha256:<digest>"). Obtain
the correct sha256 by pulling the desired image version and inspecting it
(docker pull thumbrise/commitlint-scope:latest-alpine && docker inspect
--format='{{index .RepoDigests 0}}' ...) or via the registry manifest, then
update the Taskfile command "docker run --rm -v \"$(pwd):/repo\" -w /repo
thumbrise/commitlint-scope:latest-alpine run --from main --to HEAD" to use the
`@sha256` pin instead of :latest-alpine.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6bd627c7-3994-4c85-b6b7-cad330ed2e1c

📥 Commits

Reviewing files that changed from the base of the PR and between 7e8cba5 and bf290f4.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (6)
  • .commitlint-scope.yml
  • .github/workflows/ci.yml
  • Taskfile.yaml
  • go.mod
  • pkg/validator/config.go
  • pkg/validator/config_test.go

Comment thread .github/workflows/ci.yml
Comment on lines +66 to +79
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Lint commit scopes
run: |
docker run --rm \
-v "${{ github.workspace }}:/repo" \
-w /repo \
thumbrise/commitlint-scope:latest-alpine \
run \
--from ${{ github.event.pull_request.base.sha }} \
--to ${{ github.event.pull_request.head.sha }} \
--verbose
Copy link
Copy Markdown

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/ci.yml"
if [ ! -f "$FILE" ]; then
  echo "Missing $FILE" >&2
  exit 1
fi

echo "== File: $FILE =="
python3 - <<'PY'
import itertools
path=".github/workflows/ci.yml"
with open(path,'r',encoding='utf-8') as f:
    lines=f.readlines()
for i in range(1, len(lines)+1):
    if 60 <= i <= 95:
        print(f"{i:4d}: {lines[i-1].rstrip()}")
PY

echo
echo "== Extract relevant uses/run lines =="
rg -n "actions/checkout@|persist-credentials|commitlint-scope:" "$FILE" || true

Repository: thumbrise/commitlint-scope

Length of output: 1530


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE=".github/workflows/ci.yml"
echo "== Search persist-credentials =="
rg -n "persist-credentials" "$FILE" || true

echo
echo "== Search all commitlint-scope image tags =="
rg -n "thumbrise/commitlint-scope:" "$FILE" || true

Repository: thumbrise/commitlint-scope

Length of output: 207


🌐 Web query:

actions/checkout persist-credentials default true

💡 Result:

In GitHub Actions, the actions/checkout input persist-credentials defaults to true (i.e., credentials are persisted unless you set persist-credentials: false). [1][2] What “persist-credentials” does: - When persist-credentials is enabled, actions/checkout stores the auth token in the local git config so later steps can run authenticated git commands; the token is removed during post-job cleanup. [2][1] How to opt out: - Set persist-credentials: false on the checkout step where you don’t need authenticated git operations (e.g., read-only workflows). [2][3]

Citations:


Harden commitlint-scope job supply-chain + token hygiene

  • Pin actions/checkout@v6 to a full commit SHA (line 66) instead of a moving tag.
  • Replace thumbrise/commitlint-scope:latest-alpine (line 75) with an immutable image digest.
  • Disable checkout credential persistence by adding persist-credentials: false to the checkout step (currently unset, so it defaults to true).
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 66-68: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 66-66: 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/ci.yml around lines 66 - 79, Update the "actions/checkout"
step to use a fixed commit SHA instead of the v6 tag and add
persist-credentials: false to disable credential persistence; in the "Lint
commit scopes" step replace the mutable Docker image
thumbrise/commitlint-scope:latest-alpine with its immutable image digest
(sha256@...) so the run uses a pinned image; ensure these changes are applied in
the checkout step and the Lint commit scopes docker run invocation (the two
unique identifiers to edit are the actions/checkout usage and the
thumbrise/commitlint-scope image reference).

Comment thread pkg/validator/config.go
)

const ConfigName = ".commitlint-scope"
const ConfigName = ".commitlint-scope.yaml"
Copy link
Copy Markdown

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

Keep the config filename contract consistent.

Line 16 turns ConfigName into a full filename, but cmd/commands/init.go:42-45 still appends ".yml". That means init now writes .commitlint-scope.yaml.yml, while LoadConfig() only reads .commitlint-scope.yaml. It also drops support for the old .commitlint-scope filename, so existing repos can silently fall back to defaults. Please either update the downstream filename construction and add a legacy fallback here, or keep a single shared basename/filename contract.

🤖 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 `@pkg/validator/config.go` at line 16, ConfigName was turned into a full
filename which conflicts with cmd/commands/init.go appending ".yml" and drops
legacy support; change ConfigName back to the basename ".commitlint-scope" and
update LoadConfig() to look for ConfigName+".yaml", then ConfigName+".yml", then
the legacy ConfigName (no extension) so both init (which can continue using
ConfigName+".yml") and existing repos are supported. Ensure references use the
ConfigName symbol and keep the search order so ".yaml" takes precedence, then
".yml", then the legacy filename.

@thumbrise thumbrise merged commit ed53b57 into main May 30, 2026
5 checks passed
@thumbrise thumbrise deleted the self-food branch May 30, 2026 04:21
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 3.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant