forked from plume-lib/plume-scripts
-
Notifications
You must be signed in to change notification settings - Fork 4
/
ci-info
executable file
·365 lines (332 loc) · 14.6 KB
/
ci-info
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
#!/bin/sh
# Outputs information about a CI job, when run under Azure Pipelines,
# CircleCI, GitHub Actions, or Travis CI.
# On CircleCI, it depends on environment variable CIRCLE_COMPARE_URL, which is set
# for CircleCI v2 and earlier. To set CIRCLE_COMPARE_URL on V2.1 and later (per
# https://discuss.circleci.com/t/is-circle-compare-url-still-a-thing/33366):
# jobs:
# my-job:
# environment:
# CIRCLE_COMPARE_URL: << pipeline.project.git_url >>/compare/<< pipeline.git.base_revision >>..<<pipeline.git.revision>>
# Typical use:
#
# if [ -d /tmp/$USER/plume-scripts ] ; then
# git -C /tmp/$USER/plume-scripts pull -q > /dev/null 2>&1
# else
# mkdir -p /tmp/$USER && git -C /tmp/$USER clone --filter=blob:none -q https://github.com/plume-lib/plume-scripts.git
# fi
# eval $(/tmp/$USER/plume-scripts/ci-info DEFAULT-ORGANIZATION)
#
# Here are the variables that it sets:
# CI_IS_PULL_REQUEST: Either "true" or "false" (without the quotes).
# CI_ORGANIZATION: The GitHub organization. In a PR, refers to the source or head.
# Optional argument DEFAULT-ORGANIZATION is used if no organization can be determined.
# CI_BRANCH_NAME: The name of the source/head branch (in a PR) or of the branch being tested.
# CI_COMMIT_RANGE: An argument to `git diff` with the range of commits IDs.
# (Don't use it with `git log`, which interprets its argument differently.)
# CI_COMMIT_RANGE_START: The start element of CI_COMMIT_RANGE, a commit ID.
# CI_COMMIT_RANGE_END: The end element of CI_COMMIT_RANGE, a commit ID.
#
# For example use, see comments in file `lint-diff.py` in this directory.
#
# Requires the `jq` program to be installed, when used in Azure Pipelines jobs.
DEBUG=""
if [ "$1" = "--verbose" ] ; then
VERBOSE="--verbose"
shift
fi
if [ "$1" = "--debug" ] ; then
DEBUG="--debug"
VERBOSE="--verbose"
shift
fi
if [ "$#" -gt 1 ] ; then
echo "echo Usage: $0 [--verbose] [--debug] [DEFAULT-ORGANIZATION];"
echo "Usage: $0 [--verbose] [--debug] [DEFAULT-ORGANIZATION]" >&2
echo "exit 2"
exit 2
fi
# SCRIPTDIR="$( cd "$(dirname "$0")" ; pwd -P )"
if [ "$DEBUG" = "--debug" ] ; then
echo
env | sort | sed -e 's/^/echo /'
echo
git --no-pager branch -a | sed -e 's/^/echo /'
echo
git --no-pager log --graph | head --lines=1000 | sed -e 's/^/echo /'
echo
fi
### Functions
# Returns either `git rev-parse HEAD^1` if HEAD^1 exists, or `git rev-parse HEAD`.
# HEAD^1 does not exist if the clone was created with `git clone --depth=1`.
head1 () {
if git rev-parse --verify --quiet HEAD^1 > /dev/null 2>&1 ; then
git rev-parse HEAD^1
else
git rev-parse HEAD
fi
}
### Organization
## Continuous integration services
if [ "$TRAVIS" = "true" ]; then
CI_ORGANIZATION=${TRAVIS_PULL_REQUEST_SLUG%/*}
if [ "$CI_ORGANIZATION" = "" ]; then
CI_ORGANIZATION=${TRAVIS_REPO_SLUG%/*}
fi
elif [ -n "$AZURE_HTTP_USER_AGENT" ]; then
if [ "$BUILD_REASON" = "PullRequest" ]; then
SLUG=$(wget -q -O - "https://api.github.com/repos/${BUILD_REPOSITORY_NAME}/pulls/${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}" | jq .head.label | sed 's/"//g')
CI_ORGANIZATION=${SLUG%:*}
else
CI_ORGANIZATION=${BUILD_REPOSITORY_NAME%/*}
# CI_REPO=${BUILD_REPOSITORY_NAME##*/}
fi
elif [ -n "$CIRCLE_PR_USERNAME" ]; then
CI_ORGANIZATION="$CIRCLE_PR_USERNAME"
fi
## Git clone
if [ "$CI_ORGANIZATION" = "" ]; then
URL=$(git config --get remote.origin.url)
# This handles two possible forms for a URL:
# https://github.com/mernst/annotation-tools
# [email protected]:mernst/annotation-tools.git
SLUG=${URL#https://github.com/}
SLUG=${SLUG#[email protected]:}
CI_ORGANIZATION=${SLUG%/*}
# TODO: Maybe add a sanity check here.
fi
## Default
if [ "$CI_ORGANIZATION" = "" ]; then
CI_ORGANIZATION=$1
fi
### Other information (besides organization)
## Both of these commands for DEFAULT_BRANCH_NAME seem to work.
# DEFAULT_BRANCH_NAME=$(git ls-remote --symref "$(git config --get remote.origin.url)" HEAD | awk '/^ref:/ {sub(/refs\/heads\//, "", $2); print $2}')
DEFAULT_BRANCH_NAME=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
if [ "$DEBUG" = "--debug" ] ; then
echo "echo DEFAULT_BRANCH_NAME=$DEFAULT_BRANCH_NAME;"
echo "echo $(git ls-remote --symref "${URL}" HEAD);"
fi
if [ -n "$SYSTEM_PULLREQUEST_TARGETBRANCH" ] ; then
## Azure Pipelines pull request
if [ "$DEBUG" = "--debug" ] ; then
echo "echo Azure Pipelines pull request $SYSTEM_PULLREQUEST_TARGETBRANCH;"
fi
CI_IS_PULL_REQUEST=true
# WARNING! $BUILD_SOURCEBRANCHNAME is just a name, not a full ref path. For example,
# $BUILD_SOURCEBRANCHNAME may be "merge" when $BUILD_SOURCEBRANCH is "refs/pull/2971/merge".
CI_BRANCH_NAME=$SYSTEM_PULLREQUEST_SOURCEBRANCH
# For CI_COMMIT_RANGE_START: HEAD = $BUILD_SOURCEVERSION is a commit created by Azure; it isn't
# in the repo. Its first child HEAD^1 is the target branch (e.g., master); use that instead of
# $SYSTEM_PULLREQUEST_TARGETBRANCH is not fetched into this repo.
CI_COMMIT_RANGE_START=$(head1)
CI_COMMIT_RANGE_END=$SYSTEM_PULLREQUEST_SOURCECOMMITID
CI_COMMIT_RANGE=${CI_COMMIT_RANGE_START}...${CI_COMMIT_RANGE_END}
elif [ -n "$BUILD_SOURCEBRANCH" ] ; then
# Azure Pipelines build for a branch (possibly master).
if [ "$DEBUG" = "--debug" ] ; then
echo "echo Azure Pipelines build for a branch $BUILD_SOURCEBRANCH;"
echo "echo SYSTEM_PULLREQUEST_TARGETBRANCH=$SYSTEM_PULLREQUEST_TARGETBRANCH is not set but BUILD_SOURCEBRANCH=$BUILD_SOURCEBRANCH;"
fi
CI_IS_PULL_REQUEST=false
# In Azure Pipelines: BUILD_SOURCEBRANCH is a full ref path like "refs/heads/mybranch";
# BUILD_SOURCEBRANCHNAME is a short name like "mybranch"; $BUILD_SOURCEVERSION is a commit ID.
# some clients such as `git-clone-related` MUST be given a branch name, not a commit ID.
CI_BRANCH_NAME=$BUILD_SOURCEBRANCHNAME
if [ "$BUILD_SOURCEBRANCHNAME" = "$DEFAULT_BRANCH_NAME" ] ; then
DEFAULT_CI_COMMIT_RANGE_START=$(head1)
# If a build fails, we would like to continue failing subsequent
# builds until the problem is fixed. Using `git rev-parse HEAD^1`
# does not do that, because there could have been multiple pushes
# since the last successful CI job.
# Pass argument to ci-last-success.py, because in a pull request
# we are only interested in the last success on the master branch,
# not on the feature branch! The feature branch might have many
# succeeding jobs and then ci-last-success.py will return just
# part of the pull request's diffs.
## # ci-last-success.py currently doesn't work because api.github.com returns "state: pending".
# # TODO: wrap all this in a ci-last-commit.sh shell script.
# if pip3 list --format columns | tail -n +1 | grep -q '^requests ' ; then
# # echo "echo \"Python requests package is already installed\";"
# :
# else
# (sudo pip3 install requests || pip3 install --user requests || true) > /dev/null 2>&1
# fi
# if pip3 list --format columns | tail -n +1 | grep -q '^requests ' ; then
# CI_COMMIT_RANGE_START=$(${SCRIPTDIR}/ci-last-success.py ${CI_ORGANIZATION} ${CI_REPO} ${DEFAULT_CI_COMMIT_RANGE_START})
# if [ "$CI_COMMIT_RANGE_START" = "" ] ; then
# echo "echo \"WARNING: ci-last-success.py script failed; just considering last commit.\";"
# CI_COMMIT_RANGE_START=${DEFAULT_CI_COMMIT_RANGE_START}
# elif ! git cat-file -e ${CI_COMMIT_RANGE_START}^{commit}; then
# # The commit is not in the repository. Maybe it is older than the
# # commits pulled into this repository. This can happen when when
# # api.github.com incorrectly returns "state: pending" for successful
# # jobs.
# echo "echo \"WARNING: ci-last-success.py script returned commit not in repository; using last commit.\";"
# CI_COMMIT_RANGE_START=${DEFAULT_CI_COMMIT_RANGE_START}
# else
# echo "echo \"ci-last-success.py ${CI_ORGANIZATION} ${CI_REPO} succeeded with $CI_COMMIT_RANGE_START.\";"
# fi
# else
# echo "echo \"WARNING: Could not run ci-last-success.py script; just considering last commit.\";"
# CI_COMMIT_RANGE_START=${DEFAULT_CI_COMMIT_RANGE_START}
# fi
## Use this because ci-last-success.py currently doesn't work.
CI_COMMIT_RANGE_START=${DEFAULT_CI_COMMIT_RANGE_START}
else
git fetch origin "$DEFAULT_BRANCH_NAME"
CI_COMMIT_RANGE_START=$(git rev-parse "origin/$DEFAULT_BRANCH_NAME")
fi
CI_COMMIT_RANGE_END=$BUILD_SOURCEVERSION
CI_COMMIT_RANGE=${CI_COMMIT_RANGE_START}...${CI_COMMIT_RANGE_END}
elif [ "$TRAVIS" = "true" ] ; then
## Travis CI
if [ "$DEBUG" = "--debug" ] ; then
echo "echo Travis CI $TRAVIS;"
fi
CI_IS_PULL_REQUEST=$TRAVIS_PULL_REQUEST
CI_BRANCH_NAME=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo TRAVIS_PULL_REQUEST_BRANCH=$TRAVIS_PULL_REQUEST_BRANCH;"
echo "echo TRAVIS_BRANCH=$TRAVIS_BRANCH;"
echo "echo CI_BRANCH_NAME=$CI_BRANCH_NAME;"
fi
# $TRAVIS_COMMIT_RANGE is empty for builds triggered by the initial commit of a new branch.
CI_COMMIT_RANGE=$TRAVIS_COMMIT_RANGE
elif [ -n "$CIRCLE_COMPARE_URL" ] ; then
## CircleCI v2 or earlier, or CIRCLE_COMPARE_URL was set for compatibility.
if [ "$DEBUG" = "--debug" ] ; then
echo "echo CircleCI $CIRCLE_COMPARE_URL $CIRCLE_PULL_REQUEST;"
fi
if [ -n "$CIRCLE_PULL_REQUEST" ]; then
CI_IS_PULL_REQUEST=true
else
CI_IS_PULL_REQUEST=false
fi
CI_COMMIT_RANGE=$(echo "${CIRCLE_COMPARE_URL}" | cut -d/ -f7)
case $CI_COMMIT_RANGE in
*"..."*)
CI_COMMIT_RANGE_START=$(git rev-parse "${COMMIT_RANGE}")
CI_COMMIT_RANGE_END=$(git rev-parse "${COMMIT_RANGE}")
CI_COMMIT_RANGE="${CI_COMMIT_RANGE_START}...${CI_COMMIT_RANGE_END}" ;;
esac
# CIRCLE_BRANCH may be "pull/327"
case "$CIRCLE_BRANCH" in
pull/*)
CI_BRANCH_NAME=$(curl -s "https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/pulls/${CIRCLE_PR_NUMBER}" | jq -r '.head.ref') ;;
*)
CI_BRANCH_NAME=$CIRCLE_BRANCH ;;
esac
elif [ -n "$GITHUB_HEAD_REF" ] ; then
# GitHub Actions pull request (no special handling is required for non-PR GitHub Actions jobs).
CI_IS_PULL_REQUEST=true
CI_BRANCH_NAME="${GITHUB_HEAD_REF}"
CI_COMMIT_RANGE_START=$(git rev-parse "${GITHUB_BASE_REF}")
CI_COMMIT_RANGE_END=$(git rev-parse "${GITHUB_HEAD_REF}")
CI_COMMIT_RANGE="${CI_COMMIT_RANGE_START}...${CI_COMMIT_RANGE_END}"
else
# It's not a pull request (except maybe a re-run Azure Pipelines pull request).
if [ "$DEBUG" = "--debug" ] ; then
if [ -n "$CIRCLE_PULL_REQUEST" ]; then
echo "echo CircleCI pull request with CIRCLE_COMPARE_URL not set: $CIRCLE_PULL_REQUEST;"
else
echo "echo Else clause: no CI environment detected;"
fi
fi
CI_IS_PULL_REQUEST=false
# git 2.22 and later has `git branch --show-current`; CircleCI doesn't have that version yet.
CI_BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
# In an Azure Pipelines pull request, `git branch` yields "(HEAD detached at pull/4/merge)".
# If you re-run a pull request via "Queue" rather than "Rebuild",
# variables SYSTEM_PULLREQUEST_TARGETBRANCH and SYSTEM_PULLREQUEST_SOURCEBRANCH are not set.
if [ "$CI_BRANCH_NAME" = '(HEAD' ] ; then
CI_BRANCH_NAME=$DEFAULT_BRANCH_NAME
fi
fi
## The above may have not set CI_COMMIT_RANGE. Set it.
# Separate from "It's not a pull request" because sometimes this is not set for Travis.
if [ -z "$CI_COMMIT_RANGE" ]; then
if [ "$DEBUG" = "--debug" ] ; then
echo "echo Setting CI_COMMIT_RANGE from CI_BRANCH_NAME=$CI_BRANCH_NAME;"
fi
if [ "$CI_BRANCH_NAME" = "$DEFAULT_BRANCH_NAME" ]; then
if git show --summary HEAD | grep -q ^Merge: ; then
CI_COMMIT_RANGE_START=$(git merge-base HEAD^1 HEAD^2)
else
CI_COMMIT_RANGE_START=$(head1)
fi
CI_COMMIT_RANGE_END=$(git rev-parse HEAD)
else
if git rev-parse --verify --quiet "origin/$DEFAULT_BRANCH_NAME" > /dev/null 2>&1 ; then
CI_COMMIT_RANGE_START=$(git rev-parse "origin/$DEFAULT_BRANCH_NAME")
else
if git show --summary HEAD | grep -q ^Merge: ; then
CI_COMMIT_RANGE_START=$(git merge-base HEAD^1 HEAD^2)
else
CI_COMMIT_RANGE_START=$(head1)
fi
fi
CI_COMMIT_RANGE_END=$(git rev-parse "$CI_BRANCH_NAME")
fi
CI_COMMIT_RANGE=${CI_COMMIT_RANGE_START}...${CI_COMMIT_RANGE_END}
fi
if [ -z "$CI_COMMIT_RANGE_START" ]; then
if [ "$DEBUG" = "--debug" ] ; then
echo "echo Setting CI_COMMIT_RANGE_START from CI_COMMIT_RANGE=$CI_COMMIT_RANGE;"
fi
CI_COMMIT_RANGE_START=${CI_COMMIT_RANGE%%.*}
CI_COMMIT_RANGE_END=${CI_COMMIT_RANGE##*.}
if [ -z "$CI_COMMIT_RANGE_START" ] ; then
CI_COMMIT_RANGE_START=${CI_COMMIT_RANGE_END}
fi
fi
# Avoid errors regarding empty range
if [ "$CI_COMMIT_RANGE_START" = "$CI_COMMIT_RANGE_END" ]; then
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo Resetting CI_COMMIT_RANGE_START because CI_COMMIT_RANGE=$CI_COMMIT_RANGE;"
fi
if git show --summary "$CI_COMMIT_RANGE_END" | grep -q ^Merge: ; then
CI_COMMIT_RANGE_START=$(git merge-base "$CI_COMMIT_RANGE_END^1" "$CI_COMMIT_RANGE_END^2")
else
if git rev-parse --verify --quiet "$CI_COMMIT_RANGE_END^1" > /dev/null 2>&1 ; then
CI_COMMIT_RANGE_START=$(git rev-parse "$CI_COMMIT_RANGE_END^1")
fi
fi
CI_COMMIT_RANGE="${CI_COMMIT_RANGE_START}...${CI_COMMIT_RANGE_END}"
fi
# The diff might be empty if the last commit is the revert of the one before it.
### Print it out
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo CI_ORGANIZATION=$CI_ORGANIZATION;"
fi
echo "CI_ORGANIZATION=$CI_ORGANIZATION; export CI_ORGANIZATION;"
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo CI_IS_PULL_REQUEST=$CI_IS_PULL_REQUEST;"
fi
echo "CI_IS_PULL_REQUEST=$CI_IS_PULL_REQUEST; export CI_IS_PULL_REQUEST;"
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo CI_BRANCH_NAME=$CI_BRANCH_NAME;"
fi
echo "CI_BRANCH_NAME=$CI_BRANCH_NAME; export CI_BRANCH_NAME;"
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo CI_COMMIT_RANGE=$CI_COMMIT_RANGE;"
fi
echo "CI_COMMIT_RANGE=$CI_COMMIT_RANGE; export CI_COMMIT_RANGE;"
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo CI_COMMIT_RANGE_START=$CI_COMMIT_RANGE_START;"
fi
echo "CI_COMMIT_RANGE_START=$CI_COMMIT_RANGE_START; export CI_COMMIT_RANGE_START;"
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo CI_COMMIT_RANGE_END=$CI_COMMIT_RANGE_END;"
fi
echo "CI_COMMIT_RANGE_END=$CI_COMMIT_RANGE_END; export CI_COMMIT_RANGE_END;"
# Temporary, for backward compatibility
# Deprecated 2019-07-10; remove on 2020-07-10
if [ "$CI_IS_PULL_REQUEST" = "true" ]; then
echo "CI_IS_PR=1; export CI_IS_PR;"
fi
# Deprecated 2019-12-10; remove on 2020-12-10
if [ "$VERBOSE" = "--verbose" ] ; then
echo "echo CI_BRANCH=$CI_BRANCH_NAME;"
fi
echo "CI_BRANCH=$CI_BRANCH_NAME; export CI_BRANCH;"