Thank you for your interest in contributing! This guide covers development workflow, coding standards, and our AI-powered development process.
main) — Always in a releasable statemain for new features or fixesUse descriptive branch names with the following prefixes. Features and fixes use an issue number (e.g., feat/025-semantic-diff, fix/026-template-escape), while other types use descriptive names:
| Prefix | Purpose | Example |
|---|---|---|
feat/ |
New features | feat/semantic-diff-firewall-rules |
fix/ |
Bug fixes | fix/template-rendering-escape |
docs/ |
Documentation changes | docs/update-installation-guide |
refactor/ |
Code refactoring | refactor/parser-immutable-models |
chore/ |
Maintenance tasks | chore/update-dependencies |
workflow/ |
Agent/workflow changes | workflow/add-uat-skill |
website/ |
Website changes | website/add-feature-page |
Example workflow:
git checkout main
git pull origin main
git checkout -b feat/your-feature-name
All changes must include appropriate tests. The project uses a comprehensive testing strategy:
# Run all tests
dotnet test
# Run specific test categories
dotnet test --filter "FullyQualifiedName~MarkdownInvariantTests"
dotnet test --filter "FullyQualifiedName~MarkdownLintIntegrationTests"
All generated markdown must:
<details>, <summary>)This project uses Conventional Commits to automate versioning and changelog generation.
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
| Type | Description | Version Bump |
|---|---|---|
feat |
A new feature | Minor (0.x.0) |
fix |
A bug fix | Patch (0.0.x) |
docs |
Documentation only | None |
style |
Code style changes | None |
refactor |
Code refactoring | None |
test |
Adding or modifying tests | None |
chore |
Other maintenance | None |
For breaking changes, add BREAKING CHANGE: in the commit footer or use ! after the type:
feat(parser)!: change output format to JSON
BREAKING CHANGE: The output format has changed from plain text to JSON.
Each commit should focus on a single topic or change. If you find yourself using "and" repeatedly in a commit message, consider splitting it into multiple commits.
# Feature
git commit -m "feat(cli): add --output flag for custom output path"
# Bug fix
git commit -m "fix(parser): handle empty resource changes array"
# Documentation
git commit -m "docs: update installation instructions"
# Breaking change
git commit -m "feat(api)!: rename TerraformPlan to PlanResult"
maindotnet format --verify-no-changes
dotnet build
dotnet test
.editorconfig)Understanding the project layout:
src/ — Core library and CLI entry pointtests/ — All test projects (unit, integration, snapshot tests)tools/ — Helper tools (HtmlRenderer, ScreenshotGenerator, TerraformShowRenderer)docs/ — Feature specifications, ADRs, architecture documentationexamples/ — Demo Terraform plans and output sampleswebsite/ — GitHub Pages website (HTML/CSS)scripts/ — Build, test, and workflow automation scripts.github/ — GitHub Actions workflows and agent skill definitionsThis project uses rebase and merge to maintain a linear Git history:
git pull --rebase origin maingit push --force-with-leasetfplan2md is a standalone CLI tool, not a class library. Use the most restrictive access modifier that works:
private — Default for class membersinternal — For cross-assembly visibility within the solutionpublic — Only for main entry points or when absolutely necessaryNever use public just for testing. Instead, use InternalsVisibleTo to expose internal members to test projects.
All code must be thoroughly documented with XML doc comments:
<summary>, <param>, <returns>, <remarks>/// <summary>
/// Parses Terraform plan JSON and extracts resource changes.
/// </summary>
/// <param name="planFilePath">Absolute path to the plan JSON file.</param>
/// <returns>Collection of resource changes found in the plan.</returns>
/// <remarks>
/// Uses streaming deserialization for memory efficiency on large files.
/// Related feature: docs/features/008-comprehensive-demo/
/// </remarks>
internal async Task<IReadOnlyList<ResourceChange>> ParseAsync(string planFilePath)
{
// Implementation
}
# Clone the repository
git clone https://github.com/oocx/tfplan2md.git
cd tfplan2md
# Restore tools (including Husky for git hooks)
dotnet tool restore
# Install git hooks
dotnet husky install
# Build and test
dotnet build
dotnet test
This project uses Husky.Net for git hooks:
dotnet format --verify-no-changes and dotnet buildIf your commit is rejected:
dotnet format to fix formattingtype: descriptionThis project was built 100% using GitHub Copilot with a multi-agent AI workflow.
Releases are automated via GitHub Actions:
main, the CI workflow runs Versionizefeat:, fix:, or BREAKING CHANGE commits, Versionize:
.csprojCHANGELOG.mdv0.2.0)If you have questions, feel free to open an issue for discussion.