Skip to content

Commit 41f389e

Browse files
feat: add EditorConfig, issue templates, and CI/CD workflows for improved contribution and code quality
1 parent 3f09d0f commit 41f389e

16 files changed

Lines changed: 462 additions & 7 deletions

.editorconfig

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# EditorConfig — https://editorconfig.org
2+
# Top-most file; stops the search here.
3+
root = true
4+
5+
##########################################
6+
# All files
7+
##########################################
8+
[*]
9+
charset = utf-8
10+
end_of_line = lf
11+
insert_final_newline = true
12+
trim_trailing_whitespace = true
13+
indent_style = space
14+
indent_size = 4
15+
16+
[*.{yml,yaml,json,md}]
17+
indent_size = 2
18+
19+
[*.md]
20+
trim_trailing_whitespace = false # trailing spaces are significant (hard line breaks)
21+
22+
[*.{csproj,props,targets,slnx}]
23+
indent_size = 2
24+
25+
##########################################
26+
# C# files
27+
##########################################
28+
[*.cs]
29+
indent_size = 4
30+
max_line_length = 120
31+
32+
# --- Language conventions ---------------------------------------------------
33+
csharp_style_namespace_declarations = file_scoped:suggestion
34+
csharp_using_directive_placement = outside_namespace:suggestion
35+
dotnet_sort_system_directives_first = true
36+
dotnet_separate_import_directive_groups = false
37+
38+
# var usage — prefer explicit types except when obvious from the right-hand side.
39+
csharp_style_var_for_built_in_types = false:suggestion
40+
csharp_style_var_when_type_is_apparent = true:suggestion
41+
csharp_style_var_elsewhere = false:suggestion
42+
43+
# Expression-bodied members.
44+
csharp_style_expression_bodied_methods = when_on_single_line:suggestion
45+
csharp_style_expression_bodied_properties = true:suggestion
46+
csharp_style_expression_bodied_accessors = true:suggestion
47+
48+
# Modern C# preferences.
49+
csharp_prefer_braces = true:suggestion
50+
csharp_style_prefer_pattern_matching = true:suggestion
51+
csharp_style_prefer_switch_expression = true:suggestion
52+
csharp_style_throw_expression = true:suggestion
53+
csharp_prefer_simple_using_statement = true:suggestion
54+
csharp_style_prefer_range_operator = true:suggestion
55+
csharp_style_prefer_index_operator = true:suggestion
56+
57+
# --- Naming: private fields use _camelCase --------------------------------
58+
dotnet_naming_rule.private_fields_underscore.severity = suggestion
59+
dotnet_naming_rule.private_fields_underscore.symbols = private_fields
60+
dotnet_naming_rule.private_fields_underscore.style = underscore_prefix
61+
62+
dotnet_naming_symbols.private_fields.applicable_kinds = field
63+
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
64+
65+
dotnet_naming_style.underscore_prefix.required_prefix = _
66+
dotnet_naming_style.underscore_prefix.capitalization = camel_case
67+
68+
# --- 'this.' qualification --------------------------------------------------
69+
dotnet_style_qualification_for_field = false:suggestion
70+
dotnet_style_qualification_for_property = false:suggestion
71+
dotnet_style_qualification_for_method = false:suggestion
72+
dotnet_style_qualification_for_event = false:suggestion
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Bug report
2+
description: Report incorrect parsing, writing, or generator behavior.
3+
labels: [bug]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Thanks for the report! Please provide a **minimal reproduction** — a model class and
9+
a sample input line are usually enough.
10+
- type: textarea
11+
id: what-happened
12+
attributes:
13+
label: What happened?
14+
description: Describe the bug and what you expected instead.
15+
placeholder: Parsing column X returns "..." but should return "...".
16+
validations:
17+
required: true
18+
- type: textarea
19+
id: repro
20+
attributes:
21+
label: Minimal reproduction
22+
description: Model definition + input + the call you make. This will be rendered as C#.
23+
render: csharp
24+
placeholder: |
25+
public partial class MyModel : IFixedWidthModel<MyModel>
26+
{
27+
[FixedColumn(0, 10)] public string Name { get; set; }
28+
}
29+
// input: "John "
30+
validations:
31+
required: true
32+
- type: input
33+
id: version
34+
attributes:
35+
label: Package version
36+
description: Which version of FixedWidthParser.NET?
37+
placeholder: "1.0.0"
38+
validations:
39+
required: true
40+
- type: dropdown
41+
id: path
42+
attributes:
43+
label: Which path is affected?
44+
multiple: true
45+
options:
46+
- Runtime parser (char)
47+
- UTF-8 byte parser
48+
- Source generator
49+
- Writer
50+
- Reader (sync/async)
51+
- Not sure
52+
validations:
53+
required: true
54+
- type: input
55+
id: os
56+
attributes:
57+
label: OS / runtime
58+
placeholder: "Windows 11 / .NET 10.0.x"

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Question / discussion
4+
url: https://github.com/GabrielMarquezMatte/FixedWidthParser/discussions
5+
about: Ask usage questions or propose ideas before filing a formal issue.
6+
- name: Security vulnerability
7+
url: https://github.com/GabrielMarquezMatte/FixedWidthParser/security/advisories/new
8+
about: Report security issues privately — do not open a public issue.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Feature request
2+
description: Suggest a new capability or improvement.
3+
labels: [enhancement]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: Problem / motivation
9+
description: What are you trying to do that the library doesn't support today?
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: proposal
14+
attributes:
15+
label: Proposed solution
16+
description: What API or behavior would you like? A sketch of the usage is welcome.
17+
render: csharp
18+
validations:
19+
required: true
20+
- type: textarea
21+
id: alternatives
22+
attributes:
23+
label: Alternatives considered
24+
description: Workarounds you've tried or other approaches you weighed.
25+
- type: checkboxes
26+
id: contribution
27+
attributes:
28+
label: Contribution
29+
options:
30+
- label: I'd be willing to submit a PR for this.

