diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 02c814ad82..5020dea23f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,8 @@ +variables: + pip: pip3 --timeout 100 --retries 10 + + lint: image: registry.gitlab.com/fdroid/ci-images-base except: @@ -76,6 +80,27 @@ trigger-issuebot: - apk add --no-cache bash curl - ./tools/trigger-issuebot +schedule-issuebot: + image: alpine + only: + variables: + - $SCHEDULE_ISSUEBOT + variables: + GIT_DEPTH: "1" + artifacts: + name: "${CI_PROJECT_PATH}_${CI_JOB_STAGE}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}" + paths: + - logs/ + when: always + expire_in: 1 week + script: + - mkdir logs + - export | grep -F CI_ | grep -vFi -e password -e token > logs/export.txt + - apk add --no-cache bash curl ca-certificates python3 + - python3 -m ensurepip + - $pip install gitlab + - ./tools/schedule-issuebot.py + checkupdates_trigger: only: refs: diff --git a/tools/schedule-issuebot.py b/tools/schedule-issuebot.py new file mode 100755 index 0000000000..7f8b1d12f1 --- /dev/null +++ b/tools/schedule-issuebot.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +import gitlab +import json +import os +import pprint +import re +import subprocess + +os.chdir(os.path.join(os.path.dirname(__file__), '..')) + +private_token = os.getenv('PERSONAL_ACCESS_TOKEN') +gl = gitlab.Gitlab('https://gitlab.com', api_version=4, private_token=private_token) +project = gl.projects.get(os.getenv('CI_PROJECT_PATH'), lazy=True) + +TRIGGER_COMMIT_PAT = re.compile(r'([0-9a-f]{40})') + +for mr in project.mergerequests.list(state='opened', order_by='updated_at'): + commit_ids = [] + found_issuebot_post = False + for discussion in mr.discussions.list(): + for note in discussion.attributes['notes']: + if note['author']['username'] == 'fdroid-bot': + found_issuebot_post = True + m = TRIGGER_COMMIT_PAT.search(note.get('body', '')) + if m: + commit_ids.append(m.group(1)) + if not commit_ids and found_issuebot_post: + print(mr.iid, 'issuebot has posted without trigger commit ID, not running again') + elif mr.sha in commit_ids: + print(mr.iid, 'issuebot has run on %s, not running again' % mr.sha) + else: + print(mr.iid, '"%s" needs issuebot run' % mr.title) + # insecure "captcha" + with open('.issuebot') as fp: + token = subprocess.check_output( + [ + 'bash', + '-c', + 's=$((4`printf "$CI_COMMIT_SHA" | wc -c`-10));' + 'e=$((s+`echo "$CI_SERVER_HOST" | wc -c`+18));' + 'cut -b${s}-${e}', + ], + stdin=fp, + env=os.environ, + ) + # All of these are describing the project and merge request, + # so FROM_CI_JOB_ID, FROM_CI_PIPELINE_ID, etc. are not relevant, + # since this is not running the context of the user-submitted + # merge request. + cmd = [ + 'curl', + '--silent', + '--request', + 'POST', + '--form', + 'token=%s' % token.decode().strip(), + '--form', + 'ref=master', + '--form', + 'variables[FROM_CI_COMMIT_REF_NAME]=%s' % mr.source_branch, + '--form', + 'variables[FROM_CI_COMMIT_REF_SLUG]=%s' % mr.source_branch, + '--form', + 'variables[FROM_CI_COMMIT_SHA]=%s' % mr.sha, + '--form', + 'variables[FROM_CI_MERGE_REQUEST_IID]=%s' % mr.iid, + '%s/projects/36528/trigger/pipeline' % os.getenv('CI_API_V4_URL'), + ] + p = subprocess.run( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + pprint.pprint(json.loads(p.stdout)) + exit()