Skip to main content

Getting the repository onto GitLab and running the first CI

This guide walks through publishing edox-ops to GitLab and triggering the first pipeline. It assumes the pipeline is already defined in .gitlab-ci.yml.

For what each CI job does, Docker-in-Docker, and runner troubleshooting, see gitlab-ci.md.

What you need before you start

ItemNotes
GitLab accountGitLab.com or your organization’s self-managed instance
Empty or new GitLab projectYou will push this repository into it
Git on your workstationSame repo you develop in (e.g. esysdox-ops on Windows)
Authentication to GitLabSSH key in GitLab Preferences → SSH Keys, or HTTPS with a personal access token. Multiple keys: gitlab-ssh-keys.md

Cursor / IDE GitLab integration (if configured) helps with merge requests and browsing the project in the editor. Pushing code still uses normal git remotes and your SSH or HTTPS credentials unless you have separately configured them.

No extra CI/CD variables or secrets are required for the current pipeline.

Canonical SSH remote for this repo: git@gitlab-ai:libesys/esysdox-ops.git (remote name gitlab). See gitlab-ssh-keys.md.

1. Create the GitLab project

  1. Sign in to GitLab.
  2. Select New projectCreate blank project (or Import project if you use another host).
  3. Choose a project name (e.g. esysdox-ops) and namespace (group or user).
  4. Set visibility (private/internal/public) per your policy.
  5. Optional: disable “Initialize repository with a README” if you will push an existing local repository (avoids unrelated first commit on GitLab).
  6. Create the project and copy its clone URL:
    • SSH: git@gitlab.com:your-group/esysdox-ops.git
    • HTTPS: https://gitlab.com/your-group/esysdox-ops.git

Note the project’s default branch name under Settings → Repository (main or master). Your local default branch should match what you intend to push, or you should change the GitLab default branch after the first push.

2. Connect the local repository to GitLab

In your local clone (project root):

git remote -v

If no remote points at GitLab, add the project remote (uses the gitlab-ai SSH alias; see gitlab-ssh-keys.md):

git remote add gitlab git@gitlab-ai:libesys/esysdox-ops.git

HTTPS example:

git remote add gitlab https://gitlab.com/your-group/esysdox-ops.git

Confirm the branch you will push and that the working tree is clean:

git status
git log -3 --oneline

Ensure .gitlab-ci.yml is committed on that branch (it is part of this repository).

3. Push the code

First push (sets upstream tracking):

git push -u gitlab master

Use main instead of master if that is your local and GitLab default branch:

git push -u gitlab main

If GitLab rejected the push because the remote already has commits (e.g. README from project creation), either pull and merge once, or—only if you are sure—force-push an empty initial remote; prefer merging when unsure.

After a successful push, the project Repository view on GitLab should show your files, including .gitlab-ci.yml.

4. Enable CI and runners (GitLab UI)

The pipeline file alone is not enough: a GitLab Runner must execute jobs.

  1. Open the project → SettingsCI/CD.
  2. Expand Runners.
  3. Ensure shared runners are enabled for the project (common default on GitLab.com).
  4. Confirm CI/CD is not disabled under project settings.

Shared runners are the fastest way to try the first pipeline; see gitlab-ci.md if the integration job fails and you need a self-hosted runner with privileged = true.

Self-managed GitLab

  1. Register a GitLab Runner for the project or group.
  2. Use the docker executor for compatibility with .gitlab-ci.yml.
  3. For the integration job, the runner may need privileged = true in config.toml — details in gitlab-ci.md.

No CI/CD variables need to be added for lint, unit, or integration jobs today.

5. Trigger the first pipeline

Pipelines start automatically when the rules in .gitlab-ci.yml match:

EventRuns pipeline?
Push to default branch (master / main)Yes
Merge request opened or updatedYes
Tag pushedYes
Push to other branches without an MRNo (unless you change workflow: rules)

So the first pipeline usually appears right after the initial git push to the default branch, or when you open a merge request.

6. Watch the first pipeline

  1. In the project, go to BuildPipelines.
  2. Open the newest pipeline (status: running, passed, or failed).
  3. Open each job to read logs:
JobStageWhat success looks like
rufflintRuff check and format check exit 0
unittestPytest finishes; coverage % on pipeline and Cobertura on MRs
integrationintegrationrun_docker.sh completes; log ends with integration success

Jobs run in order: ruff and unit first, then integration.

If ruff or unit fails, fix the reported issues locally (same commands as in the README) and push again.

If only integration fails, read the job log for Docker, DinD, or privileged errors, then follow gitlab-ci.md.

7. Run the same checks locally (optional)

Before or after the first CI run:

pip install -e ".[dev]"
ruff check src tests scripts/pre_commit scripts/gitlint_rules.py
ruff format --check src tests scripts/pre_commit scripts/gitlint_rules.py
python -m pytest -q --cov=edox_ops

Integration (Linux):

bash tests/integration/run_docker.sh

Windows:

.\test.ps1

8. Optional next steps (not required for first CI)

StepWherePurpose
Require passing pipeline before mergeSettings → Merge requestsBlock merges when CI fails
Protect default branchSettings → Repository → Protected branchesEnforce MR workflow
Add runner tags.gitlab-ci.yml + runner registrationPin integration to a capable runner
Mirror to GitHubGitHub repo settingsUse .github/workflows/ci.yml in parallel

Quick checklist

  • GitLab project created; clone URL copied
  • git remote add gitlab … (or origin → GitLab)
  • git push -u gitlab <default-branch>
  • Shared or project runners available
  • Build → Pipelines shows a pipeline with ruff, unit, integration
  • All three jobs green (or integration investigated using gitlab-ci.md)