wandb
/
noxfile.py
366 строк · 11.7 Кб
1import os2import platform3from typing import Callable, List4
5import nox6
7CORE_VERSION = "0.17.0b9"8
9
10@nox.session(python=False, name="build-rust")11def build_rust(session: nox.Session) -> None:12"""Builds the wandb-core wheel with maturin."""13with session.chdir("client"):14session.run(15"maturin",16"build",17"--release",18"--strip",19external=True,20)21
22
23@nox.session(python=False, name="install")24def install(session: nox.Session) -> None:25# find latest wheel file in ./target/wheels/:26wheel_file = [27f
28for f in os.listdir("./client/target/wheels/")29if f.startswith(f"wandb_core-{CORE_VERSION}") and f.endswith(".whl")30][0]31session.run(32"pip",33"install",34"--force-reinstall",35f"./client/target/wheels/{wheel_file}",36external=True,37)38
39
40@nox.session(python=False, name="develop")41def develop(session: nox.Session) -> None:42with session.chdir("client"):43session.run(44"maturin",45"develop",46"--release",47"--strip",48external=True,49)50
51
52@nox.session(python=False, name="list-failing-tests-wandb-core")53def list_failing_tests_wandb_core(session: nox.Session) -> None:54"""Lists the core failing tests grouped by feature."""55import pandas as pd56import pytest57
58class MyPlugin:59def __init__(self):60self.collected = []61self.features = []62
63def pytest_collection_modifyitems(self, items):64for item in items:65marks = item.own_markers66for mark in marks:67if mark.name == "wandb_core_failure":68self.collected.append(item.nodeid)69self.features.append(70{71"name": item.nodeid,72"feature": mark.kwargs.get("feature", "unspecified"),73}74)75
76def pytest_collection_finish(self):77session.log("\n\nFailing tests grouped by feature:")78df = pd.DataFrame(self.features)79for feature, group in df.groupby("feature"):80session.log(f"\n{feature}:")81for name in group["name"]:82session.log(f" {name}")83
84my_plugin = MyPlugin()85pytest.main(86[87"-m",88"wandb_core_failure",89"tests/pytest_tests/system_tests/test_core",90"--collect-only",91],92plugins=[my_plugin],93)94
95
96@nox.session(python=False, name="build-apple-stats-monitor")97def build_apple_stats_monitor(session: nox.Session) -> None:98"""Builds the apple stats monitor binary for the current platform.99
100The binary will be located in
101core/pkg/monitor/apple/.build/<arch>-apple-macosx/release/AppleStats
102"""
103with session.chdir("core/pkg/monitor/apple"):104session.run(105"swift",106"build",107"--configuration",108"release",109"-Xswiftc",110"-cross-module-optimization",111external=True,112)113# copy the binary to core/pkg/monitor/apple/AppleStats114session.run(115"cp",116f".build/{platform.machine().lower()}-apple-macosx/release/AppleStats",117"AppleStats",118)119
120
121@nox.session(python=False, name="graphql-codegen-schema-change")122def graphql_codegen_schema_change(session: nox.Session) -> None:123"""Runs the GraphQL codegen script and saves the previous api version.124
125This will save the current generated go graphql code gql_gen.go
126in core/internal/gql/v[n+1]/gql_gen.go, run the graphql codegen script,
127and save the new generated go graphql code as core/internal/gql/gql_gen.go.
128The latter will always point to the latest api version, while the versioned
129gql_gen.go files can be used in versioning your GraphQL API requests,
130for example when communicating with an older server.
131
132Should use whenether there is a schema change on the Server side that
133affects your GraphQL API. Do not use this if there is no schema change
134and you are e.g. just adding a new query or mutation
135against the schema that already supports it.
136"""
137session.run(138"./core/scripts/generate-graphql.sh",139"--schema-change",140external=True,141)142
143
144@nox.session(python=False, name="local-testcontainer-registry")145def local_testcontainer_registry(session: nox.Session) -> None:146"""Ensure we collect and store the latest local-testcontainer in the registry.147
148This will find the latest released version (tag) of wandb/core,
149find associated commit hash, and then pull the local-testcontainer
150image with the same commit hash from
151us-central1-docker.pkg.dev/wandb-production/images/local-testcontainer
152and push it to the SDK's registry with the release tag,
153if it doesn't already exist there.
154
155To run locally, you must have the following environment variables set:
156- GITHUB_ACCESS_TOKEN: a GitHub personal access token with the repo scope
157- GOOGLE_APPLICATION_CREDENTIALS: path to a service account key file
158or a JSON string containing the key file contents
159
160To run this for a specific release tag, use:
161nox -s local-testcontainer-registry -- <release_tag>
162"""
163tags: List[str] = session.posargs or []164
165import subprocess166
167def query_github(payload: dict[str, str]) -> dict[str, str]:168import json169
170import requests171
172headers = {173"Authorization": f"bearer {os.environ['GITHUB_ACCESS_TOKEN']}",174"Content-Type": "application/json",175}176
177url = "https://api.github.com/graphql"178response = requests.post(url, headers=headers, data=json.dumps(payload))179data = response.json()180
181return data182
183def get_release_tag_and_commit_hash(tags: List[str]):184if not tags:185# Get the latest release tag and commit hash186query = """187{
188repository(owner: "wandb", name: "core") {
189latestRelease {
190tagName
191tagCommit {
192oid
193}
194}
195}
196}
197"""
198payload = {"query": query}199
200data = query_github(payload)201
202return (203data["data"]["repository"]["latestRelease"]["tagName"],204data["data"]["repository"]["latestRelease"]["tagCommit"]["oid"],205)206else:207# Get the commit hash for the given release tag208query = """209query($owner: String!, $repo: String!, $tag: String!) {
210repository(owner: $owner, name: $repo) {
211ref(qualifiedName: $tag) {
212target {
213oid
214}
215}
216}
217}
218"""
219# TODO: allow passing multiple tags?220variables = {"owner": "wandb", "repo": "core", "tag": tags[0]}221payload = {"query": query, "variables": variables}222
223data = query_github(payload)224
225return tags[0], data["data"]["repository"]["ref"]["target"]["oid"]226
227local_release_tag, commit_hash = get_release_tag_and_commit_hash(tags)228
229release_tag = local_release_tag.removeprefix("local/v")230session.log(f"Release tag: {release_tag}")231session.log(f"Commit hash: {commit_hash}")232
233if not release_tag or not commit_hash:234session.error("Failed to get release tag or commit hash.")235
236subprocess.check_call(["gcloud", "config", "set", "project", "wandb-client-cicd"])237
238# Check if image with tag already exists in the SDK's Artifact registry239images = (240subprocess.Popen(241[242"gcloud",243"artifacts",244"docker",245"tags",246"list",247"us-central1-docker.pkg.dev/wandb-client-cicd/images/local-testcontainer",248],249stdout=subprocess.PIPE,250)251.communicate()[0]252.decode()253.split("\n")254)255images = [img for img in images if img]256
257if any(release_tag in img for img in images):258session.warn(f"Image with tag {release_tag} already exists.")259return260
261source_image = f"us-central1-docker.pkg.dev/wandb-production/images/local-testcontainer:{commit_hash}"262target_image = f"us-central1-docker.pkg.dev/wandb-client-cicd/images/local-testcontainer:{release_tag}"263
264# install gcrane: `go install github.com/google/go-containerregistry/cmd/gcrane@latest`265subprocess.check_call(["gcrane", "cp", source_image, target_image])266
267session.log(f"Successfully copied image {target_image}")268
269
270@nox.session(python=False, name="bump-core-version")271def bump_core_version(session: nox.Session) -> None:272args = session.posargs273if not args:274session.log("Usage: nox -s bump-core-version -- <args>\n")275# Examples:276session.log(277"For example, to bump from 0.17.0b8/0.17.0-beta.8 to 0.17.0b9/0.17.0-beta.9:"278)279session.log("nox -s bump-core-version -- pre")280return281
282for cfg in (".bumpversion.core.cfg", ".bumpversion.cargo.cfg"):283session.run(284"bump2version",285"--config-file",286cfg,287*args,288)289
290
291@nox.session(python=False, name="proto-go")292def proto_go(session: nox.Session) -> None:293"""Generate Go bindings for protobufs."""294_generate_proto_go(session)295
296
297def _generate_proto_go(session: nox.Session) -> None:298session.run("./core/scripts/generate-proto.sh", external=True)299
300
301@nox.session(name="proto-python")302@nox.parametrize("pb", [3, 4])303def proto_python(session: nox.Session, pb: int) -> None:304"""Generate Python bindings for protobufs.305
306The pb argument is the major version of the protobuf package to use.
307
308Tested with Python 3.10 on a Mac with an M1 chip.
309Absolutely does not work with Python 3.7.
310"""
311_generate_proto_python(session, pb=pb)312
313
314def _generate_proto_python(session: nox.Session, pb: int) -> None:315if pb == 3:316session.install("protobuf~=3.20.3")317session.install("mypy-protobuf~=3.3.0")318session.install("grpcio~=1.48.0")319session.install("grpcio-tools~=1.48.0")320elif pb == 4:321session.install("protobuf~=4.23.4")322session.install("mypy-protobuf~=3.5.0")323session.install("grpcio~=1.50.0")324session.install("grpcio-tools~=1.50.0")325else:326session.error("Invalid protobuf version given. `pb` must be 3 or 4.")327
328session.install("-r", "requirements_build.txt")329session.install(".")330
331with session.chdir("wandb/proto"):332session.run("python", "wandb_internal_codegen.py")333
334
335def _ensure_no_diff(336session: nox.Session,337after: Callable[[], None],338in_directory: str,339) -> None:340"""Fails if the callable modifies the directory."""341saved = session.create_tmp()342session.run("cp", "-r", in_directory, saved, external=True)343after()344session.run("diff", in_directory, saved, external=True)345session.run("rm", "-rf", saved, external=True)346
347
348@nox.session(name="proto-check-python", tags=["proto-check"])349@nox.parametrize("pb", [3, 4])350def proto_check_python(session: nox.Session, pb: int) -> None:351"""Regenerates Python protobuf files and ensures nothing changed."""352_ensure_no_diff(353session,354after=lambda: _generate_proto_python(session, pb=pb),355in_directory=f"wandb/proto/v{pb}/.",356)357
358
359@nox.session(name="proto-check-go", tags=["proto-check"])360def proto_check_go(session: nox.Session) -> None:361"""Regenerates Go protobuf files and ensures nothing changed."""362_ensure_no_diff(363session,364after=lambda: _generate_proto_go(session),365in_directory="core/pkg/service/.",366)367