Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ and allow reuse in both branches. The change:

- Eliminates all three intermediate object allocations present in the original interface-type branch
- Kills the equivalent Stryker mutation by removing the conditional that had no observable effect
- Keeps the same logical behaviour: concrete types are found via their interfaces; types
- Keeps the same logical behavior: concrete types are found via their interfaces; types
that are themselves `IEnumerable<T>` are found via the fallback check
- Build passes with zero warnings; all tests pass across `net8.0`, `net472`, and `net48`
<!-- SECTION:FINAL_SUMMARY:END -->
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
---
id: TASK-15
title: Add backlog CLI reference to AGENTS.md
status: Done
assignee:
- claude
- piotrzajac
created_date: '2026-04-17 12:13'
updated_date: '2026-04-17 12:18'
labels: []
dependencies: []
priority: low
---

## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Backlog CLI Reference section added to AGENTS.md before the MCP guidelines block
- [x] #2 Section survives future backlog agents --update-instructions runs
<!-- AC:END -->
---
id: TASK-15
title: Add backlog CLI reference to AGENTS.md
status: Done
assignee:
- claude
- piotrzajac
created_date: '2026-04-17 12:13'
updated_date: '2026-04-17 12:18'
labels: []
dependencies: []
priority: low
---
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Backlog CLI Reference section added to AGENTS.md before the MCP guidelines block
- [x] #2 Section survives future backlog agents --update-instructions runs
<!-- AC:END -->
2 changes: 1 addition & 1 deletion .backlog/config.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
project_name: "AutoFixture.XUnit2.AutoMock"
default_status: "To Do"
statuses: ["To Do", "In Progress", "Done"]
labels: ["sec", "feature", "fix", "ci-cd", "dx", "doc", "agent"]
labels: ["sec", "feature", "fix", "ci-cd", "dx", "doc", "agent", "performance"]
date_format: yyyy-mm-dd
max_column_width: 20
auto_open_browser: true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-1
title: Share fixture across member data rows by default
date: '2017-01-20'
status: accepted
---
## Context

`[MemberAutoMockData]` combines static member data with auto-generated parameters. When a member provides multiple data rows, each row could receive its own fresh `IFixture` instance (producing different mock objects per row) or share one fixture across all rows (preserving mock identity). The right default was non-obvious.

## Decision

Default `MemberAutoDataBaseAttribute.ShareFixture = true`. The same `IFixture` instance — with all its customizations and registered mock objects — is reused across every data row produced by the member. Users can opt out with `ShareFixture = false` when independent fixtures per row are required.

## Consequences

- Related test cases receive consistent mock instances, which is the expected behavior in the majority of scenarios where member data provides complementary inputs.
- This is the unique differentiator of `[MemberAutoMockData]` over plain `[MemberData]` with manual fixture setup.
- Tests that need isolation between rows require explicit `ShareFixture = false`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-10
title: Adopt GitHub Actions as CI/CD platform
date: '2023-03-24'
status: accepted
---
## Context

The project previously used Travis CI. Travis CI's free tier for open-source projects was reduced, and it lacked deep integration with GitHub security features (CodeQL, Dependabot, secret scanning). GitHub Actions offered native integration, a richer ecosystem of community actions, and free minutes for public repositories.

## Decision

Migrate all CI/CD pipelines from Travis CI to GitHub Actions. Organize workflows into reusable modules: `init.yml` (GitVersion, module detection), `build-test-pack.yml`, `publish.yml`, `tag.yml`. Run all jobs on `windows-latest` to support `net472`/`net48` test slices. Security and quality tools could run as parallel jobs in the same pipeline.

## Consequences

- No external CI service dependency; pipeline definition lives in the same repository.
- Native access to GitHub security tab, Dependabot alerts, and environment secrets.
- `windows-latest` runner is required for every job due to `net472`/`net48` constraints, which limits Linux-only optimizations.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-11
title: Integrate FOSSA for license compliance scanning
date: '2023-03-31'
status: accepted
---
## Context

Open-source libraries carry licensing obligations for both maintainers and consumers. Transitive NuGet dependencies may introduce copyleft or commercially incompatible licenses that must be detected before distribution. Manual license auditing does not scale as the dependency graph grows.

## Decision

Integrate FOSSA into the CI pipeline to automatically scan all direct and transitive NuGet dependencies for license compatibility on every build. FOSSA generates a compliance report and raises alerts when new dependencies introduce problematic licenses.

## Consequences

- License violations are caught before packages are published to NuGet.org.
- A machine-readable compliance report is produced automatically.
- Reduces legal risk for enterprise consumers who have strict license policies.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-12
title: Use GitVersion in ContinuousDelivery mode
date: '2023-08-30'
status: accepted
---
## Context

Manual version management in `.csproj` files is error-prone: versions can be forgotten, duplicated across projects, or incremented inconsistently. The project needed an automated versioning strategy aligned with semantic versioning and the git workflow.

## Decision

Adopt GitVersion in `ContinuousDelivery` mode. Versions are computed entirely from git history: commits on `master` produce stable semantic versions; feature branches produce pre-release suffixes. No `<Version>` element is set manually in any `.csproj`. The `Directory.Build.props` default of `1.0.0.0` is a local fallback only, never used in CI.

## Consequences

- Version is always derivable from git history and requires no manual intervention.
- CI sets the version automatically before build and pack steps.
- Developers must follow branching conventions for GitVersion to compute the correct version; ad-hoc commits directly to master advance the stable version.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
id: decision-13
title: Exclude Moq from Dependabot; group remaining NuGet updates
date: '2023-09-21'
status: accepted
---
## Context

Moq introduced SponsorLink in a controversial update that embedded telemetry and caused significant community backlash. Automatically upgrading Moq via Dependabot could silently introduce this behavior without a deliberate review.

## Decision

Explicitly exclude `Moq` from Dependabot NuGet updates — it requires manual review and a deliberate upgrade decision.
Group all other NuGet updates into logical Dependabot groups: `xUnit`, `AutoFixture`, `Analyzers`, `Testing`, `Common`, and `Other`.
GitHub Actions dependencies are also grouped and updated weekly with a `chore(github-actions):` prefix.

## Consequences

- Moq version is frozen until explicitly and consciously upgraded.
- Grouped updates reduce weekly PR noise from many individual bumps to a handful of grouped PRs.
- Any future Moq upgrade must be reviewed for licensing, telemetry, and breaking changes before merging.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
id: decision-14
title: Enable CodeQL for C# static security analysis
date: '2023-09-21'
status: accepted
---
## Context

Manual code review is insufficient for systematically catching security vulnerabilities. As a NuGet library consumed by other projects, a vulnerability in this library propagates to all consumers. An automated static analysis tool integrated with GitHub's security infrastructure would provide continuous protection at no operational cost for public repos.

## Decision

Enable GitHub CodeQL for C# as a required CI check. CodeQL runs on push and pull request to master, analyzing the full C# codebase for vulnerabilities. Results surface in the GitHub Security tab and can block merges when configured as a required status check.

## Consequences

- Continuous vulnerability scanning without additional tooling setup for contributors.
- Security findings are visible to maintainers in the GitHub Security tab.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
id: decision-15
title: Integrate Stryker mutation testing into CI
date: '2023-09-30'
status: accepted
---
## Context

Traditional code coverage metrics verify that tests execute code paths, not that they detect bugs. A test suite with 100% coverage can still pass while missing every meaningful regression. The project needed a higher-confidence quality gate.

## Decision

Integrate Stryker.NET mutation testing into the CI pipeline as a separate, slow-running stage. Configuration lives in `stryker-config.yml` at the repository root; the tool is invoked from the `src/` directory. Stryker runs are expected before raising a PR rather
than on every commit.

## Consequences

- Tests are verified to actually kill mutations, raising confidence beyond coverage alone.
- Slow step kept out of the fast feedback loop; developers opt in before submitting a PR.
- Surviving mutants become explicit action items, not silent gaps.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
id: decision-16
title: Publish symbols and enable SourceLink
date: '2023-10-13'
status: accepted
---
## Context

Developers using the library could not step into library code during debugging because no symbol packages were published. Stack traces showed only method names without source lines, making it difficult to diagnose failures inside the attribute pipeline.

## Decision

Publish `.snupkg` symbol packages to NuGet.org alongside the main `.nupkg` packages.
Enable `Microsoft.SourceLink.GitHub` so that debuggers automatically fetch the corresponding source code from GitHub at the exact commit matching the installed version.

## Consequences

- Consumers can step into library code in their debugger without any manual setup.
- Stack traces show full source file paths and line numbers for library frames.
- Symbol packages are published automatically as part of the same CI release step as the main packages.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
id: decision-17
title: Add data-narrowing parameter attributes
date: '2023-12-05'
status: accepted
---
## Context

AutoFixture generates arbitrary values for parameters. Tests for boundary conditions, enum subsets, or constrained numeric domains needed values from a restricted range, requiring manual fixture setup that negated the boilerplate reduction the library provides.

## Decision

Add four parameter-level attributes to Core, all implemented via `IParameterCustomizationSource`:

- `[Except(v1, v2)]` — generate values excluding the specified set
- `[PickFromValues(v1, v2)]` — pick randomly from a fixed set
- `[PickFromRange(min, max)]` — generate within a numeric range
- `[PickNegative]` — generate only negative numeric values

All four are backed by new specimen builders (`RandomExceptValuesGenerator`, `RandomFixedValuesGenerator`) and request types (`ExceptValuesRequest`, `FixedValuesRequest`).

## Consequences

- Constrained test data without any manual fixture configuration.
- All three mock modules benefit automatically via Core.
- Attributes are combinable with `[Frozen]` and `[CustomizeWith]` in the same parameter list.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-18
title: Integrate Semgrep for SAST scanning
date: '2023-12-20'
status: accepted
---
## Context

