Skip to content

About

Conventional Commits with ticket references and GitLab merge requests, from inside Claude Code. Zero configuration.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

gitlab-flow

Every change you ship to a GitLab with strict push rules costs the same ritual. You copy the ticket ID out of the branch name. You shape the commit message until the push hook stops rejecting it. You push, open the merge request, retype the summary you already wrote in the commit, paste the ticket link, and add the same reviewers as last time.

It is mechanical work, and every single input to it is already sitting in the repository — in the remote URL, in the branch name, in the diff.

gitlab-flow is a Claude Code plugin that does the whole thing for you, and it works with nothing configured.

What it does

  • Creates the ticketed branch. <type>/<TICKET>-<kebab-description>, always cut from an up-to-date origin/<base> so the merge request does not open already behind its target. Direct commits on protected branches are refused.
  • Writes the commit message. Conventional Commits with the ticket reference at the end — fix(api): resolve null pointer exception [PROJ-456] — with the type inferred from the diff and always confirmed with you before committing.
  • Opens the merge request. Pushes if needed, generates the title and description from the commits and the diff, detects the target branch, and applies your assignee and reviewers.

Install

/plugin marketplace add Nonillo/gitlab-flow
/plugin install gitlab-flow@gitlab-flow

Then just ask: "commit this", or "open the merge request".

Requirements

  • glab 1.89.0 or newer — the GitLab CLI. Installation instructions.
  • git.
  • A repository whose origin points at a GitLab — self-hosted or gitlab.com, either works.

Authenticate once, against the host your repository actually uses:

glab auth login --hostname gitlab.example.com

That hostname flag matters. glab auth login on its own targets gitlab.com, so on a self-hosted GitLab you can be perfectly logged in and still have no access to your own server. gitlab-flow checks for exactly this and tells you which host is missing.

Example

You:    commit this
Claude: You are on main, which is protected, so I will not commit here.
        I can branch first — what is the ticket?
You:    PROJ-123
Claude: Creating feat/PROJ-123-add-oauth-login from origin/main.
        Staged src/auth.js and src/auth.test.js.
        Proposed message — this is a `feat`, from the diff. Confirm?

            feat(auth): add oauth login support [PROJ-123]

You:    yes, then open the MR
Claude: Committed. Pushed feat/PROJ-123-add-oauth-login.
        Merge request !42 → develop
        Title:     PROJ-123: Add OAuth login support
        Assignee:  your-username
        Reviewers: @reviewer-one @reviewer-two
        https://gitlab.example.com/acme/web-app/-/merge_requests/42

The commit message format

<type>(<scope>)<!>: <description> [<TICKET>]
Part Required Notes
type yes one of build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test
scope no in parentheses, e.g. feat(api):
! no immediately before the colon, marks a breaking change
description yes letters, digits, spaces and - _ . , / — no colons, parentheses or emoji
[<TICKET>] yes at the end of the message; [skip ci] may accompany or replace it
feat: implement user authentication [PROJ-123]
fix(api): resolve null pointer exception [PROJ-456]
feat(api)!: change response format [PROJ-567]
chore(release): bump version to 1.2.0 [skip ci]

This is Conventional Commits plus a bracketed ticket reference — a widely used public convention, not any one company's rule. If you want your own GitLab to enforce it, the equivalent push rule is:

^(Merge branch '[^']+' into '[^']+'|(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([\w-]+\))?!?: [a-zA-Z0-9-_.,/ ]+(\[[A-Z0-9]{2,}-\d+\]\s?(\[skip ci\])?|\[skip ci\]\s?(\[[A-Z0-9]{2,}-\d+\])?))$

Paste it into Settings → Repository → Push rules → Commit message.

Configuration

Entirely optional — zero configuration is the supported default. With no config file at all, everything above works: the plugin infers the host, the project, the ticket, the type, the summary and the target branch from the repository itself.

Configure only what is genuinely a preference. Put .gitlab-flow.json at the repository root for per-project settings, or ~/.config/gitlab-flow/config.json for global ones. The repository file wins key by key.

{
  "jiraBaseUrl": "https://jira.example.com",
  "defaultAssignee": "your-username",
  "reviewers": ["reviewer-one", "reviewer-two"],
  "protectedBranches": ["main", "master", "develop"]
}
Key Default when absent
jiraBaseUrl none — the ticket renders as plain text, never as a broken link
defaultAssignee the user glab is authenticated as
reviewers none — the /assign_reviewer line is omitted entirely
protectedBranches ["main", "master"]

If your repository has its own .gitlab/merge_request_templates/, the plugin finds it and offers to fill that in instead of its own template.

What it deliberately does not do

  • It stores no tokens and handles no credentials. No prompts, no environment variables, no keyring of its own. It shells out to glab and reads its status, and glab already solves this properly.
  • It never commits on your behalf without showing you the message first.
  • It does not touch JIRA. The ticket is a text identifier; there is no API call, no ticket creation, no status transition.
  • It does not triage CI or review code. Those are separate problems.

Development

The plugin is markdown plus two JSON manifests — no build, no dependencies.

Validate the manifests and skills:

claude plugin validate . --strict
claude plugin validate ./plugin/claude-code --strict
claude plugin validate ./plugin/claude-code/skills --strict

Run the behavioural eval suite (this spawns real model runs and costs a few dollars):

claude plugin eval ./plugin/claude-code --no-publish --trust-plugin

The aggregate normally lands a bit under 1.00 by design — see plugin/claude-code/evals/README.md for why, and judge a run by that per-case breakdown rather than by a --threshold flag.

License

MIT.

About

Conventional Commits with ticket references and GitLab merge requests, from inside Claude Code. Zero configuration.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors