deploydocs.py 6.53 KB
Newer Older
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Deployment utilities for sphinx documentation via webDAV.

Requires you ``pip install webdavclient3``
"""


import os
import sys
import logging

logger = logging.getLogger("deploy")

_SERVER = "http://www.idiap.ch"

_WEBDAV_PATHS = {
    True: {  # stable?
        False: {  # visible?
            "root": "/private-upload",
            "conda": "/conda",
            "docs": "/docs",
        },
        True: {  # visible?
            "root": "/public-upload",
            "conda": "/conda",
            "docs": "/docs",
        },
    },
    False: {  # stable?
        False: {  # visible?
            "root": "/private-upload",
            "conda": "/conda/label/beta",
            "docs": "/docs",
        },
        True: {  # visible?
            "root": "/public-upload",
            "conda": "/conda/label/beta",
            "docs": "/docs",
        },
    },
}
"""Default locations of our webdav upload paths"""


def _setup_webdav_client(server, root, username, password):
    """Configures and checks the webdav client."""

    # setup webdav connection
    webdav_options = dict(
        webdav_hostname=server,
        webdav_root=root,
        webdav_login=username,
        webdav_password=password,
    )

    from webdav3.client import Client

    retval = Client(webdav_options)
    assert retval.valid()

    return retval


def deploy_documentation(
    path,
    package,
    stable,
    latest,
    public,
    branch,
    tag,
    username,
    password,
    dry_run,
):
    """Deploys sphinx documentation to the appropriate webdav locations.

    Parameters
    ==========

    path : str
        Path leading to the root of the documentation to be deployed

    package : str
        Full name (with namespace) of the package being treated

    stable : bool
        Indicates if the documentation corresponds to the latest stable build

    latest : bool
        Indicates if the documentation being deployed correspond to the latest
        stable for the package or not.  In case the documentation comes from a
        patch release which is not on the master branch, please set this flag
        to ``False``, which will make us avoid deployment of the documentation
        to ``master`` and ``stable`` sub-directories.

    public : bool
        Indicates if the documentation is supposed to be distributed publicly
        or privatly (within Idiap network)

    branch : str
        The name of the branch for the current build

    tag : str
        The name of the tag currently built (may be ``None``)

    username : str
        The name of the user on the webDAV server to use for uploading the
        package

    password : str
        The password of the user on the webDAV server to use for uploading the
        package

    dry_run : bool
        If we're supposed to really do the actions, or just log messages.

    """

    # uploads documentation artifacts
    if not os.path.exists(path):
        raise RuntimeError(
            "Documentation is not available at %s - "
            "ensure documentation is being produced for your project!" % path
        )

    server_info = _WEBDAV_PATHS[stable][public]
    davclient = _setup_webdav_client(
        _SERVER, server_info["root"], username, password
    )

    remote_path_prefix = "%s/%s" % (server_info["docs"], package)

    # finds out the correct mixture of sub-directories we should deploy to.
    # 1. if ref-name is a tag, don't forget to publish to 'master' as well -
    # all tags are checked to come from that branch
    # 2. if ref-name is a branch name, deploy to it
    # 3. in case a tag is being published, make sure to deploy to the special
    # "stable" subdir as well
    deploy_docs_to = set([branch])
    if stable:
        if tag is not None:
            deploy_docs_to.add(tag)
        if latest:
            deploy_docs_to.add("master")
            deploy_docs_to.add("stable")

    # creates package directory, and then uploads directory there
    for k in deploy_docs_to:
        if not davclient.check(remote_path_prefix):  # base package directory
            logger.info("[dav] mkdir %s", remote_path_prefix)
            if not dry_run:
                davclient.mkdir(remote_path_prefix)
        remote_path = "%s/%s" % (remote_path_prefix, k)
        logger.info(
            "[dav] %s -> %s%s%s",
            path,
            _SERVER,
            server_info["root"],
            remote_path,
        )
        if not dry_run:
            davclient.upload_directory(local_path=path, remote_path=remote_path)


if __name__ == "__main__":

    import argparse

    parser = argparse.ArgumentParser(
        description="Deploys documentation from python-only packages"
    )
    parser.add_argument(
        "directory",
        help="Directory containing the sphinx build to deploy",
    )
    parser.add_argument(
        "-p",
        "--package",
        default=os.environ.get("CI_PROJECT_PATH", None),
        help="The package being built [default: %(default)s]",
    )
    parser.add_argument(
        "-x",
        "--visibility",
        default=os.environ.get("CI_PROJECT_VISIBILITY", "private"),
        help="The visibility of the package being built [default: %(default)s]",
    )
    parser.add_argument(
        "-b",
        "--branch",
        default=os.environ.get("CI_COMMIT_REF_NAME", None),
        help="Name of the branch being built [default: %(default)s]",
    )
    parser.add_argument(
        "-t",
        "--tag",
        default=os.environ.get("CI_COMMIT_TAG", None),
        help="If building a tag, pass it with this flag [default: %(default)s]",
    )
    parser.add_argument(
        "-u",
        "--username",
        default=os.environ.get("DOCUSER", None),
        help="Username for webdav deployment [default: %(default)s]",
    )
    parser.add_argument(
        "-P",
        "--password",
        default=os.environ.get("DOCPASS", None),
        help="Password for webdav deployment [default: %(default)s]",
    )
    parser.add_argument(
        "-v",
        "--verbose",
        help="Be verbose (enables INFO logging)",
        action="store_const",
        dest="loglevel",
        default=logging.WARNING,
        const=logging.INFO,
    )

    args = parser.parse_args()
    logging.basicConfig(level=args.loglevel)

    deploy_documentation(
        args.directory,
        package=args.package,
        stable=(args.tag is not None),
        latest=True,
        public=(args.visibility == "public"),
        branch=args.branch,
        tag=args.tag,
        username=args.username,
        password=args.password,
        dry_run=False,
    )