Gitlab 11.6.0 just released, and one of the new features is deleting a pipeline. Why might you want to delete a little bit of history? Well, perhaps you have inadvertently caused some private information to be printed (a password). Or perhaps you left Auto DevOps enabled and ended up with a whole slew of useless failures. Either way you want to go and delete the pipeline in question and all of its output, artifacts, etc. Well here’s a quick ‘hack’ to achieve the goal.

You run it as ‘python -t token -u url -g group -p project’ and it will list all the pipeline id’s. You can then run it with “-d ‘*'” to delete all of them, or “-d #,#,#…” to delete specific ones. You’ll likely want ‘pip install python-gitlab’ first.

Its a quick and dirty hack, but it worked for me. YMMV.

#!/usr/bin/env python3
import gitlab
import argparse
import os
import requests
import sys

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--url', help='API url', default=url)
parser.add_argument('-t', '--token', help='personal token', default=private_token)
parser.add_argument('-g', '--group', help='group', default=None, required=True)
parser.add_argument('-p', '--project', help='project', default=None, required=True)
parser.add_argument('-d', '--delete', help='delete id(s)', default=None)

args = parser.parse_args()

if args.delete:
    args.delete = args.delete.split(',')

gl = gitlab.Gitlab(args.url, args.token)

def find_group(gl, group):
    groups = gl.groups.list()
    for g in groups:
        if == group:
            return g
    return None

def find_subgroup(gl, group, subgroup):
    subgroups = group.subgroups.list()
    for sg in subgroups:
        if == subgroup:
            return sg;
    return None

# if project is of form x/y, then assume x is a subgroup
def find_project(gl, group, project_with_subgroup):
    pws = project_with_subgroup.split('/')
    if len(pws) == 2:
        subgroup = find_subgroup(gl, group, pws[0])
        project = pws[1]
        group = gl.groups.get(, lazy=True)
        project = pws[0]
    projects = group.projects.list()
    for p in projects:
        if == project:
            return p
    return None

group = find_group(gl,
gproject = find_project(gl, group, args.project)
if not gproject:
    print("Error: %s / %s does not exist" % (, args.project))

project = gl.projects.get(
pipelines = project.pipelines.list()
for pid in pipelines:
    pl = project.pipelines.get(
    if args.delete and (str( in args.delete or args.delete == ['*']):
        path = "%s/api/v4/projects/%s/pipelines/%s" % (args.url,,
        r = requests.delete(path, headers={'PRIVATE-TOKEN': args.token})
        print("%s %s %s -- DELETE" % (,, pl.status))
        print("%s %s %s" % (,, pl.status))