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
52 changes: 37 additions & 15 deletions .reviewmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,45 +66,67 @@ reviews:
- "test/**/RepoConnectors/GitHub/MockGitHubGraphQLHttpMessageHandlerTests.cs"
- "test/**/RepoConnectors/GitHub/MockableGitHubRepoConnector.cs"

- id: BuildMark-RepoConnectors-ConnectorBase
title: Review of BuildMark RepoConnectors/ConnectorBase Unit
paths:
- "docs/reqstream/build-mark/repo-connectors/repo-connector-base.yaml"
- "docs/design/build-mark/repo-connectors/repo-connector-base.md"
- "src/**/RepoConnectors/IRepoConnector.cs"
- "src/**/RepoConnectors/RepoConnectorBase.cs"

- id: BuildMark-RepoConnectors-MockConnector
title: Review of BuildMark RepoConnectors/MockRepoConnector Unit
paths:
- "docs/reqstream/build-mark/repo-connectors/mock-repo-connector.yaml"
- "docs/design/build-mark/repo-connectors/mock-repo-connector.md"
- "src/**/RepoConnectors/MockRepoConnector.cs"
- "test/**/RepoConnectors/MockRepoConnectorTests.cs"

- id: BuildMark-RepoConnectors-ProcessRunner
title: Review of BuildMark RepoConnectors/ProcessRunner Unit
paths:
- "docs/reqstream/build-mark/repo-connectors/process-runner.yaml"
- "docs/design/build-mark/repo-connectors/process-runner.md"
- "src/**/RepoConnectors/ProcessRunner.cs"
- "test/**/RepoConnectors/ProcessRunnerTests.cs"

- id: BuildMark-RepoConnectors-Factory
title: Review of BuildMark RepoConnectors/RepoConnectorFactory Unit
paths:
- "docs/reqstream/build-mark/repo-connectors/repo-connector-factory.yaml"
- "docs/design/build-mark/repo-connectors/repo-connector-factory.md"
- "src/**/RepoConnectors/RepoConnectorFactory.cs"
- "test/**/RepoConnectors/RepoConnectorFactoryTests.cs"

- id: BuildMark-Cli
title: Review of BuildMark Cli subsystem (command-line interface)
paths:
- "docs/reqstream/build-mark/cli/cli.yaml"
- "docs/design/build-mark/cli/cli.md"
- "docs/design/build-mark/cli/context.md"
- "docs/design/build-mark/program.md"
- "test/**/Cli/ContextTests.cs"

- id: BuildMark-SelfTest
title: Review of BuildMark SelfTest subsystem (self-validation)
paths:
- "docs/reqstream/build-mark/self-test/self-test.yaml"
- "docs/design/build-mark/self-test/self-test.md"
- "docs/design/build-mark/self-test/validation.md"
- "test/**/SelfTest/ValidationTests.cs"

- id: BuildMark-Utilities
title: Review of BuildMark Utilities subsystem (shared utilities)
paths:
- "docs/reqstream/build-mark/utilities/utilities.yaml"
- "docs/design/build-mark/utilities/utilities.md"
- "docs/design/build-mark/utilities/path-helpers.md"
- "test/**/Utilities/PathHelpersTests.cs"

- id: BuildMark-RepoConnectors
title: Review of BuildMark RepoConnectors subsystem (repository connectors)
paths:
- "docs/reqstream/build-mark/repo-connectors/repo-connectors.yaml" # subsystem requirements
- "docs/design/build-mark/repo-connectors/repo-connectors.md" # subsystem design
- "docs/design/build-mark/repo-connectors/github-repo-connector.md" # GitHubRepoConnector unit design
- "src/**/RepoConnectors/IRepoConnector.cs" # connector interface
- "src/**/RepoConnectors/RepoConnectorBase.cs" # connector base class
- "src/**/RepoConnectors/RepoConnectorFactory.cs" # connector factory
- "src/**/RepoConnectors/MockRepoConnector.cs" # mock connector
- "src/**/RepoConnectors/ProcessRunner.cs" # process runner
- "test/**/RepoConnectors/MockRepoConnectorTests.cs" # mock connector tests
- "test/**/RepoConnectors/ProcessRunnerTests.cs" # process runner tests
- "test/**/RepoConnectors/RepoConnectorFactoryTests.cs" # factory tests
- "docs/reqstream/build-mark/repo-connectors/repo-connectors.yaml"
- "docs/design/build-mark/repo-connectors/repo-connectors.md"
- "test/**/RepoConnectors/MockRepoConnectorTests.cs"
- "test/**/RepoConnectors/ProcessRunnerTests.cs"
- "test/**/RepoConnectors/RepoConnectorFactoryTests.cs"

