Skip to content

feat(gitlab): default pipeline schedule on the least used slot - #67

Merged
beliven-alex-zongaro merged 8 commits into
mainfrom
feat/gitlab-default-pipeline-schedule
Oct 6, 2026
Merged

beliven-alex-zongaro merged 8 commits into
mainfrom
feat/gitlab-default-pipeline-schedule

Conversation

@beliven-alex-zongaro

@beliven-alex-zongaro beliven-alex-zongaro commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

New projects had no pipeline schedule, so whoever wanted a periodic run (e.g. to rebuild the Docker images with the latest patches) created it by hand, usually at the same time as everyone else. This adds an opt-in default schedule whose time is chosen by the tool, so the pipelines are spread.

The schedule (defaults in code, no configuration)

  • weekly, on a working day, between 09:00 and 18:00 (Europe/Rome), 15 minutes slots
  • runs on main when the project has it, otherwise on the default branch
  • description opsi default schedule
  • the slot is the least used one, counting the active schedules of every project (also the ones in another time zone, and the ones created in the same run). Among equal slots the choice depends on the project, so it is stable

Commands

  • opsi gitlab project create <name> ... -c (--schedule): creates the schedule at the end of the creation. Without the flag nothing changes.
  • opsi gitlab schedule create {project_id}...: creates the schedule on existing projects. A project that already has an active schedule is skipped; a failing project does not stop the others.
  • opsi gitlab schedule update [project_id]...: fixes the active schedules that lost their owner (the owner does not exist anymore, is blocked or is deactivated). A schedule runs as its owner, so it stops silently when the owner goes away. Those schedules are given to the user of the token with take_ownership. The schedules of an active user are left alone, and cron, branch and description are not touched. It never creates or activates anything. Without projects it checks all of them (5 at a time, progress on one line); projects whose schedules cannot be read (pipelines disabled) are skipped. --dry-run only shows the schedules with their description and owner, and asks no confirmation.

The projects are referred to by numeric ID, like the other commands.

Also fixes the hint of mirror create, which still suggested the removed update mirroring command.

Notes

  • A schedule is owned by the user of the token that creates it. Today the existing schedules belong to cicd; the ones created with a personal token will belong to that user. Giving them to cicd would need a token with the sudo scope (Sudo header) or the cicd token: not part of this PR.

Test plan

  • go vet ./... and go test ./... (slot choice and spreading, existing cron parsing and time zone conversion, create with an existing schedule / without main / failing project, update dry run, orphan owner, inactive schedules, projects without pipelines)
  • opsi gitlab schedule update --dry-run on git.beliven.dev (241 projects): the 3 active schedules, all owned by cicd, are left alone
  • opsi gitlab schedule create <id> on a test repo, twice (second run skips), and check it in Build > Pipeline schedules
  • opsi gitlab project create ... -c on a test group

🤖 Generated with Claude Code

beliven-alex-zongaro and others added 8 commits October 6, 2026 14:44
The message shown when a project already has a mirror still suggested the
old `opsi gitlab update mirroring` command, removed by the command reorder.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add `opsi gitlab schedule create <project>...`, which creates a weekly
pipeline schedule on one or more existing projects (ID or path).

The slot is not chosen by hand: it is the least used one among the working
days between 09:00 and 18:00 (Europe/Rome, 15 minutes slots), counting the
active schedules of every project, the ones in another time zone included,
and the ones created in the same run. So the pipelines are spread instead
of starting together. The schedule runs on `main` when the project has it,
otherwise on the default branch. A project that already has an active
schedule is left alone, and a failing project does not stop the others.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
`opsi gitlab project create <name> -c` creates the default weekly pipeline
schedule at the end of the creation, on the least used slot. Without the
flag nothing changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add `opsi gitlab schedule update <project>...`, which gives to the user of
the token the pipeline schedules of one or more projects that belong to
someone else, or to nobody. A schedule runs as its owner, so it stops when
the owner is blocked, deactivated or removed; taking the ownership works in
every case. Cron, branch and description are not touched.

--dry-run only shows the schedules with their owner, and asks no
confirmation. Without it the command asks for a confirmation, unless -f.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
`schedule update` took every schedule owned by someone else, so launching it
with a personal token would have stolen the schedules of a service user.
Take only the schedules whose owner is missing, blocked or deactivated, the
ones that stopped running; the schedules of an active user are left alone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
`opsi gitlab schedule update` without projects checks all of them, 5 at a
time, with the progress on a single line. It only looks at the active
schedules: it never creates or activates one, so the projects without an
active schedule are ignored. A project whose schedules cannot be read
(pipelines disabled) is skipped without failing the command, unless it was
named explicitly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A project can have more schedules with the same cron, so the lines looked
like duplicates. Show the description of each schedule next to the project.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The other commands take the numeric ID of the project (and of the group),
so the schedule commands do the same instead of also accepting the path.
Support for the path can be added to every command later.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@beliven-alex-zongaro
beliven-alex-zongaro merged commit 700ec5a into main Oct 6, 2026
1 check passed
@beliven-alex-zongaro
beliven-alex-zongaro deleted the feat/gitlab-default-pipeline-schedule branch October 7, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant