SOP: GitLab Merge Request - Developer Role
Purpose
This guide provides a step-by-step workflow for creating and managing merge requests in GitLab. It is designed for developers of all experience levels, from those new to Git/GitLab to seasoned contributors.
Quick Reference Workflow
Issue > Branching > Merging
- Create Issue
- Discuss Issue in comments and summarise off-line discussions
- Assign Issue to Assignee (Implementer)
- Create MR from Issue (create branch + draft MR)
- Prepare to make changes (locally or Web IDE)
- Make changes (commit frequently)
- Push to branch
- Monitor CI (fix failures, push again)
- Prepare MR (description, verify settings)
- Remove Draft status
- Request review (assign reviewer/assignee)
- Engage with review comments
- Make changes > Push > Request re-review
- Reviewer(s) approve
- Maintainer merges
- Celebrate the merge!
Full Workflow
This section describes the workflow for Developers who make changes to the content of the project in GitLab. The workflow used has a larger number of steps. The main points in the workflow are:
- Create an Issue and discuss
- Assign person to implement solution
- Create Merge Request + Branch from the issue
- Work
- Initiate Merge Request review
- Celebrate merge of the branch into
development
Step 1: Create an Issue
What: Document the bug, feature, or task before making any changes.
Why: Creating an issue first ensures that every piece of work is documented, visible to everyone, and properly discussed before any changes are made. It helps us track what we’re doing, why we’re doing it, and how we decided on the solution - making it easier for anyone, present and future, to understand the context later. Skipping this step makes it harder to follow the project’s progress and can lead to duplicated or misaligned work.
How:
- Navigate to the relevant project in GitLab
- Go to Issues > New Issue
- Select an appropriate template from the drop down menu under the word 'Description'
- We have 4 Issue templates and one merge request template
- Bug Report Schema: Used to describe a problem with the metadata schema
- Bug Report Service: Used to describe a problem with a service or other piece of software
- EPIC Issue: Used to describe large multitask issues
- Feature Request: Used to describe a new feature
- Templates for issues and merge requests are maintained at NFDI4Immuno / Utilities / project-templates.
- Fill in:
- Title: Clear, concise and action oriented description -- is required
- Think of the title as a headline - it enables others to understand what the specific task is about
- See below for examples
- Description: Detailed explanation of what needs to be done and why. Use the template as a guide and feel free to add additional information as needed for greater clarity
- The Issue description is important as is the seed for the following discussion and ultimately resolution
- Write the description as explaining the issue to someone unfamiliar with the bug or feature
- Labels: Add relevant labels
- Assignee: Leave empty or assign to yourself (only one assignee per issue in free tier GitLab)
- Click Create Issue
Examples of title forms to avoid and to strive for:
| Vague titles (Avoid) | Descriptive & Action-Oriented (Preferred) |
|---|---|
| Error on page | 404 Error when clicking 'Submit' on Metadata form |
| Layout broken | Search bar overlaps navigation menu on mobile view |
| Add export | Add 'Export to JSON' button to Schema Viewer |
| Update README | Update installation instructions for macOS users in README |
| Clean up code | Refactor authentication logic to use environment variables |
Tips:
- Write issues as if explaining to someone unfamiliar with the context
- Reference related issues if applicable
- Add screenshots or examples when helpful
- Include acceptance criteria: "This is done when..." if applicable
Avoid:
- Skipping issue creation - even for "quick fixes"
- Vague titles like "Fix bug" or "Update code"
Step 2: Discuss the Issue
What: Engage with others to clarify requirements and approach.
Why: Discussing the issue upfront helps us align on the goal, avoid misunderstandings, and agree on the best way to solve the problem. It gives everyone a chance to ask questions, suggest alternatives, and catch potential issues early - before any changes are made. This saves time later and ensures we’re all on the same page, especially when multiple people might be involved. Decisions and reasoning for a particular suggestion is documented.
How:
- Team members comment on the issue
- Discuss:
- Implementation approach
- Potential challenges
- Scope and boundaries
- Testing requirements
- Reach consensus before starting development
Tips:
- Use
@<name>to notify specific people - Ask questions early rather than making assumptions
- Document decisions in the issue comments for future reference
Step 3: Assign Issue to Assignee
What: Identify and assign the person who can implement the changes.
Why: Assigning an issue to a person makes it clear who is responsible for coordinating the implementation of the changes.
How:
- Open the issue in GitLab
- In the right-hand sidebar, click Edit next to "Assignee"
- Select the person who will implement the changes - the assignee is automatically notified
Tips:
- Only one person can be assigned per issue (due to limitations in GitLab Free tier)
- If the work is complex or spans multiple areas additional people can be included by mentioning them in a comment
Avoid:
- Using assignment as a mean of notifying people - use
@<name>a comment instead
Step 4: Create Merge Request from Issue
What: Create a feature branch and draft merge requests directly from the issue.
Why:
- Creating the merge request directly from the issue links the work to the original discussion, keeping everything in one place. It automatically creates a dedicated feature branch, so there is no development work on stable branches like
developmentormain. - Setting a 'Draft' status signals that the work is still in progress - this prevents premature reviews and keeps the workflow clean and intentional.
- Changing the label of the issue or task makes it easy to exclude or include these in searches.
How:
- Open the issue you're working on
- Click the Create merge request button near the top right
- This automatically creates:
- A new branch named
{issue-number}-{issue-title}(e.g.,42-add-user-authentication) - A draft merge request linked to the issue
- Sets the source branch (your new branch) and target branch
- IMPORTANT: In the merge request creation page, verify:
- Target branch is set to
development(NOTmain) - The merge request is marked as Draft
- Click Create merge request at the bottom
- Change the label of issue or task to
status::in-process - Go to the task or issue handled by the merge request
- Go to ‘Labels’ in the side bar, click ‘Edit’, unselect
status::to-doand selectstatus::in-process
Tips:
- Always branch from
developmentunless you have a specific reason not to - The auto-generated branch name keeps naming consistent
- Draft status prevents accidental early reviews
Step 5: Prepare to Make Changes
What: Get the code locally or prepare to use GitLab's Web IDE.
Why: This step ensures that work is done on the right branch and has the latest state. This prevents mistakes like accidentally making changes on the wrong branch or missing recent updates. Starting from the correct branch (always development) keeps work aligned with the current state of the project and limits merge conflicts later.
Option A - For developers with Git access (Command Line or IDE):
Clone the project repository if it does not exist locally:
# Clone the repository (only needed once)
git clone <repository-url>
cd <project-directory>
Fetch the new branch from the server and check it out for work:
# Fetch the latest changes
git fetch origin
# Switch to your new branch
git checkout {issue-number}-{issue-title}
Option B - For developers using GitLab Web IDE:
- Open the merge request you created
- Click Code > Open in Web IDE
- The Web IDE opens with your branch already selected
Tips:
- Verify you're on the correct branch before making changes
- Keep your local
developmentbranch updated regularly
Step 6: Make Changes
What: Implement the changes discussed in the issue.
Why: Breaking work into small, focused changes makes it easier to review, test, and understand. Commit messages help the reviewer to understand the intent. See Git Commit Messages for the use of prefixes and commit message structure.
How:
- Make changes to the necessary files
- Run unit tests to test changes (if possible)
- Document functions and complex steps
- Add unit tests for new functions and other additions
- Commit work regularly using the structure and prefixes described in Git Commit Messages
Good Practices for Commits:
- One logical change = One commit
- Small, focused commits are better than large, monolithic ones
- Example progression:
- Commit 1: "feat: Add user model"
- Commit 2: "feat: Add user validation logic"
- Commit 3: "feat: Add user authentication endpoint"
- Commit 4: "test: Add user authentication tests"
Commit Commands (for CLI/IDE users):
# Stage your changes`
git add <file1> <file2>
# Or stage all changes`
git add .
# Commit with a message
git commit -m "feat: Add user model with email and password fields"
Pre-commit hooks:
Pre-commit hooks are automated checks done before a commit is created. These checks enforce coding standards and help identifying issues before the code is integrated in the code base (CI).
Once you run the git commit -m ... command, the pre-commit framework in our repository will do the following:
- Format the code
- Lint the code
- Check types
- Ensure dependencies are up to date
If any hook fails, the commit will be blocked until all identified fixes are made. This will help you integrate clean and validated code. As a team, it will help building a unified code base with consistent quality.
Tips:
- Commit frequently - it's easier to review smaller chunks
- A commit is stored only locally at first. To make it visible on GitLab, see next step.
- Commits will be squashed on merge, meaning all commits on the feature branch will be merged into one when merging into
development - Use pre-commit hooks to help you commit clean code, e.g. read well error and warning messages.
Avoid:
- Committing commented-out code or debugging statements
- Committing configuration files with personal settings, e.g. usernames, secrets and passwords
- Committing unrelated changes in the same commit
- Ignoring the suggested corrections made by pre-commit hooks. You won't be able to finalize your commit until these are solved
- Disabling pre-commit hooks
Step 7: Push Changes
What: Add commits to GitLab so they're visible in the merge request.
Why: Pushing changes to the remote branch on GitLab makes them visible to others and triggers the CI pipeline automatically. Pushing regularly also means that the work is safely backed up and not lost if something goes wrong locally.
How: Command Line:
git push origin {issue-number}-{issue-title}
VS Code/IDE:
- Click the Push button in your Git interface
GitLab Web IDE:
- Click Commit > Write commit message > Commit & Push
Tips:
- Push regularly, not just when finished - this helps preventing loss of changes
- Each push automatically triggers a CI pipeline, which runs unit tests
- Pushing early lets others see your progress
Step 8: Monitor CI Pipeline
What: Automated tests and checks run on every push. Ensure they pass.
Why: The CI pipeline runs automated tests and checks to ensure the changes don’t break existing functionality.
How:
- Go to the merge request in GitLab
- Scroll down to see the Pipeline status
- Click on the pipeline to see individual job results
- If any jobs fail:
- Click on the failed job to see the error log
- Fix the issues locally
- Commit and push the fixes
- CI will run again automatically
- For unit tests
- Go to Test summary, click on downward arrow (show details)
- Inspect failed tests individually
What Must Pass:
- All unit tests
- Documentation building jobs, if present
- Some jobs (like external publishing) may be allowed to fail if due to external factors
Tips:
- Don't move to the next step until CI has passed
- Read error messages carefully - they indicate exactly what's wrong, even when it is hard to read
- If stuck, ask a maintainer for help
Avoid:
- Ignoring CI failures hoping they'll "work in production"
- Asking for review while tests are failing
Step 9: Prepare the Merge Request
What: Write a clear description and verify settings before requesting review.
Why: A well-written merge request description gives reviewers the context they need to quickly and thoroughly understand the changes. It explains what changed and why. This also ensures the work is properly documented for future reference, even after the MR is merged.
How:
- Click Edit on the merge request
- Update the Description with:
- What changed: Summary of the implementation
- Why: Reference the issue and explain your approach
- How to test: Steps reviewers can follow to verify
- Screenshots: If UI changes, add before/after images
- Verify settings:
- Target branch is
development (check below MR header) - "Delete source branch after merge" is checked (default)
- CI pipeline passed
- The original issue is linked (should show "Closes #XX")
- Apply applicable labels
Example MR Descriptions
A simple solution:
## Merge Request Checklist
Before merging, ensure you have completed the following:
- [x] Code/Schema is thoroughly tested locally.
- [x] Documentation (internal/external) is updated, if necessary.
- [x] All new code/definitions are covered by tests.
- [x] This MR targets the correct branch (e.g., `development`, or a specific feature branch).
## Summary
Added a new `email` slot to the Person class to support contact information requirements. This change enables downstream applications to store and validate email addresses for person records.
## Implementation Details
- Added `email` slot to `Person` class in `schema/core.yaml`
- Set slot as optional with pattern validation for email format
- Added example usage in inline documentation
- Updated `examples/person_example.yaml` to demonstrate email field
### Type of Change (Select one or more)
- [ ] Feature / Enhancement
- [x] Bug Fix
- [x] Metadata/Schema Change
- [ ] Refactoring / Technical Debt
- [ ] Documentation Update
## Related Issues
Closes #123
MR for a more complex problem:
## Merge Request Checklist
Before merging, ensure you have completed the following:
- [x] Code/Schema is thoroughly tested locally.
- [x] Documentation (internal/external) is updated, if necessary.
- [x] All new code/definitions are covered by tests.
- [x] This MR targets the correct branch (e.g., `development`, or a specific feature branch).
## Summary
Implemented batch processing endpoint for data ingestion with validation, deduplication, and error handling. This replaces the single-item POST endpoint which caused performance issues when processing large datasets, reducing ingestion time from ~30 minutes to ~2 minutes for 10k records.
## Implementation Details
- Created new `/api/v1/batch/ingest` POST endpoint in `routers/batch.py`
- Implemented chunked processing (configurable batch size, default 100 items)
- Added async processing with progress tracking via job ID
- Added comprehensive error handling for database connection failures and timeouts
- Added integration tests covering success cases, partial failures, and edge cases
- Added unit tests for deduplication logic and validation rules
- Updated `docs/api-reference.md` with batch endpoint usage examples
- Added monitoring metrics for batch size, processing time, and failure rates
### Type of Change (Select one or more)
- [x] Feature / Enhancement
- [ ] Bug Fix
- [ ] Metadata/Schema Change
- [ ] Refactoring / Technical Debt
- [x] Documentation Update
## Related Issues
Closes #123, #456, #789
The merge request template can be found under NFDI4Immuno / Utilities / project-templates / merge_request_templates.
Tips:
- A good description helps reviewers understand context quickly
- Include anything unusual or tricky about the implementation
- If there are deviations from the original issue discussion, explain why
Step 10: Remove Draft Status and Change Label of Issue or Task
What: Signal that the merge request is ready for review.
Why: Removing the draft status signals that your work is complete, tested, and ready for formal review. Changing the label of the issue or task makes it easy to exclude these from searches.
How:
- At the top of the merge request, click Mark as ready
- The "Draft:" prefix is removed from the title
- The MR is now visible to reviewers as ready for review
- Change the label of issue or task to
status::in-review - Go to the task or issue handled by the merge request
- Go to ‘Labels’ in the side bar, click ‘Edit’, unselect
status::in-processand selectstatus::in-review
Tips:
- A good description helps reviewers understand context quickly
Include anything unusual or tricky about the implementation
If there are deviations from the original issue discussion, explain why
- Only remove Draft when:
- All changes are complete
- CI pipeline has passed
- MR description is complete
- The Draft status can be reenabled if larger changes are needed - or the MR cannot be completed before other changes have been merged
Step 11: Request Review
What: Assign reviewers to examine the changes. Because of the limitations in the GitLab Free tier, only one reviewer can be assigned. If an additional reviewer is needed add this as assignee.
Why: Review brings in fresh eyes to check the changes, legibility, and documentation and is a key part of the quality process.
How:
For single reviewer:
- In the merge request, find the Reviewers section
- Click Edit and select one reviewer
- GitLab notifies them automatically
For two reviewers:
- Assign one person as Reviewer
- Assign the other as Assignee
- Add a comment: "@reviewer1 @reviewer2 - Ready for review, please coordinate approval"
- Both reviewers work together and use the Approve button to signal completion
Tips:
- Choose reviewers based on:
- Expertise in the affected area
- Complexity (simple changes: 1 reviewer, complex: 2 reviewers)
Step 12: Engage with Review Comments
What: Respond to feedback from reviewers.
Why: Different views and opinions are opportunities to improve the code, to clarify decisions, and to learn.
How:
- GitLab notifies you when reviewers leave comments
- For each comment, it is possible to:
- Reply with explanations or questions
- Make the requested change > commit > push
- Start a discussion if there is disagreement or questions
- After addressing a comment:
- Click Resolve discussion (or ask the reviewer to resolve it)
- If you made changes, mention which commit addressed it
Types of Comments:
- Suggestions: Reviewer may propose specific code changes you can apply directly
- Questions: Answer clearly; they help improve understanding
- Required changes: Must be addressed before approval
- Optional/Nit-picks: Nice to have but not blocking
Tips:
- Don't take feedback personally - it's about the code, not you
- Ask for clarification if you don't understand a comment
- Explain your reasoning if you disagree with a suggestion
Avoid:
- Resolve discussions without addressing them
- Ignore comments hoping they'll be forgotten
Step 13: Request Re-Review
What: After making changes based on feedback, ask reviewers to check again.
How:
- After pushing your changes, click the circle-arrow icon ⟲ by the reviewers name to return the merge request to the reviewer.
- Alternatively, add a comment mentioning the reviewers:
- "@reviewer @assignee - I've addressed your comments in commits. Ready for another look!"
Tips:
- Summarize what changed since the last review
- Point to specific commits that addressed feedback
- If changes were significant, explain your approach
Step 14: Approval
What: Reviewers formally approve the merge request.
Why: An approval from a reviewer means they’ve reviewed and accepted the changes.
How:
- Once reviewers are satisfied, they click the Approve button
- The approval appears on the merge request
- This signals to maintainers that the MR is ready to merge
For multiple reviewers (workaround):
- Both the assigned reviewer and assignee should agree to approve
- This gives maintainers clear signal that both have signed off
Tips:
- Approval means "I've reviewed this and it meets our quality standards"
- It doesn't mean the code is perfect - just that it's good enough to merge
Step 15: Maintainer Merges
What: A maintainer performs the final merge into development.
Why: Only maintainers can merge changes into development to protect the stability of the codebase. They ensure that all checks are passed, approvals are in place, and no unresolved issues remain.
Who: Only users with a Maintainer role can merge.
How (for maintainers):
- Verify:
- MR is approved
- CI pipeline is green
- No unresolved discussions
- Target branch is
development - Click Merge
- Confirm CI passes all jobs
- Confirm the merge
- The MR is merged, and:
- The branch is automatically deleted
- The linked issue is automatically closed
- Changes are now in
development
Step 16: Celebrate
What: Changes are now part of the project! Time to party!
Why: Because we can and it is a good reason.
Good Practices Summary
Do
- Create issues before writing code
- Branch from
development(unless exceptional circumstances) - Commit frequently with clear messages
- Push regularly to trigger CI
- Respond to review comments promptly and professionally
- Test changes thoroughly
Do not
- Skip issue creation for "quick fixes"
- Push directly to
developmentormain - Request review while CI is failing
- Ignore review comments
- Take feedback personally
- Resolve discussions without addressing them
Additional Resources
- GitLab Documentation: https://docs.gitlab.com
- Git Basics: https://git-scm.com/book/en/v2/Getting-Started-What-is-Git