- id: BuildMark-Architecture
title: Review of BuildMark system-level behavior and integration
Expand Down
35 changes: 35 additions & 0 deletions docs/design/build-mark/repo-connectors/mock-repo-connector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# MockRepoConnector

## Overview

`MockRepoConnector` is an in-memory implementation of `IRepoConnector` used for
self-validation and unit testing. It returns a fixed, deterministic dataset
without making any network or filesystem calls.

## Data Model

The connector holds hard-coded mappings used to build the `BuildInformation` response:

| Field | Type | Description |
|----------------------|------------------------------------|----------------------------------------------|
| `_issueTitles` | `Dictionary<string, string>` | Issue ID -> title |
| `_issueTypes` | `Dictionary<string, string>` | Issue ID -> type (bug/feature/documentation) |
| `_pullRequestIssues` | `Dictionary<string, List<string>>` | PR ID -> linked issue IDs |
| `_tagHashes` | `Dictionary<string, string>` | Tag name -> commit hash |
| `_openIssues` | `List<string>` | IDs of issues that remain open |

## Methods

### `GetBuildInformationAsync(version?) → BuildInformation`

Resolves tag history and the current commit hash from the internal dictionaries,
determines the target and baseline versions, collects changes and known issues,
and returns a fully populated `BuildInformation` record. The logic mirrors the
production GitHubRepoConnector flow but operates entirely on in-memory data.

## Interactions

| Unit / Subsystem | Role |
|---------------------|----------------------------------------------------------------|
| `RepoConnectorBase` | Base class providing `FindVersionIndex` and command delegation |
| `Validation` | Instantiates `MockRepoConnector` directly for self-tests |
29 changes: 29 additions & 0 deletions docs/design/build-mark/repo-connectors/process-runner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# ProcessRunner

## Overview

`ProcessRunner` is a static helper class that executes external shell commands and
captures their standard output. It provides two public methods: `RunAsync`, which
throws on failure, and `TryRunAsync`, which returns `null` on failure.

## Methods

### `RunAsync(command, arguments) → string`

Starts the specified process, captures stdout and stderr asynchronously, waits for
exit, and returns the trimmed stdout string. Throws `InvalidOperationException` if
the process exits with a non-zero exit code.

### `TryRunAsync(command, arguments) → string?`

Executes the process and returns the stdout string if the exit code is zero, or
`null` if the process fails or throws any exception. This method never propagates
exceptions to its callers.

## Interactions

| Unit / Subsystem | Role |
|------------------------|---------------------------------------------------------|
| `RepoConnectorBase` | Delegates `RunCommandAsync` to `ProcessRunner.RunAsync` |
| `RepoConnectorFactory` | Uses `TryRunAsync` to inspect the git remote URL |
| `GitHubRepoConnector` | Calls `RunCommandAsync` (via base) for git and gh CLI |
35 changes: 35 additions & 0 deletions docs/design/build-mark/repo-connectors/repo-connector-base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# IRepoConnector and RepoConnectorBase

## Overview

`IRepoConnector` defines the contract that all repository connectors must satisfy.
`RepoConnectorBase` is an abstract class implementing `IRepoConnector` and providing
shared utilities used by concrete connectors.

## Interface

`IRepoConnector` exposes a single method:

| Member | Kind | Description |
|-------------------------------------|--------|----------------------------------|
| `GetBuildInformationAsync(version)` | Method | Fetch complete build information |

## Base Class

`RepoConnectorBase` provides:

| Member | Kind | Description |
|------------------------------------------|-------------------|------------------------------------------------------|
| `RunCommandAsync(command, arguments)` | Protected virtual | Delegates shell commands to `ProcessRunner.RunAsync` |
| `FindVersionIndex(versions, normalized)` | Protected static | Locates a version by normalized version string |

The `RunCommandAsync` method is `virtual` so that test subclasses can override it
with mock implementations that return fixed strings without spawning real processes.

## Interactions

