Hi there!
Have a question regarding scheduling pipelines, the core functionality is that I only want to push a new build at a specific time weekly if we had a successful merge request during the week. If there are no merge requests done during the week, then the scheduled pipeline should not run.
Can that be achieved?
I see that CI_PIPELINE_SOURCE
can be equal to a number of options including schedule
or merge_request_event
Because I know people look at forums in the future because of web crawlers and wanting the same functionality, I was able to make something that does the logic I want. I do not know if it’s the most elegant and there are probably ways to reduce the size & make it more secure, not use just a template for the schedule, blah blah. I just wanted to get it out there for other people to see.
.gitlab-ci.yml:
stages:
- schedule
- build
- push
.prod_variables: &prod_variables
ENV: production
.template-schedule: &template-schedule
stage: schedule
image: ubuntu:22.04 # I want to reduce this image overhead, if replacing with busybox, I just need date command to give me ISO8601 from a week ago & curl
script:
- apt update -y && apt upgrade -y
- apt-get install -y curl
# - printenv # just for debugging
- ./linuxdeploy.sh
environment:
name: $ENV
check-schedule-prod:
<<: *template-schedule
variables:
<<: *prod_variables
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
build-schedule-prod:
stage: build
variables:
<<: *prod_variables
script:
- echo "Building" # just a placeholder for a docker build that then can be used in the next stage for a push
environment:
name: $ENV
rules:
- if: '$CI_PIPELINE_SOURCE == "api"'
push-schedule-prod:
stage: push
variables:
<<: *prod_variables
script:
- echo "Pushing" # just a placeholder for like a docker push stage to a repo with the artifact from the previous stage
environment:
name: $ENV
rules:
- if: '$CI_PIPELINE_SOURCE == "api"'
linuxdeploy.sh
#!/bin/bash
set -e -o pipefail
main()
{
get_mergerequests 0
}
get_mergerequests() {
# 5 vars within the script
gitlab_url=gitlab.example.com
dateISO8601=$(date --date="7 day ago" +"%Y-%m-%dT%H:%M:%SZ") # 7 days ago in a format the gitlab API needs
project_id=1 # Pipeline sample
state=merged
approved=yes
# $GitlabPAT needs to be set in the schedule vars and be created by a user who allows it access to the API
# Just to verify your system is displaying ISO8601
echo $dateISO8601
# Get a response back checking for MRs using a gitlab PAT ENV VAR on a specific project, approved, merged and within the past week
MR_RESP=$(curl --request GET --silent --header "PRIVATE-TOKEN: $GitlabPAT" "$gitlab_url/api/v4/projects/$project_id/merge_requests?approved=$approved&created_after=$dateISO8601&state=$state")
if [ "$MR_RESP" = [] ]; then
echo "Detected No Merge Requests that were approved, merged and created within the last week, completed check"
else
echo "Detected a MR that was approved, merged and created with the last week, calling create pipeline to activate deployment, schedule will need GitlabPAT defined with a proper API key to work"
NEWPIPELINE_RESP=$(curl --request POST --silent --header "PRIVATE-TOKEN: $GitlabPAT" "$gitlab_url/api/v4/projects/$project_id/pipeline?ref=main")
fi
}
main
2 Likes