Thank you for your interest in contributing to FormCraft! This document provides guidelines and instructions for contributing.
🌐 Try the live demo to explore the library's capabilities before contributing.
By participating in this project, you are expected to uphold our Code of Conduct:
- Be respectful and inclusive
- Welcome newcomers and help them get started
- Focus on constructive criticism
- Respect differing viewpoints and experiences
- Check if the issue already exists
- Include a clear title and description
- Provide steps to reproduce the issue
- Include code samples if applicable
- Mention your environment (OS, .NET version, etc.)
- Open an issue with the "enhancement" label
- Clearly describe the feature and its benefits
- Provide use cases and examples
- Be open to discussion and feedback
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add or update tests as needed
- Ensure all tests pass (
dotnet test) - Update documentation if needed
- Commit your changes (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
- .NET 9.0 SDK or later
- Visual Studio 2022, VS Code, or JetBrains Rider
- Git
# Clone the repository
git clone https://github.com/phmatray/DynamicFormBlazor.git
cd DynamicFormBlazor
# Restore dependencies
dotnet restore
# Build the solution
dotnet build
# Run tests
dotnet test# Windows
./pack-local.ps1
# macOS/Linux
./pack-local.sh- Follow C# coding conventions
- Use meaningful variable and method names
- Add XML documentation to public APIs
- Keep methods small and focused
- Write unit tests for new functionality
- Maintain existing code style
- Write unit tests for all new code
- Ensure existing tests continue to pass
- Aim for high code coverage
- Test edge cases and error conditions
- Use the existing test patterns
This project follows Semantic Versioning, and the version is never chosen
by hand. release-please derives it from the
Conventional Commits that have landed on dev and creates the vX.Y.Z tag when the release PR is
merged; MinVer then reads that tag to stamp the assemblies and
packages. The tag is the single source of truth — no file in the repository records the version.
Between releases MinVer produces height-based pre-release versions (e.g. 3.1.1-preview.4) from your
local commits, which is what you will see when you build or pack locally.
We use Conventional Commits for commit messages:
feat:for new featuresfix:for bug fixesdocs:for documentation changesstyle:for formatting changesrefactor:for code refactoringtest:for test additions/changeschore:for maintenance tasks
Examples:
feat: add field groups layout support
fix: resolve null reference in field renderer
docs: update API documentation
Pull requests are squash-merged, so the PR title — not the individual commits on your branch —
becomes the commit message on dev, and that is what release-please parses. A PR titled
feat(mudblazor): add a colour-picker field (#123) produces a minor bump and a changelog entry; a PR
titled Update stuff produces neither, silently.
.github/workflows/pr-title-lint.yml checks this on every non-draft PR, so a non-conforming title is
caught before merge rather than quietly dropping your change out of the next release.
The full convention is <type>(<scope>): <subject> (#<issue>).
CHANGELOG.md is owned entirely by release-please, which rewrites it in the standing release PR.
- Do not hand-edit
CHANGELOG.md, and do not add an entry for your change — your PR title is the entry. - Nothing in the build generates it either. git-cliff,
cliff.toml, the NukeGenerateChangelogtarget and the changelog pre-commit hook were all removed: with release-please owning the file, a second generator would rewrite it out from under the open release PR.
Those installer scripts are gone, but they are not self-uninstalling — a hook they wrote is still in
your local clone, and it still tries to regenerate and git add CHANGELOG.md on every commit. That
is a second writer to a file release-please now owns. Check and remove it:
cat .git/hooks/pre-commit # if it mentions generate-changelog, remove it:
rm .git/hooks/pre-commit(git commit --no-verify skips it for a single commit, but removing it is the fix.)
- Update XML documentation for public APIs
- Update README.md if adding features
- Add examples for new functionality
- Keep documentation clear and concise
Releasing is one action: merge the release PR. Nothing is tagged by hand.
- Every push to
devruns.github/workflows/release-please.yml, which keeps a release PR open showing the next version and the changelog it would publish. If nothing releasable has landed (for example onlychore(deps):commits), no PR is opened — that is correct. - A maintainer reviews that PR and merges it.
- release-please tags
vX.Y.Zand creates the GitHub Release. - In the same workflow run, the
nupkgjob checks out the new tag — MinVer resolves the version from it — and publishesFormCraftandFormCraft.ForMudBlazorto NuGet.org via Trusted Publishing (OIDC, a short-lived key; no long-lived secret), then attaches the packages to the release.
Publishing lives in that same workflow run by necessity: release-please creates the tag with
GITHUB_TOKEN, and GitHub does not fire on: push: tags for events created by that token, so a
tag-triggered publish workflow would never run.
The tag and the GitHub Release are created before the nupkg job builds anything, so a failure
there leaves a tagged, announced release with no packages attached.
Recover with “Re-run failed jobs”. Do not use “Re-run all jobs”: that re-runs release-please,
which sees the release already exists, reports release_created: false, and skips the nupkg job
entirely — so nothing is retried and the failure looks resolved. Pushing to NuGet is idempotent
(--skip-duplicate), so re-running the publish is always safe.
Only feat, fix, perf, refactor and revert commits produce a release; chore, ci, docs,
style, test and build are hidden and do not trigger one. That is intentional — it matches what
the previous git-cliff config did — but it means a period of pure chore(deps): updates opens no
release PR, even if one of those bumps matters (a shipped runtime dependency, say).
Hand-tagging is no longer an escape hatch. To force a release, add a Release-As: footer to the
squashed commit, e.g. a PR whose body ends with:
Release-As: 3.2.1
Feel free to:
- Open an issue for questions
- Start a discussion in GitHub Discussions
- Contact the maintainers
Thank you for contributing to FormCraft!