Skip to content
Open
Changes from 1 commit
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
113 changes: 113 additions & 0 deletions documentation/specs/enable-binlog-collection-by-env-var
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
## Purpose

Enable binary logging in CI/CD pipelines when `-noAutoResponse` blocks response files, without modifying build scripts or project files.

## Supported Arguments

- `-bl` / `/bl` / `-binarylogger` / `/binarylogger` (with optional parameters)
- `-check` / `/check` (with optional parameters - requires code modification to support `deferred` mode)

**All other switches are blocked** as security risks. These two switches are diagnostic/monitoring tools that don't affect build behavior or enable code execution.

## Argument Processing Order

1. **MSBuild.rsp** (next to MSBuild.exe) - skipped if `-noAutoResponse` present
2. **Directory.Build.rsp** (next to project) - skipped if `-noAutoResponse` present
3. **MSBUILD_LOGGING_ARGS** - always processed, regardless of `-noAutoResponse`
4. **Command-line arguments** - highest precedence

The environment variable is processed **after** checking for `-noAutoResponse`, making it a reliable fallback when response files are disabled.

## Parameter Merging

### Challenge

Multiple sources can specify the same argument type (e.g., `-bl` from both environment variable and command line). MSBuild must determine how to handle conflicts.

### Merging Strategy

**Binary Logger (-bl)**
- Multiple `-bl` arguments are **allowed and cumulative**
- Each creates a separate binlog file
- Example: `MSBUILD_LOGGING_ARGS=-bl:env.binlog` + command line `-bl:cmd.binlog` → both files created

**Build Check (-check)**
- Multiple `-check` arguments are **merged**
- Later specifications override earlier ones for the same check
- Example: `MSBUILD_LOGGING_ARGS=-check:deferred` + command line `-check` (immediate) → immediate mode wins

### Precedence for Conflicts

When the same parameter is specified in multiple locations:

1. Command-line arguments (highest priority)
2. MSBUILD_LOGGING_ARGS environment variable
3. Directory.Build.rsp
4. MSBuild.rsp (lowest priority)

**Implementation Note**: MSBuild's existing argument parser handles merging logic. The environment variable arguments are prepended to the command line before parsing, ensuring natural precedence.

## Implementation Flow

1. MSBuildApp.Execute() called
2. Check for `-noAutoResponse` in command line
3. Process response files (if no `-noAutoResponse`)
4. Read MSBUILD_LOGGING_ARGS environment variable
5. Validate and filter arguments
6. Prepend valid arguments to command line
7. **Parse combined command line** (merging happens here)
8. Execute build

## Warning Messages

All issues are logged as **warnings**, never errors. Builds must not fail due to environment variable processing.

- **Informational**: "Using arguments from MSBUILD_LOGGING_ARGS environment variable: {0}"
- **Rejected Argument**: "MSBUILD_LOGGING_ARGS: Ignoring unsupported argument '{0}'. Only -bl and -check arguments are allowed."
- **Processing Error**: "Error processing MSBUILD_LOGGING_ARGS environment variable: {0}"

## Build Check (-check) Handling

### Deferred Analysis Mode

`-check:deferred` enables binlog replay analysis without build-time overhead:

- **During build**: Flag recorded in binlog, BuildCheck NOT activated
- **During replay**: Binlog reader activates BuildCheck for analysis

**Rationale**: BuildCheck analysis can be expensive. Environment variable is for diagnostics that can be analyzed later, allowing teams to record data without performance impact.

### Example Workflow

```bash
# 1. Configure environment
set MSBUILD_LOGGING_ARGS=-bl:build.binlog -check:deferred

# 2. Run build (normal speed, no BuildCheck overhead)
msbuild solution.sln

# 3. Later: Replay binlog (BuildCheck analyzes recorded events)
msbuild build.binlog
```

## CI/CD Integration

### Approach A: Response File (Traditional)
- Create `Directory.Build.rsp` with binlog argument
- Might be blocked by `-noAutoResponse`

### Approach B: Environment Variable (New)
- Set `MSBUILD_LOGGING_ARGS=-bl:build.binlog`
- Works with `-noAutoResponse`
- No file creation needed

### Combining Both Approaches

```bash
# Environment provides base logging
set MSBUILD_LOGGING_ARGS=-bl:base.binlog -check:deferred

# Command line adds specific logging
msbuild solution.sln -bl:detailed.binlog

# Result: Two binlog files created (base.binlog + detailed.binlog)
Loading