-
Notifications
You must be signed in to change notification settings - Fork 104
/
deploy.py
148 lines (117 loc) · 4.61 KB
/
deploy.py
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
#! /usr/bin/env python
# Author: Abhilash Raj
#
# This is the primary deployment script for the docker-mailman repo. It does
# deployment for stable and rolling releases both. It should be *always* invoked
# and it will make the deployment decision based on the environment variables
# that it sees.
#
# There are two kinds of deploymnets primarily:
# 1. Rolling tags, which are built from each commit. These are typically run
# in CI every day as well. These always update the "rolling" tag in the
# docker registry.
# 2. Stable tags, which are built from git tags with "va.b.c" tags. We don't
# do the tag verification because for now, Circle CI does this for us. We
# will tag and release a stable version whenever the right ENV var is set.
#
# Publishing:
# We are typically publishing all the images to three repositories:
# 1. Docker Hub: This is now rate-limited and might cause issues for people
# pulling too frequently.
# 2. Quay: This is an old registry that we started publishing too, so let's
# continue publishing here too.
# 3. Github Registry: This is the newest one in the mix and supports free
# uploads and downloads (without very strict rate limits like Dockerhub.)
import os
import subprocess
from packaging import version
#: Default user, which owns the repositories.
USER = 'maxking'
TAG_VAR = 'CIRCLE_TAG'
BRANCH_VAR = 'CIRCLE_BRANCH'
PRIMARY_BRANCH = 'main'
ROLLING_VAR = "BUILD_ROLLING"
def tag(original, final):
"""Tag the source image with final tag."""
try:
print('Tagging {0} to {1}'.format(original, final))
subprocess.run(
['docker', 'tag', original, final],
check=True,
)
except subprocess.CalledProcessError:
print('Failed to tag {0}'.format(original))
def login(url):
"""Login to the registry."""
if 'quay' in url.lower():
password = os.environ['QUAY_PASSWORD']
elif 'docker' in url.lower():
password = os.environ['DOCKER_PASSWORD']
elif 'ghcr' in url.lower():
password = os.environ['GITHUB_PASSWORD']
else:
print('Password not found for {0}'.format(url))
return None
print('Logging in to {0}'.format(url))
subprocess.run(
['docker', 'login', '-u', USER, '-p', password, url],
check=True
)
print('Logged in to {0}'.format(url))
def push(image):
"""Push all the images."""
print('Pushing {}'.format(image))
subprocess.run(['docker', 'push', image], check=True)
def tag_and_push(image_names, url, img_tag):
"""Given the URL to repository, tag and push the images."""
# Tag recently built images.
source, final = image_names
tag(source, final)
# Finall, push all the images.
push(final)
def get_tag_without_patch(tag):
"""Given A.B.C return A.B"""
v = version.parse(tag)
return '{}.{}'.format(v.major, v.minor)
def get_urls(url, img_tag):
core = ('maxking/mailman-core:rolling',
'{0}/maxking/mailman-core:{1}'.format(url, img_tag))
web = ('maxking/mailman-web:rolling',
'{0}/maxking/mailman-web:{1}'.format(url, img_tag))
postorius = ('maxking/postorius:rolling',
'{0}/maxking/postorius:{1}'.format(url, img_tag))
return (core, web, postorius)
def main():
"""Primary entrypoint to this script."""
# Boolean signifying if this is a stable release tag or just a branch.
is_release = False
if os.environ.get(TAG_VAR) not in (None, ''):
img_tag = os.environ.get(TAG_VAR)
# Released versions are tagged vA.B.C, so remove
# v from the tag when creating the release.
if img_tag.startswith('v'):
img_tag = img_tag[1:]
is_release = True
elif os.environ.get(BRANCH_VAR) == PRIMARY_BRANCH and os.environ.get(ROLLING_VAR) == "yes":
img_tag = 'rolling'
else:
print('Not running on {PRIMARY_BRANCH} branch or Git tag so not publishing...'.format(
PRIMARY_BRANCH=PRIMARY_BRANCH))
exit(0)
# All the registries we are pushing to.
for url in ('quay.io', 'docker.io', 'ghcr.io'):
try:
login(url)
except subprocess.CalledProcessError:
print('Failed to login to {}'.format(url))
continue
# Push all the container images.
for each in get_urls(url, img_tag):
tag_and_push(each, url, img_tag)
# If this is a release tag, tag them also with a.b version.
if is_release:
rel_tag = get_tag_without_patch(img_tag)
for each in get_urls(url, rel_tag):
tag_and_push(each, url, rel_tag)
if __name__ == '__main__':
main()