Skip to content

Commit b22f49f

Browse files
committed
Merge branch 'v2_develop' into v2_release
2 parents 53ca729 + 25b7a77 commit b22f49f

929 files changed

Lines changed: 38441 additions & 32772 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.config/dotnet-tools.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {}
5+
}

.github/workflows/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
## CI/CD Workflows
2+
3+
The repository uses multiple GitHub Actions workflows. What runs and when:
4+
5+
### 1) Build Solution (`.github/workflows/build.yml`)
6+
7+
- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`); supports `workflow_call`
8+
- **Runner/timeout**: `ubuntu-latest`, 10 minutes
9+
- **Steps**:
10+
- Checkout and setup .NET 8.x GA
11+
- `dotnet restore`
12+
- Build Debug: `dotnet build --configuration Debug --no-restore -property:NoWarn=0618%3B0612`
13+
- Build Release (library): `dotnet build Terminal.Gui/Terminal.Gui.csproj --configuration Release --no-incremental --force -property:NoWarn=0618%3B0612`
14+
- Pack Release: `dotnet pack Terminal.Gui/Terminal.Gui.csproj --configuration Release --output ./local_packages -property:NoWarn=0618%3B0612`
15+
- Restore NativeAot/SelfContained examples, then restore solution again
16+
- Build Release for `Examples/NativeAot` and `Examples/SelfContained`
17+
- Build Release solution
18+
- Upload artifacts named `build-artifacts`, retention 1 day
19+
20+
### 2) Build & Run Unit Tests (`.github/workflows/unit-tests.yml`)
21+
22+
- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`)
23+
- **Matrix**: Ubuntu/Windows/macOS
24+
- **Timeout**: 15 minutes per job
25+
- **Process**:
26+
1. Calls build workflow to build solution once
27+
2. Downloads build artifacts
28+
3. Runs `dotnet restore` (required for `--no-build` to work)
29+
4. **Performance optimizations**:
30+
- Disables Windows Defender on Windows runners (significant speedup)
31+
- Collects code coverage **only on Linux** (ubuntu-latest) for performance
32+
- Windows and macOS skip coverage collection to reduce test time
33+
- Increased blame-hang-timeout to 120s for Windows/macOS (60s for Linux)
34+
5. Runs two test jobs:
35+
- **Non-parallel UnitTests**: `Tests/UnitTests` with blame/diag flags; `xunit.stopOnFail=false`
36+
- **Parallel UnitTestsParallelizable**: `Tests/UnitTestsParallelizable` with blame/diag flags; `xunit.stopOnFail=false`
37+
6. Uploads test logs and diagnostic data from all runners
38+
7. **Uploads code coverage to Codecov only from Linux runner**
39+
40+
**Test results**: All tests output to unified `TestResults/` directory at repository root
41+
42+
### 3) Build & Run Integration Tests (`.github/workflows/integration-tests.yml`)
43+
44+
- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`)
45+
- **Matrix**: Ubuntu/Windows/macOS
46+
- **Timeout**: 15 minutes
47+
- **Process**:
48+
1. Calls build workflow
49+
2. Downloads build artifacts
50+
3. Runs `dotnet restore`
51+
4. **Performance optimizations** (same as unit tests):
52+
- Disables Windows Defender on Windows runners
53+
- Collects code coverage **only on Linux**
54+
- Increased blame-hang-timeout to 120s for Windows/macOS
55+
5. Runs IntegrationTests with blame/diag flags; `xunit.stopOnFail=true`
56+
6. Uploads logs per-OS
57+
7. **Uploads coverage to Codecov only from Linux runner**
58+
59+
### 4) Publish to NuGet (`.github/workflows/publish.yml`)
60+
61+
- **Triggers**: push to `v2_release`, `v2_develop`, and tags `v*`(ignores `**.md`)
62+
- Uses GitVersion to compute SemVer, builds Release, packs with symbols, and pushes to NuGet.org using `NUGET_API_KEY`
63+
64+
### 5) Build and publish API docs (`.github/workflows/api-docs.yml`)
65+
66+
- **Triggers**: push to `v1_release` and `v2_develop`
67+
- Builds DocFX site on Windows and deploys to GitHub Pages when `ref_name` is `v2_release` or `v2_develop`
68+
69+
70+
### Replicating CI Locally
71+
72+
```bash
73+
# Full CI sequence:
74+
dotnet restore
75+
dotnet build --configuration Debug --no-restore
76+
dotnet test Tests/UnitTests --no-build --verbosity normal
77+
dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal
78+
dotnet build --configuration Release --no-restore
79+
```

.github/workflows/unit-tests.yml

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ jobs:
120120
matrix:
121121
os: [ ubuntu-latest, windows-latest, macos-latest ]
122122

123-
timeout-minutes: 15
123+
timeout-minutes: 60
124124
steps:
125125

126126
- name: Checkout code
@@ -154,35 +154,81 @@ jobs:
154154
shell: bash
155155
run: echo "VSTEST_DUMP_PATH=logs/UnitTestsParallelizable/${{ runner.os }}/" >> $GITHUB_ENV
156156

157-
- name: Run UnitTestsParallelizable
157+
- name: Run UnitTestsParallelizable (10 iterations with varying parallelization)
158158
shell: bash
159159
run: |
160-
if [ "${{ runner.os }}" == "Linux" ]; then
161-
# Run with coverage on Linux only
162-
dotnet test Tests/UnitTestsParallelizable \
163-
--no-build \
164-
--verbosity normal \
165-
--collect:"XPlat Code Coverage" \
166-
--settings Tests/UnitTests/runsettings.coverage.xml \
167-
--diag:logs/UnitTestsParallelizable/${{ runner.os }}/logs.txt \
168-
--blame \
169-
--blame-crash \
170-
--blame-hang \
171-
--blame-hang-timeout 60s \
172-
--blame-crash-collect-always
173-
else
174-
# Run without coverage on Windows/macOS for speed
175-
dotnet test Tests/UnitTestsParallelizable \
176-
--no-build \
177-
--verbosity normal \
178-
--settings Tests/UnitTestsParallelizable/runsettings.xml \
179-
--diag:logs/UnitTestsParallelizable/${{ runner.os }}/logs.txt \
180-
--blame \
181-
--blame-crash \
182-
--blame-hang \
183-
--blame-hang-timeout 60s \
184-
--blame-crash-collect-always
185-
fi
160+
# Run tests 3 times with different parallelization settings to expose concurrency issues
161+
for RUN in {1..3}; do
162+
echo "============================================"
163+
echo "Starting test run $RUN of 3"
164+
echo "============================================"
165+
166+
# Use a combination of run number and timestamp to create different execution patterns
167+
SEED=$((1000 + $RUN + $(date +%s) % 1000))
168+
echo "Using randomization seed: $SEED"
169+
170+
# Vary the xUnit parallelization based on run number to expose race conditions
171+
# Runs 1-3: Default parallelization (2x CPU cores)
172+
# Runs 4-6: Max parallelization (unlimited)
173+
# Runs 7-9: Single threaded (1)
174+
# Run 10: Random (1-4 threads)
175+
if [ $RUN -le 3 ]; then
176+
XUNIT_MAX_PARALLEL_THREADS="2x"
177+
echo "Run $RUN: Using default parallelization (2x)"
178+
elif [ $RUN -le 6 ]; then
179+
XUNIT_MAX_PARALLEL_THREADS="unlimited"
180+
echo "Run $RUN: Using maximum parallelization (unlimited)"
181+
elif [ $RUN -le 9 ]; then
182+
XUNIT_MAX_PARALLEL_THREADS="1"
183+
echo "Run $RUN: Using single-threaded execution"
184+
else
185+
# Random parallelization based on seed
186+
PROC_COUNT=$(( ($SEED % 4) + 1 ))
187+
XUNIT_MAX_PARALLEL_THREADS="$PROC_COUNT"
188+
echo "Run $RUN: Using random parallelization with $PROC_COUNT threads"
189+
fi
190+
191+
# Run tests with or without coverage based on OS and run number
192+
if [ "${{ runner.os }}" == "Linux" ] && [ $RUN -eq 1 ]; then
193+
echo "Run $RUN: Running with coverage collection"
194+
dotnet test Tests/UnitTestsParallelizable \
195+
--no-build \
196+
--verbosity normal \
197+
--collect:"XPlat Code Coverage" \
198+
--settings Tests/UnitTests/runsettings.coverage.xml \
199+
--diag:logs/UnitTestsParallelizable/${{ runner.os }}/run${RUN}-logs.txt \
200+
--blame \
201+
--blame-crash \
202+
--blame-hang \
203+
--blame-hang-timeout 60s \
204+
--blame-crash-collect-always \
205+
-- xUnit.MaxParallelThreads=${XUNIT_MAX_PARALLEL_THREADS}
206+
else
207+
dotnet test Tests/UnitTestsParallelizable \
208+
--no-build \
209+
--verbosity normal \
210+
--settings Tests/UnitTestsParallelizable/runsettings.xml \
211+
--diag:logs/UnitTestsParallelizable/${{ runner.os }}/run${RUN}-logs.txt \
212+
--blame \
213+
--blame-crash \
214+
--blame-hang \
215+
--blame-hang-timeout 60s \
216+
--blame-crash-collect-always \
217+
-- xUnit.MaxParallelThreads=${XUNIT_MAX_PARALLEL_THREADS}
218+
fi
219+
220+
if [ $? -ne 0 ]; then
221+
echo "ERROR: Test run $RUN failed!"
222+
exit 1
223+
fi
224+
225+
echo "Test run $RUN completed successfully"
226+
echo ""
227+
done
228+
229+
echo "============================================"
230+
echo "All 10 test runs completed successfully!"
231+
echo "============================================"
186232
187233
- name: Upload UnitTestsParallelizable Logs
188234
if: always()

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,4 @@ log.*
7373
!/Tests/coverage/.gitkeep # keep folder in repo
7474
/Tests/report/
7575
*.cobertura.xml
76+
/docfx/docs/migratingfromv1.md

0 commit comments

Comments
 (0)