Tutorials

How to Sync AI Rules in GitLab CI

Automate AI rule distribution across GitLab repositories using GitLab CI/CD pipelines. A pipeline configuration that syncs rules, creates merge requests, and tracks adoption across your GitLab groups.

6 min readยทJuly 5, 2025

GitLab CI + group-level variables: one token configuration syncs AI rules to every project in the group automatically.

Pipeline configuration, automated MR creation, group features, compliance frameworks, and GitLab Pages dashboard

GitLab Sync Architecture

GitLab's model differs from GitHub: repositories are organized into Groups and Subgroups. The sync architecture leverages this: the central rules repo lives in a dedicated group (e.g., gitlab.com/org/platform/ai-rules). Target repos are in their respective team groups. The CI pipeline: triggered by changes in the central repo, iterates over target repos listed in a manifest, and creates merge requests in each target repo with the updated rules.

GitLab-specific advantages: group-level CI/CD variables (store the access token once at the group level, all projects inherit it), GitLab API for merge request creation (native API, no external tools needed), and multi-project pipelines (trigger pipelines in downstream projects). These features: make the GitLab sync workflow slightly simpler than the GitHub equivalent.

The pipeline: defined in .gitlab-ci.yml in the central rules repo. Stages: generate (compose rules per target repo), compare (check if the target's rules differ from the generated version), and sync (create or update merge requests for repos with differences). The pipeline runs: on push to the default branch and on a weekly schedule for drift detection.

Step 1: Pipeline Configuration

The .gitlab-ci.yml: defines the sync job. Image: a lightweight image with git and curl (for GitLab API calls). Variables: RULES_TOKEN (a project access token or group access token with API and write_repository scope). Script: reads manifest.yml (list of target projects with their rule composition), generates the composed rules for each target, clones each target repo, compares the generated rules against the existing rules, and calls the GitLab API to create a merge request if they differ.

Manifest format (manifest.yml): a YAML file mapping each target project to its rule layers. Example: projects: - path: org/team-a/frontend, rules: [base.md, typescript.md, react.md]. - path: org/team-b/api-service, rules: [base.md, go.md]. - path: org/team-c/ml-pipeline, rules: [base.md, python.md]. The pipeline reads this manifest and generates the correct composed rules for each project.

Merge request creation: using the GitLab API (POST /api/v4/projects/:id/merge_requests). The MR: source branch (rules-update-v2.4.0), target branch (main or the project's default branch), title ('Update AI rules to v2.4.0'), description (changelog of what changed). If an MR already exists for this source branch: update it instead of creating a duplicate. AI rule: 'GitLab's API handles MR creation natively. No need for external tools like gh CLI. The pipeline script: curl calls to the GitLab API with the access token.'

๐Ÿ’ก Group-Level Variables = One Token for All Projects

GitHub Actions: you configure the sync token in each target repo's secrets (or use an organization secret). GitLab: store the token as a group-level CI/CD variable once. Every project in the group: inherits it. Add a new project to the group: it gets the token automatically. Rotate the token: update once at the group level, all projects use the new token. This is one of GitLab's genuine advantages for multi-repo management.

Step 2: Leveraging GitLab Group Features

Group-level variables: store the RULES_TOKEN as a group-level CI/CD variable. All projects in the group inherit it. No need to configure the token in each project individually. This simplifies: onboarding new repos (they inherit the token automatically) and token rotation (update once at the group level, all projects get the new token). AI rule: 'Group-level variables are the GitLab advantage for rule sync. One configuration point: serves all projects in the group.'

GitLab compliance frameworks: GitLab Premium/Ultimate supports compliance frameworks that can enforce pipeline configurations across projects. You can: require that all projects run the rule compliance check, enforce that the CLAUDE.md file exists and is not empty, and report compliance status to the group dashboard. AI rule: 'For GitLab Premium/Ultimate users: compliance frameworks add automated enforcement beyond the sync workflow. Projects that remove or empty their CLAUDE.md: flagged automatically.'

GitLab Pages for adoption dashboard: host an adoption dashboard as a GitLab Pages site in the central rules repo. The sync pipeline: generates an HTML report showing which projects have current rules, which have pending MRs, and which are outdated. The report: accessible at the GitLab Pages URL, updated on every sync run. AI rule: 'GitLab Pages for the adoption dashboard: no separate hosting needed. The dashboard lives alongside the rules in the central repo.'

โš ๏ธ Test the Token Before Configuring the Pipeline

A misconfigured token: causes every sync run to fail silently. The pipeline runs, attempts to push a branch, gets a 403, and logs an error that nobody reads. For weeks: rules are not syncing. Fix: before configuring the pipeline, test the token manually: curl --header 'PRIVATE-TOKEN: <token>' 'https://gitlab.com/api/v4/projects/<id>/repository/branches'. If it returns data: the token works. If 403: the token lacks permissions.

Step 3: Troubleshooting and Best Practices

Common issue 1 โ€” Token permissions: the access token needs API scope (for MR creation) and write_repository scope (for pushing branches). Without write_repository: the pipeline cannot push the rules-update branch to the target repo. Without API: the pipeline cannot create the MR. AI rule: 'Test the token manually (curl the GitLab API with the token) before configuring the pipeline. A token issue: causes every sync run to fail silently.'

Common issue 2 โ€” Protected branches: if the target repo's default branch is protected (requires approval): the MR is created but cannot be auto-merged. This is expected behavior โ€” the team must review and merge. For unprotected branches (development environments): auto-merge can be enabled in the MR creation API call. AI rule: 'Protected branches: the MR waits for team review. This is the desired behavior for production repos. Auto-merge: only for non-production repos where speed is prioritized over review.'

Best practice โ€” Schedule + trigger: run the sync on both: push to the central rules repo (immediate propagation of rule changes) and a weekly schedule (drift detection for repos where someone manually edited the rules file). The dual trigger: ensures rules are propagated quickly AND drift is caught within one week. AI rule: 'Push trigger: for immediate propagation. Schedule trigger: for drift detection. Both are needed. Push alone misses drift. Schedule alone delays propagation.'

โ„น๏ธ Push + Schedule = Immediate Propagation + Drift Detection

Push trigger alone: rules propagate immediately when changed. But: someone manually edits CLAUDE.md in a target repo. The push trigger: does not detect this (no push to the central repo). Schedule trigger alone: drift is detected weekly. But: a rule change takes up to 7 days to propagate. Both triggers together: rule changes propagate immediately (push) AND drift is detected within one week (schedule). Each trigger: covers the other's blind spot.

GitLab CI Sync Summary

Complete GitLab CI rule sync setup.

  • Architecture: central rules repo โ†’ GitLab CI pipeline โ†’ MRs to target repos
  • Pipeline: .gitlab-ci.yml with generate โ†’ compare โ†’ sync stages
  • Manifest: manifest.yml mapping projects to rule layers (base + language-specific)
  • Auth: project or group access token with API + write_repository scope
  • MR creation: GitLab API (curl). One active MR per target. Update existing if present
  • Group features: group-level variables (one token config), compliance frameworks (enforcement)
  • Dashboard: GitLab Pages site showing adoption status. Updated on every sync run
  • Triggers: push to central repo (immediate) + weekly schedule (drift detection)