зеркало из https://github.com/twbs/bootlint.git
Travis CI: Drop custom caching and switch to node.js 8.
This commit is contained in:
Родитель
84f649b794
Коммит
94c6ac06a8
29
.travis.yml
29
.travis.yml
|
@ -1,21 +1,18 @@
|
|||
{
|
||||
"sudo": false,
|
||||
"dist": "trusty",
|
||||
"language": "node_js",
|
||||
"node_js": ["6"],
|
||||
"node_js": ["8"],
|
||||
"before_install": [
|
||||
"travis_retry pip install -r test-infra/requirements.txt --user",
|
||||
"rvm install 2.2",
|
||||
"rvm use 2.2 --fuzzy",
|
||||
"export GEMDIR=$(rvm gemdir)",
|
||||
"echo \"ruby=$(basename $GEMDIR) jekyll=$JEKYLL_VERSION\" > pseudo_Gemfile.lock"
|
||||
"if [[ `npm -v` != 5* ]]; then npm install -g npm@5; fi"
|
||||
],
|
||||
"install": [
|
||||
"npm install -g grunt-cli",
|
||||
"./test-infra/s3_cache.py download npm-modules",
|
||||
"./test-infra/s3_cache.py download rubygems"
|
||||
"npm install",
|
||||
"bundle install --deployment --jobs=3 --retry=3"
|
||||
],
|
||||
"before_script": [
|
||||
"git clone --depth 1 https://github.com/twbs/bootstrap.git",
|
||||
"git clone --depth 1 https://github.com/twbs/bootstrap.git --branch v3-dev",
|
||||
"pushd bootstrap && jekyll build; popd"
|
||||
],
|
||||
"script": [
|
||||
|
@ -26,16 +23,12 @@
|
|||
"diff test/fixtures/cli/x-ua-compatible-missing.output.txt x-ua-compatible-missing.output.actual.txt"
|
||||
],
|
||||
"after_script": [
|
||||
"npm run coveralls",
|
||||
"./test-infra/s3_cache.py upload npm-modules",
|
||||
"./test-infra/s3_cache.py upload rubygems"
|
||||
"npm run coveralls"
|
||||
],
|
||||
"env": {
|
||||
"global": [
|
||||
{"JEKYLL_VERSION": "3.1.2"},
|
||||
{"secure": "dRdiG/5UykFAVW6GWWcaNHGSPy16PiCeF9XySPDdCSbw+pI2zqE8VNyXgn1kORhLFsKjdIQaLnmFWR1Xw7sP59zpnIRUkZ77spw7hKNf1RlAv3uckE8LFxO1FkMFNOlSHgmCXnyseUNGMDL/lIBMCLfsTOlc6KvbQir7pz+TDwM="},
|
||||
{"secure": "Ej9x2sBilYq9Wr86j7NujcPN0qAMHgUzjB9tX0vN90nKOPfAmWWcO9omFzwkuH0VZkZmauK/YQlEqKhx99quVwRHctu0LhZRnBgaCnsGp6CnRorFW4IKZwJSM38BF9XXvCCnQtz6PyItpE+ycbpFI0MHvs0H3BXFmwifvY/Q4/Y="},
|
||||
{"secure": "Oq9mxJduZiy0oZmKlg3kkFFWlBTuCynRpZoz0SyG3hHt2uipWfXlm0AlpcjU6jB6g8kNtGF4ZA5uGiMUePSOfK0RveYQa95ixUY6VrbuAIzdDtz/rbMajtGCVpMBgOf5o33rEfocwgADE/i1lE1JJeNjdUBsO1Iyron1ZiT52mE="}
|
||||
"cache": {
|
||||
"directories": [
|
||||
"node_modules",
|
||||
"vendor/bundle"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,7 @@ Assuming that you don't see any red, you're ready to go. Just be sure to run `gr
|
|||
3. Fix stuff.
|
||||
4. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done.
|
||||
5. Update the documentation to reflect any changes.
|
||||
6. If you upgraded or added any dependencies in `package.json`, run `grunt update-shrinkwrap` and (in a separate commit) commit the updated `/test-infra/npm-shrinkwrap.json` file. This updates the package versions used by the Travis CI build.
|
||||
7. Push to your fork and submit a pull request.
|
||||
6. Push to your fork and submit a pull request.
|
||||
|
||||
### Licensing
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
group :development, :test do
|
||||
gem 'jekyll', '~> 3.4.5'
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.5.1)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
colorator (1.1.0)
|
||||
ffi (1.9.18)
|
||||
ffi (1.9.18-x64-mingw32)
|
||||
forwardable-extended (2.6.0)
|
||||
jekyll (3.4.5)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 1.1)
|
||||
kramdown (~> 1.3)
|
||||
liquid (~> 3.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pathutil (~> 0.9)
|
||||
rouge (~> 1.7)
|
||||
safe_yaml (~> 1.0)
|
||||
jekyll-sass-converter (1.5.0)
|
||||
sass (~> 3.4)
|
||||
jekyll-watch (1.5.0)
|
||||
listen (~> 3.0, < 3.1)
|
||||
kramdown (1.14.0)
|
||||
liquid (3.0.6)
|
||||
listen (3.0.8)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
mercenary (0.3.6)
|
||||
pathutil (0.14.0)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (2.0.5)
|
||||
rb-fsevent (0.10.2)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
rouge (1.11.1)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.5.1)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
x64-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
jekyll (~> 3.4.5)
|
||||
|
||||
BUNDLED WITH
|
||||
1.15.3
|
24
Gruntfile.js
24
Gruntfile.js
|
@ -13,9 +13,6 @@ module.exports = function (grunt) {
|
|||
// Force use of Unix newlines
|
||||
grunt.util.linefeed = '\n';
|
||||
|
||||
var fs = require('fs');
|
||||
var npmShrinkwrap = require('npm-shrinkwrap');
|
||||
|
||||
// Load all grunt tasks
|
||||
require('load-grunt-tasks')(grunt);
|
||||
// Show elapsed time at the end.
|
||||
|
@ -120,11 +117,6 @@ module.exports = function (grunt) {
|
|||
files: '<%= jshint.test.src %>',
|
||||
tasks: ['jshint:test', 'nodeunit']
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
npmUpdate: {
|
||||
command: 'npm update'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -133,20 +125,4 @@ module.exports = function (grunt) {
|
|||
grunt.registerTask('dist', ['browserify', 'usebanner']);
|
||||
grunt.registerTask('test', ['lint', 'dist', 'nodeunit', 'qunit']);
|
||||
grunt.registerTask('default', ['test']);
|
||||
|
||||
// Task for updating the cached npm packages used by the Travis build (which are controlled by test-infra/npm-shrinkwrap.json).
|
||||
// This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
|
||||
grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', '_update-shrinkwrap']);
|
||||
grunt.registerTask('_update-shrinkwrap', function () {
|
||||
var done = this.async();
|
||||
npmShrinkwrap({dev: true, dirname: __dirname}, function (err) {
|
||||
if (err) {
|
||||
grunt.fail.warn(err);
|
||||
}
|
||||
var dest = 'test-infra/npm-shrinkwrap.json';
|
||||
fs.renameSync('npm-shrinkwrap.json', dest);
|
||||
grunt.log.writeln('File ' + dest.cyan + ' updated.');
|
||||
done();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -58,14 +58,12 @@
|
|||
"grunt-contrib-qunit": "^1.0.1",
|
||||
"grunt-contrib-watch": "^1.0.0",
|
||||
"grunt-eslint": "^18.0.0",
|
||||
"grunt-exec": "^0.4.6",
|
||||
"grunt-jscs": "^2.8.0",
|
||||
"jquery": "^3.1.0",
|
||||
"jscoverage": "^0.6.0",
|
||||
"jscs-jsdoc": "^1.3.1",
|
||||
"load-grunt-tasks": "^3.1.0",
|
||||
"nodeunit": "^0.9.0",
|
||||
"npm-shrinkwrap": "^200.1.0",
|
||||
"rewire": "^2.3.1",
|
||||
"sinon": "^1.12.2",
|
||||
"time-grunt": "^1.0.0"
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"npm-modules": {
|
||||
"key": "./npm-shrinkwrap.json",
|
||||
"cache": "../node_modules",
|
||||
"generate": "./uncached-npm-install.sh"
|
||||
},
|
||||
"rubygems": {
|
||||
"key": "../pseudo_Gemfile.lock",
|
||||
"cache": "$GEMDIR",
|
||||
"generate": "gem install -N jekyll -v $JEKYLL_VERSION"
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1 +0,0 @@
|
|||
boto==2.25.0
|
|
@ -1,188 +0,0 @@
|
|||
#!/usr/bin/env python2.7
|
||||
# pylint: disable=C0301
|
||||
#
|
||||
# Copyright 2011-2014 Twitter, Inc.
|
||||
# Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
|
||||
from __future__ import absolute_import, unicode_literals, print_function, division
|
||||
|
||||
from sys import argv
|
||||
from os import environ, stat, chdir, remove as _delete_file
|
||||
from os.path import dirname, basename, abspath, realpath, expandvars
|
||||
from hashlib import sha256
|
||||
from subprocess import check_call as run
|
||||
from json import load, dump as save
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime
|
||||
|
||||
from boto.s3.connection import S3Connection
|
||||
from boto.s3.key import Key
|
||||
from boto.exception import S3ResponseError
|
||||
|
||||
|
||||
CONFIG_FILE = './S3Cachefile.json'
|
||||
UPLOAD_TODO_FILE = './S3CacheTodo.json'
|
||||
BYTES_PER_MB = 1024 * 1024
|
||||
|
||||
|
||||
@contextmanager
|
||||
def timer():
|
||||
start = datetime.utcnow()
|
||||
yield
|
||||
end = datetime.utcnow()
|
||||
elapsed = end - start
|
||||
print("\tDone. Took", int(elapsed.total_seconds()), "second(s).")
|
||||
|
||||
|
||||
@contextmanager
|
||||
def todo_file(writeback=True):
|
||||
try:
|
||||
with open(UPLOAD_TODO_FILE, 'rt') as json_file:
|
||||
todo = load(json_file)
|
||||
except (IOError, OSError, ValueError):
|
||||
todo = {}
|
||||
|
||||
yield todo
|
||||
|
||||
if writeback:
|
||||
try:
|
||||
with open(UPLOAD_TODO_FILE, 'wt') as json_file:
|
||||
save(todo, json_file)
|
||||
except (OSError, IOError) as save_err:
|
||||
print("Error saving {}:".format(UPLOAD_TODO_FILE), save_err)
|
||||
|
||||
|
||||
def _sha256_of_file(filename):
|
||||
hasher = sha256()
|
||||
with open(filename, 'rb') as input_file:
|
||||
hasher.update(input_file.read())
|
||||
file_hash = hasher.hexdigest()
|
||||
print('sha256({}) = {}'.format(filename, file_hash))
|
||||
return file_hash
|
||||
|
||||
|
||||
def _delete_file_quietly(filename):
|
||||
try:
|
||||
_delete_file(filename)
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
|
||||
|
||||
def mark_needs_uploading(cache_name):
|
||||
with todo_file() as todo:
|
||||
todo[cache_name] = True
|
||||
|
||||
|
||||
def mark_uploaded(cache_name):
|
||||
with todo_file() as todo:
|
||||
todo.pop(cache_name, None)
|
||||
|
||||
|
||||
def need_to_upload(cache_name):
|
||||
with todo_file(writeback=False) as todo:
|
||||
return todo.get(cache_name, False)
|
||||
|
||||
|
||||
def _tarball_size(directory):
|
||||
kib = stat(_tarball_filename_for(directory)).st_size // BYTES_PER_MB
|
||||
return "{} MiB".format(kib)
|
||||
|
||||
|
||||
def _tarball_filename_for(directory):
|
||||
return abspath('./{}.tar.gz'.format(basename(directory)))
|
||||
|
||||
|
||||
def _create_tarball(directory):
|
||||
print("Creating tarball of {}...".format(directory))
|
||||
with timer():
|
||||
run(['tar', '-czf', _tarball_filename_for(directory), '-C', dirname(directory), basename(directory)])
|
||||
|
||||
|
||||
def _extract_tarball(directory):
|
||||
print("Extracting tarball of {}...".format(directory))
|
||||
with timer():
|
||||
run(['tar', '-xzf', _tarball_filename_for(directory), '-C', dirname(directory)])
|
||||
|
||||
|
||||
def download(directory):
|
||||
mark_uploaded(cache_name) # reset
|
||||
try:
|
||||
print("Downloading {} tarball from S3...".format(cache_name))
|
||||
with timer():
|
||||
key.get_contents_to_filename(_tarball_filename_for(directory))
|
||||
except S3ResponseError as err:
|
||||
mark_needs_uploading(cache_name)
|
||||
raise SystemExit("Cached {} download failed!".format(cache_name))
|
||||
print("Downloaded {}.".format(_tarball_size(directory)))
|
||||
_extract_tarball(directory)
|
||||
print("{} successfully installed from cache.".format(cache_name))
|
||||
|
||||
|
||||
def upload(directory):
|
||||
_create_tarball(directory)
|
||||
print("Uploading {} tarball to S3... ({})".format(cache_name, _tarball_size(directory)))
|
||||
with timer():
|
||||
key.set_contents_from_filename(_tarball_filename_for(directory))
|
||||
print("{} cache successfully updated.".format(cache_name))
|
||||
mark_uploaded(cache_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Uses environment variables:
|
||||
# AWS_ACCESS_KEY_ID -- AWS Access Key ID
|
||||
# AWS_SECRET_ACCESS_KEY -- AWS Secret Access Key
|
||||
argv.pop(0)
|
||||
if len(argv) != 2:
|
||||
raise SystemExit("USAGE: s3_cache.py <download | upload> <cache name>")
|
||||
mode, cache_name = argv
|
||||
script_dir = dirname(realpath(__file__))
|
||||
chdir(script_dir)
|
||||
try:
|
||||
with open(CONFIG_FILE, 'rt') as config_file:
|
||||
config = load(config_file)
|
||||
except (IOError, OSError, ValueError) as config_err:
|
||||
print(config_err)
|
||||
raise SystemExit("Error when trying to load config from JSON file!")
|
||||
|
||||
try:
|
||||
cache_info = config[cache_name]
|
||||
key_file = expandvars(cache_info["key"])
|
||||
fallback_cmd = cache_info["generate"]
|
||||
directory = expandvars(cache_info["cache"])
|
||||
except (TypeError, KeyError) as load_err:
|
||||
print(load_err)
|
||||
raise SystemExit("Config for cache named {!r} is missing or malformed!".format(cache_name))
|
||||
|
||||
try:
|
||||
try:
|
||||
BUCKET_NAME = environ['TWBS_S3_BUCKET']
|
||||
except KeyError:
|
||||
raise SystemExit("TWBS_S3_BUCKET environment variable not set!")
|
||||
|
||||
conn = S3Connection()
|
||||
bucket = conn.lookup(BUCKET_NAME)
|
||||
if bucket is None:
|
||||
raise SystemExit("Could not access bucket!")
|
||||
|
||||
key_file_hash = _sha256_of_file(key_file)
|
||||
|
||||
key = Key(bucket, key_file_hash)
|
||||
key.storage_class = 'REDUCED_REDUNDANCY'
|
||||
|
||||
if mode == 'download':
|
||||
download(directory)
|
||||
elif mode == 'upload':
|
||||
if need_to_upload(cache_name):
|
||||
upload(directory)
|
||||
else:
|
||||
print("No need to upload anything.")
|
||||
else:
|
||||
raise SystemExit("Unrecognized mode {!r}".format(mode))
|
||||
except BaseException as exc:
|
||||
if mode != 'download':
|
||||
raise
|
||||
print("Error!:", exc)
|
||||
print("Unable to download from cache.")
|
||||
print("Running fallback command to generate cache directory {!r}: {}".format(directory, fallback_cmd))
|
||||
with timer():
|
||||
run(fallback_cmd, shell=True)
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2011-2014 Twitter, Inc.
|
||||
# Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
set -e
|
||||
cd .. # /bootlint/
|
||||
cp test-infra/npm-shrinkwrap.json npm-shrinkwrap.json
|
||||
# npm is flaky, so try multiple times
|
||||
MAXTRIES=3
|
||||
TRIES=1
|
||||
while ! npm install; do
|
||||
if [ $TRIES -ge $MAXTRIES ]; then
|
||||
exit 1
|
||||
fi
|
||||
TRIES=$(($TRIES + 1))
|
||||
echo "Retrying npm install (Try $TRIES of $MAXTRIES)..."
|
||||
done
|
||||
rm npm-shrinkwrap.json
|
Загрузка…
Ссылка в новой задаче