mirror of https://github.com/docker/compose.git
commit
0898c783ad
|
@ -1,6 +1,14 @@
|
|||
Change log
|
||||
==========
|
||||
|
||||
1.21.2 (2018-05-03)
|
||||
-------------------
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- Fixed a bug where the ip_range attirbute in IPAM configs was prevented
|
||||
from passing validation
|
||||
|
||||
1.21.1 (2018-04-27)
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
__version__ = '1.21.1'
|
||||
__version__ = '1.21.2'
|
||||
|
|
|
@ -311,7 +311,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"subnet": {"type": "string"},
|
||||
"iprange": {"type": "string"},
|
||||
"ip_range": {"type": "string"},
|
||||
"gateway": {"type": "string"},
|
||||
"aux_addresses": {
|
||||
"type": "object",
|
||||
|
|
|
@ -365,7 +365,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"subnet": {"type": "string"},
|
||||
"iprange": {"type": "string"},
|
||||
"ip_range": {"type": "string"},
|
||||
"gateway": {"type": "string"},
|
||||
"aux_addresses": {
|
||||
"type": "object",
|
||||
|
|
|
@ -374,7 +374,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"subnet": {"type": "string"},
|
||||
"iprange": {"type": "string"},
|
||||
"ip_range": {"type": "string"},
|
||||
"gateway": {"type": "string"},
|
||||
"aux_addresses": {
|
||||
"type": "object",
|
||||
|
|
|
@ -418,7 +418,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"subnet": {"type": "string"},
|
||||
"iprange": {"type": "string"},
|
||||
"ip_range": {"type": "string"},
|
||||
"gateway": {"type": "string"},
|
||||
"aux_addresses": {
|
||||
"type": "object",
|
||||
|
|
|
@ -417,7 +417,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"subnet": {"type": "string"},
|
||||
"iprange": {"type": "string"},
|
||||
"ip_range": {"type": "string"},
|
||||
"gateway": {"type": "string"},
|
||||
"aux_addresses": {
|
||||
"type": "object",
|
||||
|
|
|
@ -44,16 +44,10 @@ virtualenv .\venv
|
|||
# pip and pyinstaller generate lots of warnings, so we need to ignore them
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
# Install dependencies
|
||||
# Fix for https://github.com/pypa/pip/issues/3964
|
||||
# Remove-Item -Recurse -Force .\venv\Lib\site-packages\pip
|
||||
# .\venv\Scripts\easy_install pip==9.0.1
|
||||
# .\venv\Scripts\pip install --upgrade pip setuptools
|
||||
# End fix
|
||||
.\venv\Scripts\pip install pypiwin32==220
|
||||
.\venv\Scripts\pip install -r requirements.txt
|
||||
.\venv\Scripts\pip install --no-deps .
|
||||
.\venv\Scripts\pip install --allow-external pyinstaller -r requirements-build.txt
|
||||
.\venv\Scripts\pip install -r requirements-build.txt
|
||||
|
||||
git rev-parse --short HEAD | out-file -encoding ASCII compose\GITSHA
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ RUN mkdir -p /src && pip install -U Jinja2==2.10 \
|
|||
PyGithub==1.39 \
|
||||
pypandoc==1.4 \
|
||||
GitPython==2.1.9 \
|
||||
requests==2.18.4 && \
|
||||
requests==2.18.4 \
|
||||
twine==1.11.0 && \
|
||||
apt-get update && apt-get install -y pandoc
|
||||
|
||||
VOLUME /src/script/release
|
||||
|
|
|
@ -27,6 +27,7 @@ from release.utils import ScriptError
|
|||
from release.utils import update_init_py_version
|
||||
from release.utils import update_run_sh_version
|
||||
from release.utils import yesno
|
||||
from twine.commands.upload import main as twine_upload
|
||||
|
||||
|
||||
def create_initial_branch(repository, args):
|
||||
|
@ -78,10 +79,9 @@ def monitor_pr_status(pr_data):
|
|||
continue
|
||||
summary[detail.state] += 1
|
||||
print('{pending} pending, {success} successes, {failure} failures'.format(**summary))
|
||||
if status.total_count == 0:
|
||||
# Mostly for testing purposes against repos with no CI setup
|
||||
return True
|
||||
elif summary['pending'] == 0 and summary['failure'] == 0:
|
||||
if summary['pending'] == 0 and summary['failure'] == 0 and summary['success'] > 0:
|
||||
# This check assumes at least 1 non-DCO CI check to avoid race conditions.
|
||||
# If testing on a repo without CI, use --skip-ci-check to avoid looping eternally
|
||||
return True
|
||||
elif summary['failure'] > 0:
|
||||
raise ScriptError('CI failures detected!')
|
||||
|
@ -156,6 +156,7 @@ def resume(args):
|
|||
if not pr_data:
|
||||
pr_data = repository.create_release_pull_request(args.release)
|
||||
check_pr_mergeable(pr_data)
|
||||
if not args.skip_ci:
|
||||
monitor_pr_status(pr_data)
|
||||
downloader = BinaryDownloader(args.destination)
|
||||
files = downloader.download_all(args.release)
|
||||
|
@ -195,6 +196,7 @@ def start(args):
|
|||
create_initial_branch(repository, args)
|
||||
pr_data = repository.create_release_pull_request(args.release)
|
||||
check_pr_mergeable(pr_data)
|
||||
if not args.skip_ci:
|
||||
monitor_pr_status(pr_data)
|
||||
downloader = BinaryDownloader(args.destination)
|
||||
files = downloader.download_all(args.release)
|
||||
|
@ -239,8 +241,8 @@ def finalize(args):
|
|||
if not merge_status.merged:
|
||||
raise ScriptError('Unable to merge PR #{}: {}'.format(pr_data.number, merge_status.message))
|
||||
print('Uploading to PyPi')
|
||||
run_setup(os.path.join(REPO_ROOT, 'setup.py'), script_args=['upload'])
|
||||
img_manager.push_images(args.release)
|
||||
twine_upload(['dist/*'])
|
||||
img_manager.push_images()
|
||||
repository.publish_release(gh_release)
|
||||
except ScriptError as e:
|
||||
print(e)
|
||||
|
@ -310,6 +312,10 @@ def main():
|
|||
'--no-cherries', '-C', dest='cherries', action='store_false',
|
||||
help='If set, the program will not prompt the user for PR numbers to cherry-pick'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--skip-ci-checks', dest='skip_ci', action='store_true',
|
||||
help='If set, the program will not wait for CI jobs to complete'
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.action == 'start':
|
||||
|
|
|
@ -19,6 +19,7 @@ docker run -e GITHUB_TOKEN=$GITHUB_TOKEN -e BINTRAY_TOKEN=$BINTRAY_TOKEN -it \
|
|||
--mount type=bind,source=$(pwd),target=/src \
|
||||
--mount type=bind,source=$(pwd)/.git,target=/src/.git \
|
||||
--mount type=bind,source=$HOME/.docker,target=/root/.docker \
|
||||
--mount type=bind,source=$HOME/.gitconfig,target=/root/.gitconfig \
|
||||
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
|
||||
--mount type=bind,source=$HOME/.ssh,target=/root/.ssh \
|
||||
-v $HOME/.pypirc:/root/.pypirc \
|
||||
|
|
|
@ -23,6 +23,7 @@ class ImageManager(object):
|
|||
distdir = os.path.join(REPO_ROOT, 'dist')
|
||||
os.makedirs(distdir, exist_ok=True)
|
||||
shutil.copy(files['docker-compose-Linux-x86_64'][0], distdir)
|
||||
os.chmod(os.path.join(distdir, 'docker-compose-Linux-x86_64'), 0o755)
|
||||
print('Building docker/compose image')
|
||||
logstream = docker_client.build(
|
||||
REPO_ROOT, tag='docker/compose:{}'.format(self.version), dockerfile='Dockerfile.run',
|
||||
|
|
|
@ -196,6 +196,24 @@ class Repository(object):
|
|||
f.flush()
|
||||
self.git_repo.git.am('--3way', f.name)
|
||||
|
||||
def get_prs_in_milestone(self, version):
|
||||
milestones = self.gh_repo.get_milestones(state='open')
|
||||
milestone = None
|
||||
for ms in milestones:
|
||||
if ms.title == version:
|
||||
milestone = ms
|
||||
break
|
||||
if not milestone:
|
||||
print('Didn\'t find a milestone matching "{}"'.format(version))
|
||||
return None
|
||||
|
||||
issues = self.gh_repo.get_issues(milestone=milestone, state='all')
|
||||
prs = []
|
||||
for issue in issues:
|
||||
if issue.pull_request is not None:
|
||||
prs.append(issue.number)
|
||||
return sorted(prs)
|
||||
|
||||
|
||||
def get_contributors(pr_data):
|
||||
commits = pr_data.get_commits()
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
VERSION="1.21.1"
|
||||
VERSION="1.21.2"
|
||||
IMAGE="docker/compose:$VERSION"
|
||||
|
||||
|
||||
|
|
|
@ -1344,6 +1344,38 @@ class ConfigTest(unittest.TestCase):
|
|||
assert ('networks.foo.ipam.config contains an invalid type,'
|
||||
' it should be an object') in excinfo.exconly()
|
||||
|
||||
def test_config_valid_ipam_config(self):
|
||||
ipam_config = {
|
||||
'subnet': '172.28.0.0/16',
|
||||
'ip_range': '172.28.5.0/24',
|
||||
'gateway': '172.28.5.254',
|
||||
'aux_addresses': {
|
||||
'host1': '172.28.1.5',
|
||||
'host2': '172.28.1.6',
|
||||
'host3': '172.28.1.7',
|
||||
},
|
||||
}
|
||||
networks = config.load(
|
||||
build_config_details(
|
||||
{
|
||||
'version': str(V2_1),
|
||||
'networks': {
|
||||
'foo': {
|
||||
'driver': 'default',
|
||||
'ipam': {
|
||||
'driver': 'default',
|
||||
'config': [ipam_config],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
filename='filename.yml',
|
||||
)
|
||||
).networks
|
||||
|
||||
assert 'foo' in networks
|
||||
assert networks['foo']['ipam']['config'] == [ipam_config]
|
||||
|
||||
def test_config_valid_service_names(self):
|
||||
for valid_name in ['_', '-', '.__.', '_what-up.', 'what_.up----', 'whatup']:
|
||||
services = config.load(
|
||||
|
|
Loading…
Reference in New Issue