Skip to content

Latest commit

 

History

History
366 lines (302 loc) · 11.6 KB

File metadata and controls

366 lines (302 loc) · 11.6 KB

GitFlow Workflow

This document describes the GitFlow workflow used in the SKaiNET project for managing feature development, releases, and hotfixes.

GitFlow is a branching model for Git that defines specific branch types and their purposes. It provides a robust framework for managing larger projects with scheduled releases and helps teams collaborate effectively while maintaining code stability.

  • Purpose: Tracks the most recently published release — nothing more, nothing less. If it’s on main, it has a tag and a Maven Central publish behind it.

  • Lifetime: Permanent

  • Protection: Not currently enabled on GitHub (no required reviews/checks) — direct pushes are possible but should never happen outside the release step below. Enabling protection is a TODO, not a claim this document should make until it’s actually turned on.

  • Merges from: release/ and hotfix/ branches only, as an explicit last step after that branch’s tag has been pushed and its publish workflow has gone green — never before, and never automatically.

  • Reset 2026-08-29 (SKaiNET#1198 thread): main had drifted ~1,800 commits behind develop (stuck at 0.2.0) because the "merge release branch to main`" step had been opened as a PR for every release since, and closed unmerged every time — `develop was already the project’s real default branch and the actual publish trigger (a pushed tag), so nothing needed main to be current, and it wasn’t. Rather than reconcile ~1,800 commits of drift with no real value in the history itself, the old branch was renamed to legacy (its full history is still there, just not on main anymore) and a new main was created starting at the 0.51.0 tag. main before 0.51.0 lives at legacy, not in `main’s own history.

  • Purpose: Integration branch for features under development

  • Lifetime: Permanent

  • Protection: Direct commits should be minimal

  • Merges from: feature/, release/, and hotfix/* branches

  • Purpose: Develop new features for upcoming releases

  • Naming convention: feature/feature-name or feature/ISSUE-123-feature-name (e.g., feature/cnn-layers, feature/transformer-embeddings)

  • Branch from: develop

  • Merge back to: develop

  • Lifetime: Until feature is complete

  • Deletion: After successful merge to develop

  • Purpose: Prepare new production releases

  • Naming convention: release/1.2.0 (following semantic versioning)

  • Branch from: develop

  • Merge back to: main and develop

  • Lifetime: Until release is deployed

  • Activities: Bug fixes, documentation updates, release preparation

  • Purpose: Quick fixes for critical production issues

  • Naming convention: hotfix/1.2.1 or hotfix/critical-fix

  • Branch from: main

  • Merge back to: main and develop

  • Lifetime: Until fix is deployed

  • Priority: High - should be processed immediately

Note
This diagram shows the conceptual GitFlow shape (tag on main after merging the release branch in). SKaiNET’s actual sequence tags the release branch’s own commit before touching main — see Release Process below for the real order and why.
gitGraph
    commit id: "Initial"
    branch develop
    checkout develop
    commit id: "Dev setup"

    branch feature/cnn-layers
    checkout feature/cnn-layers
    commit id: "Add conv2d layer"
    commit id: "Add pooling layer"

    checkout develop
    merge feature/cnn-layers
    commit id: "Merge CNN layers"

    branch feature/tokenizer
    checkout feature/tokenizer
    commit id: "Add word embeddings"
    commit id: "Add BPE tokenizer"

    checkout develop
    merge feature/tokenizer
    commit id: "Integration"

    branch release/1.0.0
    checkout release/1.0.0
    commit id: "Prepare v1.0.0"
    commit id: "Fix tests"

    checkout main
    merge release/1.0.0
    commit id: "Release v1.0.0" tag: "v1.0.0"

    checkout develop
    merge release/1.0.0

    checkout main
    branch hotfix/1.0.1
    checkout hotfix/1.0.1
    commit id: "Fix gradient explosion"

    checkout main
    merge hotfix/1.0.1
    commit id: "Hotfix v1.0.1" tag: "v1.0.1"

    checkout develop
    merge hotfix/1.0.1

    checkout develop
    branch feature/transformer-attention
    checkout feature/transformer-attention
    commit id: "Add self-attention"
Loading
  1. Create a feature branch from develop:

    git checkout develop
    git pull origin develop
    git checkout -b feature/lstm-layers
  2. Develop the feature with regular commits:

    git add .
    git commit -m "Implement LSTM forward pass"
    git push origin feature/lstm-layers
  3. When feature is complete, create a pull request to develop

  4. After code review and approval, merge to develop:

    git checkout develop
    git pull origin develop
    git merge --no-ff feature/lstm-layers
    git push origin develop
    git branch -d feature/lstm-layers

This is the sequence actually used from 0.51.0 onward — it differs from a textbook GitFlow release in one important way: the tag lives on the release branch’s own commit, independent of main, because the Maven Central publish workflow triggers on the tag push (on: push: tags: '*' in .github/workflows/publish.yml), not on anything landing on main. main is updated *after a successful publish, as an explicit last step — never before, and never as a side effect of tagging.

  1. Create a release branch from develop:

    git checkout develop
    git pull origin develop
    git checkout -b release/1.2.0
  2. Perform release preparations, each as its own commit:

    • CHANGELOG.md: full entry for the release

    • README.md: short "What’s New" highlights for this release only, pointing to CHANGELOG.md for history — do not let a "Previously, in …​" cascade accumulate here again

    • docs/antora.yml (skainet_version) and any hardcoded dependency-coordinate snippets in the tutorials (grep for the previous version string across docs/ and README.md to catch drift)

    • ./gradlew generateKernelMatrix generateDocs — run this after the version bump below, not before, or the regenerated docs stamp the wrong version

    • gradle.properties (VERSION_NAME) — its own commit, last, matching release: X.Y.Z

    • Run final tests; fix any release-blocking bugs on the branch

  3. Open a PR from the release branch to develop and merge it once CI is green — this is what actually brings the version bump back into the integration branch:

    git push origin release/1.2.0
    gh pr create --base develop --head release/1.2.0 --title "Release 1.2.0"
    # wait for CI to go green, then merge
  4. Tag the release branch’s own release: X.Y.Z commit directly — not a commit on main, which doesn’t have this release yet:

    git tag -a 1.2.0 <release-commit-sha> -m "SKaiNET 1.2.0 — <headline>"
    git push origin 1.2.0

    Pushing the tag triggers the publish workflow. Wait for it to go green before the next step — a red publish run means the tag exists but nothing actually shipped to Maven Central; do not treat tagging alone as "released."

  5. Once the publish workflow succeeds, merge main up to the release — the step every release before 0.51.0 skipped:

    git fetch origin
    git push origin <release-commit-sha>:refs/heads/main   # fast-forward; main has no protection to route around

    This is a manual step by design (see the main Branch section above) — not automated on publish success. Do it as part of closing out the release, not as an afterthought.

  6. Delete the release branch once both merges (into develop and main) are done:

    git push origin --delete release/1.2.0
  1. Create a hotfix branch from main:

    git checkout main
    git pull origin main
    git checkout -b hotfix/1.2.1
  2. Implement the fix:

    git add .
    git commit -m "Fix memory leak in tensor operations"
  3. Merge to main:

    git checkout main
    git merge --no-ff hotfix/1.2.1
    git tag -a v1.2.1 -m "Hotfix version 1.2.1"
    git push origin main --tags
  4. Merge to develop:

    git checkout develop
    git merge --no-ff hotfix/1.2.1
    git push origin develop
    git branch -d hotfix/1.2.1
  • Use descriptive names that reflect the purpose

  • Include issue numbers when applicable: feature/ISSUE-123-transformer-embeddings

  • Use lowercase with hyphens: feature/add-attention-mechanism

  • Use present tense: "Add feature" not "Added feature"

  • Keep first line under 50 characters

  • Provide detailed description for complex changes

  • Reference issue numbers: "Fix gradient clipping in LSTM (closes #123)"

  • Always create pull requests for merging to main and develop

  • Require code review before merging

  • Include comprehensive description of changes

  • Ensure all tests pass before merging

  • Use --no-ff flag to preserve branch history

  • Follow Semantic Versioning

  • Tag all releases with version numbers

  • Update version in project files before release

  • Maintain CHANGELOG.md with release notes

  • Run tests on all feature branches

  • Run comprehensive test suite on develop and main

  • Block merges if tests fail

  • A pushed tag (any branch, in practice always the release/* branch’s own commit) is what triggers the Maven Central publish workflow — not landing on main.

  • main is a read-only mirror of "what’s been published," updated manually after the fact (see the Release Process above); it has no deploy step of its own.

  • develop is where CI runs on every push/PR; there is no separate staging deploy.

  • develop is protected today: required build-job status check, no force-pushes, no deletions, enforced for admins too.

  • main is not currently protected — turning that on (required status checks at minimum) is a TODO, tracked so this document doesn’t quietly drift from reality again.

When encountering merge conflicts:

  1. Update your branch with latest changes:

    git checkout your-branch
    git fetch origin
    git merge origin/develop
  2. Resolve conflicts manually in your editor

  3. Test the resolution

  4. Commit the merge resolution

If you commit to wrong branch:

  1. Create a new branch from the correct base:

    git checkout correct-base-branch
    git checkout -b new-feature-branch
    git cherry-pick commit-hash
  2. Reset the wrong branch:

    git checkout wrong-branch
    git reset --hard HEAD~1

GitFlow provides a structured approach to managing code changes in collaborative environments. By following this workflow consistently, the SKaiNET project maintains code quality, enables parallel development, and ensures stable releases.

For questions or clarifications about this workflow, please refer to the original GitFlow article or reach out to the project maintainers.