Skip to content

Conversation

@CybotTM
Copy link
Member

@CybotTM CybotTM commented Feb 9, 2026

Summary

  • Change MailOnlyOnError, SlackOnlyOnError, SaveOnlyOnError from bool to *bool so "not set" (nil) is distinguishable from "explicitly false"
  • Inherit *-only-on-error from global config when job doesn't set it, while allowing explicit per-job overrides in both directions
  • Add missing mergeNotificationDefaults calls to Docker label and INI config update paths

Root cause

Commit 4218a6e introduced SMTP/Slack setting inheritance from global to job configs. This made job-level MailConfig non-empty, causing a job-level Mail middleware to be created that silently replaced the global one (middlewares deduplicate by type). But mail-only-on-error was not inherited (Go bool zero-value problem), so the job-level middleware defaulted to false and sent emails on every execution.

Inheritance matrix

Global Job Result
true (not set) true (inherited)
false true true (job override)
true false false (job override)
(not set) (not set) send all (default)

Test plan

  • Unit tests for all 5 combinations (global true/false/nil × job true/false/nil)
  • Existing mail, slack, and save middleware tests updated and passing
  • INI config reload test updated and passing
  • Full test suite passes (go test ./...)

Fixes #454

Change MailOnlyOnError, SlackOnlyOnError, and SaveOnlyOnError from bool
to *bool so that "not set" (nil) is distinguishable from "explicitly
false". This enables full bidirectional inheritance:
- Global true  + Job not set → Job inherits true
- Global false + Job true    → Job keeps true
- Global true  + Job false   → Job keeps false (explicit override)

Previously, inheriting SMTP/Slack settings from global caused job-level
middleware to be created with OnlyOnError=false (Go zero value), which
silently overrode the global middleware (dedup by type) and sent
notifications on every execution — even when global set only-on-error.

Also add mergeNotificationDefaults calls to Docker label and INI config
update paths, which were missing notification config inheritance.

Fixes #454
Copilot AI review requested due to automatic review settings February 9, 2026 22:19
@gemini-code-assist
Copy link

Summary of Changes

Hello @CybotTM, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request provides a crucial fix for how notification-related boolean flags, specifically MailOnlyOnError, SlackOnlyOnError, and SaveOnlyOnError, are handled within the system's configuration. Previously, due to Go's default boolean zero-value, these settings could not be properly inherited from global configurations to individual job configurations, causing jobs to send notifications on every execution instead of only on error. The changes introduce pointer types for these booleans, allowing for a 'not set' state, and implement robust inheritance logic. This ensures that global notification preferences are respected by default, while still providing flexibility for job-specific overrides, thereby correcting the notification behavior across the application.

Highlights

  • Configuration Inheritance Fix: Resolved an issue where MailOnlyOnError, SlackOnlyOnError, and SaveOnlyOnError settings were not correctly inherited from global to job configurations, leading to unintended notification behavior.
  • Type Change for Boolean Flags: Modified MailOnlyOnError, SlackOnlyOnError, and SaveOnlyOnError fields from bool to *bool to allow distinguishing between an unset value (nil) and an explicitly set false, addressing the 'Go bool zero-value problem'.
  • Enhanced Inheritance Logic: Implemented logic to inherit *-only-on-error settings from the global configuration when not explicitly set at the job level, while still allowing explicit per-job overrides in both directions (e.g., global true overridden by job false).
  • Missing Merge Calls Added: Added previously missing mergeNotificationDefaults calls to the Docker label and INI configuration update paths, ensuring that notification settings are consistently applied across different configuration sources.
  • New Helper Functions: Introduced boolVal to safely dereference *bool (returning false if nil) and BoolPtr to create pointers to boolean values, facilitating the new *bool handling.
  • Documentation and Test Updates: Updated documentation to reflect the new inheritance behavior for boolean fields and added comprehensive unit tests to cover all inheritance scenarios for *-only-on-error settings.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • cli/config.go
    • Modified mergeSlackDefaults and mergeMailDefaults to inherit SlackOnlyOnError and MailOnlyOnError from global config if the job's setting is nil.
    • Added c.mergeNotificationDefaults and c.injectDedup calls within dockerLabelsUpdate and iniConfigUpdate for various job types (Exec, Run, Local, Compose, Service) to ensure proper notification default merging.
  • cli/config_extra_test.go
    • Updated assertions for SaveOnlyOnError to account for its new *bool type, including require.NotNil checks and dereferencing.
  • cli/config_test.go
    • Updated existing mergeMailDefaults and mergeSlackDefaults tests to use middlewares.BoolPtr and assert on dereferenced *bool values.
    • Added TestMergeMailDefaultsOnlyOnErrorInheritance to thoroughly test various inheritance combinations for MailOnlyOnError.
  • docs/CONFIGURATION.md
    • Updated the documentation to clarify that boolean fields like email-only-on-error, slack-only-on-error, and save-only-on-error are now fully inherited and can be overridden per-job.
  • docs/packages/middlewares.md
    • Updated the type definitions for MailConfig, SlackConfig, and SaveConfig to reflect the change of MailOnlyOnError, SlackOnlyOnError, and SaveOnlyOnError to *bool.
  • middlewares/common.go
    • Added boolVal(b *bool) bool helper function to safely dereference a *bool, returning false if nil.
    • Added BoolPtr(v bool) *bool helper function to return a pointer to a boolean value.
  • middlewares/mail.go
    • Changed the MailOnlyOnError field type in MailConfig from bool to *bool.
    • Updated the Run method's conditional logic to use boolVal(m.MailOnlyOnError) for correct evaluation.
  • middlewares/save.go
    • Changed the SaveOnlyOnError field type in SaveConfig from bool to *bool.
    • Updated the Run method's conditional logic to use boolVal(m.SaveOnlyOnError) for correct evaluation.
  • middlewares/save_test.go
    • Modified SaveOnlyOnError initialization in tests to use BoolPtr(true).
  • middlewares/slack.go
    • Changed the SlackOnlyOnError field type in SlackConfig from bool to *bool.
    • Updated the Run method's conditional logic to use boolVal(m.SlackOnlyOnError) for correct evaluation.
  • middlewares/slack_test.go
    • Modified SlackOnlyOnError initialization in tests to use BoolPtr(true).
Activity
  • The author, CybotTM, initiated this pull request to address a critical configuration inheritance bug.
  • The pull request includes a detailed summary, root cause analysis, and an inheritance matrix, demonstrating a thorough understanding of the problem and proposed solution.
  • Extensive unit tests have been updated and added to validate the new inheritance logic and *bool handling across various scenarios.
  • The changes involve modifications to core configuration logic, middleware structures, and documentation, indicating a comprehensive and well-engineered solution.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

github-actions[bot]
github-actions bot previously approved these changes Feb 9, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

✅ Mutation Testing Results

Mutation Score: 100.00% (threshold: 60%)

✨ Good job! Mutation score meets the threshold.

What is mutation testing?

Mutation testing measures test quality by introducing small changes (mutations) to the code and checking if tests detect them. A higher score means better test effectiveness.

  • Killed mutants: Tests caught the mutation (good!)
  • Survived mutants: Tests missed the mutation (needs improvement)

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses a bug in how *-only-on-error settings are inherited from the global configuration to job-specific configurations by changing boolean flags to pointers. However, a critical vulnerability was identified: while SaveOnlyOnError was also changed to a pointer type, the corresponding inheritance logic in the configuration loader was omitted. This oversight results in the global save-only-on-error setting being ignored for individual jobs, potentially leading to more logs being saved to disk than intended. Additionally, a minor refactoring in cli/config.go is suggested to reduce code duplication in job preparation functions, which would improve long-term maintainability.

@entelligence-ai-pr-reviews
Copy link

Walkthrough

This PR refactors boolean configuration fields (MailOnlyOnError, SlackOnlyOnError, SaveOnlyOnError) from primitive bool to *bool pointers across the codebase. This change enables proper three-state logic (true/false/unset) to distinguish between explicitly set false values and unset values, fixing inheritance behavior from global to job-level configurations. The refactoring ensures that job-level settings properly inherit global defaults only when nil, while preserving explicitly set values. Helper functions boolVal() and BoolPtr() were added for safe pointer handling. All job preparation functions now consistently apply notification settings across configuration sources, and comprehensive test coverage validates the inheritance behavior.

