Skip to content

Latest commit

 

History

History
551 lines (439 loc) · 18.5 KB

File metadata and controls

551 lines (439 loc) · 18.5 KB

Configuration Reference

glabs uses two configuration layers:

  1. Main config (global, ~/.glabs.yaml)
  2. Course configs (per course and assignment)

Configuration is merged from top to bottom: main config → course config → assignment overrides → defaults.

If you are migrating from the previous startercode structure, use migration.md.

Main config

Default file: ~/.glabs with any Viper-supported extension (for example .yaml, .yml, .json)

gitlab:
  host: https://gitlab.example.org
  token: <personal-access-token>

sshprivatekey: /path/to/private/key

coursesfilepath: /absolute/path/to/course-configs
courses:
  - mpd
  - vss

Keys

Key Purpose Required Default
gitlab.host Base URL of your GitLab instance Yes
gitlab.token Personal access token with API scope Yes
sshprivatekey Path to unencrypted SSH key for git operations No System default SSH key
coursesfilepath Directory containing course config files Yes
courses List of course file basenames to load Yes

Notes

  • sshprivatekey: Only needed if default SSH key doesn't work
  • coursesfilepath: Must be absolute path
  • courses: Filenames without extension (glabs adds .yaml/.yml/etc)

Course configuration

Create course files in coursesfilepath, for example mpd.yaml:

mpd:
  coursepath: mpd/semester          # GitLab subgroup path
  semesterpath: ob-26ss             # Optional semester identifier
  useCoursenameAsPrefix: false      # Add course name to project names
  useEmailDomainAsSuffix: true      # Add domainname to repo name

  students:
    - alice@example.org
    - bob.student@university.edu

  groups:
    team-a:
      - alice@example.org
      - charlie@example.org
    team-b:
      - bob.student@university.edu

  blatt01:
    assignmentpath: blatt-01
    description: Assignment 1
    per: student
    accesslevel: developer
    startercode: ...

  blatt02:
    # Overrides
    students:
      - alice@example.org

Course-level keys

Key Purpose Default Notes
coursepath GitLab subgroup path for course Required
semesterpath Additional grouping level Optional
useCoursenameAsPrefix Prepend course name to project names false Example: mpd-blatt01
useEmailDomainAsSuffix Use full email (with _at_...) as repo suffix true If false, only the part before @ is used (e.g. alice instead of alice_at_example.org).
students List of course-wide students Can be overridden per assignment
groups Dict of group → student lists For per: group assignments

Student/Group specification

Students and groups can be specified by:

  • Email: alice@example.org
  • Username: alice
  • User ID: 12345

You can mix formats. By default, if using emails, the @ is replaced with _at_ in project names (filesystem compatibility), e.g. mpd-blatt01-alice_at_example.org. If you set useEmailDomainAsSuffix: false, only the part before the @ is used, e.g. mpd-blatt01-alice.

Student/Group filtering

When running commands, you can filter:

# Filter by regex pattern
glabs generate mpd blatt01 'a.*'

# Multiple patterns
glabs generate mpd blatt01 alice bob

Patterns are regular expressions, so:

  • alice matches exactly "alice"
  • a.* matches "alice", "bob" (any name with 'a')
  • ^a matches names starting with 'a'

Assignment-level configuration

<course>:
  <assignment>:
    assignmentpath: blatt-01
    description: Assignment 1
    per: student
    accesslevel: developer
    containerRegistry: false
    mergeRequest:
      mergeMethod: merge        # merge | semi_linear | ff
      squashOption: default_off  # never | always | default_off | default_on

    startercode:
      ...
    seeder:
      ...
    clone:
      ...
    release:
      ...

Assignment-level keys

Key Purpose Default Notes
assignmentpath GitLab path segment for repos Required
per student or group student Determines repo naming and access
description GitLab project description generated by glabs Visible in UI
accesslevel Initial project access (see below) developer Can be changed later with setaccess
containerRegistry Enable container registry false Auto-enabled if release.dockerImages set
students Override/add assignment-specific students Merged with course-level
groups Override/add assignment-specific groups Merged with course-level

