Issues, labels, milestones, boards
Intermediate GitLab UI
Why this matters
The issue is where a piece of work begins and where its story is kept. A good one gets picked up and finished; a vague one sits in the backlog being re-read. For a non-developer this is often the main way you contribute, so it is worth doing well.
Writing an issue people can act on
Plan → Issues → New issue. The form is short; what you put in it decides everything.
| Part | What to write |
|---|---|
| Title | The problem or the outcome, in one line: "Installation guide is missing the Windows steps" — not "docs" |
| Description | What you observed, what you expected, and where. For a bug: exact steps, the exact error text, the version or environment |
| Assignee | Leave empty unless you know who; an unassigned issue is for the team to pick up |
| Labels | Kind and area, so it can be found and filtered |
| Milestone | If it must be in a particular release |
| Due date | Only if a real date exists; a made-up one is noise |
Two habits make a large difference. Paste text, not screenshots, for anything that is text: an error message in a code block can be searched and copied, an image cannot. And say where: the file, the page, the URL. "The FAQ is wrong" costs someone ten minutes of hunting.
Labels
Labels are the filing system. Most teams use two or three families:
| Family | Examples | Purpose |
|---|---|---|
| Kind | bug, feature, documentation, chore |
What sort of work |
| Area | frontend, api, docs, data |
Which part of the project |
| State | needs-info, blocked, good first issue |
Where it is stuck, or an invitation |
Labels can be defined on the project or on the group, and group labels are shared by every project inside, which keeps a team's vocabulary consistent. Manage → Labels is where they live. Scoped labels (written priority::high) are mutually exclusive: setting priority::low removes priority::high automatically, which stops an issue carrying two contradictory priorities.
Milestones
A milestone is a named goal with dates, usually a release or a sprint: Plan → Milestones. Its page shows the issues and merge requests assigned to it and a burndown of how many are closed, which is the honest answer to "will this be ready?".
If your change must ship with a particular release, put its issue in that milestone. That is the only way anyone planning the release will see it.
Boards
Plan → Issue boards shows issues as cards in columns. The columns are usually labels, so moving a card applies or removes the label, which is the part that surprises people: the board is a view of the issues, not a separate system.
A typical board: Open, workflow::doing, workflow::review, Closed. Dragging a card from Open to workflow::doing adds that label; dragging to Closed closes the issue. Boards can also be filtered by milestone, assignee or label, and a project can have several boards for different audiences.
Issues and Git
The connection is the issue number, and it works in three places (lesson 1.6):
- In a branch name:
docs/12-windows-install-steps. GitLab links branch to issue when the number is in the name, and the issue's Development section then shows the branch. - In a commit message:
docs: add Windows steps (#12)becomes a link. - In a merge request description:
Closes #12links it and closes the issue automatically when the merge request is merged.
The issue page has a Create merge request button that creates a correctly named branch and a draft merge request in one step, which is the tidiest way to start work.
How to do it
Issues live on the platform, so there is no Git command. What the terminal contributes is the number, in the branch name and the commit message:
$ git switch -c docs/12-windows-install-steps
$ git commit -m "docs: add Windows steps to installation guide (#12)"Both links appear on the issue automatically once you push.
The GitLab Workflow extension adds an Issues view in the sidebar listing issues assigned to you, and lets you create a branch from an issue with the right name. It needs a token with api scope (lesson 8.3).
With a GitLab account configured, IntelliJ's Tasks feature can open an issue as a task, create a branch named after it and pre-fill the commit message: Tools → Tasks & Contexts → Open Task….
- Plan → Issues for the list, with filters for label, milestone, assignee and text. New issue to create.
- In the description, use
/quick actions rather than the sidebar for speed. - Plan → Issue boards for the board; drag a card to change its label or close it.
- Plan → Milestones to group issues into a release or sprint.
- On an issue, Create merge request makes the branch and the draft merge request together.
The same concepts: Issues with labels, milestones and assignees, and Projects for boards, which are more flexible and separate from any one repository. Closes #12 works identically. See lesson 10.6.
Common mistakes
- A title that is a category. "Docs" or "Bug" tells nobody anything; write the problem.
- A screenshot of an error. Paste the text; it can be searched and copied.
- No location. Name the file, the page or the URL.
- Assigning to a person who has not agreed. Leave it unassigned, or ask first.
- Expecting the board to be separate from the issues. Moving a card changes labels on the real issue.
- Forgetting
Closes #12in the merge request, so the issue stays open after the work ships.
Try it yourself
Goal: write one good issue and start work from it.
- On your practice project, create an issue for a real improvement to the playground: a title that names the outcome, a description saying where and what, and a
documentationlabel (create the label if needed). - Add it to a milestone you create called
v1.3.0. - On the issue page, use Create merge request → Create branch and note the branch name GitLab suggests.
- In your clone:
git fetch, thengit switch <that branch name>, make the change, commit with(#N)in the message, and push. - Look at the issue again: the branch, the commit and the merge request are all linked from it.
Expected result: the issue's Development section lists the branch and the merge request, and the commit message is a link.
Show solution
The linking is automatic and comes entirely from the issue number appearing in the branch name and the commit message. That is why the naming convention from lesson 6.2 is worth following: it is not tidiness, it is what makes the tools connect the pieces.