1import io
2from pathlib import Path
3
4import pytest
5
6from release import cibuild
7
8root = Path(__file__).parent.parent.parent
9
10
11def test_buildenviron_live():
12    be = cibuild.BuildEnviron.from_env()
13    assert be.release_dir
14
15
16def test_buildenviron_common():
17    be = cibuild.BuildEnviron(
18        system="Linux",
19        root_dir=root,
20        branch="main",
21    )
22    assert be.release_dir == be.root_dir / "release"
23    assert be.dist_dir == be.root_dir / "release" / "dist"
24    assert be.build_dir == be.root_dir / "release" / "build"
25    assert not be.has_docker_creds
26
27    cs = io.StringIO()
28    be.dump_info(cs)
29    assert cs.getvalue()
30
31    be = cibuild.BuildEnviron(
32        system="Unknown",
33        root_dir=root,
34    )
35    with pytest.raises(cibuild.BuildError):
36        be.version
37    with pytest.raises(cibuild.BuildError):
38        be.platform_tag
39
40
41def test_buildenviron_pr(monkeypatch):
42    # Simulates a PR. We build everything, but don't have access to secret
43    # credential env variables.
44    monkeypatch.setenv("GITHUB_REF", "refs/pull/42/merge")
45    monkeypatch.setenv("CI_BUILD_WHEEL", "1")
46    monkeypatch.setenv("GITHUB_EVENT_NAME", "pull_request")
47
48    be = cibuild.BuildEnviron.from_env()
49    assert be.branch == "pr-42"
50    assert be.is_pull_request
51    assert be.should_build_wheel
52    assert not be.should_upload_pypi
53
54
55def test_buildenviron_commit():
56    # Simulates an ordinary commit on the master branch.
57    be = cibuild.BuildEnviron(
58        system="Linux",
59        root_dir=root,
60        branch="main",
61        is_pull_request=False,
62        should_build_wheel=True,
63        should_build_pyinstaller=True,
64        should_build_docker=True,
65        docker_username="foo",
66        docker_password="bar",
67        has_aws_creds=True,
68    )
69    assert be.docker_tag == "mitmproxy/mitmproxy:dev"
70    assert be.should_upload_docker
71    assert not be.should_upload_pypi
72    assert be.should_upload_docker
73    assert be.should_upload_aws
74    assert not be.is_prod_release
75    assert not be.is_maintenance_branch
76
77
78def test_buildenviron_releasetag():
79    # Simulates a tagged release on a release branch.
80    be = cibuild.BuildEnviron(
81        system="Linux",
82        root_dir=root,
83        tag="v0.0.1",
84        should_build_wheel=True,
85        should_build_docker=True,
86        should_build_pyinstaller=True,
87        has_twine_creds=True,
88        docker_username="foo",
89        docker_password="bar",
90    )
91    assert be.tag == "v0.0.1"
92    assert be.branch is None
93    assert be.version == "0.0.1"
94    assert be.upload_dir == "0.0.1"
95    assert be.docker_tag == "mitmproxy/mitmproxy:0.0.1"
96    assert be.should_upload_pypi
97    assert be.should_upload_docker
98    assert be.is_prod_release
99    assert not be.is_maintenance_branch
100
101
102def test_buildenviron_namedtag():
103    # Simulates a non-release tag on a branch.
104    be = cibuild.BuildEnviron(
105        system="Linux",
106        root_dir=root,
107        tag="anyname",
108        should_build_wheel=True,
109        should_build_docker=True,
110        should_build_pyinstaller=True,
111        has_twine_creds=True,
112        docker_username="foo",
113        docker_password="bar",
114    )
115    assert be.tag == "anyname"
116    assert be.branch is None
117    assert be.version == "anyname"
118    assert be.upload_dir == "anyname"
119    assert be.docker_tag == "mitmproxy/mitmproxy:anyname"
120    assert not be.should_upload_pypi
121    assert not be.should_upload_docker
122    assert not be.is_prod_release
123    assert not be.is_maintenance_branch
124
125
126def test_buildenviron_dev_branch():
127    # Simulates a commit on a development branch on the main repo
128    be = cibuild.BuildEnviron(
129        system="Linux",
130        root_dir=root,
131        branch="mybranch",
132        should_build_wheel=True,
133        should_build_docker=True,
134        should_build_pyinstaller=True,
135        has_twine_creds=True,
136        docker_username="foo",
137        docker_password="bar",
138    )
139    assert be.tag is None
140    assert be.branch == "mybranch"
141    assert be.version == "mybranch"
142    assert be.upload_dir == "branches/mybranch"
143    assert not be.should_upload_pypi
144    assert not be.should_upload_docker
145    assert not be.is_maintenance_branch
146
147
148def test_buildenviron_maintenance_branch():
149    # Simulates a commit on a release maintenance branch on the main repo
150    be = cibuild.BuildEnviron(
151        system="Linux",
152        root_dir=root,
153        branch="v0.x",
154        should_build_wheel=True,
155        should_build_docker=True,
156        should_build_pyinstaller=True,
157        has_twine_creds=True,
158        docker_username="foo",
159        docker_password="bar",
160    )
161    assert be.tag is None
162    assert be.branch == "v0.x"
163    assert be.version == "v0.x"
164    assert be.upload_dir == "branches/v0.x"
165    assert not be.should_upload_pypi
166    assert not be.should_upload_docker
167    assert be.is_maintenance_branch
168
169
170def test_buildenviron_osx(tmp_path):
171    be = cibuild.BuildEnviron(
172        system="Darwin",
173        root_dir=root,
174        tag="v0.0.1",
175    )
176    assert be.platform_tag == "osx"
177    assert be.archive_path == be.dist_dir / "mitmproxy-0.0.1-osx.tar.gz"
178
179    with be.archive(tmp_path / "arch"):
180        pass
181    assert (tmp_path / "arch").exists()
182
183
184def test_buildenviron_windows(tmp_path):
185    be = cibuild.BuildEnviron(
186        system="Windows",
187        root_dir=root,
188        tag="v0.0.1",
189    )
190    assert be.platform_tag == "windows"
191    assert be.archive_path == be.dist_dir / "mitmproxy-0.0.1-windows.zip"
192
193    with be.archive(tmp_path / "arch"):
194        pass
195    assert (tmp_path / "arch").exists()
196
197
198@pytest.mark.parametrize("version, tag, ok", [
199    ("3.0.0.dev", "", True),  # regular snapshot
200    ("3.0.0.dev", "v3.0.0", False),  # forgot to remove ".dev" on bump
201    ("3.0.0", "", False),  # forgot to re-add ".dev"
202    ("3.0.0", "v4.0.0", False),  # version mismatch
203    ("3.0.0", "v3.0.0", True),  # regular release
204    ("3.0.0.rc1", "v3.0.0.rc1", False),  # non-canonical.
205    ("3.0.0.dev", "anyname", True),  # tagged test/dev release
206    ("3.0.0", "3.0.0", False),  # tagged, but without v prefix
207])
208def test_buildenviron_check_version(version, tag, ok, tmpdir):
209    tmpdir.mkdir("mitmproxy").join("version.py").write(f'VERSION = "{version}"')
210
211    be = cibuild.BuildEnviron(
212        root_dir=tmpdir,
213        system="Windows",
214        tag=tag,
215    )
216    if ok:
217        be.check_version()
218    else:
219        with pytest.raises(ValueError):
220            be.check_version()
221
222
223def test_bool_from_env(monkeypatch):
224    monkeypatch.setenv("FOO", "1")
225    assert cibuild.bool_from_env("FOO")
226
227    monkeypatch.setenv("FOO", "0")
228    assert not cibuild.bool_from_env("FOO")
229
230    monkeypatch.setenv("FOO", "false")
231    assert not cibuild.bool_from_env("FOO")
232
233    monkeypatch.setenv("FOO", "")
234    assert not cibuild.bool_from_env("FOO")
235
236    monkeypatch.delenv("FOO")
237    assert not cibuild.bool_from_env("FOO")
238