Skip to content

Instantly share code, notes, and snippets.

@wakaba
Last active July 12, 2021 03:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wakaba/9970857 to your computer and use it in GitHub Desktop.
Save wakaba/9970857 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
open $file, '>', '.travis-merge';
print $file q{#!/bin/sh
curl -s -S -L -o travis_after_all.py https://gist.githubusercontent.com/wakaba/9970857/raw/travis_after_all.py && \
python travis_after_all.py && \
(ls .to_export_back || echo "BUILD_LEADER=YES BUILD_AGGREGATE_STATUS=others_succeeded" > .to_export_back)
export DUMMY=0 $(cat .to_export_back)
echo "BUILD_LEADER = $BUILD_LEADER, BUILD_AGGREGATE_STATUS = $BUILD_AGGREGATE_STATUS, TRAVIS_BRANCH = $TRAVIS_BRANCH, TRAVIS_COMMIT = $TRAVIS_COMMIT"
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then
if [ "$TRAVIS_BRANCH" = "staging" ] || [ "$TRAVIS_BRANCH" = "nightly" ] || [ "$TRAVIS_BRANCH" = "nightlywp" ]; then
echo "Merge $TRAVIS_BRANCH ($TRAVIS_COMMIT) into master..."
curl -s -S --request POST --header "Authorization:token $TRAVISMERGER_GH_TOKEN" \
--header "Content-Type:application/json" \
--data-binary "{\"base\":\"master\",\"head\":\"$TRAVIS_COMMIT\",\"commit_message\":\"auto-merge $TRAVIS_BRANCH into master\"}" \
"https://api.github.com/repos/$TRAVIS_REPO_SLUG/merges"
fi
fi
fi
};
close $file;
exec 'sh', '.travis-merge';
## License: Public Domain.
#!/usr/bin/perl
open $file, '>', '.travis-merge';
print $file q{#!/bin/sh
curl -s -S -L -o travis_after_all.py https://gist.githubusercontent.com/wakaba/9970857/raw/travis_after_all.py && \
python travis_after_all.py && \
(ls .to_export_back || echo "BUILD_LEADER=YES BUILD_AGGREGATE_STATUS=others_succeeded" > .to_export_back)
export DUMMY=0 $(cat .to_export_back)
echo "BUILD_LEADER = $BUILD_LEADER, BUILD_AGGREGATE_STATUS = $BUILD_AGGREGATE_STATUS, TRAVIS_BRANCH = $TRAVIS_BRANCH, TRAVIS_COMMIT = $TRAVIS_COMMIT"
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then
if [ "$TRAVIS_BRANCH" = "staging" ] || [ "$TRAVIS_BRANCH" = "nightly" ] || [ "$TRAVIS_BRANCH" = "nightlywp" ]; then
echo "Merge $TRAVIS_BRANCH ($TRAVIS_COMMIT) into master..."
git config --global user.email "merger@travis.test"
git config --global user.name "Travis Merger"
git config --global url.https://$TRAVISMERGER_GH_TOKEN:@github.com/.pushInsteadOf https://github.com/
if [ -s "$(git rev-parse --git-dir)/shallow" ]; then
git fetch --unshallow origin master && git checkout FETCH_HEAD
else
git fetch origin master && git checkout FETCH_HEAD
fi
git merge $TRAVIS_COMMIT && \
(git push -q origin HEAD:master 2> /dev/null || (echo "push failed" && false))
fi
fi
fi
};
close $file;
exec 'sh', '.travis-merge';
## License: Public Domain.
#!/usr/bin/perl
open $file, '>', '.travis-merge';
print $file q{#!/bin/sh
curl -s -S -L -o travis_after_all.py https://gist.githubusercontent.com/wakaba/9970857/raw/travis_after_all.py && \
python travis_after_all.py && \
(ls .to_export_back || echo "BUILD_LEADER=YES BUILD_AGGREGATE_STATUS=others_succeeded" > .to_export_back)
export DUMMY=0 $(cat .to_export_back)
echo "BUILD_LEADER = $BUILD_LEADER, BUILD_AGGREGATE_STATUS = $BUILD_AGGREGATE_STATUS, TRAVIS_BRANCH = $TRAVIS_BRANCH, TRAVIS_COMMIT = $TRAVIS_COMMIT"
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then
if [ "$TRAVIS_BRANCH" = "staging" ] || [ "$TRAVIS_BRANCH" = "nightly" ] || [ "$TRAVIS_BRANCH" = "nightlywp" ]; then
echo "Merge $TRAVIS_BRANCH ($TRAVIS_COMMIT) into master..."
curl -s -S --request POST --header "Authorization:token $TRAVISMERGER_GH_TOKEN" \
--header "Content-Type:application/json" \
--data-binary "{\"base\":\"master\",\"head\":\"$TRAVIS_COMMIT\",\"commit_message\":\"auto-merge $TRAVIS_BRANCH into master\"}" \
"https://api.github.com/repos/$TRAVIS_REPO_SLUG/merges"
elif [ "$TRAVIS_BRANCH" = "master" ]; then
echo "Merge $TRAVIS_BRANCH ($TRAVIS_COMMIT) into gh-pages..."
curl -s -S --request POST --header "Authorization:token $TRAVISMERGER_GH_TOKEN" \
--header "Content-Type:application/json" \
--data-binary "{\"base\":\"gh-pages\",\"head\":\"$TRAVIS_COMMIT\",\"commit_message\":\"auto-merge $TRAVIS_BRANCH into gh-pages\"}" \
"https://api.github.com/repos/$TRAVIS_REPO_SLUG/merges"
fi
fi
fi
};
close $file;
exec 'sh', '.travis-merge';
## License: Public Domain.
#!/usr/bin/perl
open $file, '>', '.travis-merge';
print $file q{#!/bin/sh
curl -s -S -L -f -o travis_after_all.py https://gist.githubusercontent.com/wakaba/9970857/raw/travis_after_all.py && \
python travis_after_all.py
#&& \
#(ls .to_export_back || echo "BUILD_LEADER=YES BUILD_AGGREGATE_STATUS=others_succeeded" > .to_export_back)
export DUMMY=0 $(cat .to_export_back)
echo "BUILD_LEADER = $BUILD_LEADER, BUILD_AGGREGATE_STATUS = $BUILD_AGGREGATE_STATUS, TRAVIS_BRANCH = $TRAVIS_BRANCH, TRAVIS_COMMIT = $TRAVIS_COMMIT"
if [ "$BUILD_LEADER" = "YES" ]; then
if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then
if [ "$TRAVIS_BRANCH" = "staging" ] || [ "$TRAVIS_BRANCH" = "nightly" ] || [ "$TRAVIS_BRANCH" = "nightlywp" ]; then
echo "Merge $TRAVIS_BRANCH ($TRAVIS_COMMIT) into master..."
git config --global user.email "merger@travis.test"
git config --global user.name "Travis Merger"
git config --global url.https://$TRAVISMERGER_GH_TOKEN:@github.com/.pushInsteadOf https://github.com/
if [ -s "$(git rev-parse --git-dir)/shallow" ]; then
git fetch --unshallow origin master && git checkout FETCH_HEAD
else
git fetch origin master && git checkout FETCH_HEAD
fi
git merge $TRAVIS_COMMIT && \
((git push -q origin HEAD:master 2> /dev/null && curl https://$TRAVISMERGER_BWALL_TOKEN:@bwall1$TRAVISMERGER_BWALL_APP.herokuapp.com/ping/merger.$TRAVIS_BRANCH/`perl -e '$x=$ENV{TRAVIS_REPO_SLUG};$x=~s{([^A-Za-z0-9])}{sprintf "%%%02X", ord $1}ge;print $x'` -X POST) || (echo "push failed" && false))
fi
fi
fi
};
close $file;
exec 'sh', '.travis-merge';
## License: Public Domain.
## Original: <https://raw.githubusercontent.com/dmakhno/travis_after_all/5acf1b8d164e7da313f72a8634bdd95182f890f5/travis_after_all.py>
import os
import json
import time
import logging
try:
import urllib.request as urllib2
except ImportError:
import urllib2
log = logging.getLogger("travis.leader")
log.addHandler(logging.StreamHandler())
log.setLevel(logging.INFO)
TRAVIS_JOB_NUMBER = 'TRAVIS_JOB_NUMBER'
TRAVIS_BUILD_ID = 'TRAVIS_BUILD_ID'
POLLING_INTERVAL = 'LEADER_POLLING_INTERVAL'
build_id = os.getenv(TRAVIS_BUILD_ID)
polling_interval = int(os.getenv(POLLING_INTERVAL, '5'))
#assume, first job is the leader
is_leader = lambda job_number: job_number.endswith('.1')
if not os.getenv(TRAVIS_JOB_NUMBER):
# seems even for builds with only one job, this won't get here
log.fatal("Don't use defining leader for build without matrix")
exit(1)
elif is_leader(os.getenv(TRAVIS_JOB_NUMBER)):
log.info("This is a leader")
else:
#since python is subprocess, env variables are exported back via file
with open(".to_export_back", "w") as export_var:
export_var.write("BUILD_MINION=YES")
log.info("This is a minion")
exit(0)
class MatrixElement(object):
def __init__(self, json_raw):
self.is_finished = (json_raw['finished_at'] is not None or json_raw['allow_failure'])
self.is_succeeded = (json_raw['result'] == 0 or json_raw['allow_failure'])
self.number = json_raw['number']
self.is_leader = is_leader(self.number)
def matrix_snapshot():
"""
:return: Matrix List
"""
response = urllib2.build_opener().open("https://api.travis-ci.org/builds/{0}".format(build_id)).read()
raw_json = json.loads(response)
matrix_without_leader = [MatrixElement(element) for element in raw_json["matrix"]]
return matrix_without_leader
def wait_others_to_finish():
def others_finished():
"""
Dumps others to finish
Leader cannot finish, it is working now
:return: tuple(True or False, List of not finished jobs)
"""
snapshot = matrix_snapshot()
finished = [el.is_finished for el in snapshot if not el.is_leader]
return reduce(lambda a, b: a and b, finished), [el.number for el in snapshot if
not el.is_leader and not el.is_finished]
while True:
finished, waiting_list = others_finished()
if finished: break
log.info("Leader waits for minions {0}...".format(waiting_list)) # just in case do not get "silence timeout"
time.sleep(polling_interval)
try:
wait_others_to_finish()
final_snapshot = matrix_snapshot()
log.info("Final Results: {0}".format([(e.number, e.is_succeeded) for e in final_snapshot]))
BUILD_AGGREGATE_STATUS = 'BUILD_AGGREGATE_STATUS'
others_snapshot = [el for el in final_snapshot if not el.is_leader]
if reduce(lambda a, b: a and b, [e.is_succeeded for e in others_snapshot]):
os.environ[BUILD_AGGREGATE_STATUS] = "others_succeeded"
elif reduce(lambda a, b: a and b, [not e.is_succeeded for e in others_snapshot]):
log.error("Others Failed")
os.environ[BUILD_AGGREGATE_STATUS] = "others_failed"
else:
log.warn("Others Unknown")
os.environ[BUILD_AGGREGATE_STATUS] = "unknown"
#since python is subprocess, env variables are exported back via file
with open(".to_export_back", "w") as export_var:
export_var.write("BUILD_LEADER=YES {0}={1}".format(BUILD_AGGREGATE_STATUS, os.environ[BUILD_AGGREGATE_STATUS]))
except Exception as e:
log.fatal(e)
@wakaba
Copy link
Author

wakaba commented Dec 29, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment