Skip to content

Roles & Review Workflow

Cratly is designed so that editors propose changes and chief editors publish them. The editor has no backend of its own, so it does not manage users or roles itself — it derives them entirely from the connected GitLab repository. Setting up the roles is therefore a matter of configuring GitLab correctly.

The two roles

RoleCan doCannot do
EditorCreate branches, save changes, open merge requestsPublish (merge into the published branch) — their changes need approval
Chief editorEverything an editor can, plus publish their own and others' merge requests

"Publishing" is simply merging a merge request into the published branch (usually main), which is what triggers your CI to rebuild and deploy the site. There is no separate approval step to configure: whoever is allowed to merge into the published branch is a chief editor.

GitLab setup

The roles map directly onto GitLab's member roles and a protected branch:

Cratly roleGitLab member role
EditorDeveloper
Chief editorMaintainer

Then protect the published branch so that editors can propose but not publish:

  1. Go to Settings → Repository → Protected branches

  2. Protect your published branch (e.g. main):

    SettingValue
    Allowed to push and mergeNo one
    Allowed to mergeMaintainers
    Allowed to pushNo one
  3. Make sure the published branch is also the project's default branch (Settings → Repository → Branch defaults).

With this in place:

  • Editors (Developers) can create branches and open merge requests, but the merge button is unavailable to them — their work waits for a chief editor.
  • Chief editors (Maintainers) see open merge requests, review them, and merge — the merge is the act of publishing.

Publishing from the editor

Chief editors do not need to leave the editor to publish. When a merge request is active, the editor shows a Publish button in the branch/merge-request dialog. It appears only for chief editors and becomes available once the merge request's CI pipeline (if any) has finished successfully.

Publishing opens a review & publish dialog first: it groups the changed files into Pages and Media, and lets you expand each one to see exactly what changed (line-by-line), with a Preview button for the built site and a link to open the full details in GitLab. Only when you confirm does the editor merge the changes into the published branch and return you to the public version. Editors do not see the Publish button; their changes wait for a chief editor.

Non-content changes

Changes to files that are neither pages nor media — theme implementations, build configuration, lock files — are not shown as editorial diffs by default. Such changes usually mean the draft is not up to date with the published version rather than carrying content to review. Instead of listing them, the dialog shows a warning with the number of affected files.

You can tune this behaviour in .cratly.config.yaml under publish.other_files:

  • show: true — let reviewers expand and inspect those diffs anyway.
  • block: true — prevent publishing entirely while non-content files differ.
  • warning: "…" — replace the default hint with your own text, e.g. pointing editors to a technical contact. May be a single string or a map of locale → string (with * as fallback) to localize the hint.

When publishing isn't possible

If the draft conflicts with the current published version, GitLab reports the merge request as not mergeable. The editor detects this before publishing, shows a blocking notice, and asks you to update the draft from the published version first (see below). Updating tries a clean rebase and only falls back to the manual conflict resolution when it must.

For cases an editor can't resolve alone, configure a technical support contact in .cratly.config.yaml under support.contact (a string, or a locale → string map with * fallback). It is shown on update failures, in the conflict-resolution dialog, and on the publish-conflict notice.

A small badge in the header always shows your current role (Editor or Chief editor) for the connected repository, so it is clear at a glance whether you can publish yourself or need approval.

Why "merge" and not "approve"?

GitLab's enforced approval rules (a required, separate approve step; minimum approvers; "author may not approve their own request") are a Premium/Ultimate feature. On GitLab Community Edition / Free they are not available. Because Cratly's publish point is always "the change lands in the published branch", the merge itself is the approval — so the workflow above needs no paid features. In CE the Approve button still exists as an optional, non-binding marker, and chief editors may use it to record who signed off.

How the editor detects your role

Because everything is derived on the fly, the editor works out your role from what GitLab exposes:

  1. Heuristic, on connect. From your member access level plus the published branch's merge rule — no elevated permissions required. Maintainer and above → chief editor; a Developer only counts as a chief editor if branch protection explicitly lets developers merge.
  2. Ground truth, when a merge request is open. The editor asks GitLab whether you may merge this merge request and adjusts the UI accordingly. This correctly accounts for protection rules that grant merge rights to specific users or groups.
  3. Fail-safe. If anything is unclear, the editor treats you as an editor (approval required) rather than offering a publish action that would fail at merge time.

Setup check in the editor

The branch/merge-request dialog has an expandable Check repository setup section that verifies the workflow is configured correctly. The check has two tiers, matching what GitLab lets each role read:

  • Basic (any member): Is the published branch protected? Are editors correctly prevented from pushing and merging directly? This is the security-relevant half and is visible to everyone.
  • Extended (chief editors only): The exact list of who may push and merge. Reading this requires the Maintainer role; for editors it is reported as not checked — that is expected, not an error.

If the published branch is not protected, the editor warns you: in that case the whole review workflow can be bypassed, and every editor could publish unreviewed.

Each finding is explained — with the steps to resolve it — in Repository Check.

Permissions required

All of the above works with the same api OAuth scope described in Connecting a Repository. No additional scope is needed — role detection and the setup check read branch, protection, and merge-request permission information through that scope.