Issue Tracking for Your Project: CSGitLab and GitHub

The Project Initiation Document operates at the grain of objectives (On) and deliverables (Dn) — a handful of numbered items a marker can read in five minutes. Your actual week-to-week work happens at a much finer grain, and that's what an issue tracker is for. This page covers the two trackers you're most likely to use for a final-year project: the department's own CSGitLab instance, and GitHub. The mechanics differ; the discipline you should apply is the same in both.

Which One Should You Use?

CSGitLab (csgitlab.reading.ac.uk)GitHub
HostingInstitutional — runs on department infrastructureThird-party — Microsoft-owned, public cloud
Default visibility for new reposTypically private-by-default within the institution, but always check when you create the projectPublic unless you deliberately set it to Private
Supervisor accessUsually already integrated with institutional accounts — add your supervisor as a member directlyRequires inviting your supervisor's personal GitHub account as a collaborator
CI/CDBuilt-in GitLab CI — but no department-provided runners exist for student projects; you'd need to register your own (see below)GitHub Actions, runs on GitHub-hosted runners by default, or self-hosted if you register your own
When it's the obvious choiceYour module or programme specifies it, or you want everything to stay on institutional infrastructureYour supervisor or project brief specifies it, or you're already comfortable in that ecosystem

Where you have a genuine free choice, CSGitLab is the preferred primary platform, for a reason that matters more than tooling preference: if the institutional instance suffers an outage or fault near a deadline, extensions for affected students are handled automatically, because the department can see the outage on its own infrastructure. A GitHub outage — or any problem specific to your personal GitHub account — carries no such automatic recognition; you'd need to make the case for an extension yourself, with evidence. That asymmetry alone is a reason to make CSGitLab the platform your submission depends on, whatever else you also use alongside it.

If neither is specified, ask your supervisor before committing — moving a repository's history between platforms mid-project is possible but adds friction you don't need. Whichever you pick as primary, treat that choice as fixed once work starts (though see below for why using both together is worth doing regardless).

One gap worth knowing about up front: CSGitLab has GitLab CI available, but there are currently no department-provided runners for student projects to use — a .gitlab-ci.yml pipeline on CSGitLab will sit queued with nothing to execute it unless you register a runner yourself. If you want CI on CSGitLab, you'll need to set up your own runner (a laptop, a spare machine, or a small cloud instance registered as a project or group runner) rather than assuming one is provided. This isn't a reason to avoid CSGitLab as your primary platform — it just means CI/CD there is opt-in infrastructure you build, not a service that's already running.

Keep the Repository Private

This is not optional advice, it's an academic-integrity requirement: a final-year project repository should be set to Private for the duration of the project, on either platform.

  • Plagiarism risk runs both ways. A public repository lets a future student copy your work; it also creates a channel through which your work could be flagged as having copied someone else's if timestamps and diffs get misread out of context. Private repositories remove the ambiguity entirely.
  • It's easy to get wrong by default. A GitHub personal account defaults new repositories to Public — check the visibility setting the moment you create the project, not after your first commit. CSGitLab's institutional defaults vary by how the project was created, so verify rather than assume there too.
  • Check it periodically, not just once. A repository transfer, a fork, or a settings change during the project can silently flip visibility. Glance at the setting at each milestone alongside the other checks in your PID re-read.
  • Grant access deliberately, not by making it public. If you need a marker, an external examiner, or a collaborator to see the repository, add them as a named collaborator/member with appropriate permissions — don't solve an access problem by removing the visibility restriction.
  • Going public later is a deliberate decision, not a default. If you want to showcase the finished project after your degree is awarded and marks are confirmed, that's a separate, later choice — made once the academic-integrity window has closed, not while the project is still being assessed.

Set the same visibility on both remotes if you're using the dual-remote setup below — a private CSGitLab project pushed to a public GitHub mirror by accident defeats the point entirely.

Working Practice: Push to Both Remotes

CSGitLab should be your primary platform, for the deadline-extension reason above — but that doesn't mean GitHub has no place. The recommended working practice is to set up both as git remotes on the same local repository and push to both on every commit (or at least every session). This costs almost nothing and buys real resilience:

  • Continued working if either one is down. If CSGitLab is unreachable — maintenance, an outage, a network issue specific to campus — you keep committing locally and can still push to GitHub, so work doesn't stall waiting for one service to recover. The reverse applies if GitHub has a bad day.
  • A redundant backup, not just a mirror. Two independent full copies of your history, on two organisationally separate platforms, is meaningfully safer than one copy plus a laptop. Neither platform going down, or even both accounts being compromised independently, is a single point of failure any more.
  • CSGitLab still decides your deadline protection. Pushing to GitHub as well doesn't change which platform's outages are recognised automatically — that's still CSGitLab. The dual push is insurance for your own continuity of work, not a second channel for extension claims.

Setting it up is a few minutes' work with git's native support for multiple remotes:

# after cloning from CSGitLab (origin already points there)
git remote add github https://github.com/<you>/<project>.git

# push to both with one command by adding a second push URL to origin
git remote set-url --add --push origin https://csgitlab.reading.ac.uk/<you>/<project>.git
git remote set-url --add --push origin https://github.com/<you>/<project>.git

# now a single push updates both
git push origin main

(If you'd rather keep the remotes visibly separate instead of collapsing them into one push target, git push origin main && git push github main after every commit does the same job slightly more explicitly — pick whichever you're less likely to forget to run.)

Mapping Objectives to Issues

An objective from the PID is too coarse to work on directly — it's the thing you report against, not the thing you do on a Tuesday afternoon. Break each On down into issues sized so that most close within a few days:

graph TD O1["O1: Design and implement
a cache eviction strategy"] I1["Issue: Define eviction
policy interface"] I2["Issue: Implement LRU-based
candidate strategy"] I3["Issue: Write correctness
test suite (O1.T)"] I4["Issue: Integrate strategy
into cache layer"] O1 --> I1 O1 --> I2 O1 --> I3 O1 --> I4

Whichever tracker you use, make the link explicit in both directions:

  • Issue → objective: reference the objective id in the issue description or title, e.g. "[O1] Implement LRU-based candidate strategy". A label (O1, O2, …) works well on both platforms and lets you filter the whole board by objective.
  • Objective → issues: when you re-read the PID at a milestone, you should be able to answer "what issues satisfy O1?" without hunting — a saved filter or milestone/label view answers this directly.

If an issue doesn't trace back to a numbered objective, that's the moment to ask whether it belongs in the project at all — see the scope-creep warning in Choosing a Final-Year Project.

CSGitLab: Issues, Boards, Milestones

GitLab featureUse it for
IssuesThe unit of work. Title states the concrete outcome; description links back to the PID objective id.
LabelsTag with the objective id (O1O4) and a type (bug, spike, writing). Filter the issue list by objective label to answer "what's left on O2?"
MilestonesMap to your term/phase boundaries from the PID timeline — a milestone per broaden/narrow cycle or per reporting deadline works well.
Issue BoardsA Kanban view (To Do / Doing / Done, or finer) per milestone. Useful in supervision meetings — pull it up and talk through what moved.
WeightOptional, but a rough size estimate (1/2/3/5) on each issue makes velocity visible — useful input to the "does another broaden/narrow cycle fit?" question on the project-selection page.
Merge RequestsLink each MR to the issue it closes (Closes #42) so the commit graph and the issue tracker tell the same story — this is part of what an examiner is reading when they look at your repository, per The Report as the Front-End.

GitHub: Issues, Projects, Milestones

GitHub featureUse it for
IssuesSame role as GitLab issues — one concrete outcome per issue, objective id in the title or description.
LabelsSame pattern: an O1O4 label per objective, plus type labels. GitHub's label colours are a cheap way to make the objective breakdown visually scannable on the issue list.
MilestonesSame role as GitLab milestones — phase or deadline boundaries from your PID timeline.
Projects (the board view)GitHub's Projects feature gives a Kanban/table view across issues; group or filter by the objective label the same way.
Linked pull requestsCloses #42 in a PR description links it to the issue automatically, same rationale as GitLab's MR linking above.

A Few Habits Worth Keeping

  • Write the issue before you start the work, not after. An issue written retroactively describes what happened; one written first describes what you intended, which is what makes the eventual comparison ("did I do what I planned?") meaningful.
  • Close with a comment, not just a status change. One line on what was actually done, especially if it diverged from the issue title, saves you from having to reconstruct the story later when you write the implementation chapter.
  • Don't let the tracker and the PID drift apart. If an objective's scope changes, update both the PID and the labels/milestones that reference it in the same sitting — a tracker that still says O3 for an objective you quietly renumbered is worse than no tracker at all.
  • Treat a stalled issue as a signal. An issue that's been open far longer than its peers, or reopened repeatedly, is exactly the kind of evidence The Unstuck Ladder talks about — worth noticing before it becomes a crisis in week 30.