.github/dependabot.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
version: 2
2+
updates:
3+
# .NET / NuGet dependencies (libraries, analyzers, test packages).
4+
- package-ecosystem: nuget
5+
directory: "/"
6+
schedule:
7+
interval: weekly
8+
open-pull-requests-limit: 10
9+
groups:
10+
# Bundle the many analyzer packages into a single PR to cut noise.
11+
analyzers:
12+
patterns:
13+
- "*Analyzer*"
14+
- "*.Analyzers"
15+
- "SonarAnalyzer.*"
16+
- "Roslynator.*"
17+
- "Meziantou.Analyzer"
18+
- "SharpSource"
19+
- "AsyncFixer"
20+
test:
21+
patterns:
22+
- "xunit*"
23+
- "Microsoft.NET.Test.Sdk"
24+
- "coverlet.*"
25+
labels:
26+
- dependencies
27+
28+
# GitHub Actions used across the workflows.
29+
- package-ecosystem: github-actions
30+
directory: "/"
31+
schedule:
32+
interval: weekly
33+
open-pull-requests-limit: 5
34+
labels:
35+
- dependencies
36+
- ci

.github/pull_request_template.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## Summary
2+
3+
<!-- What does this PR change and why? -->
4+
5+
## Type of change
6+
7+
- [ ] Bug fix (non-breaking change that fixes an issue)
8+
- [ ] New feature (non-breaking change that adds functionality)
9+
- [ ] Breaking change (fix or feature that changes existing behavior)
10+
- [ ] Performance improvement
11+
- [ ] Docs / tooling / CI only
12+
13+
## Checklist
14+
15+
- [ ] Tests added/updated for the change
16+
- [ ] `dotnet build --configuration Release` is warning-clean
17+
- [ ] `dotnet test --configuration Release` passes
18+
- [ ] Public API changes are documented (XML docs + README if relevant)
19+
- [ ] For performance-sensitive changes: benchmark numbers included below
20+
21+
## Benchmark impact (if applicable)
22+
23+
<!-- Paste before/after BenchmarkDotNet results, or note "N/A". -->
24+
25+
## Related issues
26+
27+
<!-- e.g. Closes #123 -->

.github/workflows/benchmark-pages.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ jobs:
5454
with:
5555
dotnet-version: '10.0.x'
5656