| Unit / Subsystem | Role |
|-----------------------|------------------------------------------------------|
| `ProcessRunner` | Used by `RunCommandAsync` to execute shell commands |
| `GitHubRepoConnector` | Concrete implementation that inherits this base |
| `MockRepoConnector` | Test implementation that overrides `RunCommandAsync` |
28 changes: 28 additions & 0 deletions docs/design/build-mark/repo-connectors/repo-connector-factory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# RepoConnectorFactory

## Overview

`RepoConnectorFactory` is a static factory class that creates the appropriate
`IRepoConnector` implementation based on the runtime environment.

## Methods

### `Create() → IRepoConnector`

Returns a new `GitHubRepoConnector` if any of the following conditions are met:

1. The `GITHUB_ACTIONS` environment variable is non-empty.
2. The `GITHUB_WORKSPACE` environment variable is non-empty.
3. The git remote URL (obtained by running `git remote get-url origin`) contains `github.com`.

If none of the above conditions are met the factory defaults to returning a new
`GitHubRepoConnector` (the only connector implementation currently available).

## Interactions

| Unit / Subsystem | Role |
|-----------------------|-------------------------------------------------------------|
| `IRepoConnector` | Return type of `Create` |
| `GitHubRepoConnector` | The concrete connector returned by `Create` |
| `ProcessRunner` | Used via `TryRunAsync` to inspect the git remote URL |
| `Program` | Calls `RepoConnectorFactory.Create()` to obtain a connector |
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ sections:
- GitHubRepoConnector_GetBuildInformationAsync_PreReleaseAllPreviousSameHash_ReturnsNullBaseline
- GitHubRepoConnector_GetBuildInformationAsync_WithDuplicateMergeCommitSha_DoesNotThrow
- GitHubRepoConnector_ImplementsInterface_ReturnsTrue
- GitHubRepoConnector_GetBuildInformationAsync_PrWithSubstringMatchLabel_NotClassifiedAsBug
- GitHubRepoConnector_GetBuildInformationAsync_IssueWithSubstringMatchLabel_NotClassifiedAsKnownIssue

- id: BuildMark-GitHub-GraphQLClient
title: The GitHubRepoConnector class shall use a GraphQL client for GitHub API interactions.
Expand Down
23 changes: 23 additions & 0 deletions docs/reqstream/build-mark/repo-connectors/mock-repo-connector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
# Software Unit Requirements for the MockRepoConnector Class
#
# MockRepoConnector is an in-memory repository connector used for
# deterministic testing. It provides fixed build information covering
# multiple versions, change types, and known issues.

sections:
- title: MockRepoConnector Unit Requirements
requirements:
- id: BuildMark-MockRepoConnector-Deterministic
title: The MockRepoConnector class shall return deterministic build information for testing.
justification: |
Tests that exercise the report generation and self-validation logic must run
without external dependencies. The MockRepoConnector provides a fixed,
predictable dataset so tests can assert exact outcomes.
tests:
- MockRepoConnector_Constructor_CreatesInstance
- MockRepoConnector_ImplementsInterface
- MockRepoConnector_GetBuildInformationAsync_ReturnsExpectedVersion
- MockRepoConnector_GetBuildInformationAsync_ReturnsCompleteInformation
- MockRepoConnector_GetBuildInformationAsync_WithValidVersionFromTags_ReturnsCorrectBaseline
- MockRepoConnector_GetBuildInformationAsync_CategorizesChangesCorrectly
23 changes: 23 additions & 0 deletions docs/reqstream/build-mark/repo-connectors/process-runner.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
# Software Unit Requirements for the ProcessRunner Class
#
# ProcessRunner provides static helpers for running external processes
# (such as git and gh CLI) and capturing their output. It exposes both
# a throwing variant (RunAsync) and a non-throwing variant (TryRunAsync).

sections:
- title: ProcessRunner Unit Requirements
requirements:
- id: BuildMark-ProcessRunner-RunAsync
title: The ProcessRunner class shall execute external commands and return their output.
justification: |
Repository connectors need to run git and gh CLI commands to discover the
repository URL, current branch, current commit hash, and authentication
tokens. A centralized process runner ensures consistent error handling and
output capture across all callers.
tests:
- ProcessRunner_TryRunAsync_WithValidCommand_ReturnsOutput
- ProcessRunner_TryRunAsync_WithInvalidCommand_ReturnsNull
- ProcessRunner_TryRunAsync_WithNonZeroExitCode_ReturnsNull
- ProcessRunner_RunAsync_WithValidCommand_ReturnsOutput
- ProcessRunner_RunAsync_WithFailingCommand_ThrowsException
29 changes: 29 additions & 0 deletions docs/reqstream/build-mark/repo-connectors/repo-connector-base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
# Software Unit Requirements for the IRepoConnector Interface and RepoConnectorBase Class
#
# IRepoConnector defines the contract for all repository connectors.
# RepoConnectorBase provides a common base implementation including process
# execution delegation and version-list search utilities.

sections:
- title: RepoConnectorBase Unit Requirements
requirements:
- id: BuildMark-RepoConnectorBase-Interface
title: The IRepoConnector interface shall define the contract for all repository connectors.
justification: |
A common interface ensures that all repository connectors are interchangeable,
enabling the factory and program to work with any connector implementation
without depending on concrete types.
tests:
- MockRepoConnector_ImplementsInterface
- GitHubRepoConnector_ImplementsInterface_ReturnsTrue

- id: BuildMark-RepoConnectorBase-CommandExecution
title: The RepoConnectorBase class shall provide a virtual command execution method for shell commands.
justification: |
Abstracting command execution behind a virtual method allows test subclasses
to override it with mock implementations, enabling deterministic unit tests
that do not spawn real processes.
tests:
- MockRepoConnector_Constructor_CreatesInstance
- GitHubRepoConnector_Constructor_CreatesInstance
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
# Software Unit Requirements for the RepoConnectorFactory Class
#
# RepoConnectorFactory creates the appropriate IRepoConnector implementation
# based on the runtime environment (GitHub Actions environment variables,
# or git remote URL inspection).

sections:
- title: RepoConnectorFactory Unit Requirements
requirements:
- id: BuildMark-RepoConnectorFactory-Create
title: The RepoConnectorFactory class shall create the appropriate repository connector for the environment.
justification: |
The factory encapsulates connector selection logic so that the Program class
does not need to know which connector to use. The correct connector is chosen
automatically based on GitHub Actions environment variables or git remote URL.
tests:
- RepoConnectorFactory_Create_ReturnsConnector
- RepoConnectorFactory_Create_ReturnsGitHubConnectorForThisRepo
20 changes: 20 additions & 0 deletions docs/reqstream/build-mark/repo-connectors/repo-connectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ sections:
- BuildMark-GitHub-BuildInformation
- BuildMark-GitHub-GraphQLClient

- id: BuildMark-RepoConnectors-ConnectorBase
title: >-
The RepoConnectors subsystem shall provide a common interface and base class for all repository connectors.
justification: |
A shared interface and base class ensure that all connector implementations
are interchangeable and benefit from common utilities such as process
execution delegation and version-list search.
tests:
- MockRepoConnector_ImplementsInterface
- GitHubRepoConnector_ImplementsInterface_ReturnsTrue
children:
- BuildMark-RepoConnectorBase-Interface
- BuildMark-RepoConnectorBase-CommandExecution

- id: BuildMark-RepoConnectors-MockConnector
title: The RepoConnectors subsystem shall provide a mock connector for testing and development.
justification: |
Expand All @@ -40,6 +54,8 @@ sections:
- MockRepoConnector_ImplementsInterface
- MockRepoConnector_GetBuildInformationAsync_ReturnsExpectedVersion
- MockRepoConnector_GetBuildInformationAsync_ReturnsCompleteInformation
children:
- BuildMark-MockRepoConnector-Deterministic

- id: BuildMark-RepoConnectors-ProcessRunner
title: The RepoConnectors subsystem shall provide a process execution utility for running shell commands.
Expand All @@ -54,6 +70,8 @@ sections:
- ProcessRunner_TryRunAsync_WithNonZeroExitCode_ReturnsNull
- ProcessRunner_RunAsync_WithValidCommand_ReturnsOutput
- ProcessRunner_RunAsync_WithFailingCommand_ThrowsException
children:
- BuildMark-ProcessRunner-RunAsync

- id: BuildMark-RepoConnectors-Factory
title: The RepoConnectors subsystem shall provide a factory for creating the appropriate repository connector.
Expand All @@ -64,3 +82,5 @@ sections:
tests:
- RepoConnectorFactory_Create_ReturnsConnector
- RepoConnectorFactory_Create_ReturnsGitHubConnectorForThisRepo
children:
- BuildMark-RepoConnectorFactory-Create
Loading