Changes

File(s) Summary
middlewares/mail.go
middlewares/slack.go
middlewares/save.go
Changed MailOnlyOnError, SlackOnlyOnError, and SaveOnlyOnError fields from bool to *bool in their respective config structs, and updated conditional logic to use boolVal() helper for safe pointer dereferencing.
middlewares/common.go Added boolVal() utility function for safe *bool dereferencing (returns false on nil) and exported BoolPtr() function for creating boolean pointers.
cli/config.go Fixed inheritance behavior for boolean notification flags by treating them as pointers; updated mergeSlackDefaults and mergeMailDefaults to inherit global settings only when job-level values are nil; added mergeNotificationDefaults and injectDedup calls to all job preparation functions in both dockerLabelsUpdate and iniConfigUpdate methods.
cli/config_test.go Refactored test cases to use middlewares.BoolPtr() for pointer initialization; added comprehensive inheritance test coverage in TestMergeMailDefaultsOnlyOnErrorInheritance with five scenarios; enhanced TestMergeSlackDefaults with additional override verification.
cli/config_extra_test.go
middlewares/save_test.go
middlewares/slack_test.go
Updated test assertions to handle pointer types using BoolPtr() helper and added require.NotNil checks before dereferencing.
docs/CONFIGURATION.md Updated documentation to reflect that boolean fields now fully support bidirectional inheritance and override between global and job-level configurations, removing previous limitation statement.
docs/packages/middlewares.md Changed type documentation from bool to *bool for MailOnlyOnError, SlackOnlyOnError, and SaveOnlyOnError fields; updated test example to use middlewares.BoolPtr(false).

Sequence Diagram

This diagram shows the interactions between components:

sequenceDiagram
    participant Config as Configuration System
    participant JobPrep as Job Preparation Functions
    participant MergeDefaults as mergeNotificationDefaults()
    participant InjectDedup as injectDedup()
    participant SlackConfig as SlackConfig
    participant MailConfig as MailConfig

    Note over Config,MailConfig: Job Configuration Flow (All Job Types)

    Config->>JobPrep: Initialize Job (exec/run/local/service/compose)
    activate JobPrep
    
    JobPrep->>JobPrep: Set defaults
    JobPrep->>JobPrep: Set Provider & RuntimeFields
    JobPrep->>JobPrep: Set Name
    
    Note over JobPrep,InjectDedup: New: Notification Configuration
    
    JobPrep->>MergeDefaults: mergeNotificationDefaults(&SlackConfig, &MailConfig)
    activate MergeDefaults
    
    MergeDefaults->>SlackConfig: Check SlackWebhook
    alt SlackWebhook is empty
        MergeDefaults->>SlackConfig: Inherit global.SlackWebhook
    end
    
    MergeDefaults->>SlackConfig: Check SlackOnlyOnError
    alt job.SlackOnlyOnError == nil AND global.SlackOnlyOnError != nil
        MergeDefaults->>SlackConfig: Inherit global.SlackOnlyOnError (via BoolPtr)
    end
    
    MergeDefaults->>MailConfig: Check EmailFrom
    alt EmailFrom is empty
        MergeDefaults->>MailConfig: Inherit global.EmailFrom
    end
    
    MergeDefaults->>MailConfig: Check MailOnlyOnError
    alt job.MailOnlyOnError == nil AND global.MailOnlyOnError != nil
        MergeDefaults->>MailConfig: Inherit global.MailOnlyOnError (via BoolPtr)
    end
    
    MergeDefaults-->>JobPrep: Defaults merged
    deactivate MergeDefaults
    
    JobPrep->>InjectDedup: injectDedup(&SlackConfig, &MailConfig)
    activate InjectDedup
    InjectDedup->>SlackConfig: Configure deduplication
    InjectDedup->>MailConfig: Configure deduplication
    InjectDedup-->>JobPrep: Dedup configured
    deactivate InjectDedup
    
    JobPrep-->>Config: Job fully configured
    deactivate JobPrep
    
    Note over Config,MailConfig: Pattern applies to:<br/>- ExecJobs (Label & INI)<br/>- RunJobs (Label & INI)<br/>- LocalJobs (Label & INI)<br/>- ServiceJobs (Label & INI)<br/>- ComposeJobs (Label & INI)