CodeQL provides GitHub-native SAST with strong C# support, but its rule coverage is focused on common vulnerability classes. Semgrep offers complementary community-maintained rule sets and custom pattern matching that can catch additional issues CodeQL does not cover.

## Decision

Add Semgrep as a parallel SAST scanning step in CI alongside CodeQL. Use the default Semgrep ruleset for C# plus any community rulesets relevant to the project. Semgrep runs on push and pull request to master.

## Consequences

- Broader SAST coverage through two independent tools with different rule philosophies.
- Some overlap with CodeQL is intentional — independent tools reaching the same conclusion increases confidence.
- Semgrep findings are reviewed in CI alongside CodeQL results; both must pass before merge.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-19
title: Adopt Qodana for code quality scanning
date: '2024-01-16'
status: accepted
---
## Context

The in-build analyzer stack (StyleCop, Roslynator, SonarAnalyzer) catches issues at compile time but cannot provide holistic quality scoring, trend analysis across the codebase, or a consolidated view of maintainability and reliability findings separate from the build log.

## Decision

Integrate JetBrains Qodana into CI as a quality gate. Qodana runs a full Roslyn-based inspection pass independently of the build and reports results in a structured format. It runs on push and pull request to master and complements CodeQL (security focus) and Semgrep (SAST focus) with maintainability and reliability checks.

## Consequences

- Quality metrics are visible in CI as a distinct step, separate from build warnings.
- Qodana's inspection coverage overlaps partially with the in-build analyzers; discrepancies surface issues that build-time suppression may have hidden.
- JetBrains Qodana supports .NET and is compatible with the `windows-latest` CI runner.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
id: decision-2
title: Decouple xUnit from AutoFixture via provider pattern
date: '2017-01-22'
status: accepted
---
## Context

The library originally derived directly from AutoFixture's `AutoDataAttribute`. This created tight coupling between the xUnit integration and AutoFixture internals, making it difficult to inject custom behavior, intercept the data-generation pipeline, or add parameter-level customization without forking AutoFixture itself.

## Decision

Stop inheriting from AutoFixture attributes. Derive from xUnit's `DataAttribute` instead and drive fixture customization through a dedicated `IAutoFixtureAttributeProvider` abstraction. The provider receives the configured `IFixture` and returns a `DataAttribute` whose
`GetData()` resolves test parameters. This separates xUnit's data-supply contract from AutoFixture's specimen-creation pipeline.

## Consequences

- Clear boundary between the xUnit layer and AutoFixture: each can evolve independently.
- The provider pattern enables per-parameter customization via `IParameterCustomizationSource` attributes applied later in the pipeline.
- All three mock modules (AutoMoq, AutoFakeItEasy, AutoNSubstitute) override only `Customize(IFixture)` — the rest of the pipeline is inherited from Core.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-20
title: Integrate Snyk for dependency vulnerability scanning
date: '2024-04-18'
status: accepted
---
## Context

CodeQL scans first-party C# code for vulnerabilities.

## Decision

Integrate Snyk into the CI pipeline to scan NuGet package dependencies for known vulnerabilities using Snyk's continuously updated database. Snyk runs on push and pull request to master and raises alerts when a dependency version matches a known CVE.

## Consequences

- Supply chain risk is monitored continuously alongside code quality and license compliance.
- Snyk findings block builds when severity exceeds the configured threshold.
- Intentional overlap with FOSSA on license scanning is acceptable given the low operational cost of running both.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
id: decision-21
title: Enforce Conventional Commits
date: '2026-04-10'
status: accepted
---
## Context

Commit messages were inconsistently formatted across contributors.

## Decision

Enforce Conventional Commits format (`<type>(<scope>): <description>`) on every commit, where scope is optional.
Enforcement uses a Husky.NET `commit-msg` hook for local validation and CommitLint.Net in CI to block merges that contain non-conforming commit messages.

## Consequences

- Consistent, machine-readable commit history across all contributors.
- Automated changelog generation becomes feasible as a follow-on step.
- Contributors receive immediate feedback at commit time rather than discovering the issue at CI.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
id: decision-22
title: Adopt CodeRabbit for AI-powered PR review
date: '2026-04-12'
status: accepted
---
## Context

Human code review is thorough for logic but inconsistent at enforcing coding conventions, catching subtle anti-patterns, and ensuring every changed file receives attention. A first-pass automated reviewer would raise quality before human reviewers engage.

## Decision

Integrate CodeRabbit as an automated AI reviewer on all pull requests. CodeRabbit posts inline review comments and a PR summary alongside human reviewers. It is configured to understand the project's conventions (BDD naming, AAA structure, attribute ordering rules).

## Consequences

- Every PR receives a first-pass review that catches convention violations and straightforward issues before human review.
- Human reviewers focus on higher-level concerns: design, correctness, and intent.
- AI review comments are advisory; maintainers retain final merge authority.
Loading
Loading