For my new open source projects, this is the basic repository structure and build approach I'm going to use.
- Trivial to apply and update via dotnet-file with just two simple
dotnet
commands. - Repo instructions should just be:
dotnet restore & dotnet build & dotnet test
right on the repo root.
After creating an empty repo (maybe with just a readme.md
), just run:
dotnet file init https://github.com/devlooped/oss/blob/main/.netconfig
This will fetch the given [dotnetconfig](https://dotnetconfig.org] and synchronize the configured files and create a .netconfig in the repo containing all the downloaded entries for future sync.
At this point, you should add a skip
value to the .netconfig
file for the entries
you don't want to keep up-to-date afterwards. The default skips would likely match
the provided .netconfig, plus any extra files you want to modify, for
example:
[file]
url = https://github.com/devlooped/oss
# don't sync the .netconfig itself, to avoid a loop
[file ".netconfig"]
url = https://github.com/devlooped/oss/blob/main/.netconfig
skip
# readme is always customized for the project
[file "readme.md"]
url = https://github.com/devlooped/oss/blob/main/readme.md
skip
# we'll be tweaking the build, say
[file ".github/workflows/build.yml"]
url = https://github.com/devlooped/oss/blob/main/.github/workflows/build.yml
skip
NOTE: you can also download the raw .netconfig from this repository and run
dotnet file update
instead. It already contains skips for the readme.
From this point on, applying template changes is as easy as running:
dotnet file update
You can also just list detected changes with:
dotnet file changes
Automation is provided via the dotnet-file.yml
workflow, which runs daily and does a dotnet file sync
and creates a PR in your
repository as needed, with a populated changelog to inspect the incoming changes.
In no particular order:
-
src
folder containsDirectory.Build.props
andDirectory.Build.targets
and those contain all the customizations for the build, packaging and versioning. In the past I went crazy factoring the targets into multiple files with single purpose groupings and it bcomes quite hard to follow even for me, having written it all. So it's better to Keep Things Simple™. Logically related properties and items have aLabel
attribute as documentation. You can customize both by adding aDirectory.props
orDirectory.targets
, which are imported at the end of both files. -
If a
src/Directory.Packages.props
is found, I turn on centrally managed package versions, but it's not required. -
GitHub Actions are provided for the CI/CD process as follows:
-
Build: regular branch builds and PRs build. By default, build and test jobs will run on
ubuntu-latest
. To customize this, create a./.github/workflows/os-matrix.json
file in the repository, with the matrix to use for the build, such as["windows-latest", "ubuntu-latest", "macOS-latest"]
. -
Changelog: when a release is released (not created, but actually released), a changelog is calculated and pushed to main. The changelog.config file defines changelog generation options.
-
Release notes: when a release (either draft or final) is published, the notes are generated using the same configuration above.
-
Includes: allows using HTML includes in markdown files for easier content reuse. Readmes should include the standard footer with:
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->
-
-
dotnet format
is enforced on builds to keep consistency with.editorconfig
. -
dependabot is configured to check for updated nuget packages daily.
-
A default strong-name key is provided by default too. If the project does not desire to strong-name the assemblies, it can be skipped as well in the
.netconfig
file. If present, the mentionedDirectory.Build.*
targets will automatically pick the file and strong name assemblies. -
Bug template provided. No addiitonal config provided since the discussions URLs cannot be relative :(.