Sitelet https://github.com/boostsecurityio/poutine/pull/425
Skip to content

feat(config): discover .github/poutine.yml as a config path - #425

Closed
mvanhorn wants to merge 1 commit into
boostsecurityio:mainfrom
mvanhorn:osc/422-github-config-path
Closed

mvanhorn wants to merge 1 commit into
boostsecurityio:mainfrom
mvanhorn:osc/422-github-config-path

Conversation

@mvanhorn

Copy link
Copy Markdown

Closes #422

Summary

When --config is not provided, poutine now checks two locations for its configuration file, in priority order:

  1. .poutine.{yml,yaml,json,toml} at the repository root (existing behaviour).
  2. .github/poutine.{yml,yaml,json,toml}.

This lets users keep CI-related configuration under .github/ alongside dependabot.yml, CODEOWNERS, etc. — the pattern mentioned in the issue and used by tools like zizmor. Root-level .poutine.yml still wins if both exist, so existing repositories are unaffected.

Implementation

cmd/root.go — added a small discoverConfigFile() helper that walks the two candidate paths and returns the first existing file. When that helper returns a non-empty path, initConfig calls viper.SetConfigFile() on it; when it returns "", the existing viper search (AddConfigPath(".") + SetConfigName(".poutine")) still runs, so the ConfigFileNotFoundError path is unchanged.

Using SetConfigFile on the resolved path is cleaner than juggling viper.AddConfigPath / SetConfigName for two differently-named files, and it keeps the error-handling branch identical for both discovery and the "no config" case.

Tests

cmd/discover_config_test.go covers:

  • No config file present
  • .poutine.yml at root takes precedence over .github/poutine.yml
  • .github/poutine.yml used when root is absent
  • Directory entries named .poutine.yml are ignored (defence against stray mkdir)
go test ./cmd/...
ok  	github.com/boostsecurityio/poutine/cmd	0.767s

Also smoke-tested the built binary in three temp directories (root config, .github config, and no config) — all succeed and use the expected file.

Docs

Updated the --config flag help text and the README "Configuration" section to mention the new fallback path and note the precedence order. The CLI flag string now reads config file (default searches .poutine.yml in the current directory, then .github/poutine.yml).

When the --config flag is not set, poutine now searches for a config
file in two locations in priority order:

1. .poutine.{yml,yaml,json,toml} at the repository root (existing
   behaviour)
2. .github/poutine.{yml,yaml,json,toml}

This lets users group CI configuration under .github/ alongside
existing GitHub config files (dependabot.yml, CODEOWNERS, etc.). The
--config flag still overrides both, and a root-level .poutine.yml
still takes precedence over one under .github/, so existing projects
are unaffected.

Closes boostsecurityio#422

Copilot AI left a comment

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.

Pull request overview

Adds config auto-discovery support for a secondary config location under .github/, allowing CI-related configuration to live alongside other GitHub tooling files while preserving existing root precedence.

Changes:

  • Extend default config discovery to check .github/poutine.{yml,yaml,json,toml} after .poutine.{yml,yaml,json,toml}.
  • Add unit tests for discovery precedence and directory-entries-as-config edge case.
  • Update CLI help text and README to document the new fallback path and precedence.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
cmd/root.go Introduces discoverConfigFile() and wires it into initConfig() to prefer root config, then .github/ fallback.
cmd/discover_config_test.go Adds tests covering discovery behavior, precedence, and ignoring directory “configs”.
README.md Documents the new fallback path and precedence in usage/configuration sections.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/root.go
Comment on lines +190 to +195
for _, ext := range extensions {
p := base + "." + ext
if fi, err := os.Stat(p); err == nil && !fi.IsDir() {
return p
}
}

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

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

discoverConfigFile() currently ignores any os.Stat error (other than nil) and just keeps searching. This can misclassify an existing config file as “not found” when Stat fails due to permission/IO errors, causing initConfig() to silently proceed with defaults instead of surfacing a read error. Consider treating non-IsNotExist errors as a hard failure (or returning the candidate path / an error) so permission issues don’t get swallowed.

Copilot uses AI. Check for mistakes.
Comment thread README.md
poutine analyze_local . --config my-config.yml
```

If a `.poutine.yml` file is not present at the repository root, poutine also looks for `.github/poutine.yml` so CI-related configuration can be grouped alongside other GitHub configuration files. A file at the repository root takes precedence over one under `.github/`, and the `--config` flag overrides both.

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

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

The text says “repository root”, but config discovery here is relative to the current working directory (matching the earlier paragraph that says “current working directory”). To avoid misleading users who run poutine from a subdirectory, reword this to “current directory/working directory” (and keep the precedence explanation).

Suggested change
If a `.poutine.yml` file is not present at the repository root, poutine also looks for `.github/poutine.yml` so CI-related configuration can be grouped alongside other GitHub configuration files. A file at the repository root takes precedence over one under `.github/`, and the `--config` flag overrides both.
If a `.poutine.yml` file is not present in the current working directory, poutine also looks for `.github/poutine.yml` under the current working directory so CI-related configuration can be grouped alongside other GitHub configuration files. A `.poutine.yml` file in the current working directory takes precedence over one under `.github/`, and the `--config` flag overrides both.

Copilot uses AI. Check for mistakes.
@fproulx-boostsecurity

Copy link
Copy Markdown
Contributor

Hey @mvanhorn, thanks for jumping in on this. Closing this one as a duplicate of #424, which @graelo opened a few hours earlier. They also filed the original issue (#422) and had already offered to implement it, so we'd like to let them run with it.

One thing for next time: before starting work on an issue, have a look at the thread and open PRs to see if someone is already on it. Avoids duplicated effort on both sides. Also, if you used AI assistance on the PR, please flag that in the description so reviewers know what to look for.

Thanks again for wanting to help out.

@mvanhorn

Copy link
Copy Markdown
Author

Sorry about that!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support .github/poutine.yml as a config file discovery path

3 participants