summaryrefslogtreecommitdiff
path: root/manual/seed-jobs.sh
blob: b148a9b04d964eabace31efe766264e0f120afd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env bash
set -e

#
# This script seeds Jenkins jobs via list of packages in jobs.json
# it iterates through all packages
# it checks if job for package exists
# it updates job if exists otherwise creates new one.
# It can also start build for all jobs.
#
# This script has two modes, first mode is create
# ./seed-jobs.sh create
# this will update or create jobs
#
# Second mode is build
# ./seed-jobs.sh build
# this will trigger build for all jobs
#
# You need to wait after create some time, Jenkins need to complete branch indexing.
# Check Jenkins Build Queue and Build Executor Status to be empty. Then you can run build.
#
# dependency: apt install -y xmlstarlet jq
#
# Refer to Jenkins documentation to create a token
# https://www.jenkins.io/doc/book/system-administration/authenticating-scripted-clients/
#   The API token is available in your personal configuration page.
#   Click your name on the top right corner on every page, then click "Configure"
#   to see your API token.

jenkinsUser="" # fill your username here or set via export JENKINS_USER
jenkinsToken="" # fill your token here or set via export JENKINS_TOKEN
jenkinsHost="172.17.17.17:8080"
workDir="/tmp/seed-jobs"

mkdir -p "$workDir"

templatePath="../jobs/jobTemplate.xml"
dockerContainerJobsPath="../jobs/docker-container-jobs.json"
projectsJobsPath="../jobs/project-jobs.json"
jenkinsUser=${jenkinsUser:-$JENKINS_USER}
jenkinsToken=${jenkinsToken:-$JENKINS_TOKEN}
jenkinsUrl="http://${jenkinsUser}:${jenkinsToken}@$jenkinsHost"
selectedBranch="$BRANCH"

mode="$1"
availableModes=("create" "build")

get() {
    curl -sS -g --fail-with-body "${jenkinsUrl}${1}"
}

post() {
    curl -sS -g --fail-with-body -X POST "${jenkinsUrl}${1}"
}

push() {
    curl -sS -g --fail-with-body -X POST -d "@${2}" -H "Content-Type: text/xml" "${jenkinsUrl}${1}"
}

echo -n "testing jenkins connection: "
get > /dev/null
echo "ok"

excludedDescription=""
if [ "$selectedBranch" == "sagitta" ]; then
    excludedDescription="equuleus-only"
elif [ "$selectedBranch" == "equuleus" ]; then
    excludedDescription="sagitta-only"
else
  >&2 echo -e "ERROR: Unknown branch: $selectedBranch, please provide valid \$BRANCH (sagitta or equuleus)"
  exit 1
fi

if [[ "$mode" == "create" ]]; then
    jobsPath="$workDir/jobs.json"
    cat "$dockerContainerJobsPath" "$projectsJobsPath" | jq -s 'add' > "$jobsPath"

    while read item
    do
        jobName=$(echo "$item" | jq -r .name)
        echo -n "$jobName:"

        description=$(echo "$item" | jq -r .description)
        gitUrl=$(echo "$item" | jq -r .gitUrl)
        branchRegex=$(echo "$item" | jq -r .branchRegex)
        jenkinsfilePath=$(echo "$item" | jq -r .jenkinsfilePath)

        if [ "$description" == "$excludedDescription" ]; then
            echo " excluded ($description)"
            continue
        fi

        # create job.xml by using jobTemplate.xml
        jobPath="$workDir/$jobName.xml"
        project="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"
        branchSource="$project/sources/data/jenkins.branch.BranchSource/source"
        regexTrait="$branchSource/traits/jenkins.scm.impl.trait.RegexSCMHeadFilterTrait"
        xmlstarlet ed --update "//$project/description" --value "$description" \
            --update "//$branchSource/remote" --value "$gitUrl" \
            --update "//$regexTrait/regex" --value "$branchRegex" \
            --update "//$project/factory/scriptPath" --value "$jenkinsfilePath" \
            "$templatePath" > "$jobPath" 2>/dev/null

        # check if job exists
        result=$(get "/checkJobName?value=$jobName" || true)
        if [[ "$result" == *"already exists"* ]]; then
            # update job
            push "/job/$jobName/config.xml" "$jobPath"
        else
            # create job
            push "/createItem?name=$jobName" "$jobPath"
        fi

        echo " ok"
    done < <(cat "$jobsPath" | jq -c '.[]')

elif [[ "$mode" == "build" ]]; then

    get "/api/xml?tree=jobs[name]" | xmlstarlet sel -t -v "//hudson/job/name" | while read jobName || [ -n "$jobName" ]; do

        echo -n "$jobName:"

        # trigger build - it's not easy to know what branches job has
        # thus we trigger all possible ones and ignore not found
        post "/job/$jobName/job/equuleus/build" > /dev/null 2>/dev/null || true
        post "/job/$jobName/job/sagitta/build" > /dev/null 2>/dev/null || true
        post "/job/$jobName/job/current/build" > /dev/null 2>/dev/null || true

        echo " ok"

    done

else
    >&2 echo "ERROR: unknown mode '$mode'"
    echo "available modes: ${availableModes[*]}"
    exit 1
fi