57+
- name: Cache NuGet packages
58+
uses: actions/cache@v4
59+
with:
60+
path: ~/.nuget/packages
61+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }}
62+
restore-keys: |
63+
${{ runner.os }}-nuget-
64+
5765
- name: Restore
5866
run: dotnet restore tests/Benchmarks/Benchmarks.csproj
5967

.github/workflows/benchmark-pr.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ jobs:
5252
with:
5353
dotnet-version: '10.0.x'
5454

55+
- name: Cache NuGet packages
56+
uses: actions/cache@v4
57+
with:
58+
path: ~/.nuget/packages
59+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }}
60+
restore-keys: |
61+
${{ runner.os }}-nuget-
62+
5563
- name: Restore
5664
run: dotnet restore tests/Benchmarks/Benchmarks.csproj
5765

.github/workflows/ci.yml

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ permissions:
1818

1919
jobs:
2020
test:
21-
name: Build & Test
22-
runs-on: ubuntu-latest
21+
name: Build & Test (${{ matrix.os }})
22+
runs-on: ${{ matrix.os }}
23+
strategy:
24+
fail-fast: false
25+
matrix:
26+
os: [ubuntu-latest, windows-latest, macos-latest]
2327

2428
steps:
2529
- name: Checkout
@@ -30,25 +34,71 @@ jobs:
3034
with:
3135
dotnet-version: '10.0.x'
3236

37+
# Cache restored NuGet packages keyed on the project/props files.
38+
# (setup-dotnet's built-in cache needs a packages.lock.json, which this repo
39+
# does not use, so we cache the global packages folder directly.)
40+
- name: Cache NuGet packages
41+
uses: actions/cache@v4
42+
with:
43+
path: ~/.nuget/packages
44+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }}
45+
restore-keys: |
46+
${{ runner.os }}-nuget-
47+
3348
- name: Restore
3449
run: dotnet restore FixedWidthParser.slnx
3550

3651
- name: Build (Release)
3752
run: dotnet build FixedWidthParser.slnx --configuration Release --no-restore
3853

39-
- name: Test (Release)
54+
- name: Test (Release) + collect coverage
4055
run: >-
4156
dotnet test FixedWidthParser.slnx
4257
--configuration Release
4358
--no-build
4459
--verbosity normal
4560
--logger "trx;LogFileName=test-results.trx"
4661
--results-directory ./TestResults
62+
--collect:"XPlat Code Coverage"
4763
4864
- name: Upload test results
4965
if: always()
5066
uses: actions/upload-artifact@v4
5167
with:
52-
name: test-results
53-
path: ./TestResults/*.trx
68+
name: test-results-${{ matrix.os }}
69+
path: ./TestResults/**/*.trx
5470
if-no-files-found: ignore
71+
72+
# Coverage is uploaded once, from the Linux leg only, to avoid duplicate reports.
73+
- name: Upload coverage to Codecov
74+
if: matrix.os == 'ubuntu-latest'
75+
uses: codecov/codecov-action@v5
76+
with:
77+
token: ${{ secrets.CODECOV_TOKEN }}
78+
files: ./TestResults/**/coverage.cobertura.xml
79+
fail_ci_if_error: false
80+
81+
# Surfaces vulnerable transitive/direct packages regardless of NoWarn suppressions
82+
# in Directory.Build.props (NU190x warnings are silenced there).
83+
audit:
84+
name: Dependency audit
85+
runs-on: ubuntu-latest
86+
steps:
87+
- uses: actions/checkout@v4
88+
89+
- uses: actions/setup-dotnet@v4
90+
with:
91+
dotnet-version: '10.0.x'
92+
93+
- name: Restore
94+
run: dotnet restore FixedWidthParser.slnx
95+
96+
- name: Check for vulnerable packages
97+
run: |
98+
echo "Scanning for known-vulnerable packages…"
99+
output=$(dotnet list FixedWidthParser.slnx package --vulnerable --include-transitive)
100+
echo "$output"
101+
if echo "$output" | grep -q -E '\b(High|Critical)\b'; then
102+
echo "::error::High or Critical severity vulnerability found in dependencies."
103+
exit 1
104+
fi

0 commit comments

Comments
 (0)