Skip to content

Latest commit

 

History

History
111 lines (83 loc) · 4.01 KB

File metadata and controls

111 lines (83 loc) · 4.01 KB

Contributing

Thanks for your interest in structalign! This document covers the development workflow, commit conventions, and the release process.

Prerequisites

  • Go 1.25+ (the floor set by golang.org/x/tools).
  • git-cliff — to regenerate CHANGELOG.md.
  • goreleaser — to validate/build releases locally.
  • Python 3 + Pillow — only needed to regenerate the README screenshot.

Development workflow

main.go (module root) is a thin entrypoint; the implementation lives in pkg/common (contracts) and internal/ (loader, align, layout, ui, app, …). _example/ holds sample structs used for manual testing and in the docs. The repo uses Task; the Makefile just delegates to task.

task build          # -> ./structalign
task ci             # lint, build, test, and a smoke test against ./_example  (what CI runs)
task --list         # list all tasks

Run task ci before pushing — it mirrors the CI job. CI also runs the matrix across Go 1.25.0 and stable.

When you change diff or inspect output, refresh the README screenshot:

task screenshot     # regenerates docs/diff.png (needs python3 + pillow)

Commit messages

Commits follow Conventional Commits. This is what drives the changelog, so the prefix matters:

Prefix Changelog section
feat: Added
fix: Fixed
perf: / refactor: / style: / revert: Changed
deprecate: Deprecated
remove: Removed
security: Security
docs: Documentation
chore: / ci: / build: / test: (excluded — not user-facing)

Mark breaking changes with a ! (e.g. feat!:) or a BREAKING CHANGE: footer.

Pull Request Process

  1. Branch off devel (e.g. feature/<topic>); never target main directly.
  2. Make your change with tests, and run task ci until it's green.
  3. Use Conventional Commits (see above) so the changelog stays accurate.
  4. Open the PR against devel and fill in the pull-request template. Keep it focused — one logical change per PR.
  5. CI (lint, build + test across the Go matrix, CodeQL, dependency review) must pass; a maintainer then reviews and merges.

Branching (git-flow)

  • main — production; every commit is a tagged release.
  • devel — integration branch and the default branch; day-to-day work targets it.
  • feature/*, release/*, hotfix/* — the usual git-flow temporaries.

Do not commit directly to main.

Releasing

Releases use git-flow to cut the version and GoReleaser (triggered by the tag push) to build the cross-platform binaries and publish the GitHub Release. Example for v0.1.0:

# 1. Start the release branch off devel.
git flow release start v0.1.0

# 2. Stamp the changelog for this version and commit it.
task release TAG=v0.1.0
git add CHANGELOG.md
git commit -m "chore(release): v0.1.0"

# 3. (Recommended) dry-run the release build locally — no publish.
task release-check          # validate .goreleaser.yaml
task snapshot               # build all artifacts into dist/

# 4. Finish: merges release -> main, tags v0.1.0, back-merges into devel.
git flow release finish v0.1.0

# 5. Push everything, including the tag (the tag is what triggers the release).
git push origin main devel --tags

# 6. Verify.
gh run list --workflow=release.yml
gh release view v0.1.0

Notes:

  • The tag (vX.Y.Z) is what fires .github/workflows/release.yml; if you forget --tags, nothing happens. The version is derived from the tag and embedded in the binary (structalign -version).
  • Release notes are GitHub's native generated notes (changelog.use: github-native in .goreleaser.yaml). The in-repo CHANGELOG.md is git-cliff-generated and bundled into the release archives.
  • GITHUB_TOKEN is provided automatically by Actions — no secret to configure for a binaries-only release.