Loading

🔗 Cross-Repository Impact Analysis

Enable automatic detection of breaking changes across your dependent repositories. → Set up now

Learn more about Cross-Repository Analysis

What It Does

  • Automatically identifies repositories that depend on this code
  • Analyzes potential breaking changes across your entire codebase
  • Provides risk assessment before merging to prevent cross-repo issues

How to Enable

  1. Visit Settings → Code Management
  2. Configure repository dependencies
  3. Future PRs will automatically include cross-repo impact analysis!

Benefits

  • 🛡️ Prevent breaking changes across repositories
  • 🔍 Catch integration issues before they reach production
  • 📊 Better visibility into your multi-repo architecture

▶️AI Code Reviews for VS Code, Cursor, Windsurf
Install the extension

Note for Windsurf Please change the default marketplace provider to the following in the windsurf settings:

Marketplace Extension Gallery Service URL: https://marketplace.visualstudio.com/_apis/public/gallery

Marketplace Gallery Item URL: https://marketplace.visualstudio.com/items

Entelligence.ai can learn from your feedback. Simply add 👍 / 👎 emojis to teach it your preferences. More shortcuts below

Emoji Descriptions:

  • ⚠️ Potential Issue - May require further investigation.
  • 🔒 Security Vulnerability - Fix to ensure system safety.
  • 💻 Code Improvement - Suggestions to enhance code quality.
  • 🔨 Refactor Suggestion - Recommendations for restructuring code.
  • ℹ️ Others - General comments and information.

Interact with the Bot:

  • Send a message or request using the format:
    @entelligenceai + *your message*
Example: @entelligenceai Can you suggest improvements for this code?
  • Help the Bot learn by providing feedback on its responses.
    @entelligenceai + *feedback*
Example: @entelligenceai Do not comment on `save_auth` function !

Also you can trigger various commands with the bot by doing
@entelligenceai command

The current supported commands are

  1. config - shows the current config
  2. retrigger_review - retriggers the review

More commands to be added soon.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes notification “only-on-error” inheritance so global settings correctly propagate to per-job middleware configs, addressing a regression where job-level middlewares could suppress global behavior due to middleware type deduplication.

Changes:

  • Change MailOnlyOnError, SlackOnlyOnError, SaveOnlyOnError from bool to *bool and add safe helpers for nil handling.
  • Update notification middlewares to interpret nil as default “send/save on all executions”, and update tests accordingly.
  • Ensure config update paths (Docker labels + INI reload) call notification-default merging and dedup injection for jobs.

Reviewed changes

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

Show a summary per file
File Description
cli/config.go Implements inheritance of *-only-on-error from global to job configs; ensures merge/inject is applied on label + INI update paths.
cli/config_test.go Adds/updates unit tests validating inheritance behavior across nil/true/false combinations.
cli/config_extra_test.go Updates INI reload test assertions for pointer-backed booleans.
middlewares/common.go Adds boolVal(*bool) and BoolPtr(bool) helpers to support tri-state booleans.
middlewares/mail.go Switches MailOnlyOnError to *bool and updates runtime logic to handle nil safely.
middlewares/slack.go Switches SlackOnlyOnError to *bool and updates runtime logic to handle nil safely.
middlewares/save.go Switches SaveOnlyOnError to *bool and updates runtime logic to handle nil safely.
middlewares/slack_test.go Updates Slack middleware test to use BoolPtr(true).
middlewares/save_test.go Updates Save middleware test to use BoolPtr(true).
docs/packages/middlewares.md Updates docs/examples to reflect *bool fields and BoolPtr(...) usage.
docs/CONFIGURATION.md Updates inheritance documentation for boolean notification fields.

- Add mergeSaveDefaults() to inherit save-folder and save-only-on-error
  from global config to job configs (was missing after *bool change)
- Add EmailSubject inheritance in mergeMailDefaults()
- Fix docs using wrong config key: email-only-on-error → mail-only-on-error
- Update inheritance table to include Save and all inherited fields
- Add tests for mergeSaveDefaults and EmailSubject inheritance
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

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.

mail-only-on-error not working anymore?

1 participant