Access level values

Level Value Permissions
guest 10 View public projects, comment on issues
reporter 20 Create issues, cannot push code
developer 30 Push code, merge pull requests (default)
maintainer 40 Full admin access including settings

Example:

blatt01:
  accesslevel: reporter  # Students can only view and comment

Change after creation:

glabs setaccess mpd blatt01 -l maintainer

Startercode options

Clone from a starter repository to each student repo:

startercode:
  url: git@gitlab.example.org:mpd/startercode/blatt-01.git
  fromBranch: template       # Clone this branch
  toBranch: main             # Into this branch
  additionalBranches: []     # Push starter/<branch> to repo/<branch>

Startercode keys

Key Purpose Default Notes
url SSH URL of starter repo Required if startercode block exists
fromBranch Source branch in starter main Must exist in starter repo
toBranch Target branch in new repos main Usually production branch
additionalBranches Additional branches mirrored from starter repo [] Each x maps starter/x -> repo/x

Important behavior:

  • Only branches listed in startercode.additionalBranches are mirrored from starter with branch-specific content.
  • All other generated branches are created from the state of startercode.toBranch.
  • This means that branches from the branches: block that are not in additionalBranches start identical to toBranch.

Branch options

Define branch creation, protection and default branch independently from startercode:

branches:
  - name: main
    protect: true
    allowForcePush: false
    default: false

  - name: develop
    mergeOnly: true
    codeOwnerApprovalRequired: true
    default: true

Branch keys

Key Purpose Default Notes
name Branch name Required
protect Maintainer-only push/merge false Same semantics as classic protected branch
mergeOnly Developers may merge but cannot push false Sets push=No one, merge=Developers
default Set as project default branch false If none is set, first branch becomes default
allowForcePush Allow force-push on protected branch false Passed through to GitLab protected branch settings
codeOwnerApprovalRequired Require Code Owner approval false Passed through to GitLab protected branch settings

Branch protection notes

  • mergeOnly: true takes precedence over protect: true for that branch
  • Branches are created for generated projects based on this list
  • Branch creation base is startercode.toBranch (or seeder.toBranch when seeder is used)
  • If a branch name is also listed in startercode.additionalBranches, the mirrored starter branch content is used for that branch
  • glabs protect applies these branch rules to existing repositories

Issue replication options

Configure issue replication separately from startercode:

issues:
  replicateFromStartercode: true
  issueNumbers: [1, 3]

Issue keys

Key Purpose Default Notes
replicateFromStartercode Copy issues from starter project false Requires startercode
issueNumbers Which issue numbers to copy [1] Used only when replication is enabled

Example: Merge-only development branch

branches:
  - name: main
    protect: true
  - name: develop
    mergeOnly: true
    default: true

Result in GitLab UI:

  • Allowed to merge: Developers and Maintainers
  • Allowed to push and merge: No one

Seeder options

Execute custom code to seed repositories:

seeder:
  cmd: python
  args:
    - /path/to/generator.py
    - generate
    - "%s"
  name: Generator Bot
  email: generator@example.org
  toBranch: main
  protectToBranch: false
  signKey: <optional-gpg-key>

Seeder keys

Key Purpose Default Notes
cmd Command to run Required if seeder block exists
args Arguments to pass %s replaced with repo path
name Git author name For commits
email Git author email For commits
toBranch Branch to commit to main
protectToBranch Protect after seeding false
signKey GPG private key Optional; you'll be prompted for passphrase

Example: Python generator

seeder:
  cmd: python3
  args:
    - /home/instructor/generators/coursework.py
    - "%s"
  name: Course Generator
  email: generator@hm.edu

The script receives the repo path and can generate files, directories, build scripts, etc.

Clone options

Configuration for glabs clone:

clone:
  localpath: /tmp/work
  branch: main
  force: false

Clone keys

Key Purpose Default Notes
localpath Where to clone . Current directory
branch Checkout branch main
force Remove existing before clone false

Release options

Configure release workflow (merge requests, Docker builds):

release:
  mergeRequest:
    source: develop           # Branch with new features
    target: main              # Production branch
    pipeline: true            # Wait for CI to pass
  dockerImages:
    - myapp/service
    - myapp/frontend

Release keys

Key Purpose Default Notes
mergeRequest.source Feature branch develop Where students work
mergeRequest.target Production branch main Where code goes live
mergeRequest.pipeline Wait for CI false Require passing checks
dockerImages Images to build [] Creates container registry entries

Notes:

  • Container registry is auto-enabled when dockerImages is set
  • Enables GitLab Flow workflow for releases
  • Works with CI/CD pipeline to build/deploy

Merge Request options

Control how merge requests are merged in every generated project:

<assignment>:
  mergeRequest:
    mergeMethod: merge        # merge | semi_linear | ff
    squashOption: default_off  # never | always | default_off | default_on
    pipeline: false           # Require successful pipeline before merge
    skippedPipelinesAreSuccessful: false
    allThreadsMustBeResolved: false
    statusChecksMustSucceed: false
    approvals:
      settings:
        preventApprovalByMergeRequestCreator: true
        preventApprovalsByUsersWhoAddCommits: false
        preventEditingApprovalRulesInMergeRequests: false
        requireUserReauthenticationToApprove: false
        whenCommitAdded: removeAllApprovals
      rules:
        - name: review-main
          branch: main
          usernames: [myusername]
          groups: []
          requiredApprovals: 1
        - name: review-release
          branches: [release, stable]
          usernames: [release-owner]
          groups: [mpd/tutors]
          requiredApprovals: 2

Merge Request keys

Key Purpose Default Notes
mergeRequest.mergeMethod Merge strategy for all MRs merge Applied at project creation
mergeRequest.squashOption Squash-on-merge setting default_off Applied at project creation
mergeRequest.pipeline Pipelines must succeed false Maps to GitLab merge check
mergeRequest.skippedPipelinesAreSuccessful Treat skipped pipelines as successful false Only relevant when mergeRequest.pipeline=true
mergeRequest.allThreadsMustBeResolved All threads must be resolved false Maps to GitLab merge check
mergeRequest.statusChecksMustSucceed Status checks must succeed false Maps to GitLab merge check
mergeRequest.approvals Approval configuration block {} Contains settings and rules
mergeRequest.approvals.settings Project-level approval settings {} Maps to GitLab approval settings API
mergeRequest.approvals.settings.preventApprovalByMergeRequestCreator Prevent approval by MR creator unset Inverted and mapped to GitLab merge_requests_author_approval
mergeRequest.approvals.settings.preventApprovalsByUsersWhoAddCommits Prevent approval by committers unset Maps to GitLab merge_requests_disable_committers_approval
mergeRequest.approvals.settings.preventEditingApprovalRulesInMergeRequests Prevent editing rules in MRs unset Maps to GitLab disable_overriding_approvers_per_merge_request
mergeRequest.approvals.settings.requireUserReauthenticationToApprove Require user re-authentication to approve unset Maps to GitLab require_reauthentication_to_approve
mergeRequest.approvals.settings.whenCommitAdded Approval reset mode on push unset keepApprovals | removeAllApprovals | removeCodeOwnerApprovalsIfTheirFilesChanged
mergeRequest.approvals.rules Project approval rules (per protected branch) [] Applied by generate and protect
mergeRequest.approvals.rules[].name Rule name in GitLab auto (glabs-approval-<branch>) For multiple branches in one rule, branch name is appended
mergeRequest.approvals.rules[].branch Single target branch Convenience alias for one branch
mergeRequest.approvals.rules[].branches Target branches [] Each branch becomes one project approval rule
mergeRequest.approvals.rules[].usernames Approvers (GitLab usernames) [] @ prefix is allowed and removed automatically
mergeRequest.approvals.rules[].groups Approver groups (full path or numeric ID) [] Example full path: mpd/tutors
mergeRequest.approvals.rules[].multiMemberGroupsOnly Only apply rule for groups with more than one member false Skipped for per: student and one-person groups
mergeRequest.approvals.rules[].requiredApprovals Required number of approvals 0 0 + empty usernames/groups removes an existing rule

Note: Email addresses and numeric user IDs are not accepted in mergeRequest.approvals.rules[].usernames and result in an explicit error. Use usernames only.

Note: Approval rules for branches that are not protected in the target project are skipped with a warning; other valid approval rules are still applied.

Requirements for approval rules:

  • Each target branch must exist in the repository.
  • Each target branch must be protected (configured with protect: true or mergeOnly: true).
  • Configured approvers must have project/group access in GitLab so they are eligible approvers.
  • Rules with multiMemberGroupsOnly: true are only applied for per: group projects with more than one member.

Merge method values

Value GitLab UI name Description
merge Merge commit Always create a merge commit (GitLab default)
semi_linear Merge commit with semi-linear history Require a linear history; fast-forward commits are rebased before merge
ff Fast-forward merge No merge commits; only fast-forward merges allowed

Squash option values

Value GitLab UI name Description
never Do not allow Squashing is disabled; the checkbox is hidden
always Require Every MR is squashed automatically; the checkbox is hidden
default_off Allow Squash checkbox visible but unchecked by default (GitLab default)
default_on Encourage Squash checkbox visible and checked by default

Warning: Although the GitLab UI sometimes displays squash settings in the context of individual branch rules, squash options are always project-wide. Changing the squash setting in any branch rule or merge request rule will affect all branches in the project. There is currently no way to configure squash behavior per branch. This is a known limitation of GitLab, even if the UI suggests otherwise.

Example:

blatt01:
  mergeRequest:
    mergeMethod: ff          # Students must keep a linear history
    squashOption: always     # All commits squashed into one on merge
    pipeline: true           # Block merge until latest pipeline succeeds
    skippedPipelinesAreSuccessful: false
    allThreadsMustBeResolved: true
    statusChecksMustSucceed: true
    approvals:
      settings:
        preventApprovalByMergeRequestCreator: true
        preventApprovalsByUsersWhoAddCommits: false
        preventEditingApprovalRulesInMergeRequests: false
        requireUserReauthenticationToApprove: false
        whenCommitAdded: removeAllApprovals
      rules:
        - name: review-main
          branch: main
          usernames:
            - instructor
          requiredApprovals: 1
        - name: review-release
          branches: [release]
          usernames:
            - release-owner
          groups:
            - mpd/tutors
          multiMemberGroupsOnly: true
          requiredApprovals: 2
        - name: no-review-next
          branch: next
          usernames: []
          groups: []
          requiredApprovals: 0

Full example

# ~/.glabs.yaml
gitlab:
  host: https://gitlab.lrz.de
  token: glpat-XXXXXXXXXXXXX

coursesfilepath: ~/courses
courses:
  - mpd
  - vss
# ~/courses/mpd.yaml
mpd:
  coursepath: teaching/2024ss/mpd
  semesterpath: semester-1
  useCoursenameAsPrefix: false

  students:
    - alice.mueller@hm.edu
    - bob.schmidt@hm.edu

  groups:
    team-1:
      - alice.mueller@hm.edu
      - charlie.weber@hm.edu

  blatt01:
    assignmentpath: blatt-01
    per: student
    accesslevel: developer
    description: Assignment 1 - Data Structures

    startercode:
      url: git@gitlab.lrz.de:teaching/2024ss/mpd/starter-blatt01.git
      fromBranch: template
      toBranch: main

    branches:
      - name: main
        protect: true
      - name: develop
        mergeOnly: true
        default: true

    issues:
      replicateFromStartercode: true
      issueNumbers: [1]

  blatt02:
    assignmentpath: blatt-02
    per: group
    startercode:
      url: git@gitlab.lrz.de:teaching/2024ss/mpd/starter-blatt02.git