members.json

Reference for the members file used during distribution.

members.json defines which UUIDs are distributed and which users receive access to each repository.

The file location is configured via config.json -> members.path.

The canonical member value is the GitLab username. Optional display-name metadata can preserve course-internal or local names without changing the username used for GitLab operations. Each entry in groups represents one distributed repository group.

Format

{
  "version": "2.0",
  "displayNames": {
    "myname_extern": "myname"
  },
  "groups": [
    {
      "uuid": "team-01",
      "label": "Team 01",
      "metadata": {
        "fruit": "banana"
      },
      "members": ["alice", "myname_extern"]
    },
    {
      "uuid": "team-02",
      "label": "Team 02",
      "members": ["charlie"],
      "unassignedMembers": ["dana"]
    }
  ]
}

Keys

KeyTypeNotes
versionstringCurrent format version. Use "2.0".
displayNamesobjectOptional map from GitLab username to local display name.
groupsarrayOne entry per distributed repository.
groups[].uuidstringStable identifier used in naming and state files.
groups[].membersarray of stringsGitLab usernames that should receive access to that repository.
groups[].unassignedMembersarray of stringsOptional members that were known locally but could not be assigned.
groups[].labelstringOptional human-readable group label. Used by repository name templates such as {{label}} and {{slug}}.
groups[].metadataobjectOptional group-level string metadata. Used by repository name templates such as {{metadata "fruit"}} or {{.Metadata.fruit}}.

Import Input

Interactive input, text files, and stdin use one repository group per non-empty row. A row with one value creates a one-person group:

tom
ada
john
ben

A row with comma-separated values creates one group with several members:

alice,bob
john,ada

CSV, TSV, and Excel files may use a header row. Headers named username, member, members, user, login, or provider_username are treated as GitLab username columns. Numbered forms such as member1, member2, username1, or username2 allow several members in one row. A metadata-only first row such as fruits is not enough to trigger header mode; include at least one recognized member column such as username, member, or email.

email is a fallback member column only when no username/member column exists. If a table contains both email and username, Divekit uses username as the GitLab username and imports email as metadata.

Any non-empty column that is not selected as a member, UUID, or label column is stored under groups[].metadata using a normalized lowercase key. For example, header Favorite Fruit becomes favorite_fruit. A header such as fruits becomes groups[].metadata.fruits.

Columns named label, group, group_label, repository, repository_label, repo, repo_label, or title are stored as groups[].label instead of metadata. Rows with the same uuid or the same label are merged into one group.

Behavior

  • One groups[] entry results in one logical repository pair per UUID.
  • If the evaluation pipeline is enabled, the same UUID is used across work and eval.
  • groups[].label and groups[].metadata are optional naming and display fields. They do not replace uuid; remotes, individuals, and linked targets still join on uuid.
  • members.permissions from config.json defines the default permission level for all listed members.
  • GitLab operations use groups[].members; displayNames only affects local display output.
  • Repository name templates can use group labels and metadata through {{label}}, {{slug}}, {{metadata "key"}}, and {{.Metadata.key}}.
  • divekit members list, divekit overview, and the GUI show aliased members as display name (@gitlab-username).
  • divekit members alias set replaces a local member name with the GitLab username in the configured members file and records the display name in displayNames.
  • divekit members alias unset removes only the display-name metadata. It leaves groups[].members unchanged.
  • divekit members add, members filter, and members exclude create replacement files instead of editing the existing file in place. They keep UUIDs for remaining groups, drop groups whose member list becomes empty, and ask for confirmation before applying the plan.
  • If work-target remotes already exist, removing members also revokes matching GitLab project memberships. It does not delete already created repositories.
  • divekit distribute also reconciles configured member changes on existing work projects when changes are applied through its interactive configured-members edit flow: current members are assigned, and previously configured members that moved away from a UUID are removed from that UUID’s work project.
  • Manual edits to members.json do not give Divekit the previous member set needed for removal planning. Use the interactive distribute edit flow, divekit members exclude, or divekit members filter when remote memberships should be revoked automatically.

Path Resolution

Divekit resolves members.path in this order:

  1. Absolute path: used directly.
  2. ./ or ../: resolved relative to the current working directory.
  3. $DIVEKIT_MEMBERS/...: resolved under the configured members base directory.
  4. Any other relative path: resolved under the members base directory.

If DIVEKIT_MEMBERS is not set, the default base directory is ~/.divekit/members.

Related pages: